Settings → Link Indication. Version: 4.4 Author: Michael Wöhrer Author URI: http://sw-guide.de/ ---------------------------------------------------------------------------- ____________________________________________________ | | | Link Indication WordPress Plugin | |____________________________________________________| Copyright © Michael Wöhrer (michael dot woehrer at gmail dot com) This program 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 (at your option) any later version. This program 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. ---------------------------------------------------------------------------- */ require_once ( dirname(__FILE__) . '/inc.swg-plugin-framework.php'); class LinkIndication extends LinkIndication_SWGPluginFramework { /** * For applying the link indication */ function ApplyLinkIndication() { switch ($this->g_opt['mwli_apply']) { case '1': // Apply to content & comments add_filter('the_content', array(&$this, 'LinkIndicationMain'), 10); add_filter('the_excerpt', array(&$this, 'LinkIndicationMain'), 10); add_filter('comment_text', array(&$this, 'LinkIndicationMain'), 10); break; case '2': // Apply to content only add_filter('the_content', array(&$this, 'LinkIndicationMain'), 10); add_filter('the_excerpt', array(&$this, 'LinkIndicationMain'), 10); break; case '3': // Apply to entire blog but not to WP admin if ( strpos($_SERVER['REQUEST_URI'], 'wp-admin') === false ) { // Calling ob_start here causes that the plugin is not applied if gzip compression is turned on in the options. // wp-config.php calls wp-settings.php, which loads the plugins. gzip_compression() isn't called until after that, // in wp-blog-header.php. But since we want to apply after the compression is turned on, we just need to hook the // earliest thing after that we can -- which seems to be the template_redirect hook. add_action('template_redirect', array(&$this, 'ForAddAction_template_redirect_ob_start')); } break; } // switch if ($this->g_opt['mwli_snapr'] == '1') { add_action('wp_head', array(&$this, 'ForAddAction_wp_head_snappr')); } if ($this->g_opt['mwli_usecssfile'] == '1') { add_action('wp_head', array(&$this, 'ForAddAction_wp_head_style')); } } function ForAddAction_template_redirect_ob_start() { ob_start(array(&$this, 'LinkIndicationMain')); } function ForAddAction_wp_head_snappr() { // Apply websnapr echo "\n\t".'' . "\n\t".'' . "\n\t".'' . "\n\t".'' . "\n\t"; } function ForAddAction_wp_head_style() { // Apply link-indication_style.css echo "\n\t".'' . "\n\t".'' . "\n\t".'' . "\n\t"; } /** * The main function */ function LinkIndicationMain($content) { /* ***************** Pattern ****************** match1 (.*?): everything between " match7 (.*?): text of the link **********************************************/ $pattern = '/(.*?)<\/a>/i'; // don't remove space between '' . $matches[7] . ''; // Don't remove space in ' } /********************** * Because of problems with JS links we skip these *********************/ if (strpos(strtolower($matches[4]), 'javascript') !== false) { return '' . $matches[7] . ''; } /********************** * Prepare blog urls *********************/ $blogurlsArray = explode(' ', $this->g_opt['mwli_blogurls']); $loopcount = 0; foreach ($blogurlsArray as $loopval) { $blogurlsArrayClean[$loopcount] = $this->GetDomainnameFromUri($loopval); $loopcount++; } /********************** * Get the domain name *********************/ // Since plugin version 4.2, we do no longer use {$domainname_link = $this->GetDomainnameFromUri($matches[4]);} // We don't want to use the domain name only but the entire URL for the search - but without its parameters... $domainname_link = $matches[4]; if ( strpos($domainname_link, '?') !== false) { $domainname_link = substr($domainname_link, 0, strpos($domainname_link, '?')); } /********************** * Get the type of the link *********************/ $linktype = 'internal'; // default is internal, e.g. g_opt['mwli_targetblank'] == '1') ) { if ( (strpos($matches[1] . $matches[6], 'target=') === false) ) { // there is no target=, so we add target="_blank" $targetblank = 'target="_blank"'; } } /********************** * For some links, we apply rel="nofollow" if activated in option and is not already there... *********************/ $nofollow = ''; $nofollowWebsiteArray = explode(' ', $this->g_opt['mwli_nofollow']); foreach ($nofollowWebsiteArray as $loopVar) { if (strpos($matches[4], $loopVar) !== false) { if ( ! preg_match("/rel=[\"\'].*?nofollow.*?[\"\']/i", $matches[1] . $matches[6] ) ) { $nofollow = 'rel="nofollow"'; } } } /********************** * Build the css class *********************/ switch ($linktype) { case 'external-http': $csssetting = $this->g_opt['mwli_external']; break; case 'external-userdefined': // nothing to do since we have set the $csssetting above. break; case 'filename-extension': // nothing to do since we have set the $csssetting above. break; case 'external-ftp': $csssetting = $this->g_opt['mwli_ftp']; break; case 'mailto': $csssetting = $this->g_opt['mwli_mailto']; break; default: // internal $csssetting = $this->g_opt['mwli_internal']; } //switch /********************** * If it is an image url, do not add CSS, but add image link class *********************/ if (substr_count($matches[7] , ' 0) { if ($this->g_opt['mwli_toimages'] != '1') { $csssetting = ''; } if ($this->g_opt['mwli_imagelinks'] !== '') { if ($csssetting === '') { // nothing has been set or it has been reset above $csssetting = $this->g_opt['mwli_imagelinks']; } else { // append the image link class $csssetting = $csssetting . ' ' . $this->g_opt['mwli_imagelinks']; } } } /********************** * Do not add CSS if we deactivated it; *********************/ if ($this->g_opt['mwli_applycssclassattr'] != '1') { $csssetting = ''; } /********************** * Add websnapr class to all external links... *********************/ if (($this->g_opt['mwli_snapr'] == '1') && (substr($linktype, 0, 8) == 'external') ) { $csssetting = $csssetting . ($csssetting == '' ? '' : ' ') . 'previewlink'; } /********************** * Do not apply the class if there is already a class inside the anchor tag *********************/ if ( (strpos($matches[1] . $matches[6], 'class=') !== false) ) { $csssetting = ''; } // Final class if ($csssetting == '') { $finalclass = ''; } else { $finalclass = 'class="' . $csssetting . '"'; } /********************** * Final preparation *********************/ // put together the result $final_stuff = $matches[1] . ' ' . $matches[6] . ' ' . $targetblank . ' ' . $nofollow . ' ' . $finalclass; // replace multiple white spaces with a single space $final_stuff = eregi_replace('[[:space:]]+', ' ', $final_stuff); // remove leading and trailing white space $final_stuff = trim($final_stuff); // replace single quotes (') with double quotes (") //$final_stuff = str_replace('\'', '"', $final_stuff); // As of version 4.2: We do no longer do this due to problems with JS links /********************** * Return the result *********************/ return '' . $matches[7] . ''; } // function ParseLinks /** * Retrieve the domain name from the URI. We consider sub domains as well. */ function GetDomainnameFromUri($uri){ $exp1 = '/^(http|https|ftp)?(:\/\/)?(www.)?([^\/]+)/i'; preg_match($exp1, $uri, $matches); if (isset($matches[4])) { return $matches[4]; } else { return ''; } } /** * Convert option prior to save ("COPTSave"). * !!!! This function is used by the framework class !!!! */ function COPTSave($optname) { if ( ($optname == 'mwli_searchstrings') || ($optname == 'mwli_cssclasses') || ($optname == 'mwli_types') ) { // Special treatment for 3 fields $urlPostArray = $_POST['mwli_searchstrings']; $cssPostArray = $_POST['mwli_cssclasses']; $typePostArray = $_POST['mwli_types']; $loopCount = 0; if (is_array($urlPostArray)) { foreach ($urlPostArray as $loopVarURL) { $loopVarURL = str_replace(' ', '', $loopVarURL); // Strip whitespace $loopVarCSS = str_replace(' ', '', $cssPostArray[$loopCount]); // Get css and strip whitespace $loopVarType = $typePostArray[$loopCount]; // Get type if ( $loopVarURL != '' ) { $urlResultArray[] = $loopVarURL; $cssResultArray[] = $loopVarCSS; $typeResultArray[] = $loopVarType; } $loopCount++; } } } switch ($optname) { case 'mwli_blogurls': return $this->LineBreakToWhiteSpaceAndFormatURL($_POST[$optname]); case 'mwli_nofollow': return $this->LinebreakToWhitespace($_POST[$optname]); case 'mwli_searchstrings': return $urlResultArray; case 'mwli_cssclasses': return $cssResultArray; case 'mwli_types': return $typeResultArray; default: if (isset($_POST[$optname])) { return $_POST[$optname]; } else { return; } } // switch } /** * Convert option before HTML output ("COPTHTML"). * *NOT* used by the framework class */ function COPTHTML($optname) { $optval = $this->g_opt[$optname]; switch ($optname) { case 'mwli_nofollow': return $this->WhitespaceToLinebreak($optval); case 'mwli_blogurls': return $this->WhitespaceToLinebreak($optval); default: return $optval; } // switch } /** * Converts line breaks to whitespace and formats the URLs. * Applied before storing value in database */ function LineBreakToWhiteSpaceAndFormatURL($input) { // Remove white spaces $input = str_replace(' ', '', $input); // Replace linebreaks with white space, considering both \n and \r $input = preg_replace("/\r|\n/s", ' ', $input); // Create result. We create an array and loop thru it but do not consider empty values. $sourceArray = explode(' ', $input); $loopcount = 0; $result = ''; foreach ($sourceArray as $loopval) { if ($loopval <> '') { // Remove everything after the tld $exp1 = '/^(http:\/\/|https:\/\/|ftp:\/\/)?([^\/]+)/i'; preg_match($exp1, $loopval, $matches); if ($matches[1] == '') $matches[1] = 'http://'; // Add http:// if there is nothing... $loopval = $matches[1] . $matches[2]; // Create separator $sep = ''; if ($loopcount >= 1) $sep = ' '; // result $result .= $sep . $loopval; $loopcount++; } } return $result; } /** * Plugin Options */ function PluginOptionsPage() { //Add options $this->AddContentMain(__('style.css and link-indication_style.css',$this->g_info['ShortName']), '

