2008-02-01 18:09:53 +00:00
< ? php
/*
2009-11-17 10:46:35 +00:00
* e107 website system
*
2010-01-16 20:49:55 +00:00
* Copyright ( C ) 2008 - 2010 e107 Inc ( e107 . org )
2009-11-17 10:46:35 +00:00
* Released under the terms and conditions of the
* GNU General Public License ( http :// www . gnu . org / licenses / gpl . txt )
*
*/
2008-02-01 18:09:53 +00:00
2010-01-02 22:57:41 +00:00
/**
* e107 Linkword plugin
*
* 'Hook' page
* The class is 'hooked' by the parser , to add linkword capability to any context where its enabled .
2010-01-16 20:49:55 +00:00
*
* @ todo Link to capability for clever display options on tooltips
2010-01-02 22:57:41 +00:00
*/
2008-02-01 18:09:53 +00:00
if ( ! defined ( 'e107_INIT' )) { exit ; }
2015-02-07 13:38:29 -08:00
// if (!e107::isInstalled('linkwords')) exit; // This will completely break a site during upgrades.
2008-02-01 18:09:53 +00:00
2012-04-26 02:42:41 +00:00
define ( 'LW_CACHE_ENABLE' , FALSE );
2008-02-01 18:09:53 +00:00
class e_tohtml_linkwords
{
2016-05-12 14:57:03 -07:00
protected $lw_enabled = FALSE ; // Default to disabled to start
2008-12-07 21:55:02 +00:00
var $lwAjaxEnabled = FALSE ; // Adds in Ajax-compatible links
var $utfMode = '' ; // Flag to enable utf-8 on regex
2019-10-26 18:42:25 +02:00
2016-05-12 14:57:03 -07:00
protected $word_list = array (); // List of link words/phrases
2008-12-07 21:55:02 +00:00
var $link_list = array (); // Corresponding list of links to apply
var $ext_list = array (); // Flags to determine 'open in new window' for link
var $tip_list = array (); // Store for tooltips
2008-12-13 18:04:52 +00:00
var $LinkID = array (); // Unique ID for each linkword
2008-12-07 21:55:02 +00:00
var $area_opts = array (); // Process flags for the various contexts
2008-02-01 18:09:53 +00:00
var $block_list = array (); // Array of 'blocked' pages
2008-12-07 21:55:02 +00:00
2016-05-12 14:57:03 -07:00
protected $word_class = array ();
2015-04-09 20:41:44 -07:00
protected $customClass = '' ;
protected $wordCount = array ();
2019-04-25 13:29:00 -07:00
protected $word_limit = array ();
2016-05-12 14:57:03 -07:00
// protected $maxPerWord = 3;
2015-04-09 20:41:44 -07:00
2019-04-25 15:52:05 -07:00
public function enable ()
{
$this -> lw_enabled = true ;
}
public function setWordData ( $arr = array ())
{
foreach ( $arr as $val )
{
$this -> word_list [] = $val [ 'word' ];
$this -> link_list [] = $val [ 'link' ];
$this -> ext_list [] = $val [ 'ext' ];
$this -> tip_list [] = $val [ 'tip' ];
$this -> word_limit [] = $val [ 'limit' ];
}
}
public function setAreaOpts ( $arr = array ())
{
$this -> area_opts = $arr ;
}
public function setLink ( $arr )
{
$this -> word_list = $arr ;
}
2008-12-07 21:55:02 +00:00
/* constructor */
2015-04-09 20:41:44 -07:00
function __construct ()
2008-02-01 18:09:53 +00:00
{
2019-10-26 18:42:25 +02:00
$tp = e107 :: getParser ();
$pref = e107 :: pref ( 'core' );
$frm = e107 :: getForm ();
2015-04-09 20:41:44 -07:00
2016-05-12 14:57:03 -07:00
// $this->maxPerWord = vartrue($pref['lw_max_per_word'], 25);
2015-04-09 20:41:44 -07:00
$this -> customClass = vartrue ( $pref [ 'lw_custom_class' ], '' );
2020-03-31 11:56:04 -07:00
$this -> area_opts = varset ( $pref [ 'lw_context_visibility' ]);
2015-04-09 20:41:44 -07:00
$this -> utfMode = ( strtolower ( CHARSET ) == 'utf-8' ) ? 'u' : '' ; // Flag to enable utf-8 on regex //@TODO utfMode probably obsolete
$this -> lwAjaxEnabled = varset ( $pref [ 'lw_ajax_enable' ], 0 );
2008-12-13 18:04:52 +00:00
// See whether they should be active on this page - if not, no point doing anything!
2016-09-17 11:17:04 -07:00
if ( e_ADMIN_AREA === true ) { return ; }
// if ((strpos(e_SELF, ADMINDIR) !== FALSE) || (strpos(e_PAGE, "admin_") !== FALSE)) return; // No linkwords on admin directories
2008-02-01 18:09:53 +00:00
2008-12-13 18:04:52 +00:00
// Now see if disabled on specific pages
2016-09-17 11:17:04 -07:00
$check_url = e_SELF . ( defined ( 'e_QUERY' ) ? " ? " . e_QUERY : '' );
2008-12-13 18:04:52 +00:00
$this -> block_list = explode ( " | " , substr ( varset ( $pref [ 'lw_page_visibility' ], '' ), 2 )); // Knock off the 'show/hide' flag
2015-04-09 20:41:44 -07:00
foreach ( $this -> block_list as $p )
2008-02-01 18:09:53 +00:00
{
2015-04-09 20:41:44 -07:00
if ( $p = trim ( $p ))
2008-12-13 18:04:52 +00:00
{
if ( substr ( $p , - 1 ) == '!' )
{
$p = substr ( $p , 0 , - 1 );
if ( substr ( $check_url , strlen ( $p ) *- 1 ) == $p ) return ;
}
else
{
if ( strpos ( $check_url , $p ) !== FALSE ) return ;
}
}
}
2008-02-01 18:09:53 +00:00
2008-12-13 18:04:52 +00:00
// Will probably need linkwords on this page - so get the info
2010-01-02 22:57:41 +00:00
define ( 'LW_CACHE_TAG' , 'nomd5_linkwords' ); // Put it here to avoid conflict on admin pages
2015-04-09 20:41:44 -07:00
if ( LW_CACHE_ENABLE && ( $temp = e107 :: getCache () -> retrieve_sys ( LW_CACHE_TAG )))
2008-12-13 18:04:52 +00:00
{
$ret = eval ( $temp );
if ( $ret )
{
echo " Error reading linkwords cache: { $ret } <br /> " ;
$temp = '' ;
2008-02-01 18:09:53 +00:00
}
else
{
2008-12-13 18:04:52 +00:00
$this -> lw_enabled = TRUE ;
2008-02-01 18:09:53 +00:00
}
2008-12-13 18:04:52 +00:00
}
2015-04-09 20:41:44 -07:00
if ( ! vartrue ( $temp )) // Either cache disabled, or no info in cache (or error reading/processing cache)
{
$link_sql = e107 :: getDb ( 'link_sql' );
if ( $link_sql -> select ( " linkwords " , " * " , " linkword_active!=1 " ))
2008-12-13 18:04:52 +00:00
{
2016-05-12 14:57:03 -07:00
$this -> lw_enabled = true ;
while ( $row = $link_sql -> fetch ())
2008-12-13 18:04:52 +00:00
{
2015-04-09 20:41:44 -07:00
2019-04-25 13:29:00 -07:00
$lw = $tp -> ustrtolower ( $row [ 'linkword_word' ]); // It was trimmed when saved *utf
2015-04-09 20:41:44 -07:00
if ( $row [ 'linkword_active' ] == 2 )
{
$row [ 'linkword_link' ] = '' ; // Make sure linkword disabled
}
if ( $row [ 'linkword_active' ] < 2 )
{
$row [ 'linkword_tooltip' ] = '' ; // Make sure tooltip disabled
}
2008-12-13 18:04:52 +00:00
$lwID = max ( $row [ 'linkword_tip_id' ], $row [ 'linkword_id' ]); // If no specific ID defined, use the DB record ID
2015-04-09 20:41:44 -07:00
if ( strpos ( $lw , ',' )) // Several words to same link
{
2008-12-13 18:04:52 +00:00
$lwlist = explode ( ',' , $lw );
foreach ( $lwlist as $lw )
{
2016-12-21 12:10:21 -08:00
$lw = trim ( $lw );
if ( empty ( $lw ))
{
continue ;
}
$this -> word_list [] = $lw ;
2016-05-12 14:57:03 -07:00
$this -> word_class [] = 'lw-' . $frm -> name2id ( $lw );
$this -> word_limit [] = vartrue ( $row [ 'linkword_limit' ], 3 );
$this -> link_list [] = $row [ 'linkword_link' ];
$this -> tip_list [] = $row [ 'linkword_tooltip' ];
$this -> ext_list [] = $row [ 'linkword_newwindow' ];
$this -> LinkID [] = $lwID ;
2008-12-13 18:04:52 +00:00
}
}
else
{
2016-12-21 12:10:21 -08:00
$lw = trim ( $lw );
if ( empty ( $lw ))
{
continue ;
}
2015-04-09 20:41:44 -07:00
$this -> word_list [] = $lw ;
2016-05-12 14:57:03 -07:00
$this -> word_class [] = 'lw-' . $frm -> name2id ( $lw );
$this -> word_limit [] = vartrue ( $row [ 'linkword_limit' ], 3 );
2015-04-09 20:41:44 -07:00
$this -> link_list [] = $row [ 'linkword_link' ];
$this -> tip_list [] = $row [ 'linkword_tooltip' ];
$this -> ext_list [] = $row [ 'linkword_newwindow' ];
2016-05-12 14:57:03 -07:00
2015-04-09 20:41:44 -07:00
$this -> LinkID [] = $lwID ;
2008-12-13 18:04:52 +00:00
}
}
2015-04-09 20:41:44 -07:00
if ( LW_CACHE_ENABLE ) // Write to file for next time
{
2008-12-13 18:04:52 +00:00
$temp = '' ;
foreach ( array ( 'word_list' , 'link_list' , 'tip_list' , 'ext_list' , 'LinkID' ) as $var )
{
$temp .= '$this->' . $var . '=' . var_export ( $this -> $var , TRUE ) . " ; \n " ;
}
2015-04-09 20:41:44 -07:00
e107 :: getCache () -> set_sys ( LW_CACHE_TAG , $temp );
2008-12-13 18:04:52 +00:00
}
}
}
2015-04-09 20:41:44 -07:00
2019-04-25 15:52:05 -07:00
2008-02-01 18:09:53 +00:00
}
2008-12-07 21:55:02 +00:00
function to_html ( $text , $area = 'olddefault' )
2008-02-01 18:09:53 +00:00
{
2019-04-25 15:52:05 -07:00
2013-04-15 19:46:35 -07:00
if ( is_string ( $this -> area_opts ))
{
$this -> area_opts = e107 :: unserialize ( $this -> area_opts );
2019-01-18 14:07:59 -08:00
}
if ( $this -> area_opts === null )
{
$this -> area_opts = array ();
}
2019-04-25 13:29:00 -07:00
if ( ! $this -> lw_enabled || empty ( $this -> area_opts ) || ! array_key_exists ( $area , $this -> area_opts ) || ! $this -> area_opts [ $area ])
{
2019-10-26 18:42:25 +02:00
// e107::getDebug()->log("Link words skipped on ".substr($text, 0, 50));
2019-04-25 13:29:00 -07:00
return $text ; // No linkwords in disabled areas
}
2011-05-04 09:19:50 +00:00
2019-10-26 18:42:25 +02:00
// Split up by HTML tags and process the odd bits here
2008-12-07 21:55:02 +00:00
$ptext = " " ;
$lflag = FALSE ;
2008-02-01 18:09:53 +00:00
2008-12-07 21:55:02 +00:00
// Shouldn't need utf-8 on next line - just looking for HTML tags
$content = preg_split ( '#(<.*?>)#mis' , $text , - 1 , PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
2019-04-25 15:52:05 -07:00
2008-12-07 21:55:02 +00:00
foreach ( $content as $cont )
{
if ( $cont [ 0 ] == " < " )
{ // Its some HTML
$ptext .= $cont ;
if ( substr ( $cont , 0 , 2 ) == " <a " ) $lflag = TRUE ;
if ( substr ( $cont , 0 , 3 ) == " </a " ) $lflag = FALSE ;
}
2015-04-09 20:41:44 -07:00
else // Its the text in between
{
if ( $lflag ) // Its probably within a link - leave unchanged
{
2008-12-07 21:55:02 +00:00
$ptext .= $cont ;
}
else
{
if ( trim ( $cont ))
2019-10-26 18:42:25 +02:00
{
// Some non-white space - worth word matching
2008-12-07 21:55:02 +00:00
$ptext .= $this -> linksproc ( $cont , 0 , count ( $this -> word_list ));
2019-10-26 18:42:25 +02:00
// echo "Check linkwords: ".count($this->word_list).'<br />';
2008-12-07 21:55:02 +00:00
}
else
{
$ptext .= $cont ;
}
}
2008-02-01 18:09:53 +00:00
}
}
2015-04-09 20:41:44 -07:00
// print_a($this->wordCount);
2008-12-07 21:55:02 +00:00
return $ptext ;
2008-02-01 18:09:53 +00:00
}
2010-01-16 20:49:55 +00:00
2015-04-09 20:41:44 -07:00
/**
* This function is called recursively - it splits the text up into blocks - some containing a particular linkword
* @ param $text
* @ param $first
* @ param $limit
* @ return string
*/
2008-02-01 18:09:53 +00:00
function linksproc ( $text , $first , $limit )
2015-04-09 20:41:44 -07:00
{
2010-01-16 20:49:55 +00:00
$tp = e107 :: getParser ();
$doSamePage = ! e107 :: getPref ( 'lw_notsamepage' );
2008-12-07 21:55:02 +00:00
2020-01-18 13:16:46 +01:00
for (; $first < $limit ; $first ++ )
2016-05-12 14:57:03 -07:00
{
2020-01-18 13:16:46 +01:00
if ( empty ( $this -> word_list [ $first ])) continue ;
if ( strpos ( $tp -> ustrtolower ( $text ), $this -> word_list [ $first ]) !== false ) break ;
}
2016-05-12 14:57:03 -07:00
if ( $first == $limit )
{
return $text ; // Return if no linkword found
}
2008-12-07 21:55:02 +00:00
// There's at least one occurrence of the linkword in the text
// Prepare all info once only
// If supporting Ajax, use the following:
// <a href='link url' rel='external linkwordId::122' class='linkword-ajax'>
// linkwordId::122 is a unique ID
2015-04-09 20:41:44 -07:00
2008-12-07 21:55:02 +00:00
$ret = '' ;
$linkwd = '' ;
$linkrel = array ();
2019-10-26 18:42:25 +02:00
// $linkwd = "href='#' "; // Not relevant for Prototype, but needed with 'pure' JS to make tooltip stuff work - doesn't find link elements without href
2008-12-07 21:55:02 +00:00
$lwClass = array ();
$lw = $this -> word_list [ $first ]; // This is the word we're matching - in lower case in our 'master' list
$tooltip = '' ;
2015-04-09 20:41:44 -07:00
2008-12-07 21:55:02 +00:00
if ( $this -> tip_list [ $first ])
{ // Got tooltip
if ( $this -> lwAjaxEnabled )
{
$linkrel [] = 'linkwordID::' . $this -> LinkID [ $first ];
2015-04-09 20:41:44 -07:00
$lwClass [] = 'lw-ajax ' . $this -> customClass ;
2008-12-07 21:55:02 +00:00
}
else
{
2019-04-25 15:52:05 -07:00
$tooltip = " title= \" { $this -> tip_list [ $first ] } \" " ;
2015-04-09 20:41:44 -07:00
$lwClass [] = 'lw-tip ' . $this -> customClass ;
2008-12-07 21:55:02 +00:00
}
2008-02-01 18:09:53 +00:00
}
2016-05-12 14:57:03 -07:00
2015-04-09 20:41:44 -07:00
if ( $this -> link_list [ $first ]) // Got link
{
2010-01-16 20:49:55 +00:00
$newLink = $tp -> replaceConstants ( $this -> link_list [ $first ], 'full' );
if ( $doSamePage || ( $newLink != e_SELF . '?' . e_QUERY ))
{
2019-04-25 15:52:05 -07:00
$linkwd = " href= \" " . $newLink . " \" " ;
2010-01-16 20:49:55 +00:00
if ( $this -> ext_list [ $first ]) { $linkrel [] = 'external' ; } // Determine external links
2015-04-09 20:41:44 -07:00
$lwClass [] = 'lw-link ' . $this -> customClass ;
2010-01-16 20:49:55 +00:00
}
2008-02-01 18:09:53 +00:00
}
2016-05-12 14:57:03 -07:00
elseif ( ! empty ( $this -> word_class [ $first ]))
{
$lwClass [] = $this -> word_class [ $first ];
}
2016-05-12 16:07:59 -07:00
2020-08-11 08:30:00 -07:00
// if (!count($lwClass))
// {
2019-10-26 18:42:25 +02:00
// return $this->linksproc($sl,$first+1,$limit); // Nothing to do - move on to next word (shouldn't really get here)
2020-08-11 08:30:00 -07:00
// }
2019-10-26 18:42:25 +02:00
2008-12-07 21:55:02 +00:00
if ( count ( $linkrel ))
{
$linkwd .= " rel=' " . implode ( ' ' , $linkrel ) . " ' " ;
}
2015-04-05 12:29:53 -07:00
2008-12-07 21:55:02 +00:00
// This splits the text into blocks, some of which will precisely contain a linkword
2016-05-12 16:07:59 -07:00
$split_line = preg_split ( '#\b(' . $lw . ')(\s|\b)#i' . $this -> utfMode , $text , - 1 , PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE ); // *utf (selected)
2019-10-26 18:42:25 +02:00
// $class = "".implode(' ',$lwClass)."' ";
2016-05-12 14:57:03 -07:00
$class = implode ( ' ' , $lwClass );
2015-04-05 12:29:53 -07:00
2015-04-09 20:41:44 -07:00
$hash = md5 ( $lw );
2015-04-09 22:19:27 -07:00
if ( ! isset ( $this -> wordCount [ $hash ]))
{
$this -> wordCount [ $hash ] = 0 ;
}
2015-04-09 20:41:44 -07:00
2016-05-12 14:57:03 -07:00
foreach ( $split_line as $count => $sl )
2008-12-07 21:55:02 +00:00
{
2019-04-25 15:52:05 -07:00
if ( $tp -> ustrtolower ( $sl ) == $lw && $this -> wordCount [ $hash ] < ( int ) $this -> word_limit [ $first ]) // Do linkword replace // We know the linkword is already lower case // *utf
2015-04-09 20:41:44 -07:00
{
$this -> wordCount [ $hash ] ++ ;
2016-05-12 14:57:03 -07:00
$classCount = " lw- " . $this -> wordCount [ $hash ];
if ( empty ( $linkwd ))
{
2019-04-25 15:52:05 -07:00
$ret .= " <span class= \" " . $class . $classCount . " \" " . $tooltip . " > " . $sl . " </span> " ;
2016-05-12 14:57:03 -07:00
}
else
{
2019-04-25 15:52:05 -07:00
$ret .= " <a class= \" " . $class . $classCount . " \" " . $linkwd . $tooltip . " > " . $sl . " </a> " ;
2016-05-12 14:57:03 -07:00
}
2008-12-07 21:55:02 +00:00
}
2015-04-09 20:41:44 -07:00
elseif ( trim ( $sl )) // Something worthwhile left - look for more linkwords in it
{
2008-12-07 21:55:02 +00:00
$ret .= $this -> linksproc ( $sl , $first + 1 , $limit );
}
else
{
$ret .= $sl ; // Probably just some white space
}
}
return $ret ;
}
2008-02-01 18:09:53 +00:00
}