EST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } $passwords = WP_Application_Passwords::get_user_application_passwords( $user->ID ); $response = array(); foreach ( $passwords as $password ) { $response[] = $this->prepare_response_for_collection( $this->prepare_item_for_response( $password, $request ) ); } return new WP_REST_Response( $response ); } /** * Checks if a given request has access to get a specific application password. * * @since 5.6.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise. */ public function get_item_permissions_check( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } if ( ! current_user_can( 'read_app_password', $user->ID, $request['uuid'] ) ) { return new WP_Error( 'rest_cannot_read_application_password', __( 'Sorry, you are not allowed to read this application password.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Retrieves one application password from the collection. * * @since 5.6.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_item( $request ) { $password = $this->get_application_password( $request ); if ( is_wp_error( $password ) ) { return $password; } return $this->prepare_item_for_response( $password, $request ); } /** * Checks if a given request has access to create application passwords. * * @since 5.6.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise. */ public function create_item_permissions_check( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } if ( ! current_user_can( 'create_app_password', $user->ID ) ) { return new WP_Error( 'rest_cannot_create_application_passwords', __( 'Sorry, you are not allowed to create application passwords for this user.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Creates an application password. * * @since 5.6.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function create_item( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } $prepared = $this->prepare_item_for_database( $request ); if ( is_wp_error( $prepared ) ) { return $prepared; } $created = WP_Application_Passwords::create_new_application_password( $user->ID, wp_slash( (array) $prepared ) ); if ( is_wp_error( $created ) ) { return $created; } $password = $created[0]; $item = WP_Application_Passwords::get_user_application_password( $user->ID, $created[1]['uuid'] ); $item['new_password'] = WP_Application_Passwords::chunk_password( $password ); $fields_update = $this->update_additional_fields_for_object( $item, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } /** * Fires after a single application password is completely created or updated via the REST API. * * @since 5.6.0 * * @param array $item Inserted or updated password item. * @param WP_REST_Request $request Request object. * @param bool $creating True when creating an application password, false when updating. */ do_action( 'rest_after_insert_application_password', $item, $request, true ); $request->set_param( 'context', 'edit' ); $response = $this->prepare_item_for_response( $item, $request ); $response->set_status( 201 ); $response->header( 'Location', $response->get_links()['self'][0]['href'] ); return $response; } /** * Checks if a given request has access to update application passwords. * * @since 5.6.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise. */ public function update_item_permissions_check( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } if ( ! current_user_can( 'edit_app_password', $user->ID, $request['uuid'] ) ) { return new WP_Error( 'rest_cannot_edit_application_password', __( 'Sorry, you are not allowed to edit this application password.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Updates an application password. * * @since 5.6.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function update_item( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } $item = $this->get_application_password( $request ); if ( is_wp_error( $item ) ) { return $item; } $prepared = $this->prepare_item_for_database( $request ); if ( is_wp_error( $prepared ) ) { return $prepared; } $saved = WP_Application_Passwords::update_application_password( $user->ID, $item['uuid'], wp_slash( (array) $prepared ) ); if ( is_wp_error( $saved ) ) { return $saved; } $fields_update = $this->update_additional_fields_for_object( $item, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $item = WP_Application_Passwords::get_user_application_password( $user->ID, $item['uuid'] ); /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-application-passwords-controller.php */ do_action( 'rest_after_insert_application_password', $item, $request, false ); $request->set_param( 'context', 'edit' ); return $this->prepare_item_for_response( $item, $request ); } /** * Checks if a given request has access to delete all application passwords for a user. * * @since 5.6.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise. */ public function delete_items_permissions_check( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } if ( ! current_user_can( 'delete_app_passwords', $user->ID ) ) { return new WP_Error( 'rest_cannot_delete_application_passwords', __( 'Sorry, you are not allowed to delete application passwords for this user.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Deletes all application passwords for a user. * * @since 5.6.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function delete_items( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } $deleted = WP_Application_Passwords::delete_all_application_passwords( $user->ID ); if ( is_wp_error( $deleted ) ) { return $deleted; } return new WP_REST_Response( array( 'deleted' => true, 'count' => $deleted, ) ); } /** * Checks if a given request has access to delete a specific application password for a user. * * @since 5.6.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise. */ public function delete_item_permissions_check( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } if ( ! current_user_can( 'delete_app_password', $user->ID, $request['uuid'] ) ) { return new WP_Error( 'rest_cannot_delete_application_password', __( 'Sorry, you are not allowed to delete this application password.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Deletes an application password for a user. * * @since 5.6.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function delete_item( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } $password = $this->get_application_password( $request ); if ( is_wp_error( $password ) ) { return $password; } $request->set_param( 'context', 'edit' ); $previous = $this->prepare_item_for_response( $password, $request ); $deleted = WP_Application_Passwords::delete_application_password( $user->ID, $password['uuid'] ); if ( is_wp_error( $deleted ) ) { return $deleted; } return new WP_REST_Response( array( 'deleted' => true, 'previous' => $previous->get_data(), ) ); } /** * Checks if a given request has access to get the currently used application password for a user. * * @since 5.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise. */ public function get_current_item_permissions_check( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } if ( get_current_user_id() !== $user->ID ) { return new WP_Error( 'rest_cannot_introspect_app_password_for_non_authenticated_user', __( 'The authenticated application password can only be introspected for the current user.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Retrieves the application password being currently used for authentication of a user. * * @since 5.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_current_item( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } $uuid = rest_get_authenticated_app_password(); if ( ! $uuid ) { return new WP_Error( 'rest_no_authenticated_app_password', __( 'Cannot introspect application password.' ), array( 'status' => 404 ) ); } $password = WP_Application_Passwords::get_user_application_password( $user->ID, $uuid ); if ( ! $password ) { return new WP_Error( 'rest_application_password_not_found', __( 'Application password not found.' ), array( 'status' => 500 ) ); } return $this->prepare_item_for_response( $password, $request ); } /** * Performs a permissions check for the request. * * @since 5.6.0 * @deprecated 5.7.0 Use `edit_user` directly or one of the specific meta capabilities introduced in 5.7.0. * * @param WP_REST_Request $request * @return true|WP_Error */ protected function do_permissions_check( $request ) { _deprecated_function( __METHOD__, '5.7.0' ); $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } if ( ! current_user_can( 'edit_user', $user->ID ) ) { return new WP_Error( 'rest_cannot_manage_application_passwords', __( 'Sorry, you are not allowed to manage application passwords for this user.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Prepares an application password for a create or update operation. * * @since 5.6.0 * * @param WP_REST_Request $request Request object. * @return object|WP_Error The prepared item, or WP_Error object on failure. */ protected function prepare_item_for_database( $request ) { $prepared = (object) array( 'name' => $request['name'], ); if ( $request['app_id'] && ! $request['uuid'] ) { $prepared->app_id = $request['app_id']; } /** * Filters an application password before it is inserted via the REST API. * * @since 5.6.0 * * @param stdClass $prepared An object representing a single application password prepared for inserting or updating the database. * @param WP_REST_Request $request Request object. */ return apply_filters( 'rest_pre_insert_application_password', $prepared, $request ); } /** * Prepares the application password for the REST response. * * @since 5.6.0 * * @param array $item WordPress representation of the item. * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function prepare_item_for_response( $item, $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } $fields = $this->get_fields_for_response( $request ); $prepared = array( 'uuid' => $item['uuid'], 'app_id' => empty( $item['app_id'] ) ? '' : $item['app_id'], 'name' => $item['name'], 'created' => gmdate( 'Y-m-d\TH:i:s', $item['created'] ), 'last_used' => $item['last_used'] ? gmdate( 'Y-m-d\TH:i:s', $item['last_used'] ) : null, 'last_ip' => $item['last_ip'] ? $item['last_ip'] : null, ); if ( isset( $item['new_password'] ) ) { $prepared['password'] = $item['new_password']; } $prepared = $this->add_additional_fields_to_object( $prepared, $request ); $prepared = $this->filter_response_by_context( $prepared, $request['context'] ); $response = new WP_REST_Response( $prepared ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $user, $item ) ); } /** * Filters the REST API response for an application password. * * @since 5.6.0 * * @param WP_REST_Response $response The response object. * @param array $item The application password array. * @param WP_REST_Request $request The request object. */ return apply_filters( 'rest_prepare_application_password', $response, $item, $request ); } /** * Prepares links for the request. * * @since 5.6.0 * * @param WP_User $user The requested user. * @param array $item The application password. * @return array The list of links. */ protected function prepare_links( WP_User $user, $item ) { return array( 'self' => array( 'href' => rest_url( sprintf( '%s/users/%d/application-passwords/%s', $this->namespace, $user->ID, $item['uuid'] ) ), ), ); } /** * Gets the requested user. * * @since 5.6.0 * * @param WP_REST_Request $request The request object. * @return WP_User|WP_Error The WordPress user associated with the request, or a WP_Error if none found. */ protected function get_user( $request ) { if ( ! wp_is_application_passwords_available() ) { return new WP_Error( 'application_passwords_disabled', __( 'Application passwords are not available.' ), array( 'status' => 501 ) ); } $error = new WP_Error( 'rest_user_invalid_id', __( 'Invalid user ID.' ), array( 'status' => 404 ) ); $id = $request['user_id']; if ( 'me' === $id ) { if ( ! is_user_logged_in() ) { return new WP_Error( 'rest_not_logged_in', __( 'You are not currently logged in.' ), array( 'status' => 401 ) ); } $user = wp_get_current_user(); } else { $id = (int) $id; if ( $id <= 0 ) { return $error; } $user = get_userdata( $id ); } if ( empty( $user ) || ! $user->exists() ) { return $error; } if ( is_multisite() && ! user_can( $user->ID, 'manage_sites' ) && ! is_user_member_of_blog( $user->ID ) ) { return $error; } if ( ! wp_is_application_passwords_available_for_user( $user ) ) { return new WP_Error( 'application_passwords_disabled_for_user', __( 'Application passwords are not available for your account. Please contact the site administrator for assistance.' ), array( 'status' => 501 ) ); } return $user; } /** * Gets the requested application password for a user. * * @since 5.6.0 * * @param WP_REST_Request $request The request object. * @return array|WP_Error The application password details if found, a WP_Error otherwise. */ protected function get_application_password( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } $password = WP_Application_Passwords::get_user_application_password( $user->ID, $request['uuid'] ); if ( ! $password ) { return new WP_Error( 'rest_application_password_not_found', __( 'Application password not found.' ), array( 'status' => 404 ) ); } return $password; } /** * Retrieves the query params for the collections. * * @since 5.6.0 * * @return array Query parameters for the collection. */ public function get_collection_params() { return array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ); } /** * Retrieves the application password's schema, conforming to JSON Schema. * * @since 5.6.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $this->schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'application-password', 'type' => 'object', 'properties' => array( 'uuid' => array( 'description' => __( 'The unique identifier for the application password.' ), 'type' => 'string', 'format' => 'uuid', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'app_id' => array( 'description' => __( 'A UUID provided by the application to uniquely identify it. It is recommended to use an UUID v5 with the URL or DNS namespace.' ), 'type' => 'string', 'format' => 'uuid', 'context' => array( 'view', 'edit', 'embed' ), ), 'name' => array( 'description' => __( 'The name of the application password.' ), 'type' => 'string', 'required' => true, 'context' => array( 'view', 'edit', 'embed' ), 'minLength' => 1, 'pattern' => '.*\S.*', ), 'password' => array( 'description' => __( 'The generated password. Only available after adding an application.' ), 'type' => 'string', 'context' => array( 'edit' ), 'readonly' => true, ), 'created' => array( 'description' => __( 'The GMT date the application password was created.' ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'last_used' => array( 'description' => __( 'The GMT date the application password was last used.' ), 'type' => array( 'string', 'null' ), 'format' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'last_ip' => array( 'description' => __( 'The IP address the application password was last used by.' ), 'type' => array( 'string', 'null' ), 'format' => 'ip', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), ), ); return $this->add_additional_fields_schema( $this->schema ); } } } $this->run_install( $this->cache_base_path ); $this->is_installed = true; wp_send_json_success(); } /** * Run Install Font Awesome library from our server. * * @since 1.8.3 * * @param string $destination Destination path. */ public function run_install( $destination ) { // phpcs:ignore WPForms.PHP.HooksMethod.InvalidPlaceForAddingHooks // WordPress assumes it's a plugin/theme and tries to get translations. We don't need that, and it breaks JS output. remove_action( 'upgrader_process_complete', [ 'Language_Pack_Upgrader', 'async_upgrade' ], 20 ); if ( ! function_exists( 'request_filesystem_credentials' ) ) { require_once ABSPATH . 'wp-admin/includes/file.php'; } // Create the Upgrader with our custom skin that reports errors as WP JSON. $installer = new PluginSilentUpgrader( new WP_Ajax_Upgrader_Skin() ); // The installer skin reports any errors via wp_send_json_error() with generic error messages. $installer->init(); $installer->run( [ 'package' => self::FONT_AWESOME_URL, 'destination' => $destination, ] ); } /** * Load all necessary Font Awesome assets. * * @since 1.7.9 * * @param string $view Current Form Builder view (panel). */ public function enqueues( $view ) { if ( ! $this->is_installed() ) { return; } wp_enqueue_style( 'wpforms-icon-choices-font-awesome', $this->cache_base_url . '/css/fontawesome.min.css', [], self::FONT_AWESOME_VERSION ); wp_enqueue_style( 'wpforms-icon-choices-font-awesome-brands', $this->cache_base_url . '/css/brands.min.css', [], self::FONT_AWESOME_VERSION ); wp_enqueue_style( 'wpforms-icon-choices-font-awesome-regular', $this->cache_base_url . '/css/regular.min.css', [], self::FONT_AWESOME_VERSION ); wp_enqueue_style( 'wpforms-icon-choices-font-awesome-solid', $this->cache_base_url . '/css/solid.min.css', [], self::FONT_AWESOME_VERSION ); } /** * Define additional field properties specific to Icon Choices feature. * * @since 1.7.9 * * @see WPForms_Field_Checkbox::field_properties() * @see WPForms_Field_Radio::field_properties() * @see WPForms_Field_Payment_Checkbox::field_properties() * @see WPForms_Field_Payment_Multiple::field_properties() * * @param array $properties Field properties. * @param array $field Field settings. * * @return array */ public function field_properties( $properties, $field ) { $properties['input_container']['class'][] = 'wpforms-icon-choices'; $properties['input_container']['class'][] = sanitize_html_class( 'wpforms-icon-choices-' . $field['choices_icons_style'] ); $properties['input_container']['class'][] = sanitize_html_class( 'wpforms-icon-choices-' . $field['choices_icons_size'] ); $icon_color = isset( $field['choices_icons_color'] ) ? wpforms_sanitize_hex_color( $field['choices_icons_color'] ) : ''; $icon_color = empty( $icon_color ) ? self::get_default_color() : $icon_color; $properties['input_container']['attr']['style'] = "--wpforms-icon-choices-color: {$icon_color};"; foreach ( $properties['inputs'] as $key => $inputs ) { $properties['inputs'][ $key ]['container']['class'][] = 'wpforms-icon-choices-item'; if ( in_array( $field['choices_icons_style'], [ 'default', 'modern', 'classic' ], true ) ) { $properties['inputs'][ $key ]['class'][] = 'wpforms-screen-reader-element'; } } return $properties; } /** * Display a single choice on the form front-end. * * @since 1.7.9 * * @see WPForms_Field_Checkbox::field_display() * @see WPForms_Field_Radio::field_display() * @see WPForms_Field_Payment_Checkbox::field_display() * @see WPForms_Field_Payment_Multiple::field_display() * * @param array $field Field settings. * @param array $choice Single choice item settings. * @param string $type Field input type. * @param string|null $label Custom label, used by Payment fields. */ public function field_display( $field, $choice, $type, $label = null ) { // Only Payment fields supply a custom label. if ( ! $label ) { $label = $choice['label']['text']; } if ( is_array( $choice['label']['class'] ) && wpforms_is_empty_string( $label ) ) { $choice['label']['class'][] = 'wpforms-field-label-inline-empty'; } printf( '', wpforms_html_attributes( $choice['label']['id'], $choice['label']['class'], $choice['label']['data'], $choice['label']['attr'] ), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped $this->get_icon( $choice['icon'], $choice['icon_style'], $field['choices_icons_size'] ), esc_attr( $type ), wpforms_html_attributes( $choice['id'], $choice['class'], $choice['data'], $choice['attr'] ), esc_attr( $choice['required'] ), checked( '1', $choice['default'], false ), wp_kses_post( $label ) ); } /** * Output inline CSS custom properties (vars). * * @since 1.7.9 * * @param null|array $forms Frontend forms, if available. * * @return void */ public function css_custom_properties( $forms = null ) { $hook = current_action(); // On the frontend, we need these properties only if Icon Choices is in use. if ( $hook === 'wpforms_frontend_css' && ! wpforms_has_field_setting( 'choices_icons', $forms, true ) ) { return; } $selectors = [ 'wpforms_frontend_css' => '.wpforms-container', 'admin_head' => '#wpforms-builder, .wpforms-icon-picker-container', ]; /** * Add CSS custom properties. * * @since 1.7.9 * * @param array $properties CSS custom properties using CSS syntax. */ $custom_properties = (array) apply_filters( 'wpforms_forms_icon_choices_css_custom_properties', [] ); $icon_sizes = $this->get_icon_sizes(); foreach ( $icon_sizes as $slug => $data ) { $custom_properties[ "wpforms-icon-choices-size-{$slug}" ] = $data['size'] . 'px'; } $custom_properties_css = ''; foreach ( $custom_properties as $property => $value ) { $custom_properties_css .= "--{$property}: {$value};"; } printf( '', esc_attr( $selectors[ $hook ] ), esc_html( $custom_properties_css ) ); } /** * Get available icon sizes. * * @since 1.7.9 * * @return array A list of all icon sizes. */ public function get_icon_sizes() { /** * Allow modifying the icon sizes. * * @since 1.7.9 * * @param array $icon_sizes { * Default icon sizes. * * @type string $key The icon slug. * @type array $value { * Individual icon size data. * * @type string $label Translatable label. * @type int $size The size value. * } * } * @param array $default_icon_sizes Default icon sizes for reference. */ $sizes = (array) apply_filters( 'wpforms_forms_icon_choices_get_icon_sizes', [], $this->default_icon_sizes ); return array_merge( $this->default_icon_sizes, $sizes ); } /** * Read icons metadata from disk. * * @since 1.7.9 * * @param array $strings Strings and values sent to the frontend. * @param array $form Current form. * * @return array */ public function get_strings( $strings, $form ) { $strings['continue'] = esc_html__( 'Continue', 'wpforms-lite' ); $strings['done'] = esc_html__( 'Done!', 'wpforms-lite' ); $strings['uh_oh'] = esc_html__( 'Uh oh!', 'wpforms-lite' ); $strings['icon_choices'] = [ 'is_installed' => false, 'is_active' => $this->is_active(), 'default_icon' => self::DEFAULT_ICON, 'default_icon_style' => self::DEFAULT_ICON_STYLE, 'default_color' => self::get_default_color(), 'icons' => [], 'icons_per_page' => self::DEFAULT_ICONS_PER_PAGE, 'strings' => [ 'install_prompt_content' => esc_html__( 'In order to use the Icon Choices feature, an icon library must be downloaded and installed. It\'s quick and easy, and you\'ll only have to do this once.', 'wpforms-lite' ), 'install_title' => esc_html__( 'Installing Icon Library', 'wpforms-lite' ), 'install_content' => esc_html__( 'This should only take a minute. Please don’t close or reload your browser window.', 'wpforms-lite' ), 'install_success_content' => esc_html__( 'The icon library has been installed successfully. We will now save your form and reload the form builder.', 'wpforms-lite' ), 'install_error_content' => wp_kses( sprintf( /* translators: %s - WPForms Support URL. */ __( 'There was an error installing the icon library. Please try again later or contact support if the issue persists.', 'wpforms-lite' ), esc_url( wpforms_utm_link( 'https://wpforms.com/account/support/', 'builder-modal', 'Icon Library Install Failure' ) ) ), [ 'a' => [ 'href' => true, 'target' => true, 'rel' => true, ], ] ), 'reinstall_prompt_content' => esc_html__( 'The icon library appears to be missing or damaged. It will now be reinstalled.', 'wpforms-lite' ), 'icon_picker_title' => esc_html__( 'Icon Picker', 'wpforms-lite' ), 'icon_picker_description' => esc_html__( 'Browse or search for the perfect icon.', 'wpforms-lite' ), 'icon_picker_search_placeholder' => esc_html__( 'Search 2000+ icons...', 'wpforms-lite' ), 'icon_picker_not_found' => esc_html__( 'Sorry, we didn\'t find any matching icons.', 'wpforms-lite' ), ], ]; if ( ! $this->is_installed() ) { return $strings; } $strings['icon_choices']['is_installed'] = true; $strings['icon_choices']['icons'] = $this->get_icons(); return $strings; } /** * Get an SVG icon code from a file for inline output in HTML. * * Note: the output does not need to escape. * * @since 1.7.9 * * @param string $icon Font Awesome icon name. * @param string $style Font Awesome style (solid, brands). * @param string|int $size Icon display size. * * @return string */ private function get_icon( string $icon, string $style, $size ): string { // Sanitize inputs. $icon = sanitize_key( $icon ); $style = sanitize_key( $style ); $size = sanitize_key( (string) $size ); $icon_sizes = $this->get_icon_sizes(); $filename = wp_normalize_path( (string) realpath( "{$this->cache_base_path}/svgs/{$style}/{$icon}.svg" ) ); $allowed_dir = wp_normalize_path( (string) realpath( $this->cache_base_path . '/svgs' ) ); // Verify the file is within the allowed directory. if ( strpos( $filename, $allowed_dir ) !== 0 ) { return ''; } if ( ! is_file( $filename ) || ! is_readable( $filename ) ) { return ''; } // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents $svg = (string) file_get_contents( $filename ); if ( strpos( $svg, ' Vorbereitungen zur DM 2022 in München - Ringtennis

Ringtennis

Offizielle Homepage

Vorbereitungen zur DM 2022 in München

26. Dezember 2021

R.F.

Nachdem 2021 die Sommersaison zusammen mit den Deutschen Meisterschaften Corona-bedingt ausgefallen ist, sind die Veranstalter der DM vom Vorjahr voller Hoffnung, dass es in diesem Jahr klappen wird. Die Sportstätte vom TSV Solln soll, wie schon im Vorjahr geplant, wieder der Austragungsort sein, wobei die Organisation der DM vom TSV Neubiberg-Ottobrunn übernommen wird.
Peter Gessener, ehemaliger Ringtennisspieler des saarländischen Vereins St. Ingbert und nun Betreiber der Vereinsgaststätte Herterichstuben des TSV Solln in München, hat mit dem Hauptverein TSV Solln einen Vertrag abgeschlossen und die gesamte Anlage inkl. Halle für Übernachtung und Parkplätze für den 1.-4. September 2022 angemietet.
Logistisch war im Vorjahr Axel Runkel als Vertreter des Fachgebiets Ringtennis der Anmieter und Vertragshalter, nun geht diese Funktion an Peter über. Er hat damit auch finanziell die Gesamtverantwortung in der Hand. Die Glaskugel bleibt auch nach 2 Jahren Corona zwar trüb, aber die Hoffnung ruht auf dem bisherigen Sommerzyklus, der Anfang September solche Veranstaltungen ermöglichte.
Geplant ist ein Festzelt mit Live Musik für ein Familienfest/Spielfest zeitgleich auf der Anlage mit unserer Deutschen Meisterschaft. Die Kombination der Veranstaltungen ist sinnvoll. Durch der lokalen Werbung könnte schon gewaltig was los sein auf der Anlage, da in der Vergangenheit Peter’s Familienfest schon guten Zulauf hatte. Zudem eröffnet dies neue Zugangswege zur Stadt München.
Ein dickes Dankeschön an Peter, der hier eine große Verantwortung und ein großes Risiko trägt.

Weiterlesen