1
0
mirror of https://github.com/e107inc/e107.git synced 2025-08-04 13:47:31 +02:00

Fixes #4700 - linkwords inconsistencies.

This commit is contained in:
Cameron
2022-03-12 11:50:27 -08:00
parent 4032c2954f
commit 748fd4b9b6
4 changed files with 97 additions and 52 deletions

View File

@@ -4191,7 +4191,7 @@ var_dump($select_options);*/
public function name2id($name) public function name2id($name)
{ {
$name = strtolower($name); $name = strtolower($name);
return rtrim(str_replace(array('[]', '[', ']', '_', '/', ' ','.', '(', ')', '::', ':', '?','='), array('-', '-', '', '-', '-', '-', '-','','','-','','-','-'), $name), '-'); return rtrim(str_replace(array('[]', '[', ']', '_', '/', ' ','.', '(', ')', '::', ':', '?','=',"'"), array('-', '-', '', '-', '-', '-', '-','','','-','','-','-',''), $name), '-');
} }
/** /**

View File

@@ -19,10 +19,7 @@ if (!getperms('P') || !e107::isInstalled('linkwords'))
} }
e107::lan('linkwords', true); e107::lan('linkwords', true);
if(!defined('LW_CACHE_TAG'))
{
define('LW_CACHE_TAG', 'nomd5_linkwords');
}
class linkwords_admin extends e_admin_dispatcher class linkwords_admin extends e_admin_dispatcher
{ {
@@ -93,11 +90,13 @@ class linkwords_ui extends e_admin_ui
'lw_notsamepage' => array('title' => LWLAN_64, 'type' => 'boolean', 'data' => 'string', 'help' => LAN_LW_HELP_03), 'lw_notsamepage' => array('title' => LWLAN_64, 'type' => 'boolean', 'data' => 'string', 'help' => LAN_LW_HELP_03),
'linkword_omit_pages' => array('title' => LWLAN_28, 'type' => 'textarea', 'data' => 'string', 'help' => LAN_LW_HELP_04), 'linkword_omit_pages' => array('title' => LWLAN_28, 'type' => 'textarea', 'data' => 'string', 'help' => LAN_LW_HELP_04),
'lw_custom_class' => array('title' => LWLAN_66, 'type' => 'text', 'writeParms' => array('placeholder' => LAN_OPTIONAL), 'data' => 'string', 'help' => LAN_LW_HELP_05), 'lw_custom_class' => array('title' => LWLAN_66, 'type' => 'text', 'writeParms' => array('placeholder' => LAN_OPTIONAL), 'data' => 'string', 'help' => LAN_LW_HELP_05),
); );
const LW_CACHE_TAG = 'linkwords';
public function init() public function init()
{ {
if($this->getAction() == 'list') if($this->getAction() == 'list')
{ {
$this->fields['linkword_word']['title'] = LWLAN_5; $this->fields['linkword_word']['title'] = LWLAN_5;
@@ -122,7 +121,7 @@ class linkwords_ui extends e_admin_ui
if(!empty($_POST['etrigger_save'])) if(!empty($_POST['etrigger_save']))
{ {
e107::getCache()->clear_sys(LW_CACHE_TAG); e107::getCache()->clear_sys(self::LW_CACHE_TAG);
} }
} }
@@ -144,7 +143,7 @@ class linkwords_ui extends e_admin_ui
public function afterCreate($new_data, $old_data, $id) public function afterCreate($new_data, $old_data, $id)
{ {
e107::getCache()->clear_sys(LW_CACHE_TAG); e107::getCache()->clear_sys(self::LW_CACHE_TAG);
// do something // do something
} }
@@ -163,7 +162,7 @@ class linkwords_ui extends e_admin_ui
public function afterUpdate($new_data, $old_data, $id) public function afterUpdate($new_data, $old_data, $id)
{ {
e107::getCache()->clear_sys(LW_CACHE_TAG); e107::getCache()->clear_sys(self::LW_CACHE_TAG);
// do something // do something
} }
@@ -175,7 +174,7 @@ class linkwords_ui extends e_admin_ui
public function afterDelete($deleted_data, $id, $deleted_check) public function afterDelete($deleted_data, $id, $deleted_check)
{ {
e107::getCache()->clear_sys(LW_CACHE_TAG); e107::getCache()->clear_sys(self::LW_CACHE_TAG);
} }

View File

@@ -12,16 +12,13 @@
if (!defined('e107_INIT')) { exit; } if (!defined('e107_INIT')) { exit; }
if(!defined('LW_CACHE_ENABLE'))
{
define('LW_CACHE_ENABLE', false);
}
class linkwords_parse class linkwords_parse
{ {
protected $lw_enabled = FALSE; // Default to disabled to start protected $lw_enabled = FALSE; // Default to disabled to start
protected $lwAjaxEnabled = FALSE; // Adds in Ajax-compatible links protected $lwAjaxEnabled = FALSE; // Adds in Ajax-compatible links
protected $utfMode = ''; // Flag to enable utf-8 on regex protected $utfMode = ''; // Flag to enable utf-8 on regex
protected $cache = true;
protected $word_list = array(); // List of link words/phrases protected $word_list = array(); // List of link words/phrases
private $link_list = array(); // Corresponding list of links to apply private $link_list = array(); // Corresponding list of links to apply
@@ -30,13 +27,15 @@ class linkwords_parse
private $rel_list = array(); private $rel_list = array();
private $LinkID = array(); // Unique ID for each linkword private $LinkID = array(); // Unique ID for each linkword
private $area_opts; // Process flags for the various contexts private $area_opts; // Process flags for the various contexts
private $block_list = array(); // Array of 'blocked' pages private $block_list; // Array of 'blocked' pages
protected $word_class = array(); protected $word_class = array();
protected $customClass = ''; protected $customClass = '';
protected $wordCount = array(); protected $wordCount = array();
protected $word_limit = array(); protected $word_limit = array();
const LW_CACHE_TAG = 'linkwords';
// protected $maxPerWord = 3; // protected $maxPerWord = 3;
public function enable() public function enable()
@@ -44,15 +43,21 @@ class linkwords_parse
$this->lw_enabled = true; $this->lw_enabled = true;
} }
public function cache($var)
{
$this->cache = (bool) $var;
}
public function setWordData($arr = array()) public function setWordData($arr = array())
{ {
foreach($arr as $val) foreach($arr as $val)
{ {
$this->word_list[] = $val['word']; $this->word_list[] = $val['word'];
$this->link_list[] = $val['link']; $this->link_list[] = varset($val['link']);
$this->ext_list[] = $val['ext']; $this->ext_list[] = varset($val['ext']);
$this->tip_list[] = $val['tip']; $this->tip_list[] = varset($val['tip']);
$this->word_limit[] = $val['limit']; $this->word_limit[] = varset($val['limit']);
$this->LinkID[] = varset($val['id']);
} }
} }
@@ -79,11 +84,16 @@ class linkwords_parse
// $this->maxPerWord = vartrue($pref['lw_max_per_word'], 25); // $this->maxPerWord = vartrue($pref['lw_max_per_word'], 25);
$this->customClass = vartrue($pref['lw_custom_class']); $this->customClass = vartrue($pref['lw_custom_class']);
$this->area_opts = (array) varset($pref['lw_context_visibility']); $this->area_opts = (array) varset($pref['lw_context_visibility']);
$this->utfMode = (strtolower(CHARSET) == 'utf-8') ? 'u' : ''; // Flag to enable utf-8 on regex //@TODO utfMode probably obsolete $this->utfMode = (strtolower(CHARSET) === 'utf-8') ? 'u' : '';
$this->lwAjaxEnabled = varset($pref['lw_ajax_enable'],0); $this->lwAjaxEnabled = varset($pref['lw_ajax_enable'],0);
$this->cache = (int) varset($pref['lw_cache'],false);
// See whether they should be active on this page - if not, no point doing anything! // See whether they should be active on this page - if not, no point doing anything!
if(e_ADMIN_AREA === true && empty($_POST['runLinkwordTest'])) { return; } if(e_ADMIN_AREA === true && empty($_POST['runLinkwordTest']))
{
$this->cache(false);
return;
}
// Now see if disabled on specific pages // Now see if disabled on specific pages
$check_url = e_SELF.(defined('e_QUERY') ? "?".e_QUERY : ''); $check_url = e_SELF.(defined('e_QUERY') ? "?".e_QUERY : '');
@@ -93,7 +103,7 @@ class linkwords_parse
{ {
if($p=trim($p)) if($p=trim($p))
{ {
if(substr($p, -1) == '!') if(substr($p, -1) === '!')
{ {
$p = substr($p, 0, -1); $p = substr($p, 0, -1);
if(substr($check_url, strlen($p)*-1) == $p) return; if(substr($check_url, strlen($p)*-1) == $p) return;
@@ -105,27 +115,27 @@ class linkwords_parse
} }
} }
// Will probably need linkwords on this page - so get the info
if(!defined('LW_CACHE_TAG'))
if($this->cache && ($temp = e107::getCache()->retrieve(self::LW_CACHE_TAG, false, true, true)))
{ {
define('LW_CACHE_TAG', 'nomd5_linkwords'); // Put it here to avoid conflict on admin pages if($data = e107::unserialize($temp))
{
foreach($data as $key=>$val)
{
$this->$key = $val;
} }
if(LW_CACHE_ENABLE && ($temp = e107::getCache()->retrieve_sys(LW_CACHE_TAG))) $this->lw_enabled = TRUE;
{
$ret = eval($temp);
if ($ret)
{
echo "Error reading linkwords cache: {$ret}<br />";
$temp = '';
} }
else else
{ {
$this->lw_enabled = TRUE; trigger_error("Error reading linkwords cache: ".self::LW_CACHE_TAG);
}
} }
if(!vartrue($temp)) // Either cache disabled, or no info in cache (or error reading/processing cache) }
if(empty($temp)) // Either cache disabled, or no info in cache (or error reading/processing cache)
{ {
$link_sql = e107::getDb('link_sql'); $link_sql = e107::getDb('link_sql');
@@ -137,6 +147,7 @@ class linkwords_parse
{ {
$lw = $tp->ustrtolower($row['linkword_word']); // It was trimmed when saved *utf $lw = $tp->ustrtolower($row['linkword_word']); // It was trimmed when saved *utf
$lw = str_replace('&#039;', "'", $lw); // Fix for apostrophies.
if($row['linkword_active'] == 2) if($row['linkword_active'] == 2)
{ {
@@ -163,21 +174,20 @@ class linkwords_parse
} }
} }
if(deftrue('LW_CACHE_ENABLE')) // Write to file for next time if($this->cache) // Write to file for next time
{ {
$temp = ''; $temp = [];
foreach (array('word_list', 'link_list', 'tip_list', 'ext_list', 'LinkID') as $var) foreach (array('word_list', 'word_class', 'word_limit', 'link_list', 'tip_list', 'ext_list', 'rel_list', 'LinkID') as $var)
{ {
$temp .= '$this->'.$var.'='.var_export($this->$var, TRUE).";\n"; $temp[$var] = $this->$var;
} }
e107::getCache()->set_sys(LW_CACHE_TAG,$temp); e107::getCache()->set(self::LW_CACHE_TAG, e107::serialize($temp, 'json'), true, true, true);
} }
} }
} }
} }
private function loadRow($lw, $row) private function loadRow($lw, $row)
@@ -216,7 +226,7 @@ class linkwords_parse
$this->area_opts = array(); $this->area_opts = array();
} }
if (!$this->lw_enabled || empty($this->area_opts) || !array_key_exists($area,$this->area_opts) || !$this->area_opts[$area]) if (!$this->lw_enabled || empty($this->area_opts) || !isset($this->area_opts[$area]))
{ {
// e107::getDebug()->log("Link words skipped on ".substr($text, 0, 50)); // e107::getDebug()->log("Link words skipped on ".substr($text, 0, 50));
return $text; // No linkwords in disabled areas return $text; // No linkwords in disabled areas
@@ -229,15 +239,29 @@ class linkwords_parse
// Shouldn't need utf-8 on next line - just looking for HTML tags // 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 ); $content = preg_split('#(<.*?>)#mis', $text, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
$range = range(1,5);
foreach($content as $cont) foreach($content as $cont)
{ {
if ($cont[0] === "<") // Its some HTML
if ($cont[0] == "<") {
{ // Its some HTML
$ptext .= $cont; $ptext .= $cont;
if (substr($cont,0,2) == "<a") $lflag = TRUE; if (strpos($cont, "<a") === 0) $lflag = true;
if (substr($cont,0,3) == "</a") $lflag = FALSE; if (strpos($cont, "</a") === 0) $lflag = false;
if($area === 'BODY' && !isset($this->area_opts['TITLE'])) // disable linking on header tag content unless enabled in prefs.
{
// loop thru <h1>, <h2> etc.
foreach($range as $c)
{
$hOpenTag = '<h'.$c;
$hCloseTag = '</h'.$c;
if (strpos($cont, $hOpenTag) === 0) $lflag = true;
if (strpos($cont, $hCloseTag) === 0) $lflag = false;
}
}
} }
else // Its the text in between else // Its the text in between
{ {
@@ -282,7 +306,7 @@ class linkwords_parse
for (; $first < $limit; $first ++) for (; $first < $limit; $first ++)
{ {
if (empty($this->word_list[$first])) continue; if (empty($this->word_list[$first])) continue;
if (strpos($tp->ustrtolower($text), $this->word_list[$first]) !== false) break; if (strpos($tp->ustrtolower($text), $tp->ustrtolower($this->word_list[$first])) !== false) break;
} }
if ($first == $limit) if ($first == $limit)
@@ -355,6 +379,7 @@ class linkwords_parse
// This splits the text into blocks, some of which will precisely contain a linkword // This splits the text into blocks, some of which will precisely contain a linkword
$split_line = preg_split('#\b('.$lw.')(\s|\b)#i'.$this->utfMode, $text, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE ); // *utf (selected) $split_line = preg_split('#\b('.$lw.')(\s|\b)#i'.$this->utfMode, $text, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE ); // *utf (selected)
// $class = "".implode(' ',$lwClass)."' "; // $class = "".implode(' ',$lwClass)."' ";
$class = implode(' ',$lwClass); $class = implode(' ',$lwClass);
$hash = md5($lw); $hash = md5($lw);
@@ -366,7 +391,7 @@ class linkwords_parse
foreach ($split_line as $count=>$sl) foreach ($split_line as $count=>$sl)
{ {
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 if ($this->wordCount[$hash] < (int) $this->word_limit[$first] && ($tp->ustrtolower($sl) === $tp->ustrtolower($lw))) // Do linkword replace // We know the linkword is already lower case // *utf
{ {
$this->wordCount[$hash]++; $this->wordCount[$hash]++;

View File

@@ -21,9 +21,10 @@
try try
{ {
$this->lw = $this->make('linkwords_parse'); $this->lw = $this->make('linkwords_parse');
} catch(Exception $e) }
catch(Exception $e)
{ {
$this->assertTrue(false, "Couldn't load e_tohtml_linkwords object"); $this->fail("Couldn't load e_tohtml_linkwords object");
} }
$words = array( $words = array(
@@ -31,11 +32,14 @@
1 => array('word'=> 'contact form', 'link'=>'/contact.php', 'ext'=>'', 'tip'=>'Click here', 'limit'=> '5'), 1 => array('word'=> 'contact form', 'link'=>'/contact.php', 'ext'=>'', 'tip'=>'Click here', 'limit'=> '5'),
2 => array('word'=> 'fill out this form', 'link'=>'', 'ext'=>'', 'tip'=>'My Tip', 'limit'=>'5'), 2 => array('word'=> 'fill out this form', 'link'=>'', 'ext'=>'', 'tip'=>'My Tip', 'limit'=>'5'),
3 => array('word'=> '', 'link'=>'', 'ext'=>'', 'tip'=>'', 'limit'=>'3'), 3 => array('word'=> '', 'link'=>'', 'ext'=>'', 'tip'=>'', 'limit'=>'3'),
4 => array('word'=> "John's place", 'link'=>'/my-link', 'ext'=>'', 'tip'=>'', 'limit'=>'3'), // test single quote as encoded in
5 => array('word'=> "link", 'link'=>'/page-link', 'ext'=>'', 'tip'=>'', 'limit'=>'3'), // test single quote as encoded in
6 => array('word'=> "body only", 'link'=>'/body-link', 'ext'=>'', 'tip'=>'', 'limit'=>'3'), // test single quote as encoded in
); );
$opts = array ('BODY' => '1', 'DESCRIPTION' => '1'); $opts = array ('BODY' => '1', 'DESCRIPTION' => '1');
$this->lw->cache(false);
$this->lw->enable(); $this->lw->enable();
$this->lw->setWordData($words); $this->lw->setWordData($words);
$this->lw->setAreaOpts($opts); $this->lw->setAreaOpts($opts);
@@ -61,6 +65,23 @@
'expected' => '<p>To know more <span class="lw-tip lw-1" title="My Tip" >fill out this form</span> right away.</p>', 'expected' => '<p>To know more <span class="lw-tip lw-1" title="My Tip" >fill out this form</span> right away.</p>',
), ),
3 => array(
'text' => "<p>Visit John's place.</p>",
'expected' => "<p>Visit <a class=\"lw-link lw-1\" href=\"/my-link\" >John's place</a>.</p>",
),
// avoid placing links within existing links.
4 => array(
'text' => "<a href=''>link</a>link",
'expected' => "<a href=''>link</a><a class=\"lw-link lw-1\" href=\"/page-link\" >link</a>",
),
// Titles should be ignored within a body context.
5 => array(
'text' => "<h3>Body only title</h3><p>body only text</p>",
'expected' => "<h3>Body only title</h3><p><a class=\"lw-link lw-1\" href=\"/body-link\" >body only</a> text</p>",
),
); );
foreach($tests as $val) foreach($tests as $val)