' . __('We use',$this->g_info['ShortName']) . ' CSS ' . __('for the indication of links. You can either add appropriate CSS rules to your style.css of your themes directory',$this->g_info['ShortName']) . ' (/wp-content/themes/…)' . __('or you apply the file',$this->g_info['ShortName']) . ' link-indication_style.css ' . __('in the plugin\'s directory by activating the following option. In this case the images in',$this->g_info['ShortName']).' ' . $this->GetPluginURL() . 'images/ ' . __('will be used in the css file.',$this->g_info['ShortName']).'
' . __('Please don\'t forget to refresh the browser\'s cache (e.g. CTRL + F5 in Firefox) after you have modified the CSS file, otherwise you will not see your changes immediately.',$this->g_info['ShortName']) .'

' ); //Add options $this->AddContentMain(__('Plugin\'s Application',$this->g_info['ShortName']), '

COPTHTML('mwli_apply')=='1'?'checked="checked"':'') . ' />
COPTHTML('mwli_apply')=='2'?'checked="checked"':'') . ' />
COPTHTML('mwli_apply')=='3'?'checked="checked"':'') . ' />

'); //Add options $this->AddContentMain(__('Apply indicators and attributes to links',$this->g_info['ShortName']), '

'.__('Apply CSS Class Attributes',$this->g_info['ShortName']).'

