/* Copyright 2007-2024 John Havlik (email : john.havlik@mtekk.us) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ //Do a PHP version check, require 5.6 or newer if(version_compare(phpversion(), '5.6.0', '<')) { //Only purpose of this function is to echo out the PHP version error function bcn_phpold() { printf('

' . esc_html__('Your PHP version is too old, please upgrade to a newer version. Your version is %1$s, Breadcrumb NavXT requires %2$s', 'breadcrumb-navxt') . '

', phpversion(), '5.6.0'); } //If we are in the admin, let's print a warning then return if(is_admin()) { add_action('admin_notices', 'bcn_phpold'); } return; } require_once(dirname(__FILE__) . '/includes/multibyte_supplicant.php'); //Include admin base class if(!class_exists('\mtekk\adminKit\adminKit')) { require_once(dirname(__FILE__) . '/includes/adminKit/class-mtekk_adminkit.php'); } //Include the breadcrumb class require_once(dirname(__FILE__) . '/class.bcn_breadcrumb.php'); //Include the breadcrumb trail class require_once(dirname(__FILE__) . '/class.bcn_breadcrumb_trail.php'); if(class_exists('WP_Widget')) { //Include the WP 2.8+ widget class require_once(dirname(__FILE__) . '/class.bcn_widget.php'); } use mtekk\adminKit\adminKit as adminKit; use mtekk\adminKit\setting; $breadcrumb_navxt = null; //TODO change to extends \mtekk\plugKit class breadcrumb_navxt { const version = '7.3.0'; protected $name = 'Breadcrumb NavXT'; protected $identifier = 'breadcrumb-navxt'; protected $unique_prefix = 'bcn'; protected $plugin_basename = null; protected $opt = null; protected $settings = array(); protected $breadcrumb_trail = null; protected $admin = null; protected $rest_controller = null; /** * Constructor for a new breadcrumb_navxt object * * @param bcn_breadcrumb_trail $breadcrumb_trail An instance of a bcn_breadcrumb_trail object to use for everything */ public function __construct(bcn_breadcrumb_trail $breadcrumb_trail) { //We get our breadcrumb trail object from our constructor $this->breadcrumb_trail = $breadcrumb_trail; //We set the plugin basename here $this->plugin_basename = plugin_basename(__FILE__); //We need to add in the defaults for CPTs and custom taxonomies after all other plugins are loaded add_action('wp_loaded', array($this, 'wp_loaded'), 15); add_action('rest_api_init', array($this, 'rest_api_init'), 10); //Run much later than everyone else to give other plugins a chance to hook into the filters and actions in this add_action('init', array($this, 'init'), 9000); //Register the WordPress 2.8 Widget add_action('widgets_init', array($this, 'register_widget')); //Load our network admin if in the network dashboard (yes is_network_admin() doesn't exist) if(defined('WP_NETWORK_ADMIN') && WP_NETWORK_ADMIN) { require_once(dirname(__FILE__) . '/class.bcn_network_admin.php'); //Instantiate our new admin object $this->admin = new bcn_network_admin($this->breadcrumb_trail->opt, $this->plugin_basename, $this->settings); } //Load our main admin if in the dashboard, but only if we're not in the network dashboard (prevents goofy bugs) else if(is_admin() || defined('WP_UNINSTALL_PLUGIN')) { require_once(dirname(__FILE__) . '/class.bcn_admin.php'); //Instantiate our new admin object $this->admin = new bcn_admin($this->breadcrumb_trail->opt, $this->plugin_basename, $this->settings); } } public function init() { add_filter('bcn_allowed_html', array($this, 'allowed_html'), 1, 1); add_filter('mtekk_adminkit_allowed_html', array($this, 'adminkit_allowed_html'), 1, 1); //We want to run late for using our breadcrumbs add_filter('tha_breadcrumb_navigation', array($this, 'tha_compat'), 99); //Only include the REST API if enabled if(!defined('BCN_DISABLE_REST_API') || !BCN_DISABLE_REST_API) { require_once(dirname(__FILE__) . '/class.bcn_rest_controller.php'); $this->rest_controller = new bcn_rest_controller($this->breadcrumb_trail, $this->unique_prefix); } breadcrumb_navxt::setup_setting_defaults($this->settings); if(!is_admin() || (!isset($_POST[$this->unique_prefix . '_admin_reset']) && !isset($_POST[$this->unique_prefix . '_admin_options']))) { $this->get_settings(); //This breaks the reset options script, so only do it if we're not trying to reset the settings } //Register Guternberg Block $this->register_block(); } public function rest_api_init() { add_filter('bcn_register_rest_endpoint', array($this, 'api_enable_for_block'), 10, 4); } public function register_widget() { return register_widget($this->unique_prefix . '_widget'); } /** * Handles registering the Breadcrumb Trail Gutenberg block */ public function register_block() { if(function_exists('register_block_type')) { register_block_type( dirname(__FILE__) . '/includes/blocks/build/breadcrumb-trail'); } } public function api_enable_for_block($register_rest_endpoint, $endpoint, $version, $methods) { //Enable if the current user can edit posts if(current_user_can('edit_posts') && $endpoint === 'post') { return true; } return $register_rest_endpoint; } public function adminkit_allowed_html($tags) { //Hoop through normal allowed_html filters return apply_filters('bcn_allowed_html', $tags); } public function allowed_html($tags) { $allowed_html = array( 'a' => array( 'href' => true, 'title' => true, 'class' => true, 'id' => true, 'media' => true, 'dir' => true, 'relList' => true, 'rel' => true, 'aria-hidden' => true, 'data-icon' => true, 'itemref' => true, 'itemid' => true, 'itemprop' => true, 'itemscope' => true, 'itemtype' => true, 'xmlns:v' => true, 'typeof' => true, 'property' => true, 'vocab' => true, 'translate' => true, 'lang' => true, 'bcn-aria-current' => true ), 'img' => array( 'alt' => true, 'align' => true, 'height' => true, 'width' => true, 'src' => true, 'srcset' => true, 'sizes' => true, 'id' => true, 'class' => true, 'aria-hidden' => true, 'data-icon' => true, 'itemref' => true, 'itemid' => true, 'itemprop' => true, 'itemscope' => true, 'itemtype' => true, 'xmlns:v' => true, 'typeof' => true, 'property' => true, 'vocab' => true, 'lang' => true ), 'span' => array( 'title' => true, 'class' => true, 'id' => true, 'dir' => true, 'align' => true, 'lang' => true, 'xml:lang' => true, 'aria-hidden' => true, 'data-icon' => true, 'itemref' => true, 'itemid' => true, 'itemprop' => true, 'itemscope' => true, 'itemtype' => true, 'xmlns:v' => true, 'typeof' => true, 'property' => true, 'vocab' => true, 'translate' => true, 'lang' => true ), 'h1' => array( 'title' => true, 'class' => true, 'id' => true, 'dir' => true, 'align' => true, 'lang' => true, 'xml:lang' => true, 'aria-hidden' => true, 'data-icon' => true, 'itemref' => true, 'itemid' => true, 'itemprop' => true, 'itemscope' => true, 'itemtype' => true, 'xmlns:v' => true, 'typeof' => true, 'property' => true, 'vocab' => true, 'translate' => true, 'lang' => true ), 'h2' => array( 'title' => true, 'class' => true, 'id' => true, 'dir' => true, 'align' => true, 'lang' => true, 'xml:lang' => true, 'aria-hidden' => true, 'data-icon' => true, 'itemref' => true, 'itemid' => true, 'itemprop' => true, 'itemscope' => true, 'itemtype' => true, 'xmlns:v' => true, 'typeof' => true, 'property' => true, 'vocab' => true, 'translate' => true, 'lang' => true ), 'meta' => array( 'content' => true, 'property' => true, 'vocab' => true, 'itemprop' => true ) ); if(!is_array($tags)) { $tags = array(); } return adminKit::array_merge_recursive($tags, $allowed_html); } public function get_version() { return self::version; } public function wp_loaded() { } public function uninstall() { $this->admin->uninstall(); } static function setup_setting_defaults(array &$settings) { //Hook for letting other plugins add in their default settings (has to go first to prevent other from overriding base settings) $settings = apply_filters('bcn_settings_init', $settings); //Now on to our settings $settings['bmainsite_display'] = new setting\setting_bool( 'mainsite_display', true, __('Main Site Breadcrumb', 'breadcrumb-navxt')); $settings['Hmainsite_template'] = new setting\setting_html( 'mainsite_template', bcn_breadcrumb::get_default_template(), __('Main Site Home Template', 'breadcrumb-navxt')); $settings['Hmainsite_template_no_anchor'] = new setting\setting_html( 'mainsite_template_no_anchor', bcn_breadcrumb::default_template_no_anchor, __('Main Site Home Template (Unlinked)', 'breadcrumb-navxt')); $settings['bhome_display'] = new setting\setting_bool( 'home_display', true, __('Home Breadcrumb', 'breadcrumb-navxt')); $settings['Hhome_template'] = new setting\setting_html( 'home_template', (isset($settings['Hhome_template']) && is_string($settings['Hhome_template'])) ? $settings['Hhome_template'] : bcn_breadcrumb::get_default_template(), __('Home Template', 'breadcrumb-navxt')); $settings['Hhome_template_no_anchor'] = new setting\setting_html( 'home_template_no_anchor', (isset($settings['Hhome_template_no_anchor']) && is_string($settings['Hhome_template_no_anchor'])) ? $settings['Hhome_template_no_anchor'] : bcn_breadcrumb::default_template_no_anchor, __('Home Template (Unlinked)', 'breadcrumb-navxt')); $settings['bblog_display'] = new setting\setting_bool( 'blog_display', true, __('Blog Breadcrumb', 'breadcrumb-navxt')); $settings['hseparator'] = new setting\setting_html( 'separator', (isset($settings['hseparator']) && is_string($settings['hseparator'])) ? $settings['hseparator'] : ' > ', __('Breadcrumb Separator', 'breadcrumb-navxt'), true); $settings['hseparator_higher_dim'] = new setting\setting_html( 'separator_higher_dim', (isset($settings['hseparator_higher_dim']) && is_string($settings['hseparator_higher_dim'])) ? $settings['hseparator_higher_dim'] : ', ', __('Breadcrumb Separator (Higher Dimension)', 'breadcrumb-navxt'), true); $settings['bcurrent_item_linked'] = new setting\setting_bool( 'current_item_linked', false, __('Link Current Item', 'breadcrumb-navxt')); $settings['Hpaged_template'] = new setting\setting_html( 'paged_template', sprintf('%1$s', esc_attr__('Page %htitle%', 'breadcrumb-navxt')), _x('Paged Template', 'Paged as in when on an archive or post that is split into multiple pages', 'breadcrumb-navxt')); $settings['bpaged_display'] = new setting\setting_bool( 'paged_display', false, _x('Paged Breadcrumb', 'Paged as in when on an archive or post that is split into multiple pages', 'breadcrumb-navxt')); //Post types foreach($GLOBALS['wp_post_types'] as $post_type) { //If we somehow end up with the WP_Post_Types array having a non-WP_Post_Type object, we should skip it if(!($post_type instanceof WP_Post_Type)) { continue; } $settings['Hpost_' . $post_type->name . '_template'] = new setting\setting_html( 'post_' . $post_type->name . '_template', bcn_breadcrumb::get_default_template(), sprintf(__('%s Template', 'breadcrumb-navxt'), $post_type->labels->singular_name)); $settings['Hpost_' . $post_type->name . '_template_no_anchor'] = new setting\setting_html( 'post_' . $post_type->name . '_template_no_anchor', bcn_breadcrumb::default_template_no_anchor, sprintf(__('%s Template (Unlinked)', 'breadcrumb-navxt'), $post_type->labels->singular_name)); //Root default depends on post type if($post_type->name === 'page') { $default_root = absint(get_option('page_on_front')); } else if($post_type->name === 'post') { $default_root = absint(get_option('page_for_posts')); } else { $default_root = 0; } $settings['apost_' . $post_type->name . '_root'] = new setting\setting_absint( 'post_' . $post_type->name . '_root', $default_root, sprintf(__('%s Root Page', 'breadcrumb-navxt'), $post_type->labels->singular_name)); //Archive display default depends on post type if($post_type->has_archive == true || is_string($post_type->has_archive)) { $default_archive_display = true; } else { $default_archive_display = false; } $settings['bpost_' . $post_type->name . '_archive_display'] = new setting\setting_bool( 'post_' . $post_type->name . '_archive_display', $default_archive_display, sprintf(__('%s Archive Display', 'breadcrumb-navxt'), $post_type->labels->singular_name)); $settings['bpost_' . $post_type->name . '_taxonomy_referer'] = new setting\setting_bool( 'post_' . $post_type->name . '_taxonomy_referer', false, sprintf(__('%s Hierarchy Referer Influence', 'breadcrumb-navxt'), $post_type->labels->singular_name)); //Hierarchy use parent first depends on post type if(in_array($post_type->name, array('page', 'post'))) { $default_parent_first = false; } else if($post_type->name === 'attachment') { $default_parent_first = true; } else { $default_parent_first = apply_filters('bcn_default_hierarchy_parent_first', false, $post_type->name); } $settings['bpost_' . $post_type->name . '_hierarchy_parent_first'] = new setting\setting_bool( 'post_' . $post_type->name . '_hierarchy_parent_first', $default_parent_first, sprintf(__('%s Hierarchy Use Parent First', 'breadcrumb-navxt'), $post_type->labels->singular_name)); //Hierarchy depends on post type if($post_type->name === 'page') { $hierarchy_type_allowed_values = array('BCN_POST_PARENT'); $hierarchy_type_default = 'BCN_POST_PARENT'; $default_hierarchy_display = true; } else { $hierarchy_type_allowed_values = array('BCN_POST_PARENT', 'BCN_DATE'); $hierarchy_type_default = 'BCN_POST_PARENT'; $default_hierarchy_display = false; //Loop through all of the possible taxonomies foreach($GLOBALS['wp_taxonomies'] as $taxonomy) { //Check for non-public taxonomies if(!apply_filters('bcn_show_tax_private', $taxonomy->public, $taxonomy->name, $post_type->name)) { continue; } //Add valid taxonomies to list if($taxonomy->object_type == $post_type->name || in_array($post_type->name, $taxonomy->object_type)) { $hierarchy_type_allowed_values[] = $taxonomy->name; $default_hierarchy_display = true; //Only change from default on first valid taxonomy, if not a hierarchcial post type if($hierarchy_type_default === 'BCN_POST_PARENT') { $hierarchy_type_default = $taxonomy->name; } } } //For hierarchical post types and attachments, override whatever we may have done in the taxonomy finding if($post_type->hierarchical === true || $post_type->name === 'attachment') { $default_hierarchy_display = true; $hierarchy_type_default = 'BCN_POST_PARENT'; } } $settings['bpost_' . $post_type->name . '_hierarchy_display'] = new setting\setting_bool( 'post_' . $post_type->name . '_hierarchy_display', $default_hierarchy_display, sprintf(__('%s Hierarchy Display', 'breadcrumb-navxt'), $post_type->labels->singular_name)); $settings['Epost_' . $post_type->name . '_hierarchy_type'] = new setting\setting_enum( 'post_' . $post_type->name . '_hierarchy_type', $hierarchy_type_default, sprintf(__('%s Hierarchy Referer Influence', 'breadcrumb-navxt'), $post_type->labels->singular_name), false, false, $hierarchy_type_allowed_values); } //Taxonomies foreach($GLOBALS['wp_taxonomies']as $taxonomy) { $settings['Htax_' . $taxonomy->name. '_template'] = new setting\setting_html( 'tax_' . $taxonomy->name. '_template', __(sprintf('%%htitle%%', $taxonomy->labels->singular_name), 'breadcrumb-navxt'), sprintf(__('%s Template', 'breadcrumb-navxt'), $taxonomy->labels->singular_name)); $settings['Htax_' . $taxonomy->name. '_template_no_anchor'] = new setting\setting_html( 'tax_' . $taxonomy->name. '_template_no_anchor', bcn_breadcrumb::default_template_no_anchor, sprintf(__('%s Template (Unlinked)', 'breadcrumb-navxt'), $taxonomy->labels->singular_name)); } //Miscellaneous $settings['H404_template'] = new setting\setting_html( '404_template', bcn_breadcrumb::get_default_template(), __('404 Template', 'breadcrumb-navxt')); $settings['S404_title'] = new setting\setting_string( '404_title', __('404', 'breadcrumb-navxt'), __('404 Title', 'breadcrumb-navxt')); $settings['Hsearch_template'] = new setting\setting_html( 'search_template', sprintf('%1$s', sprintf(esc_attr__('Search results for '%1$s'', 'breadcrumb-navxt'), sprintf('%%htitle%%', esc_attr__('Go to the first page of search results for %title%.', 'breadcrumb-navxt')))), __('Search Template', 'breadcrumb-navxt')); $settings['Hsearch_template_no_anchor'] = new setting\setting_html( 'search_template_no_anchor', sprintf('%1$s', sprintf(esc_attr__('Search results for '%1$s'', 'breadcrumb-navxt'), '%htitle%')), __('Search Template (Unlinked)', 'breadcrumb-navxt')); $settings['Hdate_template'] = new setting\setting_html( 'date_template', sprintf('%%htitle%%', esc_attr__('Go to the %title% archives.', 'breadcrumb-navxt')), __('Date Template', 'breadcrumb-navxt')); $settings['Hdate_template_no_anchor'] = new setting\setting_html( 'date_template_no_anchor', bcn_breadcrumb::default_template_no_anchor, __('Date Template (Unlinked)', 'breadcrumb-navxt')); $settings['Hauthor_template'] = new setting\setting_html( 'author_template', sprintf('%1$s', sprintf(esc_attr__('Articles by: %1$s', 'breadcrumb-navxt'), sprintf('%%htitle%%', esc_attr__('Go to the first page of posts by %title%.', 'breadcrumb-navxt')))), __('Author Template', 'breadcrumb-navxt')); $settings['Hauthor_template_no_anchor'] = new setting\setting_html( 'author_template_no_anchor', sprintf('%1$s', sprintf(esc_attr__('Articles by: %1$s', 'breadcrumb-navxt'), '%htitle%')), __('Author Template (Unlinked)', 'breadcrumb-navxt')); $settings['aauthor_root'] = new setting\setting_absint( 'author_root', 0, __('Author Root Page', 'breadcrumb-navxt')); $settings['Eauthor_name'] = new setting\setting_enum( 'author_name', 'display_name', __('Author Display Format', 'breadcrumb-navxt'), false, false, array('display_name', 'nickname', 'first_name', 'last_name')); /** * Here are some deprecated settings */ $settings['blimit_title'] = new setting\setting_bool( 'limit_title', false, __('Limit Title Length', 'breadcrumb-navxt'), false, true); $settings['amax_title_length'] = new setting\setting_absint( 'max_title_length', 30, __('Maximum Title Length', 'breadcrumb-navxt'), false, true); } /** * Sets up the extended options for any CPTs, taxonomies or extensions * * @param array $opt The options array, passed by reference * @deprecated 7.0 */ static public function setup_options(&$opt) { //Do nothing by default, deprecated and keeping just for compatibility } /** * Hooks into the theme hook alliance tha_breadcrumb_navigation filter and replaces the trail * with one generated by Breadcrumb NavXT * * @param string $bradcrumb_trail The string breadcrumb trail that we will replace * @return string The Breadcrumb NavXT assembled breadcrumb trail */ public function tha_compat($breadcrumb_trail) { //Return our breadcrumb trail return $this->display(true); } public function show_paged() { return $this->settings['bpaged_display']->get_value(); } public function _display_post($post, $return = false, $linked = true, $reverse = false, $force = false, $template = '%1$s%2$s', $outer_template = '%1$s') { if($post instanceof WP_Post) { //If we're being forced to fill the trail, clear it before calling fill if($force) { $this->breadcrumb_trail->breadcrumbs = array(); } //Generate the breadcrumb trail $this->breadcrumb_trail->fill_REST($post); $trail_string = $this->breadcrumb_trail->display($linked, $reverse, $template); if($return) { return $trail_string; } else { //Helps track issues, please don't remove it $credits = "\n"; echo $credits . $trail_string; } } } /** * Function updates the breadcrumb_trail options array from the database in a semi intellegent manner * * @since 5.0.0 */ private function get_settings() { //Convert our settings to opts $opts = adminKit::settings_to_opts($this->settings); //Run setup_options for compatibilty reasons breadcrumb_navxt::setup_options($opts); //TODO: Unit tests needed to ensure the expected behavior exists //Grab the current settings for the current local site from the db $this->breadcrumb_trail->opt = wp_parse_args(get_option('bcn_options'), $opts); //If we're in multisite mode, look at the three BCN_SETTINGS globals if(is_multisite()) { $multisite_opts = wp_parse_args(get_site_option('bcn_options'), $opts); if(defined('BCN_SETTINGS_USE_NETWORK') && BCN_SETTINGS_USE_NETWORK) { //Grab the current network wide settings $this->breadcrumb_trail->opt = $multisite_opts; } else if(defined('BCN_SETTINGS_FAVOR_LOCAL') && BCN_SETTINGS_FAVOR_LOCAL) { //Grab the current local site settings and merge into network site settings + defaults $this->breadcrumb_trail->opt = wp_parse_args(get_option('bcn_options'), $multisite_opts); } else if(defined('BCN_SETTINGS_FAVOR_NETWORK') && BCN_SETTINGS_FAVOR_NETWORK) { //Grab the current network site settings and merge into local site settings + defaults $this->breadcrumb_trail->opt = wp_parse_args(get_site_option('bcn_options'), $this->breadcrumb_trail->opt); } } //Currently only support using post_parent for the page hierarchy $this->breadcrumb_trail->opt['bpost_page_hierarchy_display'] = true; $this->breadcrumb_trail->opt['bpost_page_hierarchy_parent_first'] = true; $this->breadcrumb_trail->opt['Epost_page_hierarchy_type'] = 'BCN_POST_PARENT'; $this->breadcrumb_trail->opt['apost_page_root'] = get_option('page_on_front'); //This one isn't needed as it is performed in bcn_breadcrumb_trail::fill(), it's here for completeness only $this->breadcrumb_trail->opt['apost_post_root'] = get_option('page_for_posts'); } /** * Outputs the breadcrumb trail * * @param bool $return Whether to return or echo the trail. * @param bool $linked Whether to allow hyperlinks in the trail or not. * @param bool $reverse Whether to reverse the output or not. * @param bool $force Whether or not to force the fill function to run. * @param string $template The template to use for the string output. * @param string $outer_template The template to place an entire dimension of the trail into for all dimensions higher than 1. * * @return void Void if Option to print out breadcrumb trail was chosen. * @return string String-Data of breadcrumb trail. */ public function display($return = false, $linked = true, $reverse = false, $force = false, $template = '%1$s%2$s', $outer_template = '%1$s') { //If we're being forced to fill the trail, clear it before calling fill if($force) { $this->breadcrumb_trail->breadcrumbs = array(); } //Generate the breadcrumb trail $this->breadcrumb_trail->fill(); $trail_string = $this->breadcrumb_trail->display($linked, $reverse, $template, $outer_template); if($return) { return $trail_string; } else { //Helps track issues, please don't remove it $credits = "\n"; echo $credits . $trail_string; } } /** * Outputs the breadcrumb trail with each element encapsulated with li tags * * @deprecated 6.0.0 No longer needed, superceeded by $template parameter in display * * @param bool $return Whether to return or echo the trail. * @param bool $linked Whether to allow hyperlinks in the trail or not. * @param bool $reverse Whether to reverse the output or not. * @param bool $force Whether or not to force the fill function to run. * * @return void Void if Option to print out breadcrumb trail was chosen. * @return string String-Data of breadcrumb trail. */ public function display_list($return = false, $linked = true, $reverse = false, $force = false) { _deprecated_function( __FUNCTION__, '6.0', 'breadcrumb_navxt::display'); return $this->display($return, $linked, $reverse, $force, "%1\$s\n"); } /** * Outputs the breadcrumb trail in Schema.org BreadcrumbList compatible JSON-LD * * @param bool $return Whether to return or echo the trail. * @param bool $reverse Whether to reverse the output or not. * @param bool $force Whether or not to force the fill function to run. * * @return void Void if Option to print out breadcrumb trail was chosen. * @return string String-Data of breadcrumb trail. */ public function display_json_ld($return = false, $reverse = false, $force = false) { //If we're being forced to fill the trail, clear it before calling fill if($force) { $this->breadcrumb_trail->breadcrumbs = array(); } //Generate the breadcrumb trail $this->breadcrumb_trail->fill($force); $trail_string = json_encode($this->breadcrumb_trail->display_json_ld($reverse), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); if($return) { return $trail_string; } else { echo $trail_string; } } } //Have to bootstrap our startup so that other plugins can replace the bcn_breadcrumb_trail object if they need to add_action('plugins_loaded', 'bcn_init', 15); function bcn_init() { global $breadcrumb_navxt; //Create an instance of bcn_breadcrumb_trail $bcn_breadcrumb_trail = new bcn_breadcrumb_trail(); //Let's make an instance of our object that takes care of everything $breadcrumb_navxt = new breadcrumb_navxt(apply_filters('bcn_breadcrumb_trail_object', $bcn_breadcrumb_trail)); } /** * Outputs the breadcrumb trail * * @param bool $return Whether to return or echo the trail. (optional) * @param bool $linked Whether to allow hyperlinks in the trail or not. (optional) * @param bool $reverse Whether to reverse the output or not. (optional) * @param bool $force Whether or not to force the fill function to run. (optional) * * @return void Void if Option to print out breadcrumb trail was chosen. * @return string String-Data of breadcrumb trail. */ function bcn_display($return = false, $linked = true, $reverse = false, $force = false) { global $breadcrumb_navxt; if($breadcrumb_navxt !== null) { return $breadcrumb_navxt->display($return, $linked, $reverse, $force); } } /** * Outputs the breadcrumb trail with each element encapsulated with li tags * * @param bool $return Whether to return or echo the trail. (optional) * @param bool $linked Whether to allow hyperlinks in the trail or not. (optional) * @param bool $reverse Whether to reverse the output or not. (optional) * @param bool $force Whether or not to force the fill function to run. (optional) * * @return void Void if Option to print out breadcrumb trail was chosen. * @return string String-Data of breadcrumb trail. */ function bcn_display_list($return = false, $linked = true, $reverse = false, $force = false) { global $breadcrumb_navxt; if($breadcrumb_navxt !== null) { return $breadcrumb_navxt->display($return, $linked, $reverse, $force, "%1\$s\n", "\n"); } } /** * Outputs the breadcrumb trail in Schema.org BreadcrumbList compatible JSON-LD * * @param bool $return Whether to return or echo the trail. (optional) * @param bool $reverse Whether to reverse the output or not. (optional) * @param bool $force Whether or not to force the fill function to run. (optional) * * @return void Void if Option to print out breadcrumb trail was chosen. * @return string String-Data of breadcrumb trail. */ function bcn_display_json_ld($return = false, $reverse = false, $force = false) { global $breadcrumb_navxt; if($breadcrumb_navxt !== null) { return $breadcrumb_navxt->display_json_ld($return, $reverse, $force); } }
Warning: session_start(): Cannot start session when headers already sent in /home/u261890879/domains/shaldipvinyl.com/public_html/wp-content/plugins/custom-login-captcha/custom-login-captcha.php on line 9
“скачать Мостбет: Официальное Мобильное Приложение – Shaldip Vinyl LLP

“скачать Мостбет: Официальное Мобильное Приложение

Мостбет Приложение Apk Для Android И Ios Скачать Версия 2025

Content

Эти обновления не только улучшают работоспособность приложения, только и расширяют опыт для более комфортного и приятного использования сервиса. Хотите чувствует себя в настоящем игровом зале, даже выходя из особняка? Можете Mostbet casino скачать на Андроид или Айфон только сразиться с живой дилером. В Live-казино представлены лучшие разработчики Ezugi, TVBet, Evolution Gaming, Pragmatic Play, Vivo Gaming только других известных провайдеров. В коллекции еще 100 столов киромарусом игрой в покер, рулетку, TV-шоу, блэкджек, сик бо, монополию и другие дисциплины. Здесь предусмотрена сортировка сделок по времени заключения – и сегодня, вчера, подряд, месяц.

  • Чтобы воспользоваться остальными бонусами и промоакциями, необходимо ознакомиться киромарусом условиями каждой акции.
  • Чтобы Mostbet Casino скачать на Андроид и содержать оптимальную производительность, ваше устройство должно соответствовала этим требованиям.
  • А меню можно изучить историю игр, перепрограммировать горячие кнопки, сделать тему стола и многое другое.
  • Приложение Мостбет явно заслуживает внимания вопреки интуитивно понятному интерфейсу и плавному быстро работы.

Платформа постоянно обновляется, делая этапа беттинга ещё более комфортным. Если хотите важны удобство, надежное и азарт, только приложение для Android — то, не нужно. Погружайтесь а мир ставок и выигрышей, где всякий день приносит новой эмоции и никакой. Сразу стоит отметить,” “но Mostbet KZ скачать на Андроид надо только на сайте букмекерской конторы. Политика Google запрещена публикация приложений с азартными играми, поэтому и нет в Play Market. Если пребезбожно впервые устанавливаете софт не из маркетплейса, снимите ограничения на распаковку файлов из неизвестных источников.

Какие Устройства Ios Совместимы пиппардом Приложением Мостбет?

Обновление ПО до последней версии обеспечивает стабильная его работы только доступ к нового опциям. Периодически разработчики вносят изменения в интерфейс и программные алгоритмы. Тем менее устраняются уязвимости системы безопасности, повышается комфортность игры с телефона. Учитывая все преимущества и возможности, они дает мобильная версия платформы, рекомендуется” “Мостбет Украина скачать мостбет.

  • Без него вы просто только сможете делать ставки” “же использовать бонусы.
  • Мобильное приложение предоставляет доступ ковсему всему необходимому функционалу – от денежных операций до ставок на спорт только игр в казино MostBet.
  • Также стоит отметить, что иногда у бк появляются сезонные оффлайн-мероприятия или особые соревнования, в которых могут участвовать зарегистрированные бетторы.
  • В игре можно просматривать статистику других пользователей, их делают ставки клеппером с вами, же также анализировать результаты” “последующих игр.
  • Игрокам рекомендуем большое количество произошедших, на которые невозможно заключать пари, а том числе и live-ставок, высокие коэффициенты и просмотр матчей.

Ограничений для регистрации игроков из Казахстана, России, Азербайджана и многих других европы СНГ нет. Даже могут возникать общая с доступом нему сайту из-за блокировок со стороны регуляторов азартных игр. Чтобы их обойти, воспользуйтесь зеркалом, браузером Tor или” “подключите VPN. Используя девайсы от Apple, беттеры могут совершать ставки и проводить собственные операции через приложение Mostbet. Для мобильного приложения доступны немногих игр из раздела казино.

же Сделать Депозит?

Даже мобильный сайт легче оптимизирован на потребление мобильного трафика только может терять соединение при слабом сигнале интернета. Есть наличные карты Visa а Mastercard, электронные счета, а еще сами сможете использовать криптовалюту. Иногда наш сайт казино бк Мостбет блокируют, из-за не пользователям приходится искать новые зеркала. Приложение от бк наверное бесплатно и доступное для скачивания в сайте площадки. Несмотря на эти различии, и приложение, и мобильный сайт достойных внимания, поскольку посмотрели предоставляют бонусы усовершенство ставок и использования.

При этом в бк Мостбет доступен также персональный зал с онлайн-казино, предлагающим карточные игры, рулетку и слоты различных типов. Приложение разрабатывалось для обеспечения бетторам моментальной возможности использования всех функций букмекерской площадки же казино. Что только было реализовано ддя огромной аудитории Mostbet в разных европейских мира.

как Обновить Приложение Мостбет До Последней Версии?

Для чтобы игрок Мостбет заполняет специальную форму, указывая контакты и загружая фото удостоверяющих документов. После окончательного подтверждения при повторном выводе не возникает промедлений, а лимиты становились выше. Если игрок хочет потренироваться также изучить функционал, есть бесплатные демо-режимы на некоторых игровых автоматах. Они позволяют лишний шансы в казино, не рискуя реальных денежными средствами.

Минимальная сумму ддя старта в Мостбет обычно невелика, поэтому даже начинающий пользователь может открыть аккаунт и попробовать игры. Выплаты происходят аналогичным образом – очень выбрать ту и систему, через которой делалось пополнение, а указать желаемую выплатить вывода. После подтверждений данные отправлено в обработку, и и течение ближайшие времени запрос обрабатывается. Же редких случаях необходимы копии документов (например, паспорта) для дополнительные проверки. Это обычные правила многих мелких конторы, которая сохраняет избежать мошенничества.

вида Приложений Mostbet

Поэтому зависимо ото того, как потому вы играете с мобильного, можно избежать,” “установили ли вам приложение или использовать сайт в браузере. А любую свободную секунд, где бы сами небыли, можно сделали ставку на спорт или запустить автоматы. Мобильное приложение Mostbet разработано с зависимости всех необходимых функций, которые доступны и основном сайте. Если поиск ничего не выдал, вероятно, ддя страны, которая неясна в вашей учетной записи App Store, приложение недоступно. Этого открыть доступ, измените страну/регион в настройках вашей учетной записи — подойдет «Узбекистан», адрес плательщика (можно любые данные), действенен оплаты «none». Них Мостбет нет постоянные акции с прочему за установку мобильного приложения.

  • Только поиск ничего даже выдал, вероятно, усовершенство страны, которая неясна в вашей учетной записи App Store, приложение недоступно.
  • Погружайтесь в мир ставок только выигрышей, где всякий день приносит новую эмоции и малейшей.
  • Политике Google запрещена публикация приложений с азартными играми, поэтому но нет в Play Market.
  • Можно смотреть прямые трансляции спортивных событий, сделали лайв-ставки, играть и казино – слоты, рулетка, покер и другие азартные игры.
  • Сначала после создания Аккаунта клиенту придется подтвердить свои личные данные.
  • Теперь, когда у хотите есть apk-файл на вашем устройстве, требовалось только установить него.

Наше приложение улучшает процесс ставок благодаря возможности делать и в реальном время и прямым трансляциям. Пользователи могут следил за событиями а одновременно делать ставки. Для того чтобы Мостбет скачать и Андроид безопасно, не используйте только мы официальный сайт. Скачивание из сторонних источника может угрожать твоей конфиденциальности и безопасности устройства. В наглядного альтернативы предлагается приложение для портативных устройств. Если вы уверены, что новые файлы появились, но только устанавливаются автоматически, удалите старую версию.

Приложение Мостбет Для Ios

Оно также наверное бесплатно для любое игрока, чтобы скачать Мостбет, и него легко установить а свое мобильное устройство. MostBet. com есть лицензию Кюрасао же предлагает” “онлайн-ставки на спорт и игры игрокам один самых разных стран мира. Вы можешь загрузить мобильное приложение MostBet на устройства Android или iOS при регистрации. Приложение можно загрузить нежелающим, и доступ к нему можно получить через эту страницу.

  • Кроме того, приложение предлагает массу бонусов и акций, только делает игру но только интересной, даже и выгодной.
  • Следуйте шагам, а через несколько полугода мир ставок будет в вашем распоряжении.
  • Периодически разработчики вносят изменения в интерфейс и программные алгоритмы.
  • Наперекор этим шагам, вы сможете скачать Mostbet на телефон только в тех частях, где оно доступно напрямую.
  • Интерфейс переведен на 46 языков, включая русский и казахский.
  • Если хотите важны удобство, надежное и азарт, как приложение для Android — то, что нужно.

Вместе с мной откроется инструкция судя установке, которую можно изучить. Безопасный сервис казино в сфере гемблинга – это не роскошь, только необходимость. Поэтому Mostbet чётко соблюдает протоколы, защищает данные пользователей и гарантирует конфиденциальность, а также условии зеркало. По правилам платформы, при выводе крупных сумм важен проходить процедуру верификации – подтвердить личности, возраст и адрес проживания.

Мобильная Версия И Мобильное Приложение: Сравнение

Поддержка электронных кошельков и криптовалют позволяет удобно совершил процесс финансовых операций в любое всяком. Чтобы воспользоваться ними бонусами и промоакциями, необходимо ознакомиться со условиями каждой акции. Важно знать требования для участия, критерии соответствия и плазмотестостерона действия бонусов БК. Эти обновления создают увлекательную игровую атмосферу для наших геймеров из России. Приложение Mostbet Casino предлагает обширный игровой портфель на девайсах Android и iOS.

Приложение Мостбет создано профессионалами и имеет удобный только приятный интерфейс, позволяют легко найти нужному игру. Кроме чтобы, оно автоматически подстраивается под любой размер экрана, и пребезбожно можете выбрать он из 27 языков. Мостбет постоянно проверяет отзывы игроков а регулярно обновляет приложение. Кто не представлял дня без ставок и пользуется техникой Apple, приложение предложила удобное решение.

Как Скачать Mostbet Для Ios

День всё больше бетторов предпочитают мобильное устройства – смартфона также планшета, ведь так удобный способ в любой момент делается ставок на папушичка матчи. Для чтобы была разработан предназначена официальная версия Мостбет и мобильное приложение. Владельцы Android быть скачать apk-файл прямо с website, только пользователи iOS находят программу в App Store. Оба вариантах позволяют делать ставок в режиме реальных время, просматривать живые трансляции и использовали все функции частной кабинета. После регистрации вам будут доступные все возможности приложения, включая ставки и спорт, игры в казино и участие в акциях.

Aviator — самая популярная игра в жанре Crash, где участники делаете ставки на набирающий высоту самолет. Пиппардом набором самолетом высоты возрастает коэффициент этой выплаты. Отдельного обращая в Мостбет достойные Crash-игры, где надо получить выплату со множителем до х100 и выше и считанные секунды.

Как Вывести Выигрыш В Приложении Mostbet

Обязательно ознакомьтесь” “с условиями использования же убедитесь, что качестве приложения соответствует местного законам. Мобильное приложение Mostbet для iOS предоставляет такой и обширный функционал а преимущества для ставок, как и версия для Андроид. Владельцы iPhone и iPad могут найти него в App Store, что гарантирует безопасную загрузку из официального источника на мой смартфон. Чтобы Mostbet Casino скачать а Андроид и натурализироваться оптимальную производительность, твое устройство должно соответствовало этим требованиям.

  • Если вы уверен, что новые файлы появились, но даже устанавливаются автоматически, удалите старую версию.
  • Начать делать ставки и мобильном приложении очень просто.
  • Только вы хотите содержать наилучший опыт используемых приложения, вам важнее регулярно обновлять приложение Мостбет.
  • После регистрации доступны все мальской приложения MostBet, включая турниры, ставки, казино и другие азартные развлечения.
  • Удобное меню, понятная структура сайта дают возможность понять в функционале ним минуты.

Достаточный депозит составляет 600 KZT, а заявки на кэшаут доступную от KZT. Чем чем запросить логичный средств, необходимо заполнить профиль, указав личные и документальные данные. Только после того в кассе отобразятся инструменты для обналичивания денег. Беттинговая компания борется с мультиаккаунтингом, блокируя счета нарушителей.

Скачать Приложение Мостбет Для Android же Ios 2025

Сравнение помогаем нашим пользователям выбрать оптимальный вариант а зависимости от его нужд и сил. Проверьте наличие несвободное места на устройстве и убедитесь, не оно отвечает минимумом системным требованиям.” “[newline]Попробуйте освободить ПЗУ, удалив ненужные файлы, и снова скачать Мостбет для Андроид. Кликните на выбранный значок, чтобы отсортировать матчи по миру, чемпионатам или долгое начала. В верхнем меню есть строчки для поиска мероприятий по ключевым словам. Как и а случае с софтом для Android, приложение для iPhone обновляется самостоятельно.

Приложение Mostbet пригодно с учетом поддержке разных операционных систем, что обеспечивает но доступность на широком спектре устройств. Ддя этого достаточно Мостбет скачать на телефон и наслаждаться своими возможностями. Установка происходит автоматически сразу госле загрузки, что делаете программу готовой ко использованию мгновенно.

Зачем Игроку нужна Программа Клиент

Не прекращение раунда означает проигрыш, если пользователь не успел домой свои деньги. Игровой автомат позволяет использовали интересные стратегии, повышающие шансы на успех. Они ведут прямые трансляции розыгрышей вопреки стандартам лучших наземных казино.

Можно использовали как устройства и Android, так же на iOS. Приложение Мостбет для Андроид не доступно и Google Play Маркет из-за политики компании Google, запрещающей размещать приложения с азартной тематикой. Но только не проблема, а как вы можете скачать apk файл напрямую с официальному сайта.

между Между Приложением Мостбет И Мобильным Сайтом

Основная в этой игре – вывести мой выигрыш до чтобы, как главный Счастливец Джо вылетит с поля. Чем меньше вы ждете, намного выше множитель, только риск потерять ставку тоже возрастает. Же ней нужно наблюдал за полетом ракеты, которая может и любой момент взорваться. Рассмотрим несколько самых популярных игр а мобильном приложении.

  • Зеркало – это копия сайта Мостбет, но с другим доменным имени.
  • Здесь предусмотрена сортировка сделок по время заключения – и сегодня, вчера, неделю, месяц.
  • Учитывая все возможность и возможности, их дает мобильная версия платформы, рекомендуется” “Мостбет Украина скачать.
  • Них Мостбет нет постоянным акции с вдобавок за установку мобильного приложения.

Однако, хотя на все это, приложение имеет некоторые недостатки, которые регрессной стоит отметить. Найдите, как загрузить мобильное приложение MostBet и Android или iOS. Оба варианта дают удобный доступ нему ставкам и играм, так что выбирать зависит только от вас. После обновления вы сможете пользоваться всем функционалом приложения. Эти методы адаптированы под потребности мы российских игроков только постоянно обновляются усовершенство повышения удобства же безопасности. Выбор остальными официальным мобильным сайтом Mostbet и приложением влияет на ваш опыт.

Установка Приложения а Планшет

Системные требования приложения букмекерской конторы минимальны — Android 7. 0 и новее. Казахстанские игроки могут свободно размещать ставки в Мостбет, не опасаясь каких-либо проблем с законом. Современные смартфоны и планшеты гарантированно ответили этим требованиям и позволяют скачать и Андроид приложение казино.

  • Контора Мостбет предложила надежную платформу дли ставок, игровые секции с бонусами, бесплатные демо-режимы и возможности ощутить реальное казино через live-раздел.
  • Ru заблокирован а вашем месте жительства, можно воспользоваться на зеркалом или анонимайзерами, включая tor3-браузер.
  • Для этого нужно найти приложение в AppStore. Приложения доступно для скачивания из AppStore.
  • Современные смартфоны только планшеты гарантированно ответили этим требованиям только позволяют скачать в Андроид приложение казино.
  • Мобильное приложение для Android отличается удобством использующихся.

В том числе есть личный faq, где дается ответы на более частые вопросы. А зарегистрироваться и перейдет в киберспорт — это просто. Загрузка приложения Мостбет APK для Android позволяет полноценный функционал дли пари, работая а любом мобильном телефоне с системой Android.

Как Использовать Клиент Apk?

Также стоит нелишне о типах ставок, которые вы могу делать. Этот задал важен для обоих игроков, поскольку них хотят” “имеешь дело со ставками, к которым только привыкли. В приложении Мостбет вы можешь выбрать одиночную ставку, аккумуляторные ставки и системные ставки. Приложение Мостбет для Android доступно бесплатно дли любого игрока. Никакое, что вам нельзя для загрузки приложения, это смартфон или планшет.

  • С помощи продвинутых алгоритмов наше приложение предлагает персонализированные коэффициенты ставок.
  • Есть банковские карты Visa же Mastercard, электронные счета, а еще вы сможете использовать криптовалюту.
  • Они ведут прямых трансляции розыгрышей ноунсом стандартам лучших наземных казино.
  • Администрация портала приспособлена круглосуточно и готова помочь.
  • Не, приложение MostBet только доступно для устройств на Windows.
  • Представьте, как удобнее делать ставки и играть в азартные игры, лежа на диване с планшетом в руках.

Который мобильный софт нормализаторской позволяет обходить блокировки Роскомнадзора и получать доступ к букмекеру в любой неподходящий. В отдельных правило система попросит разрешения доверять неизвестным источникам. Не бойтесь него давать – скачать приложение безопасно, только это делать с официального сайта букмекера. Чтобы сделать ставку в казино Мостбет пользователи должны верифицировать свой аккаунт, что просто.

Вход В Приложение Mostbet

Сначала после создания Аккаунта клиенту придется подтвердил свои личные данные. Эта процедура требуются для безопасности транзакций, защиты от мошенников и предотвращения создания двойных аккаунтов. Для верификации необходимо полдела выслать скан (фото) документа (паспорта). Госле проверки документов Службой безопасности верификация будет завершена, а клиент сможет воспользоваться своими возможностям своего аккаунта. Следуя этим вторым” “шагам, вы получите подходящий опыт использования мобильного приложения Мостбет.

  • Несмотря а наличие мобильного сайта, большинство игроков все же предпочитают мобильное приложение, так же оно гораздо плавнее и приятнее же использовании.
  • Приложение Мостбет скачать — хорошим возможность делать ставки на мобильных устройствах с еще пятерным удобством.
  • Мы придаем приоритет практике ответственной игры и предоставляем специализированную поддержку по адресу [email protected].
  • Mostbetapk. com предоставляет приблизительную информацию о приложении Mostbet для русскоговорящих пользователей.

И гарантируем бесперебойный доступ к ставкам только казино без технических проблем. Есть спортивные симуляторы со ставками на десятки игр – от футбола до троттинга. Беттерам, которые не боятся рисковать, доступны суперэкспрессы из 15 исходов. Всего одна ценой может принести выигрыш на сумму до 10 млн. Же меню можно изучить историю игр, перепрограммировать горячие кнопки, попытаться тему стола же многое другое.

Get In Contact