* @return array $attrs */ private function remove_link_class( $attrs ) { if ( ! $this->remove_class || empty( $attrs['class'] ) || strpos( $attrs['class'], 'rank-math-link' ) === false ) { return $attrs; } $this->is_dirty = true; $attrs['class'] = str_replace( 'rank-math-link', '', $attrs['class'] ); if ( ! trim( $attrs['class'] ) ) { unset( $attrs['class'] ); } return $attrs; } /** * Set External attributs * * @since 1.0.44.2 * * @param array $attrs Array of link attributes. * * @return array $attrs */ private function set_external_attrs( $attrs ) { if ( ! $this->add_attributes ) { return $attrs; } // Skip if there is no href or it's a hash link like "#id". // Skip if relative link. // Skip for same domain ignoring sub-domain if any. if ( ! Url::is_external( $attrs['href'] ) ) { return $attrs; } if ( $this->should_add_nofollow( $attrs['href'] ) ) { if ( $this->nofollow_link || ( $this->nofollow_image && $this->is_valid_image( $attrs['href'] ) ) ) { $this->is_dirty = true; $this->set_rel_attribute( $attrs, 'nofollow', ( isset( $attrs['rel'] ) && ! Str::contains( 'dofollow', $attrs['rel'] ) && ! Str::contains( 'nofollow', $attrs['rel'] ) ) ); } } if ( $this->new_window_link && ! isset( $attrs['target'] ) ) { $this->is_dirty = true; $attrs['target'] = '_blank'; } if ( $this->add_noopener && $this->do_filter( 'noopener/domain', Url::get_domain( $attrs['href'] ) ) ) { $this->is_dirty = true; $this->set_rel_attribute( $attrs, 'noopener', ( isset( $attrs['rel'] ) && ! Str::contains( 'noopener', $attrs['rel'] ) ) ); } if ( Url::is_affiliate( $attrs['href'] ) ) { $this->is_dirty = true; $this->set_rel_attribute( $attrs, 'sponsored', ( isset( $attrs['rel'] ) && ! Str::contains( 'sponsored', $attrs['rel'] ) ) ); } return $attrs; } /** * Check if we need to add nofollow for this link, based on "nofollow_domains" & "nofollow_exclude_domains" * * @param string $url Link URL. * @return bool */ private function should_add_nofollow( $url ) { if ( ! $this->nofollow_link && ! $this->nofollow_image ) { return false; } $include_domains = $this->get_nofollow_domains( 'include' ); $exclude_domains = $this->get_nofollow_domains( 'exclude' ); $parent_domain = Url::get_domain( $url ); $parent_domain = preg_replace( '/^www\./', '', $parent_domain ); // Check if domain is in list. if ( ! empty( $include_domains ) ) { return in_array( $parent_domain, $include_domains, true ); } // Check if domain is NOT in list. if ( ! empty( $exclude_domains ) && in_array( $parent_domain, $exclude_domains, true ) ) { return false; } return true; } /** * Get domain for nofollow * * @param string $type Type either include or exclude. * @return array */ private function get_nofollow_domains( $type ) { static $rank_math_nofollow_domains; if ( isset( $rank_math_nofollow_domains[ $type ] ) ) { return $rank_math_nofollow_domains[ $type ]; } $setting = 'include' === $type ? 'nofollow_domains' : 'nofollow_exclude_domains'; $domains = Helper::get_settings( "general.{$setting}" ); $domains = Str::to_arr_no_empty( $domains ); // Strip off www. prefixes. $domains = array_map( function( $domain ) { $domain = preg_replace( '#^http(s)?://#', '', trim( $domain, '/' ) ); return preg_replace( '/^www\./', '', $domain ); }, $domains ); $rank_math_nofollow_domains[ $type ] = $domains; return $rank_math_nofollow_domains[ $type ]; } /** * Is a valid image url. * * @param string $url Image url. * * @return boolean */ private function is_valid_image( $url ) { foreach ( [ '.jpg', '.jpeg', '.png', '.gif' ] as $ext ) { if ( Str::contains( $ext, $url ) ) { return true; } } return false; } }