'.__('This is the main purpose of the plugin: applying CSS class attributes to links. Further options are below in the section «CSS Class Attributes».',$this->g_info['ShortName']).'

'.__('target="_blank"',$this->g_info['ShortName']).'

' .__('This option will add',$this->g_info['ShortName']) .' target="_blank" ' .__('to all external hyperlinks. Please note that target="_blank" is not recommended according to',$this->g_info['ShortName']) .' W3C ' .__('and your website will not validate as XHTML Strict when activating this option.',$this->g_info['ShortName']).'

'.__('Websnapr preview thumbnails',$this->g_info['ShortName']).'

'.__('Displays overlay bubbles showing hyperlink target thumbnails, uses',$this->g_info['ShortName']).' websnapr.com JS' .__('. Please note that visitors may find these thumbnail previews pretty annoying.',$this->g_info['ShortName']).'

'.__('Add \'nofollow\' attribute',$this->g_info['ShortName']).'

' . __('When an URL contains any of these expressions, a rel="nofollow" attribute will be assigned. One expression per line. It will match inside URLS, so the expression wp-admin will match http://testblog.com/wp-admin/options-general.php.',$this->g_info['ShortName']).'
'.__('Example: If you want to assign nofollow to all links to Wikipedia, then enter wikipedia.org. This will apply nofollow to all links including subdomains like de.wikipedia.org, fr.wikipedia.org, etc. By the way, Wikipedia is adding nofollow tags to all external links, therefore it is listed below as default value.',$this->g_info['ShortName']).'' . '' ); // Add options; for the link types # Get options $tmpSearchStringArray = $this->COPTHTML('mwli_searchstrings'); $tmpCssArray = $this->COPTHTML('mwli_cssclasses'); $tmpTypeArray = $this->COPTHTML('mwli_types'); # Add a few empty values $tmpSearchStringArray[] = ''; $tmpCssArray[] = ''; $tmpTypeArray[] = ''; $tmpSearchStringArray[] = ''; $tmpCssArray[] = ''; $tmpTypeArray[] = ''; $tmpSearchStringArray[] = ''; $tmpCssArray[] = ''; $tmpTypeArray[] = ''; $tmpSearchStringArray[] = ''; $tmpCssArray[] = ''; $tmpTypeArray[] = ''; $tmpSearchStringArray[] = ''; $tmpCssArray[] = ''; $tmpTypeArray[] = ''; // Loop thru each value... $loopCount = 0; $fieldoutput = ''; foreach($tmpSearchStringArray as $loopVar) { $fieldoutput .= ' ' . ($loopCount + 1) . '.   '; $loopCount++; } $this->AddContentMain(__('CSS Class Attributes',$this->g_info['ShortName']),'

