File: /var/www/html/wp-content/plugins/wp-external-links/includes/class-wpel-front.php
<?php
/**
* Class WPEL_Front
*
* @package WPEL
* @category WordPress Plugin
* @version 2.3
* @link https://www.webfactoryltd.com/
* @license Dual licensed under the MIT and GPLv2+ licenses
*/
final class WPEL_Front extends WPRun_Base_1x0x0
{
/**
* @var WPEL_Settings_Page
*/
private $settings_page = null;
/**
* Initialize
* @param WPEL_Settings_Page $settings_page
*/
protected function init( WPEL_Settings_Page $settings_page )
{
$this->settings_page = $settings_page;
// load front ignore
WPEL_Front_Ignore::create( $settings_page );
// load template tags
WPEL_Template_Tags::create( $this );
// apply page sections
if ( $this->opt( 'apply_all' ) ) {
// create final_output filterhook
FWP_Final_Output_1x0x0::create();
add_action( 'final_output', $this->get_callback( 'scan' ), 10000000000 );
} else {
$filter_hooks = array();
if ( $this->opt( 'apply_post_content' ) ) {
array_push( $filter_hooks, 'the_title', 'the_content', 'the_excerpt', 'get_the_excerpt' );
}
if ( $this->opt( 'apply_comments' ) ) {
array_push( $filter_hooks, 'comment_text', 'comment_excerpt' );
}
if ( $this->opt( 'apply_widgets' ) ) {
// create widget_output filterhook
FWP_Widget_Output_1x0x0::create();
array_push( $filter_hooks, 'widget_output' );
}
foreach ( $filter_hooks as $hook ) {
add_filter( $hook, $this->get_callback( 'scan' ), 10000000000 );
}
}
}
/**
* Turn off output buffer for REST API calls
* @param type $wp_rest_server
*/
protected function action_rest_api_init()
{
ob_end_flush();
}
/**
* Get option value
* @param string $key
* @param string|null $type
* @return string
* @triggers E_USER_NOTICE Option value cannot be found
*/
protected function opt( $key, $type = null )
{
return $this->settings_page->get_option_value( $key, $type );
}
/**
* Action for "wp_enqueue_scripts"
*/
protected function action_wp_enqueue_scripts()
{
$icon_type_int = $this->opt( 'icon_type', 'internal-links' );
$icon_type_ext = $this->opt( 'icon_type', 'external-links' );
$icon_type_excl = $this->opt( 'icon_type', 'excluded-links' );
if ( 'dashicon' === $icon_type_int || 'dashicon' === $icon_type_ext || 'dashicon' === $icon_type_excl ) {
wp_enqueue_style( 'dashicons' );
}
if ( 'fontawesome' === $icon_type_int || 'fontawesome' === $icon_type_ext || 'fontawesome' === $icon_type_excl) {
wp_enqueue_style( 'wpel-font-awesome' );
}
if ( $this->opt( 'icon_type', 'excluded-links' ) || $this->opt( 'icon_type', 'external-links' ) || $this->opt( 'icon_type', 'internal-links' ) ) {
wp_enqueue_style( 'wpel-style' );
}
}
/**
* Scan content for links
* @param string $content
* @return string
*/
public function scan( $content )
{
/**
* Filter whether the plugin settings will be applied on links
* @param boolean $apply_settings
*/
$apply_settings = apply_filters( 'wpel_apply_settings', true );
if ( false === $apply_settings ) {
return $content;
}
/**
* Filters before scanning content (for internal use)
* @param string $content
*/
$content = apply_filters( '_wpel_before_filter', $content );
$regexp_link = '/<a[^A-Za-z>](.*?)>(.*?)<\/a[\s+]*>/is';
$content = preg_replace_callback( $regexp_link, $this->get_callback( 'match_link' ), $content );
/**
* Filters after scanning content (for internal use)
* @param string $content
*/
$content = apply_filters( '_wpel_after_filter', $content );
return $content;
}
/**
* Pregmatch callback for handling link
* @param array $matches [ 0 ] => link, [ 1 ] => atts_string, [ 2 ] => label
* @return string
*/
protected function match_link( $matches )
{
$original_link = $matches[ 0 ];
$atts = $matches[ 1 ];
$label = $matches[ 2 ];
if(strpos($atts,'href') === false){
return $original_link;
}
$created_link = $this->get_created_link( $label, $atts );
if ( false === $created_link ) {
return $original_link;
}
return $created_link;
}
/**
* Create html link
* @param string $label
* @param string $atts
* @return string
*/
protected function get_created_link( $label, $atts )
{
$link = new WPEL_Link( 'a', $label );
$link->set_atts( $atts );
/**
* Action triggered before link settings will be applied
* @param WPEL_Link $link
* @return void
*/
do_action( 'wpel_before_apply_link', $link );
// has ignore flag
if ( $link->is_ignore() ) {
return false;
}
$this->set_link( $link );
return $link->get_html( false );
}
/**
* Set link
* @param WPEL_Link $link
*/
protected function set_link( WPEL_Link $link )
{
$url = $link->get_attr( 'href' );
$excludes_as_internal_links = $this->opt( 'excludes_as_internal_links' );
// internal, external or excluded
$is_excluded = $link->is_exclude() || $this->is_excluded_url( $url );
$is_internal = $link->is_internal() || ( $this->is_internal_url( $url ) && ! $this->is_included_url( $url ) ) || ( $is_excluded && $excludes_as_internal_links );
$is_external = $link->is_external() || ( ! $is_internal && ! $is_excluded );
if (strpos($url,'#') === 0) {
// skip anchors
} else if ( $is_external ) {
$link->set_external();
$this->apply_link_settings( $link, 'external-links' );
} else if ( $is_internal ) {
$link->set_internal();
$this->apply_link_settings( $link, 'internal-links' );
} else if ( $is_excluded ) {
$link->set_exclude();
$this->apply_link_settings( $link, 'excluded-links' );
}
/**
* Action for changing link object
* @param WPEL_Link $link
* @return void
*/
do_action( 'wpel_link', $link );
}
/**
* @param WPEL_Link $link
* @param string $type
*/
protected function apply_link_settings( WPEL_Link $link, $type )
{
if ( ! $this->opt( 'apply_settings', $type ) ) {
return;
}
// set target
$target = $this->opt( 'target', $type );
$target_overwrite = $this->opt( 'target_overwrite', $type );
$has_target = $link->has_attr( 'target' );
if ( $target && ( ! $has_target || $target_overwrite ) ) {
$link->set_attr( 'target', $target );
}
// add "follow" / "nofollow"
$follow = $this->opt( 'rel_follow', $type );
$follow_overwrite = $this->opt( 'rel_follow_overwrite', $type );
$has_follow = $link->has_attr_value( 'rel', 'follow' ) || $link->has_attr_value( 'rel', 'nofollow' );
if ( $follow && ( ! $has_follow || $follow_overwrite ) ) {
if ( $has_follow ) {
$link->remove_from_attr( 'rel', 'follow' );
$link->remove_from_attr( 'rel', 'nofollow' );
}
$link->add_to_attr( 'rel', $follow );
}
// add "external"
if ( 'external-links' === $type && $this->opt( 'rel_external', $type ) ) {
$link->add_to_attr( 'rel', 'external' );
}
// add "noopener"
if ( $this->opt( 'rel_noopener', $type ) ) {
$link->add_to_attr( 'rel', 'noopener' );
}
// add "noreferrer"
if ( $this->opt( 'rel_noreferrer', $type ) ) {
$link->add_to_attr( 'rel', 'noreferrer' );
}
// add "sponsored"
if ( 'external-links' === $type && $this->opt( 'rel_sponsored', $type ) ) {
$link->add_to_attr( 'rel', 'sponsored' );
}
// add "ugc"
if ( 'external-links' === $type && $this->opt( 'rel_ugc', $type ) ) {
$link->add_to_attr( 'rel', 'ugc' );
}
// set title
$title_format = $this->opt( 'title', $type );
if ( $title_format ) {
$title = $link->get_attr( 'title' );
$text = $link->get_content();
$new_title = str_replace( array( '{title}', '{text}', '{text_clean}' ), array( wp_strip_all_tags( $title ), wp_strip_all_tags( $text ), wp_strip_all_tags( $text ) ), $title_format );
if ( $new_title ) {
$link->set_attr( 'title', $new_title );
}
}
// add classes
$class = $this->opt( 'class', $type );
if ( $class ) {
$link->add_to_attr( 'class', $class );
}
// add icon
$icon_type = $this->opt( 'icon_type', $type );
$no_icon_for_img = $this->opt( 'no_icon_for_img', $type );
$has_img = preg_match( '/<img([^>]*)>/is', $link->get_content() );
if ( $icon_type && ! ( $has_img && $no_icon_for_img ) && ! $link->has_attr_value( 'class', 'wpel-no-icon' ) ) {
if ( 'dashicon' === $icon_type ) {
$dashicon = $this->opt( 'icon_dashicon', $type );
$icon = '<i class="wpel-icon dashicons-before '. $dashicon .'" aria-hidden="true"></i>';
} else if ( 'fontawesome' === $icon_type ) {
$fa = $this->opt( 'icon_fontawesome', $type );
$icon = '<i class="wpel-icon fa '. $fa .'" aria-hidden="true"></i>';
} else if ( 'image' === $icon_type ) {
$image = $this->opt( 'icon_image', $type );
$icon = '<span class="wpel-icon wpel-image wpel-icon-'. $image .'"></span>';
}
if ( 'left' === $this->opt( 'icon_position', $type ) ) {
$link->add_to_attr( 'class', 'wpel-icon-left' );
$link->set_content( $icon . $link->get_content() );
} else if ( 'right' === $this->opt( 'icon_position', $type ) ) {
$link->add_to_attr( 'class', 'wpel-icon-right' );
$link->set_content( $link->get_content() . $icon );
}
}
}
/**
* Check if url is included as external link
* @param string $url
* @return boolean
*/
protected function is_included_url( $url )
{
// should be using private property, but static is more practical
static $include_urls_arr = null;
if ( null === $include_urls_arr ) {
$include_urls = $this->opt( 'include_urls' );
$include_urls = str_replace( "\n", ',', $include_urls );
if ( '' === trim( $include_urls ) ) {
$include_urls_arr = array();
} else {
$include_urls_arr = explode( ',', $include_urls );
}
$include_urls_arr = array_filter( $include_urls_arr, function ( $url ) {
return '' !== trim( $url );
} );
}
foreach ( $include_urls_arr as $include_url ) {
if ( false !== strpos( $url, $include_url ) ) {
return true;
}
}
return false;
}
/**
* Check if url is excluded as external link
* @param string $url
* @return boolean
*/
protected function is_excluded_url( $url )
{
// should be using private property, but static is more practical
static $exclude_urls_arr = null;
if ( null === $exclude_urls_arr ) {
$exclude_urls = $this->opt( 'exclude_urls' );
$exclude_urls = str_replace( "\n", ',', $exclude_urls );
if ( '' === trim( $exclude_urls ) ) {
$exclude_urls_arr = array();
} else {
$exclude_urls_arr = explode( ',', $exclude_urls );
}
$exclude_urls_arr = array_filter( $exclude_urls_arr, function ( $url ) {
return '' !== trim( $url );
} );
}
foreach ( $exclude_urls_arr as $exclude_url ) {
if ( false !== strpos( $url, $exclude_url ) ) {
return true;
}
}
return false;
}
/**
* Check url is internal
* @param string $url
* @return boolean
*/
protected function is_internal_url( $url )
{
// all relative url's are internal
if ( substr( $url, 0, 7 ) !== 'http://'
&& substr( $url, 0, 8 ) !== 'https://'
&& substr( $url, 0, 6 ) !== 'ftp://'
&& substr( $url, 0, 2 ) !== '//' ) {
return true;
}
// is internal
$url_without_protocol = preg_replace('#^http(s)?://#', '', home_url( '' ));
$clean_home_url = preg_replace('/^www\./', '', $url_without_protocol);
if ( 0 === strpos( $url, 'http://'.$clean_home_url )
|| 0 === strpos( $url, 'https://'.$clean_home_url )
|| 0 === strpos( $url, 'http://www.'.$clean_home_url )
|| 0 === strpos( $url, 'https://www.'.$clean_home_url )
) {
return true;
}
// check subdomains
if ( $this->opt( 'subdomains_as_internal_links' ) && false !== strpos( $url, $this->get_domain() ) ) {
return true;
}
return false;
}
/**
* Get domain name
* @return string
*/
protected function get_domain() {
// should be using private property, but static is more practical
static $domain_name = null;
if ( null === $domain_name ) {
preg_match(
'/[a-z0-9\-]{1,63}\.[a-z\.]{2,6}$/'
, parse_url( home_url(), PHP_URL_HOST )
, $domain_tld
);
if ( count( $domain_tld ) > 0 ) {
$domain_name = $domain_tld[ 0 ];
} else if(isset($_SERVER[ 'SERVER_NAME' ])){
$domain_name = sanitize_text_field(wp_unslash($_SERVER[ 'SERVER_NAME' ]));
} else {
$domain_name = '';
}
}
return $domain_name;
}
}