friends = $friends; $this->register_hooks(); } /** * Register the WordPress hooks */ private function register_hooks() { if ( ! function_exists( 'register_block_type' ) ) { return; } if ( function_exists( 'classicpress_version' ) ) { return; } add_action( 'admin_enqueue_scripts', array( $this, 'language_data' ) ); add_filter( 'render_block', array( $this, 'render_friends_block_visibility' ), 10, 2 ); add_filter( 'get_the_excerpt', array( $this, 'current_excerpt_start' ), 9, 2 ); add_filter( 'get_the_excerpt', array( $this, 'current_excerpt_end' ), 11, 2 ); add_filter( 'wp_loaded', array( $this, 'add_block_visibility_attribute' ), 10, 2 ); add_filter( 'template_redirect', array( $this, 'handle_follow_me' ), 10, 2 ); add_action( 'enqueue_block_editor_assets', array( $this, 'register_friends_block_visibility' ) ); add_action( 'init', array( $this, 'register_blocks' ) ); } /** * Register our blocks. */ public function register_blocks() { if ( ! function_exists( 'register_block_type_from_metadata' ) ) { // Blocks is not active. return; } register_block_type_from_metadata( FRIENDS_PLUGIN_DIR . '/blocks/friends-list', array( 'render_callback' => array( $this, 'render_friends_list_block' ), ) ); register_block_type_from_metadata( FRIENDS_PLUGIN_DIR . '/blocks/friend-posts', array( 'render_callback' => array( $this, 'render_friend_posts_block' ), ) ); register_block_type_from_metadata( FRIENDS_PLUGIN_DIR . '/blocks/follow-me', array( 'render_callback' => array( $this, 'render_follow_me_block' ), ) ); register_block_type_from_metadata( FRIENDS_PLUGIN_DIR . '/blocks/message' ); } /** * Render the Friends List block * * @param array $attributes Attributes set by Blocks. * @return string The new block content. */ public function render_friends_list_block( $attributes ) { if ( ! isset( $attributes['user_types'] ) ) { $attributes['user_types'] = 'friends'; } switch ( $attributes['user_types'] ) { case 'friend_requests': $friends = User_Query::all_friend_requests(); $no_users = __( "You currently don't have any friend requests.", 'friends' ); break; case 'friends_subscriptions': $friends = User_Query::all_associated_users(); $no_users = __( "You don't have any friends or subscriptions yet.", 'friends' ); break; case 'subscriptions': $friends = User_Query::all_subscriptions(); $no_users = __( "You don't have any subscriptions yet.", 'friends' ); break; case 'friends': default: $friends = User_Query::all_friends(); $no_users = __( "You don't have any friends yet.", 'friends' ); } if ( $friends->get_total() === 0 ) { return '' . $no_users . ''; } if ( $attributes['users_inline'] ) { $out = ''; $first = true; } else { $out = ''; } return $out; } /** * Render the Friend Posts block * * @param array $attributes Attributes set by Blocks. * @return string The new block content. */ public function render_friend_posts_block( $attributes ) { $date_formats = array( 'Y m d H' => 'human', 'Y m d' => 'H:i', 'Y w' => 'D j, H:i', 'Y' => 'M j', '' => 'M j, Y', ); $last_author = false; $only_users = array(); if ( isset( $attributes['only_users'] ) ) { $only_users = array_flip( array_filter( preg_split( '/[, ]+/', $attributes['only_users'] ) ) ); } $exclude_users = array(); if ( isset( $attributes['exclude_users'] ) ) { $exclude_users = array_flip( array_filter( preg_split( '/[, ]+/', $attributes['exclude_users'] ) ) ); } $count = max( 1, min( 100, $attributes['count'] ) ); $remaining = $count; $offset = 0; $out = ''; } $last_author = $author; $out .= '
  • '; if ( $attributes['author_avatar'] ) { $out .= ''; } if ( $attributes['author_name'] ) { $out .= esc_html( $author ); } if ( $attributes['author_inline'] ) { $out .= ' '; } else { $out .= '
  • '; } $out .= ''; return $out; } /** * Register the Block Visibility script. */ public function register_friends_block_visibility() { wp_enqueue_script( 'friends-block-visibility', plugins_url( 'blocks/block-visibility/build/index.js', FRIENDS_PLUGIN_FILE ), array( 'wp-blocks', 'wp-element', 'wp-i18n', 'wp-editor' ), Friends::VERSION ); wp_enqueue_style( 'friends-blocks', plugins_url( 'friends-blocks.css', FRIENDS_PLUGIN_FILE ), array(), Friends::VERSION ); } /** * Adds a block visibility attribute. */ public function add_block_visibility_attribute() { $registered_blocks = \WP_Block_Type_Registry::get_instance()->get_all_registered(); foreach ( $registered_blocks as $block ) { $block->attributes['friendsVisibility'] = array( 'type' => 'string', 'default' => '', ); } } /** * Handle the follow me button click. */ public function handle_follow_me() { if ( ! isset( $_REQUEST['friends_friend_request_url'] ) ) { return; } if ( ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'friends_follow_me' ) ) { wp_safe_redirect( add_query_arg( 'error', __( 'Unable to verify nonce, please try again.', 'friends' ) ) ); exit; } $access_transient_key = 'friends_follow_me_' . crc32( $_SERVER['REMOTE_ADDR'] ); $access_count = get_transient( $access_transient_key ); if ( $access_count >= 10 ) { header( 'HTTP/1.0 529 Too Many Requests' ); wp_die( 'Too Many Requests' ); } set_transient( $access_transient_key, $access_count + 1, 3600 ); $url = $_REQUEST['friends_friend_request_url']; $fqdn_regex = '(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}(? 5, 'redirection' => 5, 'headers' => array( 'Accept: text/html', ), ) ); if ( 200 !== wp_remote_retrieve_response_code( $response ) ) { wp_safe_redirect( add_query_arg( 'error', sprintf( /* translators: %s is an HTTP status code */ __( 'The server returned an HTTP status: %s', 'friends' ), wp_remote_retrieve_response_code( $response ) ) ) ); exit; } $links = (array) wp_remote_retrieve_header( $response, 'link' ); if ( ! empty( $links ) ) { $friends_base_url_endpoints = array_filter( $links, function ( $link ) { return preg_match( '/rel="friends-base-url"/', $link ); } ); if ( ! empty( $friends_base_url_endpoints ) ) { header( 'Location: ' . $url . '?add-friend=' . urlencode( home_url() ) ); exit; } } // Try again for servers that filter out the Link headers. $response = wp_safe_remote_get( $url, array( 'timeout' => 5, 'redirection' => 5, ) ); if ( 200 !== wp_remote_retrieve_response_code( $response ) ) { wp_safe_redirect( add_query_arg( 'error', sprintf( /* translators: %s is an HTTP status code */ __( 'The server returned an HTTP status: %s', 'friends' ), wp_remote_retrieve_response_code( $response ) ) ) ); exit; } $content = wp_remote_retrieve_body( $response ); $mf = Mf2\parse( $content, $url ); if ( isset( $mf['rel-urls'] ) ) { foreach ( $mf['rel-urls'] as $link_url => $link ) { if ( in_array( 'friends-base-url', $link['rels'] ) ) { header( 'Location: ' . $link_url . '?add-friend=' . urlencode( home_url() ) ); exit; } } } header( 'Location: https://wpfriends.at/follow-me?url=' . urlencode( $_REQUEST['friends_friend_request_url'] ) ); exit; } /** * Add a CSRF to the Follow Me block. * * @param array $attributes Block attributes. * @param string $content Block default content. * @param \WP_Block $block Block instance. * @return string The rendered content. */ public function render_follow_me_block( $attributes, $content, $block ) { $input = 'current_excerpt ) { return $content; } return '' . __( 'Only friends', 'friends' ) . '' . $content . ''; } if ( current_user_can( 'friend' ) ) { return $content; } return ''; case 'not-friends': if ( friends::has_required_privileges() ) { if ( $this->current_excerpt ) { return $content; } return '' . __( 'Not friends', 'friends' ) . '' . $content . ''; } if ( current_user_can( 'friend' ) ) { return ''; } return $content; } return $content; } /** * Remember the current post being excerpted. With this we can change the visibility rendering. * * @param string $text The text. * @param \WP_Post $post The post. * * @return string The text. */ public function current_excerpt_start( $text = '', $post = null ) { if ( $post ) { $this->current_excerpt = $post->ID; } return $text; } /** * Stop remembering the current post being excerpted. * * @param string $text The text. * @param \WP_Post $post The post. * * @return string The text. */ public function current_excerpt_end( $text = '', $post = null ) { if ( $post && $this->current_excerpt === $post->ID ) { $this->current_excerpt = null; } return $text; } /** * Load up the language data for the Blocks blocks */ public function language_data() { $locale_data = array(); if ( function_exists( 'wp_get_jed_locale_data' ) ) { $locale_data = wp_get_jed_locale_data( 'friends' ); } elseif ( function_exists( 'blocks_get_jed_locale_data' ) ) { $locale_data = blocks_get_jed_locale_data( 'friends' ); } if ( ! empty( $locale_data ) ) { wp_add_inline_script( 'friends-block-not-friends', 'wp.i18n.setLocaleData( ' . wp_json_encode( $locale_data ) . ', "friends" );', 'before' ); } } }