'.__('These CSS class attributes will be added to your hyperlinks. Please make sure that you have activated the option «Apply CSS Class Attributes» above.',$this->g_info['ShortName']).'
'.__('Example: If you have entered "liexternal" in the field "External links:", external links like <a href="http://www.google.com">Google</a> will become to <a class="liexternal" href="http://www.google.com">Google</a>.',$this->g_info['ShortName']).'

'.__('General links to external websites such as google.com, wordpress.org etc.',$this->g_info['ShortName']).'
'.__('Links to FTP server (ftp://...).',$this->g_info['ShortName']).'
'.__('E-mail links, e.g. mailto:test@site.com.',$this->g_info['ShortName']).'
'.__('All internal links.',$this->g_info['ShortName']).'
'.__('All links containing an image (<img> tags inside the <a> tag).',$this->g_info['ShortName']).'

'.__('Specific link types',$this->g_info['ShortName']).'

' . $fieldoutput . '
  '.__('Type',$this->g_info['ShortName']).' '.__('Search string',$this->g_info['ShortName']).' '.__('CSS class',$this->g_info['ShortName']).'

'.__('Explanation:',$this->g_info['ShortName']).'

' ); //Add options $this->AddContentMain(__('Expert options',$this->g_info['ShortName']), '

'.__('Blog URLs (your internal URLs)',$this->g_info['ShortName']).'

'. '

' . __('Enter one ore more blog URLs. Separate multiple URLs with line breaks. Links that are based on these URLs are considered as internal links. Chars which follow the',$this->g_info['ShortName']) . ' ' . __('tld',$this->g_info['ShortName']) . ' ' . __('(e.g. xxx in http://www.test.google.com/xxx) will be removed.
Your current blog URL: ',$this->g_info['ShortName']) . '' . get_bloginfo('url') . '' . '
' . __('Normally you don\'t need to change anything here and the blog URL is just fine.',$this->g_info['ShortName']) . '' . '

'.__('Apply CSS Class Attributes also to images',$this->g_info['ShortName']).'

' . '' ); // Sidebar, we can also add individual items... $this->PrepareStandardSidebar(); $this->GetGeneratedOptionsPage(); } } // class if( !isset($myLinkIndication) ) { // Create a new instance of your plugin that utilizes the WordpressPluginFramework and initialize the instance. $myLinkIndication = new LinkIndication(); $myLinkIndication->Initialize( // 1. We define the plugin information now and do not use get_plugin_data() due to performance. array( # Plugin name 'Name' => 'Link Indication', # Author of the plugin 'Author' => 'Michael Wöhrer', # Authot URI 'AuthorURI' => 'http://sw-guide.de/', # Plugin URI 'PluginURI' => 'http://sw-guide.de/wordpress/plugins/link-indication/', # Support URI: E.g. WP or plugin forum, wordpress.org tags, etc. 'SupportURI' => 'http://wordpress.org/tags/link-indication', # Name of the options for the options database table 'OptionName' => 'plugin_link-indication', # Old option names to delete from the options table 'DeleteOldOpt' => array('mw_linkindication_plugin', 'plugin_linkindication', 'plugin_linkindication3'), # Plugin version 'Version' => '4.4', # First plugin version of which we do not reset the plugin options to default; # Normally we reset the plugin's options after an update; but if we for example # update the plugin from version 2.3 to 2.4 und did only do minor changes and # not any option modifications, we should enter '2.3' here. In this example # options are being reset to default only if the old plugin version was < 2.3. 'UseOldOpt' => '4.0', # Copyright year(s) 'CopyrightYear' => '2006-2010', # Minimum WordPress version 'MinWP' => '2.3', # Do not change; full path and filename of the plugin 'PluginFile' => __FILE__, # Used for language file, nonce field security, etc. 'ShortName' => 'link-indication', ), // 2. We define the plugin option names and the initial options array( 'pluginversion' => '', //Please leave it always empty, we fill it later anyway. 'mwli_blogurls' => get_bloginfo('url'), 'mwli_applycssclassattr' => '1', 'mwli_external' => 'liexternal', 'mwli_ftp' => 'liftp', 'mwli_mailto' => 'limailto', 'mwli_internal' => 'liinternal', 'mwli_imagelinks' => 'liimagelink', 'mwli_apply' => '1', 'mwli_toimages' => '', 'mwli_targetblank' => '', 'mwli_searchstrings' => array('wikipedia.org', 'wordpress.org', 'pdf','zip|rar|tar|lzh|gz|ace|arj'), 'mwli_cssclasses' => array('liwikipedia', 'liwp', 'lipdf','lizip'), 'mwli_types' => array('External URL', 'External URL', 'File Extension', 'File Extension'), 'mwli_snapr' => '', 'mwli_nofollow' => '/wp-admin/ wp-login.php wikipedia.org', 'mwli_usecssfile' => '', ) ); $myLinkIndication->ApplyLinkIndication(); } // if( !isset($myLinkIndication) ) ?>