/** * Plugin Name: Elementor * Description: The Elementor Website Builder has it all: drag and drop page builder, pixel perfect design, mobile responsive editing, and more. Get started now! * Plugin URI: https://elementor.com/?utm_source=wp-plugins&utm_campaign=plugin-uri&utm_medium=wp-dash * Author: Elementor.com * Version: 3.20.1 * Author URI: https://elementor.com/?utm_source=wp-plugins&utm_campaign=author-uri&utm_medium=wp-dash * * Text Domain: elementor * * @package Elementor * @category Core * * Elementor 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 3 of the License, or * any later version. * * Elementor 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. */ if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } define( 'ELEMENTOR_VERSION', '3.20.1' ); define( 'ELEMENTOR__FILE__', __FILE__ ); define( 'ELEMENTOR_PLUGIN_BASE', plugin_basename( ELEMENTOR__FILE__ ) ); define( 'ELEMENTOR_PATH', plugin_dir_path( ELEMENTOR__FILE__ ) ); if ( defined( 'ELEMENTOR_TESTS' ) && ELEMENTOR_TESTS ) { define( 'ELEMENTOR_URL', 'file://' . ELEMENTOR_PATH ); } else { define( 'ELEMENTOR_URL', plugins_url( '/', ELEMENTOR__FILE__ ) ); } define( 'ELEMENTOR_MODULES_PATH', plugin_dir_path( ELEMENTOR__FILE__ ) . '/modules' ); define( 'ELEMENTOR_ASSETS_PATH', ELEMENTOR_PATH . 'assets/' ); define( 'ELEMENTOR_ASSETS_URL', ELEMENTOR_URL . 'assets/' ); add_action( 'plugins_loaded', 'elementor_load_plugin_textdomain' ); if ( ! version_compare( PHP_VERSION, '7.4', '>=' ) ) { add_action( 'admin_notices', 'elementor_fail_php_version' ); } elseif ( ! version_compare( get_bloginfo( 'version' ), '6.0', '>=' ) ) { add_action( 'admin_notices', 'elementor_fail_wp_version' ); } else { require ELEMENTOR_PATH . 'includes/plugin.php'; } /** * Load Elementor textdomain. * * Load gettext translate for Elementor text domain. * * @since 1.0.0 * * @return void */ function elementor_load_plugin_textdomain() { load_plugin_textdomain( 'elementor' ); } /** * Elementor admin notice for minimum PHP version. * * Warning when the site doesn't have the minimum required PHP version. * * @since 1.0.0 * * @return void */ function elementor_fail_php_version() { $message = sprintf( /* translators: 1: `

` opening tag, 2: `

` closing tag, 3: PHP version. 4: Link opening tag, 5: Link closing tag. */ esc_html__( '%1$sElementor isn’t running because PHP is outdated.%2$s Update to PHP version %3$s and get back to creating! %4$sShow me how%5$s', 'elementor' ), '

', '

', '7.4', '', '' ); $html_message = sprintf( '
%s
', wpautop( $message ) ); echo wp_kses_post( $html_message ); } /** * Elementor admin notice for minimum WordPress version. * * Warning when the site doesn't have the minimum required WordPress version. * * @since 1.5.0 * * @return void */ function elementor_fail_wp_version() { $message = sprintf( /* translators: 1: `

` opening tag, 2: `

` closing tag, 3: WP version. 4: Link opening tag, 5: Link closing tag. */ esc_html__( '%1$sElementor isn’t running because WordPress is outdated.%2$s Update to version %3$s and get back to creating! %4$sShow me how%5$s', 'elementor' ), '

', '

', '6.0', '', '' ); $html_message = sprintf( '
%s
', wpautop( $message ) ); echo wp_kses_post( $html_message ); }/** * Exit if accessed directly. */ if ( ! defined( 'ABSPATH' ) ) { exit; } #[AllowDynamicProperties] class Wpzoom_Instagram_Widget_API { /** * @var Wpzoom_Instagram_Widget_API The reference to *Singleton* instance of this class */ private static $instance; /** * Request headers. * * @var array */ public $headers = array(); /** * Errors collector. * * @var array|WP_Error */ public $errors = array(); /** * Instagram Settings * * @var array */ public $settings; /** * Instagram Access Token * * @var string */ protected $access_token; /** * Feed ID * * @var string */ protected $feed_id; /** * Class constructor */ protected function __construct() { $this->is_forced_timeout = (bool) WPZOOM_Instagram_Widget_Settings::get_feed_setting_value( get_the_ID(), 'enable-request-timeout' ); $this->request_timeout_value = 15; if ( $this->is_forced_timeout && ! empty( $this->request_timeout_value ) ) { $this->headers['timeout'] = $this->request_timeout_value; } $this->image_uploader = WPZOOM_Instagram_Image_Uploader::getInstance(); $this->errors = new WP_Error(); } public function init() { add_action( 'init', array( $this, 'set_schedule' ) ); add_action( 'wpzoom_instagram_widget_cron_hook', array( $this, 'execute_cron' ) ); add_filter( 'cron_schedules', array( $this, 'add_cron_interval' ) ); } /** * Returns the *Singleton* instance of this class. * * @return Wpzoom_Instagram_Widget_API The *Singleton* instance. */ public static function getInstance() { if ( null === self::$instance ) { self::$instance = new self(); self::$instance->init(); } return self::$instance; } /** * Manually set the access token. * * @since 2.0.0 * * @param string $token The access token to set. * @return void */ public function set_access_token( $token ) { $this->access_token = $token; } /** * Manually set the access token. * * @since 2.0.0 * * @param string $token The access token to set. * @return void */ public function set_feed_id( $id ) { $this->feed_id = $id; } /** * Fetches a remote URL either safely or not, depending on a setting. * * @since 2.0.6 * * @param string $url URL to retrieve. * @param array $args Optional. Request arguments. Default empty array. * @return array|WP_Error The response or WP_Error on failure. */ public static function remote_get( $url, $args = array() ) { $settings = get_option( 'wpzoom-instagram-general-settings' ); $enable_unsafe_requests = ! empty( $settings['enable-unsafe-requests'] ) ? wp_validate_boolean( $settings['enable-unsafe-requests'] ) : false; return $enable_unsafe_requests ? wp_remote_get( $url, $args ) : wp_safe_remote_get( $url, $args ); } /** * Register custom cron intervals * * @since 1.8.0 * * @param array $schedules Registered schedules array. * @return array */ public function add_cron_interval( $schedules ) { $schedules['before_access_token_expires'] = array( 'interval' => 5097600, // 59 days. 'display' => esc_attr__( 'Before Access Token Expires', 'instagram-widget-by-wpzoom' ), ); return $schedules; } /** * Register schedule event * * @return void */ public function set_schedule() { if ( ! wp_next_scheduled( 'wpzoom_instagram_widget_cron_hook' ) ) { wp_schedule_event( time(), 'before_access_token_expires', 'wpzoom_instagram_widget_cron_hook' ); } } /** * Execute cron event * * @return boolean */ public function execute_cron() { $all_users = get_posts( array( 'numberposts' => -1, 'post_type' => 'wpz-insta_user', ) ); if ( ! empty( $all_users ) && is_array( $all_users ) ) { foreach ( $all_users as $user ) { if ( $user instanceof WP_Post ) { $user_name = get_the_title( $user ); $user_display = sprintf( '@%s', $user_name ); $token = get_post_meta( $user->ID, '_wpz-insta_token', true ); if ( false !== $token && ! empty( $token ) ) { $request_url = add_query_arg( array( 'grant_type' => 'ig_refresh_token', 'access_token' => $token, ), 'https://graph.instagram.com/refresh_access_token' ); $response = self::remote_get( $request_url, $this->headers ); $response_code = wp_remote_retrieve_response_code( $response ); if ( ! is_wp_error( $response ) ) { $body = wp_remote_retrieve_body( $response ); $data = json_decode( $body ); } if ( 200 === $response_code ) { $date_format = get_option( 'date_format' ); $time_format = get_option( 'time_format' ); $notice_status = 'success'; $notice_message = sprintf( __( 'WPZOOM Instagram Widget: The Instagram Access Token was refreshed automatically on %1$s at %2$s for the account %3$s.', 'instagram-widget-by-wpzoom' ), date( $date_format ), date( $time_format ), esc_html( $user_display ) ); update_post_meta( $user->ID, '_wpz-insta_token', $data->access_token ); update_post_meta( $user->ID, '_wpz-insta_token_expire', strtotime( '+60 days' ) ); } else { if ( ! isset( $data->error ) ) { error_log( __( 'Something wrong! Doesn\'t isset $data->error.', 'instagram-widget-by-wpzoom' ) ); return false; } else { error_log( $data->error->error_user_msg ); } $notice_status = 'error'; $notice_message = ''; $settings_url = admin_url( 'edit.php?post_type=wpz-insta_user' ); if ( 190 === $data->error->code ) { // Error validating access token: Session has expired. $notice_message = wp_kses_post( __( 'WPZOOM Instagram Widget: ', 'instagram-widget-by-wpzoom' ) ) . $data->error->message; } elseif ( 10 === $data->error->code && ! self::is_access_token_valid( $token ) ) { // Application does not have permission for this action. // User need to generate new Access Token manually. $notice_message = sprintf( __( 'WPZOOM Instagram Widget: The Access Token for the account %1$s has expired!
', 'instagram-widget-by-wpzoom' ), $user_display ); $notice_message .= sprintf( __( 'We cannot update access tokens automatically for Instagram private accounts. You need to manually generate a new access token, reauthorize here: %1$s', 'instagram-widget-by-wpzoom' ), '' . __( 'Instagram Widget Settings', 'instagram-widget-by-wpzoom' ) . '' ); } } update_option( '_wpz-insta_cron-result', array( $user->ID => array( 'status' => $notice_status, 'message' => $notice_message ) ) + (array) get_option( '_wpz-insta_cron-result', array() ) ); } } } } } public static function reset_cache( $sanitized_data ) { delete_transient( 'zoom_instagram_is_configured' ); delete_transient( 'zoom_instagram_user_info' ); // Remove schedule hook `wpzoom_instagram_widget_cron_hook`. if ( empty( $sanitized_data['basic-access-token'] ) ) { wp_clear_scheduled_hook( 'wpzoom_instagram_widget_cron_hook' ); } } /** * @param $screen_name string Instagram username * @param $image_limit int Number of images to retrieve * @param $image_width int Desired image width to retrieve * * @return array|bool Array of tweets or false if method fails */ public function get_items( $instance ) { $sliced = wp_array_slice_assoc( $instance, array( 'image-limit', 'image-width', 'image-resolution', 'username', 'disable-video-thumbs', 'include-pagination', 'bypass-transient', ) ); $image_limit = $sliced['image-limit']; $image_width = $sliced['image-width']; $image_resolution = ! empty( $sliced['image-resolution'] ) ? $sliced['image-resolution'] : 'low_resolution'; $injected_username = ! empty( $sliced['username'] ) ? $sliced['username'] : ''; $disable_video_thumbs = ! empty( $sliced['disable-video-thumbs'] ); $include_pagination = ! empty( $sliced['include-pagination'] ); $bypass_transient = ! empty( $sliced['bypass-transient'] ); if( isset( $instance['widget-id'] ) ) { $transient = 'zoom_instagram_is_configured_' . $instance['widget-id']; } else { $transient = 'zoom_instagram_is_configured'; } if ( ! empty( $this->access_token ) ) { $transient = $transient . '_' . substr( $this->access_token, 0, 20 ); } $injected_username = trim( $injected_username ); if ( ! $bypass_transient ) { $data = json_decode( get_transient( $transient ) ); if ( false !== $data && is_object( $data ) && ! empty( $data->data ) ) { return self::processing_response_data( $data, $image_width, $image_resolution, $image_limit, $disable_video_thumbs, $include_pagination ); } } if ( ! empty( $this->access_token ) ) { $request_url = add_query_arg( array( 'fields' => 'media_url,media_type,caption,username,permalink,thumbnail_url,timestamp,children{media_url,media_type,thumbnail_url}', 'access_token' => $this->access_token, 'limit' => $image_limit, ), 'https://graph.instagram.com/me/media' ); $response = self::remote_get( $request_url, $this->headers ); if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { if ( ! $bypass_transient ) { set_transient( $transient, wp_json_encode( false ), MINUTE_IN_SECONDS ); } $error_data = $this->get_error( 'items-with-token-invalid-response' ); $this->errors->add( $error_data['code'], $error_data['message'] ); return false; } $raw_data = json_decode( wp_remote_retrieve_body( $response ) ); $data = self::convert_items_to_old_structure( $raw_data, $bypass_transient ); if ( $include_pagination && property_exists( $raw_data, 'paging' ) ) { $data->paging = $raw_data->paging; } } if ( ! empty( $data->data ) ) { if ( ! $bypass_transient ) { set_transient( $transient, wp_json_encode( $data ), $this->get_transient_lifetime( $this->feed_id ) ); } } else { if ( ! $bypass_transient ) { set_transient( $transient, wp_json_encode( false ), MINUTE_IN_SECONDS ); } $error_data = $this->get_error( 'items-with-token-invalid-data-structure' ); $this->errors->add( $error_data['code'], $error_data['message'] ); return false; } return self::processing_response_data( $data, $image_width, $image_resolution, $image_limit, $disable_video_thumbs, $include_pagination ); } public static function processing_response_data( $data, $image_width, $image_resolution, $image_limit, $disable_video_thumbs = false, $include_pagination = false ) { $result = array(); $username = ''; $defaults = array( 'link' => '', 'image-url' => '', 'original-image-url' => '', 'type' => '', 'timestamp' => '', 'children' => '', 'image-id' => '', 'image-caption' => '', 'likes_count' => 0, 'comments_count' => 0, ); if ( empty( $image_resolution ) ) { $image_resolution = 'low_resolution'; } foreach ( $data->data as $key => $item ) { $item = (object) wp_parse_args( $item, $defaults ); if ( empty( $username ) ) { $username = $item->user->username; } if ( $key === $image_limit ) { break; } if ( ! empty( $disable_video_thumbs ) && isset( $item->type ) && 'VIDEO' == $item->type ) { $image_limit ++; continue; } $best_size = self::get_best_size( $image_width, $image_resolution ); $image_url = $item->images->{$best_size}->url; $regexPattern = '/-\d+[Xx]\d+\./'; $subst = '.'; $local_image_url = preg_replace( $regexPattern, $subst, $image_url, 1 ); $result[] = array( 'link' => $item->link, 'image-url' => $image_url, 'local-image-url' => $local_image_url, 'original-image-url' => property_exists( $item, 'media_url' ) && ! empty( $item->media_url ) ? $item->media_url : '', 'type' => $item->type, 'timestamp' => property_exists( $item, 'timestamp' ) && ! empty( $item->timestamp ) ? $item->timestamp : '', 'children' => property_exists( $item, 'children' ) && ! empty( $item->children ) ? $item->children : '', 'image-id' => ! empty( $item->id ) ? esc_attr( $item->id ) : '', 'image-caption' => ! empty( $item->caption->text ) ? esc_attr( $item->caption->text ) : '', 'likes_count' => ! empty( $item->likes->count ) ? esc_attr( $item->likes->count ) : 0, 'comments_count' => ! empty( $item->comments->count ) ? esc_attr( $item->comments->count ) : 0, ); } $result = array( 'items' => $result, 'username' => $username, ); if ( $include_pagination && property_exists( $data, 'paging' ) ) { $result['paging'] = $data->paging; } return $result; } /** * @param $desired_width int Desired image width in pixels * * @return string Image size for Instagram API */ public static function get_best_size( $desired_width, $image_resolution = 'low_resolution' ) { $size = 'thumbnail'; $sizes = array( 'thumbnail' => 150, 'low_resolution' => 306, 'standard_resolution' => 640, 'full_resolution' => 9999, ); $diff = PHP_INT_MAX; if ( array_key_exists( $image_resolution, $sizes ) ) { return $image_resolution; } foreach ( $sizes as $key => $value ) { if ( abs( $desired_width - $value ) < $diff ) { $size = $key; $diff = abs( $desired_width - $value ); } } return $size; } /** * Retrieve error message by key. * * @param $key * * @return bool|mixed */ public function get_error( $key ) { $errors = $this->get_errors(); return array_key_exists( $key, $errors ) ? $errors[ $key ] : false; } /** * Get error messages collection. * * @return array */ public function get_errors() { return array( 'user-info-without-token' => array( 'code' => 'user-info-without-token', 'message' => esc_html__( 'Empty json user info from Public Feed.', 'instagram-widget-by-wpzoom' ), ), 'response-data-without-token-from-json-invalid-response' => array( 'code' => 'response-data-without-token-from-json-invalid-response', 'message' => esc_html__( 'The request from the Public Feed failed. Invalid server response from Public JSON API url.', 'instagram-widget-by-wpzoom' ), ), 'response-data-without-token-from-json-invalid-json-format' => array( 'code' => 'response-data-without-token-from-json-invalid-json-format', 'message' => esc_html__( 'The request from the Public Feed failed. Invalid JSON format from Public JSON API url.', 'instagram-widget-by-wpzoom' ), ), 'response-data-without-token-from-html-invalid-response' => array( 'code' => 'response-data-without-token-from-html-invalid-response', 'message' => esc_html__( 'The request from the Public Feed failed. Check username.', 'instagram-widget-by-wpzoom' ), ), 'response-data-without-token-from-html-invalid-json-format' => array( 'code' => 'response-data-without-token-from-html-invalid-json-format', 'message' => esc_html__( 'The request from the Public Feed failed. Invalid JSON format from parsed html body.', 'instagram-widget-by-wpzoom' ), ), 'items-without-token-invalid-response' => array( 'code' => 'items-without-token-invalid-response', 'message' => esc_html__( 'Get items from the Public Feed failed. Invalid response.', 'instagram-widget-by-wpzoom' ), ), 'items-without-token-invalid-json-structure' => array( 'code' => 'items-without-token-invalid-json-structure', 'message' => esc_html__( 'Get items from the Public Feed failed. Malformed data structure.', 'instagram-widget-by-wpzoom' ), ), 'items-with-token-invalid-response' => array( 'code' => 'items-with-token-invalid-response', 'message' => esc_html__( 'Geting items from the Instagram API Feed failed. Invalid response.', 'instagram-widget-by-wpzoom' ), ), 'items-with-token-invalid-data-structure' => array( 'code' => 'items-with-token-invalid-data-structure', 'message' => esc_html__( 'Get items from the Instagram API Feed failed. Malformed data structure.', 'instagram-widget-by-wpzoom' ), ), 'user-with-token-invalid-response' => array( 'code' => 'user-with-token-invalid-response', 'message' => esc_html__( 'Get user data from the Instagram API Feed failed. Invalid response.', 'instagram-widget-by-wpzoom' ), ), 'user-with-token-invalid-data-structure' => array( 'code' => 'user-with-token-invalid-data-structure', 'message' => esc_html__( 'Get user data from the Instagram API Feed failed. Malformed data structure.', 'instagram-widget-by-wpzoom' ), ), ); } public static function convert_items_to_old_structure( $data, $preview = false ) { $converted = new stdClass(); $converted->data = array(); $image_uploader = WPZOOM_Instagram_Image_Uploader::getInstance(); foreach ( $data->data as $key => $item ) { $is_video = property_exists( $item, 'media_type' ) && 'VIDEO' === $item->media_type; $media_url = $is_video && property_exists( $item, 'thumbnail_url' ) && ! empty( $item->thumbnail_url ) ? $item->thumbnail_url : $item->media_url; $converted->data[] = (object) array( 'id' => $item->id, 'media_url' => ( $is_video ? $item->media_url : $media_url ), 'user' => (object) array( 'id' => null, 'fullname' => null, 'profile_picture' => null, 'username' => $item->username, ), 'images' => (object) array( 'thumbnail' => (object) array( 'url' => $preview ? $media_url : $image_uploader->get_image( 'thumbnail', $media_url, $item->id ), 'width' => 150, 'height' => 150, ), 'low_resolution' => (object) array( 'url' => $preview ? $media_url : $image_uploader->get_image( 'low_resolution', $media_url, $item->id ), 'width' => 320, 'height' => 320, ), 'standard_resolution' => (object) array( 'url' => $preview ? $media_url : $image_uploader->get_image( 'standard_resolution', $media_url, $item->id ), 'width' => 640, 'height' => 640, ), 'full_resolution' => (object) array( 'url' => $preview ? $media_url : $image_uploader->get_image( 'full_resolution', $media_url, $item->id ), 'width' => 9999, 'height' => 9999, ), ), 'type' => $item->media_type, 'likes' => null, 'comments' => null, 'created_time' => null, 'timestamp' => $item->timestamp, 'children' => ( isset( $item->children ) ? $item->children : null ), 'link' => $item->permalink, 'caption' => (object) array( 'text' => isset( $item->caption ) ? $item->caption : '', ), ); } return $converted; } function get_transient_lifetime( $id ) { $feed_id = isset( $id ) ? $id : 0; $interval = (int) WPZOOM_Instagram_Widget_Settings::get_feed_setting_value( $feed_id, 'check-new-posts-interval-number' ); $interval_suffix = (int) WPZOOM_Instagram_Widget_Settings::get_feed_setting_value( $feed_id, 'check-new-posts-interval-suffix' ); $values = array( MINUTE_IN_SECONDS, HOUR_IN_SECONDS, DAY_IN_SECONDS, WEEK_IN_SECONDS, MONTH_IN_SECONDS, ); $keys = array_keys( $values ); $type = in_array( $interval_suffix, $keys ) ? $values[ $interval_suffix ] : $values[2]; return intval( $type * $interval ) ; } public function get_user_info( $injected_username = '' ) { $transient = 'zoom_instagram_user_info'; $injected_username = rtrim( $injected_username ); if ( false !== ( $data = json_decode( get_transient( $transient ) ) ) && is_object( $data ) && ! empty( $data->data ) ) { return $data; } if ( ! empty( $this->access_token ) ) { $request_url = add_query_arg( array( 'access_token' => $this->access_token, 'fields' => 'account_type,id,media_count,username', ), 'https://graph.instagram.com/me' ); $response = self::remote_get( $request_url, $this->headers ); if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) ) { set_transient( $transient, wp_json_encode( false ), MINUTE_IN_SECONDS ); $error_data = $this->get_error( 'user-with-token-invalid-response' ); $this->errors->add( $error_data['code'], $error_data['message'] ); return false; } $data = json_decode( wp_remote_retrieve_body( $response ) ); $data = $this->convert_user_info_to_old_structure( $data ); } if ( ! empty( $data->data ) ) { set_transient( $transient, wp_json_encode( $data ), $this->get_transient_lifetime( $this->feed_id ) ); } else { set_transient( $transient, wp_json_encode( false ), MINUTE_IN_SECONDS ); $error_data = $this->get_error( 'user-with-token-invalid-data-structure' ); $this->errors->add( $error_data['code'], $error_data['message'] ); return false; } return $data; } public static function get_basic_user_info_from_token( $access_token ) { $output = false; if ( ! empty( $access_token ) ) { $request_url = add_query_arg( array( 'access_token' => $access_token, 'fields' => 'account_type,username', ), 'https://graph.instagram.com/me' ); $response = self::remote_get( $request_url ); if ( ! is_wp_error( $response ) && 200 == wp_remote_retrieve_response_code( $response ) ) { $output = json_decode( wp_remote_retrieve_body( $response ) ); } } return $output; } function convert_user_info_to_old_structure( $user_info ) { $converted = new stdClass(); $user_info_from_settings = WPZOOM_Instagram_Widget_Settings::get_instance()->get_settings(); $avatar = property_exists( $user_info, 'profile_picture' ) ? $user_info->profile_picture : null; if ( ! empty( $user_info_from_settings['user-info-avatar'] ) ) { $img_src = wp_get_attachment_image_src( $user_info_from_settings['user-info-avatar'] ); if ( ! empty( $img_src ) && is_array( $img_src ) ) { $avatar = $img_src[0]; } } $fullname = ! empty( $user_info->username ) ? $user_info->username : null; if ( ! empty( $user_info_from_settings['user-info-fullname'] ) ) { $fullname = $user_info_from_settings['user-info-fullname']; } $converted->data = (object) array( 'bio' => ! empty( $user_info_from_settings['user-info-biography'] ) ? $user_info_from_settings['user-info-biography'] : null, 'counts' => (object) array( 'followed_by' => null, 'follows' => null, 'media' => null, ), 'full_name' => $fullname, 'id' => ! empty( $user_info->id ) ? $user_info->id : '', 'is_business' => null, 'profile_picture' => $avatar, 'username' => ! empty( $user_info->username ) ? $user_info->username : '', 'website' => null, ); return $converted; } public function is_configured() { $transient = 'zoom_instagram_is_configured'; if ( false !== ( $result = json_decode( get_transient( $transient ) ) ) ) { if ( 'yes' === $result ) { return true; } if ( 'no' === $result ) { return false; } if ( ! empty( $result ) ) { return true; } } $condition = $this->is_access_token_valid( $this->access_token ); if ( true === $condition ) { set_transient( $transient, wp_json_encode( 'yes' ), DAY_IN_SECONDS ); return true; } set_transient( $transient, wp_json_encode( 'no' ), DAY_IN_SECONDS ); return false; } /** * Check if given access token is valid for Instagram Api. */ public static function is_access_token_valid( $access_token ) { if ( empty( $access_token ) ) { return false; } $request_url = add_query_arg( array( 'fields' => 'username', 'access_token' => $access_token, ), 'https://graph.instagram.com/me' ); $response = self::remote_get( $request_url ); if ( is_wp_error( $response ) ) { return $response; } if ( 200 != wp_remote_retrieve_response_code( $response ) ) { return false; } return true; } } Wpzoom_Instagram_Widget_API::getInstance(); /** * * Enqueue CSS/JS of the plugin. * * @since 2.0.2 * @package WPZOOM_Instagram_Widget */ // Exit if accessed directly. if ( ! defined( 'ABSPATH' ) ) { exit; } if ( ! class_exists( 'WPZOOM_Instagram_Widget_Assets ' ) ) { /** * Main WPZOOM_Instagram_Widget_Assets Class. * * @since 2.0.2 */ class WPZOOM_Instagram_Widget_Assets { /** * This plugin's instance. * * @var WPZOOM_Instagram_Widget_Assets * @since 2.0.2 */ private static $instance; /** * Provides singleton instance. * * @since 2.0.2 * @return self instance */ public static function instance() { if ( null === self::$instance ) { self::$instance = new WPZOOM_Instagram_Widget_Assets(); } return self::$instance; } /** * The base directory path. * * @var string $_dir */ private $_dir; /** * The base URL path. * * @var string $_url */ private $_url; /** * The Constructor. */ public function __construct() { add_action( 'enqueue_block_assets', array( $this, 'frontend_register_scripts' ), 5 ); add_action( 'enqueue_block_assets', array( $this, 'widget_styles' ), 5 ); add_action( 'enqueue_block_editor_assets', array( $this, 'register_block_assets' ) ); add_action( 'enqueue_block_editor_assets', array( $this, 'widget_styles' ) ); add_action( 'wp_enqueue_scripts', array( $this, 'widget_styles' ) ); add_action( 'wp_enqueue_scripts', array( $this, 'register_widget_scripts' ) ); add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_widget_scripts' ) ); /** * Enqueue styles and scripts for SiteOrigin Page Builder. */ add_action( 'siteorigin_panel_enqueue_admin_scripts', array( $this, 'widget_styles' ) ); add_action( 'siteorigin_panel_enqueue_admin_scripts', array( $this, 'register_widget_scripts' ) ); add_action( 'siteorigin_panel_enqueue_admin_scripts', array( $this, 'enqueue_widget_scripts' ) ); } public function frontend_register_scripts() { global $post; $general_options = get_option( 'wpzoom-instagram-general-settings' ); $should_enqueue = has_block( 'wpzoom/instagram-block' ); $has_reusable_block = self::has_reusable_block( 'wpzoom/instagram-block' ); $is_active_widget = is_active_widget( false, false, 'wpzoom_instagram_widget', false ); $has_shortcode = ( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'instagram' ) ); $has_widget_block = self::is_active_block_widget( 'wpzoom/instagram-block' ); $load_css_js = isset( $general_options['load-css-js'] ) ? true : false; $script_asset_file = include( plugin_dir_path( __FILE__ ) . 'dist/scripts/backend/block.asset.php' ); $style_asset_file = include( plugin_dir_path( __FILE__ ) . 'dist/styles/frontend/index.asset.php' ); if( is_admin() || $load_css_js || $should_enqueue || $has_reusable_block || $is_active_widget || $has_shortcode || $has_widget_block || isset( $_GET['wpz-insta-widget-preview'] ) ) { wp_register_script( 'magnific-popup', plugins_url( 'dist/scripts/library/magnific-popup.js', __FILE__ ), array( 'jquery', 'underscore', 'wp-util' ), filemtime( plugin_dir_path( __FILE__ ) . 'dist/scripts/library/magnific-popup.js' ), true ); wp_register_script( 'swiper-js', plugins_url( 'dist/scripts/library/swiper.js', __FILE__ ), array(), '7.4.1' ); wp_register_script( 'wpz-insta_block-frontend-script', plugins_url( 'dist/scripts/frontend/block.js', __FILE__ ), array( 'jquery', 'underscore', 'magnific-popup', 'swiper-js' ), $script_asset_file['version'] ); wp_register_style( 'magnific-popup', plugins_url( 'dist/styles/library/magnific-popup.css', __FILE__ ), array( 'dashicons' ), WPZOOM_INSTAGRAM_VERSION ); wp_register_style( 'wpz-insta_block-frontend-style', plugins_url( 'dist/styles/frontend/index.css', __FILE__ ), array( 'magnific-popup', 'swiper-css' ), $style_asset_file['version'] ); } } public function register_block_assets() { $script_asset_file = include( plugin_dir_path( __FILE__ ) . 'dist/scripts/backend/block.asset.php' ); $style_asset_file = include( plugin_dir_path( __FILE__ ) . 'dist/styles/frontend/index.asset.php' ); wp_register_script( 'wpz-insta_block-backend-script', plugins_url( 'dist/scripts/backend/block.js', __FILE__ ), $script_asset_file['dependencies'], $script_asset_file['version'] ); } /** * Load widget specific styles. */ public function widget_styles() { global $post; $general_options = get_option( 'wpzoom-instagram-general-settings' ); $should_enqueue = has_block( 'wpzoom/instagram-block' ); $has_reusable_block = self::has_reusable_block( 'wpzoom/instagram-block' ); $is_active_widget = is_active_widget( false, false, 'wpzoom_instagram_widget', false ); $has_shortcode = ( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'instagram' ) ); $has_widget_block = self::is_active_block_widget( 'wpzoom/instagram-block' ); $load_css_js = isset( $general_options['load-css-js'] ) ? true : false; if( is_admin() || $load_css_js || $should_enqueue || $has_reusable_block || $is_active_widget || $has_shortcode || $has_widget_block || isset( $_GET['wpz-insta-widget-preview'] ) ) { wp_enqueue_style( 'swiper-css', plugin_dir_url( __FILE__ ) . 'dist/styles/library/swiper.css', array(), '7.4.1' ); wp_enqueue_style( 'wpz-insta_block-frontend-style', plugin_dir_url( __FILE__ ) . 'dist/styles/frontend/index.css', array( 'dashicons' ), WPZOOM_INSTAGRAM_VERSION ); wp_enqueue_style( 'magnific-popup', plugin_dir_url( __FILE__ ) . 'dist/styles/library/magnific-popup.css', array( 'dashicons' ), WPZOOM_INSTAGRAM_VERSION ); } } /** * Register widget specific scripts. */ public function register_widget_scripts() { wp_register_script( 'zoom-instagram-widget-lazy-load', plugin_dir_url( __FILE__ ) . 'dist/scripts/library/lazy.js', array( 'jquery' ), filemtime( plugin_dir_path( __FILE__ ) . 'dist/scripts/library/lazy.js' ), true ); wp_register_script( 'magnific-popup', plugin_dir_url( __FILE__ ) . 'dist/scripts/library/magnific-popup.js', array( 'jquery', 'underscore', 'wp-util' ), filemtime( plugin_dir_path( __FILE__ ) . 'dist/scripts/library/magnific-popup.js' ), true ); wp_register_script( 'swiper-js', plugin_dir_url( __FILE__ ) . 'dist/scripts/library/swiper.js', array(), '7.0.0-alpha.21', true ); wp_register_script( 'zoom-instagram-widget', plugin_dir_url( __FILE__ ) . 'dist/scripts/frontend/index.js', array( 'jquery', 'underscore', 'wp-util', 'magnific-popup', 'swiper-js' ), WPZOOM_INSTAGRAM_VERSION, true ); } /** * Load widget specific scripts. */ public function enqueue_widget_scripts() { global $post; $general_options = get_option( 'wpzoom-instagram-general-settings' ); $should_enqueue = has_block( 'wpzoom/instagram-block' ); $has_reusable_block = self::has_reusable_block( 'wpzoom/instagram-block' ); $is_active_widget = is_active_widget( false, false, 'wpzoom_instagram_widget', false ); $has_shortcode = ( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'instagram' ) ); $has_widget_block = self::is_active_block_widget( 'wpzoom/instagram-block' ); $load_css_js = isset( $general_options['load-css-js'] ) ? true : false; if( is_admin() || $load_css_js || $should_enqueue || $has_reusable_block || $is_active_widget || $has_shortcode || $has_widget_block || isset( $_GET['wpz-insta-widget-preview'] ) ) { wp_enqueue_script( 'zoom-instagram-widget-lazy-load' ); wp_enqueue_script( 'magnific-popup' ); wp_enqueue_script( 'swiper-js' ); wp_enqueue_script( 'zoom-instagram-widget' ); wp_enqueue_script( 'wpz-insta_block-frontend-script' ); } } /** * Check the widget block based area has the block * * @since 2.0.2 * @param string $block_name The block name. * @return boolean Return true if post content has provided block name as reusable block, else return false. */ public static function is_active_block_widget( $blockname ) { $allwidgets = []; $widget_blocks = get_option( 'widget_block' ); $sidebars_widgets = get_option('sidebars_widgets'); if( is_array( $sidebars_widgets ) ) { foreach ( $sidebars_widgets as $key => $value ) { if( is_array( $value ) ) { foreach ($value as $widget_id) { $pieces = explode( '-', $widget_id ); $multi_number = array_pop( $pieces ); $id_base = implode( '-', $pieces ); $widget_data = get_option( 'widget_' . $id_base ); // Remove inactive widgets if( $key != 'wp_inactive_widgets' ) { unset( $widget_data['_multiwidget'] ); $allwidgets[ $key ] = $widget_data; } } } } } foreach( (array) $allwidgets as $widget ) { foreach( (array) $widget as $widget_element ) { foreach( (array)$widget_element as $value ) { if( is_string( $value ) && has_shortcode( $value, 'instagram' ) ) { return true; } } } } foreach( (array) $widget_blocks as $widget_block ) { if ( ! empty( $widget_block['content'] ) && ( has_block( $blockname, $widget_block['content'] ) || has_shortcode( $widget_block['content'], 'instagram' ) ) ) { return true; } } return false; } /** * Check the post content has reusable block * * @since 2.0.2 * @param string $block_name The block name. * @param int $post_id The post ID. * @param int $reusable_block_id The reusable block post ID. * @param boolean|int $content The post content. * @return boolean Return true if post content has provided block name as reusable block, else return false. */ public static function has_reusable_block( $block_name, $post_id = 0, $reusable_block_id = 0, $content = '' ) { $has_reusable_block = false; $post_id = $post_id > 0 ? $post_id : get_the_ID(); /** * Loop reusable blocks to get needed block * * @since 2.0.2 */ if ( ! empty( self::get_reusable_block( absint( $reusable_block_id ) ) ) ) { $args = array( 'post_type' => 'wp_block', 'posts_per_page' => -1, 'post_status' => 'publish', ); $query = new WP_Query( $args ); while ( $query->have_posts() ) { $query->the_post(); if ( absint( $reusable_block_id ) === get_the_ID() ) { $content = get_post_field( 'post_content', get_the_ID() ); if ( has_block( $block_name, $content ) ) { $has_reusable_block = true; return $has_reusable_block; } } } // Reset global post variable. After this point, we are back to the Main Query object. wp_reset_postdata(); } // Early return if $has_reusable_block is true. if ( true === $has_reusable_block ) { return; } if ( empty( $content ) ) { $content = get_post_field( 'post_content', $post_id ); } if ( $content ) { if ( has_block( 'block', $content ) ) { // Check reusable blocks. $blocks = parse_blocks( $content ); if ( ! is_array( $blocks ) || empty( $blocks ) ) { return false; } foreach ( $blocks as $block ) { if ( $block['blockName'] === 'core/block' && ! empty( $block['attrs']['ref'] ) ) { $reusable_block_id = absint( $block['attrs']['ref'] ); if ( has_block( $block_name, $reusable_block_id ) ) { return true; } elseif ( ! empty( self::get_reusable_block( $reusable_block_id ) ) ) { return true; } } } } elseif ( has_block( $block_name, $content ) ) { return true; } elseif ( has_shortcode( $content, 'reblex' ) ) { return true; } else { return false; } } return false; } /** * Get reusable block. * * @since 2.0.2 * @param int $id Reusable block id. * @return string Reusable block post content. */ public static function get_reusable_block( $id ) { $post = ''; if ( ! is_string( $id ) && $id > 0 ) { $wp_post = get_post( $id ); if ( $wp_post instanceof WP_Post ) { $post = $wp_post->post_content; } } return $post; } } } WPZOOM_Instagram_Widget_Assets::instance(); /** * WPZOOM Portfolio * * @package WPZOOM_Portfolio * @author WPZOOM * @copyright 2022 WPZOOM * @license GPL-2.0-or-later * * @wordpress-plugin * Plugin Name: WPZOOM Portfolio * Plugin URI: https://www.wpzoom.com/plugins/wpzoom-portfolio/ * Description: The ultimate solution for creatives, designers, photographers, and businesses looking to showcase their work in an elegant, professional, and fully customizable way. * Author: WPZOOM * Author URI: https://www.wpzoom.com * Text Domain: wpzoom-portfolio * Version: 1.4.2 * License: GPL2+ * License URI: http://www.gnu.org/licenses/gpl-2.0.txt */ // Exit if accessed directly defined( 'ABSPATH' ) || exit; if ( ! defined( 'WPZOOM_PORTFOLIO_VERSION' ) ) { define( 'WPZOOM_PORTFOLIO_VERSION', get_file_data( __FILE__, [ 'Version' ] )[0] ); // phpcs:ignore } // settings page url attribute define( 'WPZOOM_PORTFOLIO_SETTINGS_PAGE', 'wpzoom-portfolio-settings' ); define( 'WPZOOM_PORTFOLIO__FILE__', __FILE__ ); define( 'WPZOOM_PORTFOLIO_PLUGIN_BASE', plugin_basename( WPZOOM_PORTFOLIO__FILE__ ) ); define( 'WPZOOM_PORTFOLIO_PLUGIN_DIR', dirname( WPZOOM_PORTFOLIO_PLUGIN_BASE ) ); define( 'WPZOOM_PORTFOLIO_PATH', plugin_dir_path( WPZOOM_PORTFOLIO__FILE__ ) ); define( 'WPZOOM_PORTFOLIO_URL', plugin_dir_url( WPZOOM_PORTFOLIO__FILE__ ) ); // Instance the plugin $wpzoom_blocks = new WPZOOM_Blocks(); // Register plugin activation hook register_activation_hook( __FILE__, array( $wpzoom_blocks, 'activate' ) ); // Hook the plugin into WordPress add_action( 'init', array( $wpzoom_blocks, 'init' ) ); /** * Class WPZOOM_Blocks * * Main container class of the WPZOOM Blocks WordPress plugin. * * @since 1.0.0 */ class WPZOOM_Blocks { /** * Whether the plugin has been initialized. * * @var boolean * @access public * @since 1.0.0 */ public $initialized = false; /** * The path to this plugin's root directory. * * @var string * @access public * @since 1.0.0 */ public $plugin_dir_path; /** * The URL to this plugin's root directory. * * @var string * @access public * @since 1.0.0 */ public $plugin_dir_url; /** * The path to this plugin's "main" directory. * * @var string * @access public * @since 1.0.0 */ public $main_dir_path; /** * The URL to this plugin's "main" directory. * * @var string * @access public * @since 1.0.0 */ public $main_dir_url; /** * The path to this plugin's "blocks" directory. * * @var string * @access public * @since 1.0.0 */ public $blocks_dir_path; /** * The URL to this plugin's "blocks" directory. * * @var string * @access public * @since 1.0.0 */ public $blocks_dir_url; /** * Initializes the plugin and sets up needed hooks and features. * * @access public * @return void * @since 1.0.0 * @see WPZOOM_Blocks::load_assets() */ public function init() { // If the plugin has not already been initialized... if ( false === $this->initialized ) { // Assign the values for the plugins 'root' dir/url $this->plugin_dir_path = plugin_dir_path( __FILE__ ); $this->plugin_dir_url = plugin_dir_url( __FILE__ ); // Assign the values for the plugins 'main' dir/url $this->main_dir_path = trailingslashit( $this->plugin_dir_path . 'build' ); $this->main_dir_url = trailingslashit( $this->plugin_dir_url . 'build' ); // Assign the values for the plugins 'blocks' dir/url $this->blocks_dir_path = trailingslashit( $this->main_dir_path . 'blocks' ); $this->blocks_dir_url = trailingslashit( $this->main_dir_url . 'blocks' ); // Load the correct translation files for the plugin load_plugin_textdomain( 'wpzoom-portfolio', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' ); // Filter the Gutenberg block categories to add our custom 'WPZOOM Blocks' category if needed add_filter( 'block_categories_all', array( $this, 'filter_block_categories' ), 10, 2 ); // Load in all needed assets for the plugin $this->load_assets(); // Enqueue the main/root scripts and styles in the Gutenberg editor add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_portfolio_block_editor_assets' ) ); add_action( 'enqueue_block_assets', array( $this, 'enqueue_portfolio_block_assets' ) ); // Hook into the REST API in order to add some custom things add_action( 'rest_api_init', array( $this, 'rest_api_routes' ) ); // Add some extra needed styles on the frontend add_action( 'wp_enqueue_scripts', function() { wp_enqueue_script( 'jquery' ); wp_enqueue_style( 'dashicons' ); } ); // Mark the plugin as initialized $this->initialized = true; } } /** * Runs once during the activation of the plugin to run some one-time setup functions. * * @access public * @return void * @since 1.0.0 */ public function enqueue_portfolio_block_editor_assets() { wp_enqueue_script( 'masonry' ); $options = get_option( 'wpzoom-portfolio-settings' ); wp_enqueue_script( 'wpzoom-blocks-js-index-main' ); wp_localize_script( 'wpzoom-blocks-js-index-main', 'wpzoomPortfolioBlock', array( 'setting_options' => ( !empty( $options ) ? $options : array() ) ) ); wp_enqueue_style( 'wpzoom-blocks-css-editor-main' ); } /** * Runs once during the activation of the plugin to run some one-time setup functions. * * @access public * @return void * @since 1.0.0 */ public function enqueue_portfolio_block_assets() { $should_enqueue = has_block( 'wpzoom-blocks/portfolio' ) || has_block( 'wpzoom-blocks/portfolio-layouts' ) || WPZOOM_Portfolio_Assets_Manager::has_wpzoom_portfolio_shortcode(); if( ! $should_enqueue ) { return; } wp_enqueue_script( 'masonry' ); wp_enqueue_script( 'wpzoom-blocks-js-script-main' ); wp_enqueue_style( 'wpzoom-blocks-css-style-main' ); } /** * Runs once during the activation of the plugin to run some one-time setup functions. * * @access public * @return void * @since 1.0.0 * @see WPZOOM_Blocks::init() */ public function activate() { // Make sure the plugin is initialized $this->init(); // Flush the rewrite rules so any custom post types work correctly flush_rewrite_rules(); } /** * Loads in all the needed assets for the plugin. * * @access public * @return void * @since 1.0.0 * @see register_block_type() */ public function load_assets() { // Set a fallback for files with no version/dependency info $no_asset = array( 'dependencies' => array( 'wp-blocks', 'wp-data', 'wp-element', 'wp-i18n', 'wp-polyfill' ), 'version' => '-1' ); // Go through the main directory and each sub-directory in the blocks directory... foreach ( array_merge( array( $this->main_dir_path ), glob( $this->blocks_dir_path . '*', GLOB_ONLYDIR | GLOB_NOSORT ) ) as $path ) { // Get the slug for the directory in the current iteration $slug = 0 === substr_compare( $path, 'build/', -strlen( 'build/' ) ) ? 'main' : str_replace( $this->blocks_dir_path, '', $path ); // Get a version of the slug with dashes replaced by underscores $slug_ = str_replace( '-', '_', $slug ); // Consistent slashing $path = trailingslashit( $path ); // Go through every possible script/style there could be in the directory from the current iteration... foreach ( array( 'index' => 'js', 'script' => 'js', 'editor' => 'css', 'style' => 'css' ) as $name => $ext ) { // If a script/style with the given name exists in the directory from the current iteration... if ( file_exists( "$path$name.$ext" ) ) { // Get the version/dependency info $asset_file = "$path$name.asset.php"; $asset = file_exists( $asset_file ) ? require_once( $asset_file ) : $no_asset; // Register the script/style so it can be enqueued later $func = 'js' == $ext ? 'wp_register_script' : 'wp_register_style'; $url = trailingslashit( 'main' == $slug_ ? $this->main_dir_url : $this->blocks_dir_url . $slug ) . "$name.$ext"; $depends = 'js' == $ext ? $asset[ 'dependencies' ] : array(); $func( "wpzoom-blocks-$ext-$name-$slug_", $url, $depends, $asset[ 'version' ], ( 'main' != $slug_ && 'js' == $ext ) ); // If the file in the current iteration is a script... if ( 'js' == $ext && function_exists( 'wp_set_script_translations' ) ) { // Setup the translations for it wp_set_script_translations( "wpzoom-blocks-js-$name-$slug_", 'wpzoom-portfolio', plugin_dir_path( __FILE__ ) . 'languages' ); } } } // If the file in the current iteration is in a block... if ( 'main' != $slug_ ) { // Include the index.php file if the block has one if ( file_exists( $path . 'index.php' ) ) { require_once( $path . 'index.php' ); } // Construct the arguments array $args = array( 'editor_script' => "wpzoom-blocks-js-index-$slug_", 'editor_style' => "wpzoom-blocks-css-editor-$slug_", 'script' => "wpzoom-blocks-js-script-$slug_", 'style' => "wpzoom-blocks-css-style-$slug_" ); // Construct the class name to use below $class_name = 'WPZOOM_Blocks_' . ucwords( $slug_, '_' ); // If a class with the given name exists... if ( class_exists( $class_name ) ) { // Instantiate the class $class = new $class_name(); // Add attributes if they have been declared in the class if ( property_exists( $class, 'attributes' ) ) { $args[ 'attributes' ] = $class->attributes; } // Add a render callback if one is specified in the class if ( method_exists( $class, 'render' ) ) { $args[ 'render_callback' ] = array( $class, 'render' ); } } // Register the block with Gutenberg using the given arguments register_block_type( "wpzoom-blocks/$slug", $args ); } } } /** * Adds the WPZOOM category to the Gutenberg block categories, if not already present. * * @access public * @param array $categories Array containing all registered Gutenberg block categories. * @param WP_Post $post A WP_Post object representing the post being loaded. * @return array * @since 1.0.0 */ public function filter_block_categories( $categories, $post ) { // Get a list of all the block category slugs $category_slugs = wp_list_pluck( $categories, 'slug' ); // Return the list of categories with our custom category included return in_array( 'wpzoom-blocks', $category_slugs, true ) ? $categories : array_merge( $categories, array( array( 'slug' => 'wpzoom-blocks', 'title' => esc_html__( 'WPZOOM - Blocks', 'wpzoom-portfolio' ) ) ) ); } /** * Adds extra needed routes in the WordPress REST API. * * @access public * @return void * @since 1.0.0 * @see register_rest_route() * @see register_rest_field() * @see WPZOOM_Blocks::get_rest_image_sizes() * @see WPZOOM_Blocks::get_featured_media_urls() */ public function rest_api_routes() { // Register the 'image-sizes' REST API route register_rest_route( 'wpzoom-blocks/v1', '/image-sizes', array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_rest_image_sizes' ), 'permission_callback' => function() { return current_user_can( 'edit_posts' ); } ) ); // Register the 'featured_media_urls' REST API field on all post types register_rest_field( get_post_types(), 'featured_media_urls', array( 'get_callback' => array( $this, 'get_featured_media_urls' ), 'update_callback' => null, 'schema' => array( 'description' => esc_html__( 'Different sized featured images', 'wpzoom-portfolio' ), 'type' => 'array' ) ) ); } /** * Returns a REST response containing all available media library image sizes. * * @access public * @return array * @since 1.0.0 * @see get_intermediate_image_sizes() */ public function get_rest_image_sizes() { // Call the built-in get_intermediate_image_sizes() WordPress function to get an array of sizes $raw_sizes = get_intermediate_image_sizes(); // Build an array with sizes and their labels $sizes = array(); foreach ( $raw_sizes as $raw_size ) { $sizes[] = array( 'label' => ucwords( preg_replace( '/[_-]/', ' ', $raw_size ) ), 'value' => $raw_size ); } // Return the sizes array properly formatted for a rest response return rest_ensure_response( $sizes ); } /** * Returns an array of all the available image size URLs for the featured media from the given post object. * * @access public * @param WP_Post|Object $object The object that is the context to get the featured media ID from. * @return array * @since 1.0.0 * @see get_intermediate_image_sizes() * @see wp_get_attachment_image_src() */ function get_featured_media_urls( $object ) { // Initialize the array that will be returned $featured_media_urls = array(); // If the given object has attached featured media... if ( isset( $object[ 'featured_media' ] ) ) { // Keep track of the featured media ID $featured_media_id = $object[ 'featured_media' ]; // Call wp_get_attachment_image_src() with the default options for the best chance to get a fallback $thumb = wp_get_attachment_image_src( $featured_media_id ); // If the size above was found... if ( is_array( $thumb ) ) { // Set it so it will be present as a fallback if no other sizes can be found $featured_media_urls[ 'thumbnail' ] = $thumb; } // Go through every available image size... foreach ( get_intermediate_image_sizes() as $size ) { // Get the featured media source attached to the given object in the size from the current iteration $src = wp_get_attachment_image_src( $featured_media_id, $size, false ); // If the size was found... if ( is_array( $src ) ) { // Add it to the array of size URLs $featured_media_urls[ $size ] = $src; } } } // Return the array return $featured_media_urls; } } function wpzoom_theme_has_portfolio() { $wpzoom_themes = array( 'angle', 'inspiro', 'wpzoom-inspiro-pro', 'wpzoom-reel', 'wpzoom-rezzo' ); $current_theme = get_option( 'stylesheet' ); if( ! in_array( $current_theme, $wpzoom_themes ) ) { return false; } else { if( 'inspiro' == $current_theme ) { $theme = wp_get_theme(); if( 'https://www.wpzoom.com/free-wordpress-themes/inspiro-lite/' == $theme->get( 'ThemeURI' ) ) { return false; } } } return true; } if( ! function_exists( 'wpzoom_portfolio_load_files' ) ) { function wpzoom_portfolio_load_files() { //Add Portfolio Shortcode require_once 'classes/class-wpzoom-portfolio-shortcode.php'; require_once 'classes/class-wpzoom-portfolio-admin-menu.php'; require_once 'classes/class-wpzoom-portfolio-custom-posts.php'; require_once 'classes/class-wpzoom-portfolio-assets-manager.php'; require_once 'classes/class-wpzoom-wptt-webfont-loader.php'; //Load Settings Panel require_once 'classes/class-wpzoom-settings-fields.php'; require_once 'classes/class-wpzoom-portfolio-settings-page.php'; if( ! wpzoom_theme_has_portfolio() ) { //Load Archive template require_once 'classes/class-wpzoom-portfolio-template.php'; } if( ! wpzoom_theme_has_portfolio() ) { //Load Archive template require_once 'classes/class-wpzoom-portfolio-template.php'; } if( ! class_exists( 'WPZOOM_Portfolio_Pro' ) && ! wpzoom_theme_has_portfolio() ) { require_once 'classes/class-wpzoom-portfolio-metaboxes-upsell.php'; } } add_action( 'plugin_loaded', 'wpzoom_portfolio_load_files' ); } function load_reorder_portfolio_items() { if( ! current_user_can( 'edit_posts' ) || current_theme_supports( 'zoom-portfolio' ) ) { return; } //Load Re-Order feature require_once 'classes/featured-posts/class-wpzoom-portfolio-featured-posts.php'; $wpzoom_portfrolio_reorder_settings = array( //Unique Id that is used to add the new column in posts list table. 'id' => 'wpzoom_is_featured_id', //Label that appears in the submenu of post types 'menu_title' => __( 'Re-order', 'wpzoom-portfolio' ), //Post type in which this feature will be added. 'post_type' => 'portfolio_item', ); $featured_posts_plugin_uri = WPZOOM_PORTFOLIO_URL . '/classes/featured-posts/'; $list_table_checkbox_directory_uri = WPZOOM_PORTFOLIO_URL . '/classes/featured-posts/list-table-checkbox'; new WPZOOM_Featured_Posts( $wpzoom_portfrolio_reorder_settings, $featured_posts_plugin_uri ); } add_action( 'init', 'load_reorder_portfolio_items' ); add_action( 'init', 'WPZOOM_Blocks_Portfolio_Shortcode::instance' );/** * Plugin Name: Video Popup Block by WPZOOM * Plugin URI: https://wordpress.org/plugins/wpzoom-video-popup-block/ * Description: Quickly add a button displaying a YouTube, Vimeo or Self-Hosted (MP4) video in a popup when clicked. * Version: 1.1.1 * Author: WPZOOM * Author URI: https://www.wpzoom.com/ * Text Domain: wpzoom-video-popup-block * Domain Path: /languages * License: GPLv2 or later * License URI: https://www.gnu.org/licenses/gpl-2.0.html * Requires at least: 6.0 * Requires PHP: 7.2 * Tested up to: 6.4 * * @package Wpzoom_Video_Popup_Block */ namespace WPZOOM\Video_Popup_Block; // Exit if accessed directly. defined( 'ABSPATH' ) || exit; // Intitalize the plugin. new Plugin(); /** * Main WPZOOM Video Popup Block class. * * The entry point into WordPress for this plugin. * * @since 1.0.0 */ class Plugin { /** * The version of this plugin. * * @since 1.0.0 * @var int */ public const VERSION = '1.1.1'; /** * Path to the plugin directory. * * @since 1.0.0 * @var string */ public $plugin_path; /** * URL to the plugin directory. * * @since 1.0.0 * @var string */ public $plugin_url; /** * Main directory name of the plugin. * * @since 1.0.0 * @var string */ public $plugin_dirname; /** * Main file name of the plugin. * * @since 1.0.0 * @var string */ public $plugin_filename; /** * The name of the block this plugin adds. * * @since 1.0.0 * @var string */ public $block_name; /** * Plugin class constructor. * * @since 1.0.0 * @return void */ public function __construct() { $this->plugin_path = plugin_dir_path( __FILE__ ); $this->plugin_url = plugin_dir_url( __FILE__ ); $this->plugin_dirname = trailingslashit( wp_basename( __DIR__ ) ); $this->plugin_filename = wp_basename( __FILE__ ); $this->block_name = 'wpzoom-video-popup-block/block'; // Do some initial setup on the WordPress `init` hook. add_action( 'init', array( $this, 'init' ) ); // Add the WPZOOM block category, if needed. add_filter( 'block_categories_all', array( $this, 'block_categories' ), 10, 2 ); // Add some useful CSS classes. add_filter( 'body_class', array( $this, 'body_class' ) ); add_filter( 'admin_body_class', array( $this, 'admin_body_class' ) ); } /** * Initializes the plugin and hooks into WordPress. * * @since 1.0.0 * @return void */ public function init() { // Load the translations for the plugin. load_plugin_textdomain( 'wpzoom-video-popup-block', false, $this->plugin_dirname . 'languages/' ); // Register the main block in Gutenberg. register_block_type( $this->plugin_path . 'block.json' ); // Setup translations for the main block. wp_set_script_translations( 'wpzoom-video-popup-block-block-editor-script-js', 'wpzoom-video-popup-block', $this->plugin_path . 'languages/' ); } /** * Adds the WPZOOM block category if needed. * * @since 1.0.0 * @param array $categories The list of existing block categories. * @return array The modified list of block categories. */ public function block_categories( $categories ) { if ( empty( $categories ) || ( ! empty( $categories ) && is_array( $categories ) && ! in_array( 'wpzoom-blocks', wp_list_pluck( $categories, 'slug' ), true ) ) ) { $categories = array_merge( $categories, array( array( 'slug' => 'wpzoom-blocks', 'title' => esc_html__( 'WPZOOM - Blocks', 'wpzoom-video-popup-block' ), ), ) ); } return $categories; } /** * Returns whether the plugin is in "PRO" mode. * * @since 1.0.1 * @return bool Boolean indicating whether the plugin is in "PRO" mode. */ public function is_pro() { return boolval( apply_filters( 'wpzoom_video_popup_block_is_pro', false ) ); } /** * Adds some classes for the plugin to the `` tag of the page. * * @since 1.0.1 * @param array $classes Array of existing classes. * @return array The modified classes array. */ public function body_class( $classes ) { if ( has_block( 'wpzoom-video-popup-block/block' ) ) { $classes[] = 'wpzoom-video-popup_enabled'; if ( is_admin() ) { $classes[] = 'wpzoom-video-popup_admin'; } if ( $this->is_pro() ) { $classes[] = 'wpzoom-video-popup_is-pro'; } } return $classes; } /** * Adds some classes for the plugin to the `` tag of the WordPress admin. * * @since 1.0.1 * @param string $classes Space-separated string of existing classes. * @return string The modified classes string. */ public function admin_body_class( $classes ) { if ( has_block( 'wpzoom-video-popup-block/block' ) ) { $classes .= ' wpzoom-video-popup_enabled '; if ( is_admin() ) { $classes .= ' wpzoom-video-popup_admin '; } if ( $this->is_pro() ) { $classes .= ' wpzoom-video-popup_is-pro '; } } return $classes; } } /** * Inspiro functions and definitions * * @link https://developer.wordpress.org/themes/basics/theme-functions/ * * @package Inspiro * @since Inspiro 1.0.0 */ if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Define Constants */ define( 'INSPIRO_THEME_VERSION', '2.1.3' ); define( 'INSPIRO_THEME_DIR', trailingslashit( get_template_directory() ) ); define( 'INSPIRO_THEME_URI', trailingslashit( esc_url( get_template_directory_uri() ) ) ); define( 'INSPIRO_THEME_ASSETS_URI', INSPIRO_THEME_URI . 'dist' ); // Marketing define( 'INSPIRO_MARKETING_UTM_CODE_STARTER_SITE', '?utm_source=wpadmin&utm_medium=starter-sites&utm_campaign=upgrade-premium' ); define( 'INSPIRO_MARKETING_UTM_CODE_FOOTER_MENU', '?utm_source=wpadmin&utm_medium=footer-menu&utm_campaign=upgrade-premium' ); // This theme requires WordPress 5.3 or later. if ( version_compare( $GLOBALS['wp_version'], '5.3', '<' ) ) { require INSPIRO_THEME_DIR . 'inc/back-compat.php'; } /** * Recommended Plugins */ require INSPIRO_THEME_DIR . 'inc/classes/class-tgm-plugin-activation.php'; /** * Setup helper functions. */ require INSPIRO_THEME_DIR . 'inc/common-functions.php'; /** * Setup theme media. */ require INSPIRO_THEME_DIR . 'inc/theme-media.php'; /** * Enqueues scripts and styles */ require INSPIRO_THEME_DIR . 'inc/classes/class-inspiro-enqueue-scripts.php'; /** * Starter Content Notice */ require INSPIRO_THEME_DIR . 'inc/classes/class-inspiro-starter-content-notice.php'; /** * Setup custom wp-admin options pages */ require INSPIRO_THEME_DIR . 'inc/classes/class-inspiro-custom-wp-admin-menu.php'; /** * Additional features to include custom WP pointer function */ require INSPIRO_THEME_DIR . 'inc/classes/class-inspiro-wp-admin-menu-pointer.php'; /** * Functions and definitions. */ require INSPIRO_THEME_DIR . 'inc/classes/class-inspiro-after-setup-theme.php'; /** * Handle SVG icons. */ require INSPIRO_THEME_DIR . 'inc/classes/class-inspiro-svg-icons.php'; /** * Implement the Custom Header feature. */ require INSPIRO_THEME_DIR . 'inc/custom-header.php'; /** * Custom template tags for this theme. */ require INSPIRO_THEME_DIR . 'inc/template-tags.php'; /** * Additional features to allow styling of the templates. */ require INSPIRO_THEME_DIR . 'inc/template-functions.php'; /** * Custom Template WC functions */ require INSPIRO_THEME_DIR . 'inc/wc-custom-functions.php'; /** * Editor Fonts */ require INSPIRO_THEME_DIR . 'inc/editor-fonts.php'; /** * Custom template shortcode tags for this theme */ // require INSPIRO_THEME_DIR . 'inc/shortcodes.php'; /** * Customizer additions. */ require INSPIRO_THEME_DIR . 'inc/classes/class-inspiro-font-family-manager.php'; require INSPIRO_THEME_DIR . 'inc/classes/class-inspiro-fonts-manager.php'; // Include Customizer Guided Tour if ( is_admin() ) { // && is_customize_preview(), AJAX don't work with is_customize_preview() included require INSPIRO_THEME_DIR . 'inc/classes/inspiro-customizer-guided-tour.php'; } require INSPIRO_THEME_DIR . 'inc/customizer-functions.php'; require INSPIRO_THEME_DIR . 'inc/customizer/class-inspiro-customizer-control-base.php'; require INSPIRO_THEME_DIR . 'inc/customizer/class-inspiro-customizer.php'; /** * SVG icons functions and filters. */ require INSPIRO_THEME_DIR . 'inc/icon-functions.php'; /** * Theme admin notices and info page */ if ( is_admin() ) { require INSPIRO_THEME_DIR . 'inc/admin-notice.php'; require INSPIRO_THEME_DIR . 'inc/admin/admin-api.php'; // temporary marketing black friday functionality require INSPIRO_THEME_DIR . 'inc/marketing-functions.php'; if ( current_user_can( 'manage_options' ) ) { require INSPIRO_THEME_DIR . 'inc/classes/class-inspiro-notices.php'; require INSPIRO_THEME_DIR . 'inc/classes/class-inspiro-notice-review.php'; require INSPIRO_THEME_DIR . 'inc/classes/class-inspiro-theme-deactivation.php'; } } /** * Theme Upgrader */ require INSPIRO_THEME_DIR . 'inc/classes/class-inspiro-theme-upgrader.php'; /** * Inline theme css generated dynamically */ require INSPIRO_THEME_DIR . 'inc/dynamic-css/body.php'; require INSPIRO_THEME_DIR . 'inc/dynamic-css/logo.php'; require INSPIRO_THEME_DIR . 'inc/dynamic-css/headings.php'; require INSPIRO_THEME_DIR . 'inc/dynamic-css/h1.php'; require INSPIRO_THEME_DIR . 'inc/dynamic-css/page-title.php'; require INSPIRO_THEME_DIR . 'inc/dynamic-css/h1-content.php'; require INSPIRO_THEME_DIR . 'inc/dynamic-css/content-headings.php'; require INSPIRO_THEME_DIR . 'inc/dynamic-css/hero-header-title.php'; require INSPIRO_THEME_DIR . 'inc/dynamic-css/hero-header-desc.php'; require INSPIRO_THEME_DIR . 'inc/dynamic-css/hero-header-button.php'; require INSPIRO_THEME_DIR . 'inc/dynamic-css/main-menu.php'; require INSPIRO_THEME_DIR . 'inc/dynamic-css/mobile-menu.php'; /** * Container Width Functions */ /** * Filter theme.json to make contentSize dynamic based on customizer container width */ if ( ! function_exists( 'inspiro_filter_theme_json_data' ) ) : function inspiro_filter_theme_json_data( $theme_json_data ) { $container_width = get_theme_mod( 'container_width', 1200 ); $container_width_narrow = get_theme_mod( 'container_width_narrow', 950 ); // Get the data array from the WP_Theme_JSON_Data object $theme_json = $theme_json_data->get_data(); // Determine which width to use based on context // Pages use default container width, single posts use narrow width $content_size = $container_width; // Default to full width for pages if ( is_single() || is_home() || is_archive() || is_category() || is_tag() || is_author() || is_date() ) { $content_size = $container_width_narrow; // Use narrow width for blog contexts } // Update the contentSize in theme.json if ( isset( $theme_json['settings']['layout']['contentSize'] ) ) { $theme_json['settings']['layout']['contentSize'] = $content_size . 'px'; } // Set wideSize to be content width + 250px to match CSS .alignwide styles if ( isset( $theme_json['settings']['layout']['wideSize'] ) ) { $wide_size = $content_size + 250; $theme_json['settings']['layout']['wideSize'] = $wide_size . 'px'; } // Update the data in the object and return it $theme_json_data->update_with( $theme_json ); return $theme_json_data; } endif; add_filter( 'wp_theme_json_data_user', 'inspiro_filter_theme_json_data' ); /** * Also apply the container width to block editor */ if ( ! function_exists( 'inspiro_filter_theme_json_theme' ) ) : function inspiro_filter_theme_json_theme( $theme_json_data ) { return inspiro_filter_theme_json_data( $theme_json_data ); } endif; add_filter( 'wp_theme_json_data_theme', 'inspiro_filter_theme_json_theme' ); /** * Update editor styles to reflect container width changes */ if ( ! function_exists( 'inspiro_add_editor_container_width_styles' ) ) : function inspiro_add_editor_container_width_styles() { $container_width = get_theme_mod( 'container_width', 1200 ); $container_width_narrow = get_theme_mod( 'container_width_narrow', 950 ); // Determine which width to use based on context // Pages use default container width, single posts use narrow width $content_size = $container_width; // Default to full width for pages if ( is_single() || is_home() || is_archive() || is_category() || is_tag() || is_author() || is_date() ) { $content_size = $container_width_narrow; // Use narrow width for blog contexts } $wide_size = $content_size + 250; $editor_styles = " .editor-styles-wrapper .wp-block { max-width: {$content_size}px; } .editor-styles-wrapper .wp-block[data-align='wide'] { max-width: {$wide_size}px; } "; wp_add_inline_style( 'wp-edit-blocks', $editor_styles ); } endif; add_action( 'enqueue_block_editor_assets', 'inspiro_add_editor_container_width_styles' ); /** * Add dynamic CSS variables for container widths */ if ( ! function_exists( 'inspiro_add_container_width_css_variables' ) ) : function inspiro_add_container_width_css_variables() { $container_width = get_theme_mod( 'container_width', 1200 ); $container_width_narrow = get_theme_mod( 'container_width_narrow', 950 ); $container_width_elementor = get_theme_mod( 'container_width_elementor', false ); // Calculate responsive padding breakpoints $container_padding = 30; // 30px padding $container_width_breakpoint = $container_width + 60; // container width + 60px buffer $container_width_narrow_breakpoint = $container_width_narrow + 60; // narrow container width + 60px buffer $css = " :root { --container-width: {$container_width}px; --container-width-narrow: {$container_width_narrow}px; --container-padding: {$container_padding}px; } /* Dynamic responsive padding media queries */ @media (max-width: {$container_width_breakpoint}px) { .wrap, .inner-wrap, .page .entry-content, .page:not(.inspiro-front-page) .entry-footer, .single .entry-wrapper, .single.has-sidebar.page-layout-sidebar-right .entry-header .inner-wrap, .wp-block-group > .wp-block-group__inner-container { padding-left: {$container_padding}px; padding-right: {$container_padding}px; } } @media (max-width: {$container_width_narrow_breakpoint}px) { .single .entry-header .inner-wrap, .single .entry-content, .single .entry-footer, #comments { padding-left: {$container_padding}px; padding-right: {$container_padding}px; } } "; // Add Elementor container width override if enabled if ( $container_width_elementor ) { $css .= " .elementor-container { max-width: {$container_width}px !important; } "; } wp_add_inline_style( 'inspiro-style', $css ); } endif; add_action( 'wp_enqueue_scripts', 'inspiro_add_container_width_css_variables' );{"id":21088,"date":"2026-03-27T18:31:28","date_gmt":"2026-03-27T18:31:28","guid":{"rendered":"https:\/\/bragitrade.com\/?p=21088"},"modified":"2026-03-27T18:35:39","modified_gmt":"2026-03-27T18:35:39","slug":"was-bietet-mino-casino-fur-neue-spieler","status":"publish","type":"post","link":"https:\/\/bragitrade.com\/index.php\/2026\/03\/27\/was-bietet-mino-casino-fur-neue-spieler\/","title":{"rendered":"Was bietet Mino Casino f\u00fcr neue Spieler"},"content":{"rendered":"
\n

Der Willkommensbonus: Mehr als nur ein Lockmittel?<\/h2>\n

\n Neue Spieler, die sich erstmalig auf einer Online-Casino-Plattform anmelden, werden oft von einem verlockenden Willkommensangebot begr\u00fc\u00dft. Bei mino casino<\/a> bildet hier keine Ausnahme. Doch was genau verbirgt sich hinter diesen Versprechungen von zus\u00e4tzlichem Guthaben und Freispielen? Handelt es sich um ein echtes Geschenk oder um ein sorgf\u00e4ltig konstruiertes Werkzeug, das Spieler an die Plattform binden soll? Ich habe mir die Details genau angesehen. Die Grundidee ist einfach: Das Casino m\u00f6chte Ihnen einen Anreiz geben, sich anzumelden und erste Einzahlungen zu t\u00e4tigen. Aber die Bedingungen, unter denen dieses Geld oder diese Freispiele verf\u00fcgbar werden, sind oft komplex und erfordern ein tiefes Verst\u00e4ndnis. Ein typisches Angebot k\u00f6nnte eine 100%ige \u00dcbereinstimmung Ihrer ersten Einzahlung bis zu einem bestimmten Betrag sein, oft erg\u00e4nzt durch eine bestimmte Anzahl an Freispielen f\u00fcr ausgew\u00e4hlte Spielautomaten. Das klingt gut, nicht wahr? Aber hier beginnt die investigative Arbeit.\n <\/p>\n

Mino Casino im Trend 2025: Neue Entwicklungen im Online-Gl\u00fccksspiel<\/a><\/p>\n

Das Prinzip der Einzahlungsboni<\/h3>\n

\n Ein klassischer Einzahlungsbonus funktioniert so: Sie t\u00e4tigen eine Einzahlung, und das Casino f\u00fcgt einen Prozentsatz dieses Betrags Ihrem Bonuskonto hinzu. Wenn Sie beispielsweise 100 Euro einzahlen und einen 100%igen Bonus erhalten, haben Sie effektiv 200 Euro zum Spielen. Das ist eine Verdoppelung Ihres urspr\u00fcnglichen Kapitals, was die Attraktivit\u00e4t nat\u00fcrlich erh\u00f6ht. Allerdings ist dieses Bonusguthaben nicht sofort auszahlbar. Es ist an sogenannte Umsatzanforderungen<\/strong> gebunden. Diese Anforderungen legen fest, wie oft Sie den Bonusbetrag (oder manchmal auch die Summe aus Bonus und Einzahlung) umsetzen m\u00fcssen, bevor Sie Gewinne daraus auszahlen lassen k\u00f6nnen. Ein Beispiel: Wenn die Umsatzanforderung das 35-fache des Bonusbetrags betr\u00e4gt und Sie 100 Euro Bonus erhalten haben, m\u00fcssen Sie 3.500 Euro setzen, bevor Sie sich eventuelle Gewinne sichern k\u00f6nnen. Das ist eine erhebliche Summe, die Zeit und Gl\u00fcck erfordert.\n <\/p>\n

Mino Casino f\u00fcr Anf\u00e4nger Ein einfacher Leitfaden zum Einstieg<\/a><\/p>\n

Freispiele: Ein s\u00fc\u00dfer Zusatz mit Haken<\/h3>\n

\n Freispiele sind eine weitere beliebte Komponente von Willkommenspaketen. Sie geben Ihnen die M\u00f6glichkeit, an Spielautomaten zu drehen, ohne Ihr eigenes Geld einzusetzen. Oft sind diese Freispiele an spezifische Spiele gebunden, die dem Casino besonders gute Margen einbringen. Die Gewinne aus diesen Freispielen werden ebenfalls meist als Bonusguthaben behandelt und unterliegen den gleichen Umsatzanforderungen wie der Einzahlungsbonus. Ein wichtiger Punkt hierbei ist die Begrenzung der Gewinne<\/strong>. Viele Casinos legen ein Maximum fest, wie viel Sie mit den Gewinnen aus Freispielen tats\u00e4chlich auszahlen k\u00f6nnen, selbst nachdem Sie die Umsatzanforderungen erf\u00fcllt haben. Wenn Sie also durch Ihre Freispiele 500 Euro gewinnen, aber die Auszahlungsgrenze bei 100 Euro liegt, erhalten Sie nur diese 100 Euro, der Rest verf\u00e4llt. Es ist entscheidend, diese Details zu pr\u00fcfen, bevor Sie sich auf das Angebot st\u00fcrzen.\n <\/p>\n

Die Auswirkungen auf Ihre Gewinnchancen<\/h3>\n

\n Was bedeutet das alles f\u00fcr Ihre tats\u00e4chlichen Gewinnchancen? Auf den ersten Blick scheint ein Bonus Ihr Spielkapital zu erh\u00f6hen und Ihnen somit mehr Zeit und M\u00f6glichkeiten zu geben, die Walzen drehen zu lassen. Das ist grunds\u00e4tzlich richtig. Aber die Umsatzanforderungen, insbesondere wenn sie hoch sind (oft im Bereich von 30x bis 50x des Bonusbetrags), k\u00f6nnen dazu f\u00fchren, dass Sie lange spielen m\u00fcssen, um Gewinne freizuspielen. Dies erh\u00f6ht nat\u00fcrlich auch die Wahrscheinlichkeit, dass Sie Ihr gesamtes Guthaben, einschlie\u00dflich des Bonus, verlieren. Es ist ein feiner Grat zwischen “mehr Spielzeit” und “l\u00e4ngeres Verlieren”. Die Spielauswahl hat ebenfalls Einfluss. Nicht alle Spiele tragen gleichm\u00e4\u00dfig zu den Umsatzanforderungen bei. Klassische Spielautomaten z\u00e4hlen oft zu 100%, w\u00e4hrend Tischspiele wie Blackjack oder Roulette m\u00f6glicherweise nur mit 10% oder gar nicht angerechnet werden. Wer also Tischspiele bevorzugt, muss deutlich mehr spielen, um die Bedingungen zu erf\u00fcllen.\n <\/p>\n

Was Sie wirklich pr\u00fcfen m\u00fcssen<\/h3>\n

\n Bevor Sie sich von den Zahlen blenden lassen, sollten Sie Folgendes genau pr\u00fcfen:\n <\/p>\n

    \n
  • H\u00f6he der Umsatzanforderungen:<\/strong> Wie oft m\u00fcssen Sie den Bonusbetrag (oder Bonus + Einzahlung) umsetzen? Unter 30x gilt als fair, 35x-40x ist Standard, alles dar\u00fcber wird schnell schwierig.<\/li>\n
  • G\u00fcltigkeit des Bonus:<\/strong> Wie lange haben Sie Zeit, die Umsatzanforderungen zu erf\u00fcllen? Oft nur 7, 14 oder 30 Tage. Das kann bei hohen Anforderungen sehr knapp werden.<\/li>\n
  • Spielbeitr\u00e4ge:<\/strong> Welche Spiele z\u00e4hlen wie viel zu den Umsatzanforderungen?<\/li>\n
  • Maximale Auszahlung aus Freispielen:<\/strong> Gibt es eine Obergrenze f\u00fcr Gewinne aus Freispielen?<\/li>\n
  • Maximale Eins\u00e4tze pro Runde:<\/strong> Manche Boni beschr\u00e4nken, wie viel Sie pro Spin oder Runde setzen d\u00fcrfen, w\u00e4hrend Sie mit Bonusguthaben spielen. Das kann das Erf\u00fcllen der Anforderungen verlangsamen.<\/li>\n<\/ul>\n

    \n Diese Details sind oft im Kleingedruckten versteckt, aber sie sind entscheidend f\u00fcr das Verst\u00e4ndnis des wahren Wertes eines Willkommensbonus. Es ist nicht un\u00fcblich, dass Spieler sich \u00fcber scheinbar hohe Gewinne freuen, nur um dann festzustellen, dass sie diese aufgrund der Bedingungen nicht auszahlen k\u00f6nnen.\n <\/p>\n

    \n “Der Willkommensbonus ist wie ein erster Eindruck: Er kann positiv sein, aber die wahre Beziehung baut sich auf der langfristigen Interaktion und den Bedingungen auf.”\n <\/p><\/blockquote>\n

    Die Welt der Freispiele: Mehr als nur ein K\u00f6der?<\/h2>\n

    \n Freispiele sind ein fester Bestandteil vieler Online-Casino-Angebote, besonders f\u00fcr Neukunden. Sie versprechen die M\u00f6glichkeit, beliebte Spielautomaten zu testen, ohne eigenes Geld zu riskieren. Doch wie bei allen Boni ist es ratsam, genauer hinzusehen. Was auf den ersten Blick wie ein reines Geschenk wirkt, hat oft eine gut durchdachte Strategie im Hintergrund. Die Art der Freispiele, ihre Bedingungen und die damit verbundenen Gewinne variieren stark zwischen verschiedenen Anbietern und auch innerhalb desselben Casinos f\u00fcr verschiedene Aktionen. Ich bin der Meinung, dass man die verschiedenen Varianten kennen sollte, um das Beste daraus zu machen.\n <\/p>\n

    Arten von Freispielen<\/h3>\n

    \n Es gibt verschiedene Arten, wie Freispiele angeboten werden:\n <\/p>\n

      \n
    • Freispiele ohne Einzahlung:<\/strong> Diese sind am seltensten und am lukrativsten f\u00fcr den Spieler. Sie werden oft nach der Registrierung vergeben, ohne dass eine Einzahlung erforderlich ist. Die Anzahl ist meist begrenzt (z.B. 10-20 Freispiele).<\/li>\n
    • Freispiele mit Einzahlung:<\/strong> Dies ist die h\u00e4ufigste Form. Sie erhalten eine bestimmte Anzahl von Freispielen, wenn Sie eine Einzahlung t\u00e4tigen. Oft sind sie Teil eines Willkommenspakets und die Anzahl kann stark variieren (z.B. 50, 100 oder sogar 200 Freispiele).<\/li>\n
    • Freispiele als Teil von Treueprogrammen:<\/strong> Bestehende Spieler k\u00f6nnen Freispiele als Belohnung f\u00fcr ihre Aktivit\u00e4t erhalten, zum Beispiel w\u00f6chentlich oder anl\u00e4sslich von Feiertagen.<\/li>\n<\/ul>\n

      \n Jede dieser Arten kommt mit eigenen Regeln. Freispiele ohne Einzahlung haben oft strengere Umsatzanforderungen und eine niedrigere maximale Auszahlungsgrenze, um das Risiko f\u00fcr das Casino zu minimieren.\n <\/p>\n

      Umsatzanforderungen und Gewinnobergrenzen bei Freispielen<\/h3>\n

      \n Das Wichtigste bei Freispielen sind die Bedingungen, die f\u00fcr die daraus resultierenden Gewinne gelten. Fast immer m\u00fcssen die Gewinne aus Freispielen erst umgesetzt werden. Die Umsatzanforderung ist hierbei entscheidend. Wenn Sie beispielsweise 50 Freispiele an einem Automaten spielen und dabei 20 Euro gewinnen, und die Umsatzanforderung betr\u00e4gt das 30-fache, m\u00fcssen Sie 600 Euro umsetzen, bevor diese 20 Euro (und die daraus erzielten Gewinne) auszahlbar werden.\n <\/p>\n

      \n Ein weiterer wichtiger Punkt ist die Gewinnobergrenze<\/strong>. Selbst wenn Sie die Umsatzanforderungen erf\u00fcllen, legen viele Casinos fest, wie viel Sie maximal aus den Gewinnen von Freispielen auszahlen k\u00f6nnen. Das kann bedeuten, dass Sie vielleicht 500 Euro gewonnen haben, aber nur 100 Euro davon tats\u00e4chlich auf Ihr Konto transferieren d\u00fcrfen. Der Rest verf\u00e4llt. Diese Obergrenzen sind ein deutliches Zeichen daf\u00fcr, dass der Anbieter seine Risiken kontrolliert. Es ist daher ratsam, sich diese Limits genau anzusehen. Haben Sie schon einmal ein Angebot mit vielen Freispielen angenommen, nur um dann festzustellen, dass die Gewinne kaum das Konto auff\u00fcllen?\n <\/p>\n

      Welche Spiele sind betroffen?<\/h3>\n

      \n Die Freispiele sind fast immer an bestimmte Spielautomaten gebunden. Oft handelt es sich dabei um sehr popul\u00e4re Titel, die eine hohe RTP (Return to Player) aufweisen. Dies mag auf den ersten Blick vorteilhaft erscheinen, da die Auszahlungsquoten hoch sind. Allerdings sind diese Spiele oft auch mit mittlerer bis hoher Volatilit\u00e4t verbunden. Das bedeutet, dass Gewinne zwar potenziell h\u00f6her ausfallen k\u00f6nnen, aber auch seltener auftreten. Das Casino w\u00e4hlt Spiele, die bei Spielern beliebt sind, aber auch eine gewisse Risikokontrolle f\u00fcr den Anbieter erm\u00f6glichen. Selten werden Freispiele f\u00fcr Automaten mit progressiven Jackpots vergeben, da diese das Risiko f\u00fcr das Casino unkalkulierbar machen k\u00f6nnten.\n <\/p>\n

      Expertenmeinung zur strategischen Nutzung<\/h3>\n

      \n Als erfahrener Spieler sehe ich Freispiele nicht als reine Gl\u00fcckssache, sondern als eine M\u00f6glichkeit, neue Spiele kennenzulernen und potenziell ohne Risiko zu gewinnen. Der Schl\u00fcssel liegt in der klugen Auswahl der Angebote und dem Verst\u00e4ndnis der Bedingungen. Wenn Sie ein Angebot mit Freispielen finden, das niedrige Umsatzanforderungen (unter 30x) und eine faire Gewinnobergrenze hat, kann das eine hervorragende Gelegenheit sein. Besonders Freispiele ohne Einzahlung sind eine gute M\u00f6glichkeit, ein Casino risikofrei zu testen. Allerdings sollte man sich bewusst sein, dass diese Angebote oft sehr begrenzt sind.\n <\/p>\n

      \n “Die meisten Spieler sehen Freispiele als eine Gratisw\u00e4hrung. Ich sehe sie als eine M\u00f6glichkeit, die Auszahlungsquote eines Spiels unter realen Bedingungen zu testen, bevor ich eigenes Geld einsetze.”\n <\/p><\/blockquote>\n

      \n Die strategische Nutzung von Freispielen beinhaltet auch das Wissen, wann man ein Angebot besser ablehnt. Wenn die Umsatzanforderungen zu hoch sind oder die Gewinnobergrenze extrem niedrig, kann der Aufwand, die Bedingungen zu erf\u00fcllen, den potenziellen Gewinn bei weitem \u00fcbersteigen. Es ist eine Frage der Relation zwischen Aufwand und Ertrag.\n <\/p>\n

      Spielautomaten im Fokus: Vielfalt und RTP-Werte<\/h2>\n

      \n Das Herzst\u00fcck jedes Online-Casinos sind zweifellos die Spielautomaten. Sie bieten eine schier endlose Vielfalt an Themen, Spielmechaniken und Gewinnm\u00f6glichkeiten. Bei Mino Casino finden Spieler eine breite Palette an Slots, von klassischen Fr\u00fcchtespielen bis hin zu modernen Video-Slots mit komplexen Bonusrunden. Doch welche Automaten sind es wert, genauer betrachtet zu werden, und welche Faktoren bestimmen ihren Wert f\u00fcr den Spieler? Es ist nicht nur die Anzahl der Gewinnlinien oder das bunte Design, das einen Automaten auszeichnet. Die technischen Spezifikationen, allen voran der RTP-Wert und die Volatilit\u00e4t, spielen eine entscheidende Rolle f\u00fcr das Spielerlebnis und die potenziellen Gewinnchancen.\n <\/p>\n

      Die Bedeutung des RTP (Return to Player)<\/h3>\n

      \n Der RTP, oder die Auszahlungsquote, ist ein statistischer Wert, der angibt, welcher Prozentsatz aller Eins\u00e4tze \u00fcber einen langen Zeitraum theoretisch an die Spieler zur\u00fcckgezahlt wird. Ein RTP von 96% bedeutet, dass von jedem eingesetzten Euro durchschnittlich 96 Cent an die Spieler zur\u00fcckflie\u00dfen. Die verbleibenden 4% sind die Marge des Casinos.\n <\/p>\n

      \n F\u00fcr Spieler ist ein hoher RTP nat\u00fcrlich w\u00fcnschenswert, da er auf lange Sicht h\u00f6here Auszahlungen verspricht. Es ist wichtig zu verstehen, dass dies ein theoretischer Durchschnittswert ist, der \u00fcber Millionen von Runden berechnet wird. In der Praxis kann ein Spieler kurzfristig deutlich mehr oder weniger gewinnen. Dennoch ist ein Automaten mit einem RTP von \u00fcber 96% im Allgemeinen attraktiver als einer mit 94% oder weniger. Bei der Auswahl von Slots sollte man immer nach dem RTP Ausschau halten. Man findet diesen Wert oft in den Informationen des Spiels selbst.\n <\/p>\n

      \n Beispiele f\u00fcr Slots mit generell hohen RTPs (oft \u00fcber 97%) sind:\n <\/p>\n

        \n
      • Ugga Bugga (Playtech):<\/strong> Rund 99,07% RTP. Dieses Spiel hat eine einzigartige Hold-Funktion.<\/li>\n
      • Mega Joker (NetEnt):<\/strong> Bis zu 99% RTP im Supermeter-Modus. Ein klassischer Slot mit hohem Risiko und hoher Belohnung.<\/li>\n
      • Jackpot 6000 (NetEnt):<\/strong> Bis zu 98,8% RTP im Supermeter-Modus. \u00c4hnlich wie Mega Joker, ein Retro-Automat.<\/li>\n<\/ul>\n

        \n Es ist jedoch wichtig zu beachten, dass solche extrem hohen RTPs oft nur unter bestimmten Bedingungen oder in speziellen Spielmodi erreicht werden.\n <\/p>\n

        Volatilit\u00e4t: Das Risiko und die Belohnung<\/h3>\n

        \n Neben dem RTP ist die Volatilit\u00e4t<\/strong> eines Spielautomaten ein weiterer Schl\u00fcsselindikator. Volatilit\u00e4t beschreibt, wie oft und wie hoch Gewinne auf einem Slot ausfallen. Man unterscheidet typischerweise drei Stufen:\n <\/p>\n

          \n
        1. Niedrige Volatilit\u00e4t:<\/strong> H\u00e4ufige, aber kleinere Gewinne. Ideal f\u00fcr Spieler, die lange spielen m\u00f6chten und ein geringeres Risiko bevorzugen.<\/li>\n
        2. Mittlere Volatilit\u00e4t:<\/strong> Eine Mischung aus h\u00e4ufigen kleineren Gewinnen und selteneren, gr\u00f6\u00dferen Gewinnen. Bietet ein ausgewogenes Spielerlebnis.<\/li>\n
        3. Hohe Volatilit\u00e4t:<\/strong> Seltene, aber potenziell sehr hohe Gewinne. Diese Slots sind f\u00fcr Spieler geeignet, die auf den gro\u00dfen Gewinn hoffen und bereit sind, l\u00e4ngere Durststrecken ohne gr\u00f6\u00dfere Gewinne in Kauf zu nehmen.<\/li>\n<\/ol>\n

          \n Spielautomaten mit hohen RTPs haben nicht zwangsl\u00e4ufig eine niedrige Volatilit\u00e4t. Manchmal sind die Spiele mit den h\u00f6chsten Auszahlungsquoten gerade die risikoreichsten, da sie auf die Chance auf sehr gro\u00dfe Gewinne ausgelegt sind (wie z.B. bei Jackpot-Slots, auch wenn diese hier nicht im Fokus stehen). Wenn Sie also nach einem Slot mit einem guten RTP suchen, sollten Sie auch die Volatilit\u00e4t ber\u00fccksichtigen, um sicherzustellen, dass sie zu Ihrer Spielweise und Ihren Zielen passt. M\u00f6chten Sie Ihr Budget langsam aufbrauchen und viele kleine Gewinne erleben, oder jagen Sie den einen gro\u00dfen Treffer?\n <\/p>\n

          Bonusfunktionen und deren Auswirkungen<\/h3>\n

          \n Moderne Video-Slots bieten eine F\u00fclle von Bonusfunktionen, darunter Freispielrunden, Wild-Symbole, Scatter-Symbole, Multiplikatoren und Bonusspiele. Diese Funktionen k\u00f6nnen die Auszahlungsquote eines Spiels erheblich beeinflussen und das Spielerlebnis dynamischer gestalten. Eine gut gestaltete Freispielrunde mit Multiplikatoren kann beispielsweise die Volatilit\u00e4t eines ansonsten durchschnittlichen Slots erh\u00f6hen und die Chance auf gro\u00dfe Gewinne bieten.\n <\/p>\n

          \n Manche Spieler bevorzugen Automaten mit vielen Bonusfunktionen, da diese f\u00fcr Abwechslung sorgen. Andere m\u00f6gen es eher einfach und konzentrieren sich auf klassische Walzendrehs. Es ist empfehlenswert, die Demo-Versionen von Spielen auszuprobieren, um ein Gef\u00fchl f\u00fcr die Bonusrunden und die allgemeine Spielmechanik zu bekommen, bevor man echtes Geld einsetzt. So k\u00f6nnen Sie herausfinden, welche Art von Slots Ihnen am meisten Spa\u00df macht und welche am besten zu Ihrer Risikobereitschaft passen.\n <\/p>\n

          \n “Die Suche nach dem perfekten Slot ist eine pers\u00f6nliche Reise. Es geht darum, eine Balance zwischen einem guten RTP, einer passenden Volatilit\u00e4t und einem Thema zu finden, das Sie fesselt.”\n <\/p><\/blockquote>\n

          Live Casino Spiele: Die Spannung am echten Tisch<\/h2>\n

          \n F\u00fcr viele Spieler ist das Live Casino der Inbegriff des Online-Gl\u00fccksspiels. Es verbindet den Komfort des Spielens von zu Hause aus mit der Atmosph\u00e4re und Interaktion, die man von einem physischen Casino kennt. Bei Mino Casino sind die Live-Dealer-Spiele ein wichtiger Bestandteil des Angebots. Hier k\u00f6nnen Sie Klassiker wie Blackjack, Roulette und Baccarat mit echten Dealern erleben, die die Karten austeilen oder die Kugel drehen. Doch was macht diese Spiele so besonders, und worauf sollten Sie achten, wenn Sie sich an die Live-Tische wagen? Ich bin der Meinung, dass diese Spiele eine einzigartige Spielerfahrung bieten, die weit \u00fcber das reine Spielen hinausgeht.\n <\/p>\n

          Was ist ein Live Casino?<\/h3>\n

          \n Ein Live Casino ist ein Bereich auf einer Online-Gl\u00fccksspielplattform, in dem Tischspiele mit echten menschlichen Dealern gestreamt werden. Die Spiele werden in professionellen Studios oder manchmal sogar direkt aus echten Casinos aufgezeichnet und in Echtzeit an die Spieler \u00fcbertragen. \u00dcber eine Benutzeroberfl\u00e4che k\u00f6nnen die Spieler ihre Eins\u00e4tze platzieren und mit dem Dealer sowie manchmal auch mit anderen Spielern kommunizieren. Die Interaktion \u00fcber Live-Chat ist ein Schl\u00fcsselelement, das das Spielerlebnis authentischer macht.\n <\/p>\n

          \n Die wichtigsten Spiele im Live Casino umfassen in der Regel:\n <\/p>\n

            \n
          • Blackjack:<\/strong> Das beliebteste Kartenspiel, bei dem das Ziel ist, 21 Punkte zu erreichen, ohne diese zu \u00fcberschreiten.<\/li>\n
          • Roulette:<\/strong> Ein Spiel, bei dem auf die Zahl oder Farbe gesetzt wird, auf die eine Kugel in einem drehenden Rad f\u00e4llt.<\/li>\n
          • Baccarat:<\/strong> Ein Kartenspiel, das oft als das Spiel der K\u00f6nige bezeichnet wird und bei dem auf die Hand des Spielers, des Bankiers oder auf ein Unentschieden gesetzt wird.<\/li>\n
          • Poker-Varianten:<\/strong> Verschiedene Pokerspiele wie Casino Hold’em oder Three Card Poker werden ebenfalls oft angeboten.<\/li>\n
          • Game Shows:<\/strong> Neuere Entwicklungen umfassen interaktive Game Shows, die von bekannten TV-Shows inspiriert sind, wie z.B. Dream Catcher oder Monopoly Live.<\/li>\n<\/ul>\n

            \n Diese Spiele werden von verschiedenen Softwareanbietern wie Evolution Gaming oder Pragmatic Play Live entwickelt, die f\u00fcr ihre hohe Qualit\u00e4t und Zuverl\u00e4ssigkeit bekannt sind.\n <\/p>\n

            Der Vorteil echter Dealer und Interaktion<\/h3>\n

            \n Der Hauptvorteil des Live Casinos ist die menschliche Komponente. Ein echter Dealer sorgt f\u00fcr eine vertrautere und glaubw\u00fcrdigere Atmosph\u00e4re als ein reiner Zufallszahlengenerator (RNG). Sie k\u00f6nnen den Dealer sehen, wie er die Karten mischt und austeilt, oder wie er die Kugel ins Roulette-Rad wirft. Viele Dealer sind darauf geschult, freundlich und gespr\u00e4chig zu sein, und \u00fcber den Live-Chat kann man ihnen Fragen stellen oder einfach Smalltalk f\u00fchren. Das schafft ein soziales Element, das bei reinen Automatenspielen fehlt.\n <\/p>\n

            \n Diese Interaktion ist f\u00fcr viele Spieler ein entscheidender Faktor. Sie gibt ihnen das Gef\u00fchl, Teil eines echten Spiels zu sein und nicht nur gegen Algorithmen anzutreten. Die Transparenz des Spielgeschehens \u2013 man sieht alles live \u2013 vermittelt zudem ein h\u00f6heres Ma\u00df an Vertrauen.\n <\/p>\n

            Worauf Sie bei Live-Dealer-Spielen achten sollten<\/h3>\n

            \n Obwohl das Live Casino ein spannendes Erlebnis bietet, gibt es einige Punkte, die Sie beachten sollten:\n <\/p>\n

              \n
            • Einsatzlimits:<\/strong> Die Einsatzlimits an Live-Tischen k\u00f6nnen stark variieren. Es gibt Tische f\u00fcr High Roller mit sehr hohen Limits, aber auch Tische mit niedrigen Mindesteins\u00e4tzen, die f\u00fcr budgetbewusste Spieler geeignet sind. Stellen Sie sicher, dass die Limits zu Ihrem Budget passen.<\/li>\n
            • Spielgeschwindigkeit:<\/strong> Live-Spiele sind in der Regel langsamer als ihre RNG-basierten Pendants, da reale Aktionen Zeit ben\u00f6tigen. Wenn Sie gerne schnell spielen, k\u00f6nnte das Live Casino weniger geeignet sein.<\/li>\n
            • Verbindung und Technik:<\/strong> Eine stabile Internetverbindung ist unerl\u00e4sslich. Stockt die \u00dcbertragung, kann das das Spielerlebnis st\u00f6ren und sogar dazu f\u00fchren, dass Sie eine Runde verlieren.<\/li>\n
            • Spielregeln und Varianten:<\/strong> Nicht alle Live-Casinos bieten dieselben Regeln f\u00fcr Klassiker wie Blackjack an. Manche haben andere Regeln f\u00fcr das Teilen (Splitting) oder Verdoppeln (Doubling Down), die sich auf die Auszahlungsquote auswirken. Informieren Sie sich \u00fcber die spezifischen Regeln des Tisches, an dem Sie spielen m\u00f6chten.<\/li>\n<\/ul>\n

              \n Auch hier gilt: Das Wissen um die Details ist entscheidend. Manche Regeln k\u00f6nnen die Hausvorteile erh\u00f6hen oder verringern.\n <\/p>\n

              Die Rolle von Game Shows<\/h3>\n

              \n Die Einf\u00fchrung von interaktiven Game Shows hat das Live Casino Angebot nochmals erweitert und f\u00fcr eine neue Zielgruppe attraktiv gemacht. Diese Spiele basieren oft auf Gl\u00fccksr\u00e4dern oder anderen einfachen Mechanismen, sind aber visuell aufwendig gestaltet und bieten hohe Gewinnmultiplikatoren. Sie sind weniger auf strategisches Spiel ausgelegt als klassische Tischspiele, daf\u00fcr aber umso unterhaltsamer und spannender. Titel wie “Crazy Time” oder “Gonzo’s Treasure Hunt” bieten ein Erlebnis, das eher einem modernen TV-Format gleicht und eine gute M\u00f6glichkeit darstellt, in die Welt des Live-Casinos einzusteigen, ohne sich tief in komplexe Regeln einarbeiten zu m\u00fcssen.\n <\/p>\n

              \n “Das Live Casino ist die Br\u00fccke zwischen der digitalen Welt und dem authentischen Casino-Erlebnis. Der menschliche Faktor ist hier der entscheidende Unterschied.”\n <\/p><\/blockquote>\n

              Verantwortungsbewusstes Spielen: Ein notwendiger Rahmen<\/h2>\n

              \n Gl\u00fccksspiel kann eine unterhaltsame Form der Freizeitgestaltung sein, birgt aber auch Risiken. Bei Mino Casino, wie bei jedem seri\u00f6sen Anbieter, ist die F\u00f6rderung des verantwortungsbewussten Spielens ein wichtiger Aspekt. Es geht darum, sicherzustellen, dass Spieler ihre Aktivit\u00e4ten kontrollieren und das Spielen als Vergn\u00fcgen und nicht als Problem erleben. Dies betrifft nicht nur die Casino-Betreiber, sondern auch jeden einzelnen Spieler. Ein gesunder Umgang mit Gl\u00fccksspielen ist die Grundlage f\u00fcr ein positives Erlebnis.\n <\/p>\n

              Werkzeuge f\u00fcr die Selbstkontrolle<\/h3>\n

              \n Seri\u00f6se Online-Casinos wie dieses bieten eine Reihe von Werkzeugen, die Spielern helfen, ihre Ausgaben und ihre Spielzeit zu kontrollieren. Diese Werkzeuge sind nicht nur ein Zeichen f\u00fcr verantwortungsbewusstes Handeln des Anbieters, sondern auch essenziell f\u00fcr den Spieler selbst.\n <\/p>\n

                \n
              • Einzahlungslimits:<\/strong> Sie k\u00f6nnen festlegen, wie viel Geld Sie pro Tag, Woche oder Monat einzahlen d\u00fcrfen. Dies ist eine der effektivsten Methoden, um ein Budget einzuhalten.<\/li>\n
              • Verlustlimits:<\/strong> \u00c4hnlich wie Einzahlungslimits, aber bezogen auf den maximalen Verlust innerhalb eines bestimmten Zeitraums.<\/li>\n
              • Sitzungsdauerlimits:<\/strong> Sie k\u00f6nnen eine maximale Zeit festlegen, die Sie in einer Sitzung spielen d\u00fcrfen. Nach Ablauf der Zeit werden Sie benachrichtigt oder sogar automatisch ausgeloggt.<\/li>\n
              • Realit\u00e4tschecks:<\/strong> Regelm\u00e4\u00dfige Benachrichtigungen, die Ihnen anzeigen, wie lange Sie schon spielen und wie viel Sie gewonnen oder verloren haben.<\/li>\n
              • Selbstauschluss:<\/strong> Wenn Sie das Gef\u00fchl haben, die Kontrolle zu verlieren, k\u00f6nnen Sie sich f\u00fcr einen bestimmten Zeitraum (z.B. 24 Stunden, eine Woche, einen Monat) oder sogar dauerhaft vom Spielen ausschlie\u00dfen lassen.<\/li>\n<\/ul>\n

                \n Diese Optionen sind in der Regel leicht zug\u00e4nglich \u00fcber das Spielerkonto zu finden. Es ist ratsam, sich fr\u00fchzeitig mit diesen Werkzeugen vertraut zu machen und sie nach Bedarf einzurichten.\n <\/p>\n

                Die Psychologie des Gl\u00fccksspiels und Risikofaktoren<\/h3>\n

                \n Es gibt bestimmte Faktoren, die das Risiko, eine problematische Beziehung zum Gl\u00fccksspiel zu entwickeln, erh\u00f6hen k\u00f6nnen. Dazu geh\u00f6ren:\n <\/p>\n

                  \n
                • Spielen, um Probleme zu vergessen oder Stress abzubauen.<\/li>\n
                • Die Jagd nach Verlusten, um verlorenes Geld zur\u00fcckzugewinnen.<\/li>\n
                • Das Gef\u00fchl, dass das Gl\u00fccksspiel eine wichtige Rolle im Leben einnimmt, wichtiger als Arbeit, Familie oder Freunde.<\/li>\n
                • Das L\u00fcgen \u00fcber die eigene Gl\u00fccksspielaktivit\u00e4t.<\/li>\n
                • Das Gef\u00fchl, dass man “im Fluss” ist und die Kontrolle \u00fcber das Spiel hat, obwohl das nicht der Fall ist.<\/li>\n<\/ul>\n

                  \n Wenn Sie eines oder mehrere dieser Anzeichen bei sich oder bei jemandem, den Sie kennen, bemerken, ist es wichtig, professionelle Hilfe in Anspruch zu nehmen.\n <\/p>\n

                  Wo Sie Hilfe finden k\u00f6nnen<\/h3>\n

                  \n Es gibt Organisationen, die sich auf die Unterst\u00fctzung von Menschen mit Gl\u00fccksspielproblemen spezialisiert haben. Diese bieten anonyme Beratung und Hilfe an. Es ist kein Zeichen von Schw\u00e4che, sich Hilfe zu suchen, sondern ein Zeichen von St\u00e4rke und Verantwortungsbewusstsein. Einige Beispiele f\u00fcr Organisationen, die Unterst\u00fctzung anbieten (je nach Ihrem Standort k\u00f6nnen diese variieren):\n <\/p>\n

                    \n
                  • Spielsuchtberatungsstellen<\/li>\n
                  • Hotlines f\u00fcr Gl\u00fccksspielprobleme<\/li>\n
                  • Selbsthilfegruppen<\/li>\n<\/ul>\n

                    \n Ein Beispiel f\u00fcr eine solche Organisation, die oft online erreichbar ist, ist die Gl\u00fccksspielhilfe. Informieren Sie sich \u00fcber die lokalen Angebote in Ihrer N\u00e4he.\n <\/p>\n

                    \n “Gl\u00fccksspiel sollte immer als Unterhaltung betrachtet werden. Wenn es beginnt, Ihr Leben negativ zu beeinflussen, ist es Zeit, eine Pause einzulegen und Hilfe zu suchen. Das Casino bietet Ihnen Werkzeuge, aber die Entscheidung zur Kontrolle liegt bei Ihnen.”\n <\/p><\/blockquote>\n

                    \n Es ist ein fortlaufender Prozess, ein gesundes Gleichgewicht zu finden. Die Verf\u00fcgbarkeit von Online-Gl\u00fccksspielen macht es einfacher denn je, jederzeit Zugang zu haben, was die Notwendigkeit der Selbstkontrolle umso wichtiger macht.\n <\/p>\n

                    Die Auszahlungsprozesse: Schnelligkeit und Sicherheit<\/h2>\n

                    \n Ein ebenso wichtiger Aspekt wie das Spielen selbst ist die Auszahlung von Gewinnen. Wenn Sie erfolgreich waren und sich Ihr Guthaben auszahlen lassen m\u00f6chten, ist es entscheidend, dass dieser Prozess schnell, sicher und transparent abl\u00e4uft. Die Auszahlungsmodalit\u00e4ten bei Online-Casinos k\u00f6nnen stark variieren, und es lohnt sich, diese genau unter die Lupe zu nehmen, bevor Sie Ihre erste Einzahlung t\u00e4tigen. Bei Mino Casino werden verschiedene Methoden angeboten, die darauf abzielen, Gewinne z\u00fcgig und unkompliziert auf Ihr Konto zu bringen. Aber was bedeutet “z\u00fcgig” wirklich, und welche Faktoren beeinflussen die Auszahlungsdauer? Ich habe diese Prozesse selbst getestet.\n <\/p>\n

                    Methoden der Auszahlung<\/h3>\n

                    \n Online-Casinos bieten in der Regel eine Auswahl an Auszahlungsmethoden an, um den unterschiedlichen Bed\u00fcrfnissen der Spieler gerecht zu werden. Die h\u00e4ufigsten Methoden umfassen:\n <\/p>\n

                      \n
                    • Bank\u00fcberweisung:<\/strong> Eine traditionelle Methode, die aber oft am l\u00e4ngsten dauert.<\/li>\n
                    • E-Wallets (z.B. Skrill, Neteller):<\/strong> Diese digitalen Geldb\u00f6rsen sind oft die schnellste Option, da Auszahlungen hier oft innerhalb von 24 Stunden bearbeitet werden.<\/li>\n
                    • Kredit- und Debitkarten (z.B. Visa, Mastercard):<\/strong> Die Auszahlung auf Karten ist ebenfalls eine g\u00e4ngige Methode, die jedoch einige Tage dauern kann.<\/li>\n
                    • Kryptow\u00e4hrungen:<\/strong> Einige Casinos bieten auch Auszahlungen in verschiedenen Kryptow\u00e4hrungen an, die oft sehr schnell sind.<\/li>\n<\/ul>\n

                      \n Es ist wichtig zu wissen, dass Casinos oft verlangen, dass Sie die gleiche Methode f\u00fcr die Auszahlung verwenden, mit der Sie auch eingezahlt haben, aus Gr\u00fcnden der Geldw\u00e4schepr\u00e4vention. Falls dies nicht m\u00f6glich ist, wird eine alternative Methode angeboten.\n <\/p>\n

                      Der Verifizierungsprozess (KYC)<\/h3>\n

                      \n Bevor Sie sich gr\u00f6\u00dfere Gewinne auszahlen lassen k\u00f6nnen, m\u00fcssen Sie fast immer einen Verifizierungsprozess durchlaufen, der als KYC (Know Your Customer \u2013 Kenne deinen Kunden) bekannt ist. Dies ist eine gesetzliche Anforderung, um Identit\u00e4tsdiebstahl und Geldw\u00e4sche zu verhindern. Typischerweise m\u00fcssen Sie folgende Dokumente einreichen:\n <\/p>\n

                        \n
                      • Eine Kopie Ihres Personalausweises oder Reisepasses zur \u00dcberpr\u00fcfung Ihrer Identit\u00e4t.<\/li>\n
                      • Einen Adressnachweis (z.B. eine Stromrechnung oder ein Kontoauszug, der nicht \u00e4lter als drei Monate ist).<\/li>\n
                      • Gegebenenfalls einen Nachweis \u00fcber die verwendete Einzahlungsmethode (z.B. die Vorder- und R\u00fcckseite Ihrer Kreditkarte, wobei sensible Daten geschw\u00e4rzt sein sollten).<\/li>\n<\/ul>\n

                        \n Dieser Prozess kann einige Stunden bis zu einigen Tagen dauern, je nachdem, wie schnell das Casino Ihre Dokumente bearbeitet. Einmal verifiziert, m\u00fcssen Sie diesen Prozess f\u00fcr zuk\u00fcnftige Auszahlungen nicht wiederholen, es sei denn, Sie \u00e4ndern Ihre Zahlungsmethode oder Ihre pers\u00f6nlichen Daten. Eine schnelle und reibungslose Verifizierung ist ein gutes Zeichen f\u00fcr ein seri\u00f6ses Casino.\n <\/p>\n

                        Faktoren, die die Auszahlungsdauer beeinflussen<\/h3>\n

                        \n Die tats\u00e4chliche Dauer, bis das Geld auf Ihrem Konto ist, h\u00e4ngt von mehreren Faktoren ab:\n <\/p>\n

                          \n
                        • Bearbeitungszeit des Casinos:<\/strong> Dies ist die Zeit, die das Casino ben\u00f6tigt, um Ihre Auszahlungsanfrage zu pr\u00fcfen und zu genehmigen. Manche Casinos bearbeiten Anfragen sofort, andere lassen sich 24-48 Stunden Zeit.<\/li>\n
                        • Gew\u00e4hlte Auszahlungsmethode:<\/strong> Wie bereits erw\u00e4hnt, sind E-Wallets oft am schnellsten, w\u00e4hrend Bank\u00fcberweisungen und Kartenzahlungen l\u00e4nger dauern k\u00f6nnen.<\/li>\n
                        • Bank des Spielers:<\/strong> Die Geschwindigkeit, mit der Ihre Bank Auslands\u00fcberweisungen oder Transaktionen verarbeitet, spielt ebenfalls eine Rolle.<\/li>\n
                        • Wochenenden und Feiertage:<\/strong> W\u00e4hrend dieser Zeiten sind die Bearbeitungszeiten in der Regel l\u00e4nger, da Banken und Casino-Mitarbeiter nicht immer verf\u00fcgbar sind.<\/li>\n<\/ul>\n

                          \n Manche Casinos werben mit “schnellen Auszahlungen”, was bedeutet, dass sie bem\u00fcht sind, Ihre Anfrage innerhalb von 24 Stunden zu bearbeiten. Dies ist oft der Fall bei Anbietern, die auf E-Wallets und eine effiziente interne Bearbeitung setzen.\n <\/p>\n

                          \n “Die Auszahlungsgeschwindigkeit ist oft das, was ein gutes Casino von einem mittelm\u00e4\u00dfigen unterscheidet. Spieler wollen ihre Gewinne schnell und unkompliziert erhalten k\u00f6nnen.”\n <\/p><\/blockquote>\n

                          \n Ein Casino, das transparent \u00fcber seine Auszahlungszeiten und -methoden informiert und einen reibungslosen Verifizierungsprozess anbietet, schafft Vertrauen. Es ist immer ratsam, sich vor der ersten Einzahlung \u00fcber diese Aspekte zu informieren.\n <\/p>\n<\/article>\n","protected":false},"excerpt":{"rendered":"

                          Der Willkommensbonus: Mehr als nur ein Lockmittel? Neue Spieler, die sich erstmalig auf einer Online-Casino-Plattform anmelden, werden oft von einem verlockenden Willkommensangebot begr\u00fc\u00dft. Bei mino casino bildet hier keine Ausnahme. Doch was genau verbirgt sich hinter diesen Versprechungen von zus\u00e4tzlichem Guthaben und Freispielen? Handelt es sich um ein echtes Geschenk oder um ein sorgf\u00e4ltig konstruiertes […]<\/p>\n","protected":false},"author":15,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[807],"tags":[],"class_list":["post-21088","post","type-post","status-publish","format-standard","hentry","category-mino-casino"],"_links":{"self":[{"href":"https:\/\/bragitrade.com\/index.php\/wp-json\/wp\/v2\/posts\/21088"}],"collection":[{"href":"https:\/\/bragitrade.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bragitrade.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bragitrade.com\/index.php\/wp-json\/wp\/v2\/users\/15"}],"replies":[{"embeddable":true,"href":"https:\/\/bragitrade.com\/index.php\/wp-json\/wp\/v2\/comments?post=21088"}],"version-history":[{"count":2,"href":"https:\/\/bragitrade.com\/index.php\/wp-json\/wp\/v2\/posts\/21088\/revisions"}],"predecessor-version":[{"id":21090,"href":"https:\/\/bragitrade.com\/index.php\/wp-json\/wp\/v2\/posts\/21088\/revisions\/21090"}],"wp:attachment":[{"href":"https:\/\/bragitrade.com\/index.php\/wp-json\/wp\/v2\/media?parent=21088"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bragitrade.com\/index.php\/wp-json\/wp\/v2\/categories?post=21088"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bragitrade.com\/index.php\/wp-json\/wp\/v2\/tags?post=21088"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}