* keywords im content mit Links ersetzen
* Links mit Klasse "show-modal" bei Klick in einen JS-Modal laden, statt dem Link zu folgen git-svn-id: http://78.47.251.156/svn/dev/sterntours-3@3296 f459cee4-fb09-11de-96c3-f9c5f16c3c76
This commit is contained in:
parent
20beca7c4d
commit
c924b4af15
15 changed files with 333 additions and 75 deletions
202
trunk/src/AppBundle/Service/KeywordService.php
Normal file
202
trunk/src/AppBundle/Service/KeywordService.php
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Ulrich Hecht <ulrich.hecht@hecht-software.de>
|
||||
* @date 02/17/2017
|
||||
*/
|
||||
|
||||
namespace AppBundle\Service;
|
||||
|
||||
|
||||
use AppBundle\Entity\Keyword;
|
||||
use AppBundle\Entity\Page;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
||||
class KeywordService
|
||||
{
|
||||
protected static $DO_SKIP_KEYWORD_CHECK_BY_DOM_ELEMENT_NAME = ['h1' => true, 'h2' => true, 'h3' => true,
|
||||
'h4' => true, 'h5' => true, 'h6' => true, 'a' => true, 'audio' => true, 'video' => true, 'object' => true,
|
||||
'nav' => true, 'form' => true
|
||||
];
|
||||
|
||||
private $entityManager;
|
||||
private $dictByContext = null;
|
||||
private $globalDict = null;
|
||||
|
||||
/**
|
||||
* KeywordService constructor.
|
||||
*
|
||||
* @param EntityManager $entityManager
|
||||
*/
|
||||
public function __construct(EntityManager $entityManager)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Source: http://78.47.251.156/svn/stern-consulting/sunstarPlugin/branches/1.4/lib/sun.class.php
|
||||
*
|
||||
* @param $html
|
||||
* @param string $classes Space separated values for the "class"-attribute
|
||||
* @return string
|
||||
*/
|
||||
public function addKeywordLinksToHtml($html, $classes = '')
|
||||
{
|
||||
$dict = $this->getKeywordsToLinksDict($classes);
|
||||
$doc = new \DOMDocument('1.0', 'utf-8');
|
||||
$doc->loadHTML('<?xml encoding="utf-8" ?><html><body>'. $html .'</body></html>');
|
||||
$xp = new \DOMXPath($doc);
|
||||
$rootNodes = $xp->query('//body')->item(0)->childNodes;
|
||||
$this->addKeywordLinksToDomNodes($rootNodes, $dict, $doc);
|
||||
$ret = '';
|
||||
foreach($rootNodes as $node)
|
||||
{
|
||||
$ret .= $doc->saveHTML($node);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quelle: http://78.47.251.156/svn/stern-consulting/sunstarPlugin/branches/1.4/lib/sun.class.php
|
||||
*
|
||||
* @param \DOMNodeList|\DOMNode[] &$nodes
|
||||
* @param array &$dict
|
||||
* @param \DOMDocument &$doc
|
||||
*/
|
||||
private function addKeywordLinksToDomNodes(&$nodes, &$dict, &$doc)
|
||||
{
|
||||
// As $nodes is a direct reference to $parentNode->childNodes it will be changed when
|
||||
// replacing text-nodes due to adding keywords. Therefore we loop through this
|
||||
// auxilary array '$originalNodes' which simply contains all nodes to process.
|
||||
$originalNodes = [];
|
||||
foreach ($nodes as $node)
|
||||
{
|
||||
$originalNodes[] = $node;
|
||||
}
|
||||
|
||||
/** @var \DOMNode $node */
|
||||
foreach($originalNodes as $node)
|
||||
{
|
||||
if($node->nodeType == XML_TEXT_NODE)
|
||||
{
|
||||
$nodeValue = $node->nodeValue;
|
||||
$foundKeywords = false;
|
||||
foreach($dict as $keyword => $link)
|
||||
{
|
||||
$nodeValue = preg_replace('/(^|\W)'. preg_quote($keyword, '/') .'($|\W)/u',
|
||||
'$1'. $link .'$2', $nodeValue, 1, $count);
|
||||
if($count > 0)
|
||||
{
|
||||
$foundKeywords = true;
|
||||
unset($dict[$keyword]);
|
||||
}
|
||||
}
|
||||
if($foundKeywords)
|
||||
{
|
||||
$newNode = $doc->createDocumentFragment();
|
||||
$newNode->appendXML($nodeValue);
|
||||
$node->parentNode->replaceChild($newNode, $node);
|
||||
}
|
||||
}
|
||||
elseif($node->nodeType == XML_ELEMENT_NODE &&
|
||||
!isset(self::$DO_SKIP_KEYWORD_CHECK_BY_DOM_ELEMENT_NAME[strtolower($node->nodeName)]))
|
||||
{
|
||||
$classAttr = $node->attributes->getNamedItem("class");
|
||||
if (!(isset($classAttr) && $classAttr->nodeValue &&
|
||||
preg_match('/(^|\s)skip-keywords($|\s)/', $classAttr->nodeValue) == 1))
|
||||
{
|
||||
$this->addKeywordLinksToDomNodes($node->childNodes, $dict, $doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Source: http://78.47.251.156/svn/stern-consulting/sunstarPlugin/branches/1.4/lib/sun.class.php
|
||||
*
|
||||
* @param string $classes Space separated values for the "class"-attribute
|
||||
* @return array
|
||||
*/
|
||||
private function getKeywordsToLinksDict($classes = '', $context = null)
|
||||
{
|
||||
if ($context)
|
||||
{
|
||||
if (!isset($this->dictByContext[$context]))
|
||||
{
|
||||
$this->dictByContext[$context] = null;
|
||||
}
|
||||
$dict = &$this->dictByContext[$context];
|
||||
}
|
||||
else
|
||||
{
|
||||
$dict = &$this->globalDict;
|
||||
}
|
||||
|
||||
if($dict === null)
|
||||
{
|
||||
$dict = [];
|
||||
$keywords = $this->entityManager->getRepository('AppBundle:Keyword')->findAll();
|
||||
/** @var Keyword $keyword */
|
||||
foreach($keywords as $keyword)
|
||||
{
|
||||
if(isset($dict[$keyword->getValue()]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$dictEntry = $this->createKeywordDictEntry($keyword->getUrl(), $keyword->getValue(), $classes);
|
||||
if ($dictEntry !== null)
|
||||
{
|
||||
$dict[$keyword->getValue()] = $dictEntry;
|
||||
}
|
||||
}
|
||||
|
||||
$pages = $this->entityManager->createQueryBuilder()
|
||||
->from('AppBundle:Page', 'p')
|
||||
->select('p')
|
||||
->where('p.keyword IS NOT NULL')
|
||||
->getQuery()
|
||||
->execute()
|
||||
;
|
||||
/** @var Page $page */
|
||||
foreach($pages as $page)
|
||||
{
|
||||
if(isset($dict[$page->getKeyword()]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$dictEntry = $this->createKeywordDictEntry($page->getUrlPath(), $page->getKeyword(), $classes);
|
||||
if ($dictEntry !== null)
|
||||
{
|
||||
$dict[$page->getKeyword()] = $dictEntry;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $dict;
|
||||
}
|
||||
|
||||
private function createKeywordDictEntry($url, $keywordValue, $classes)
|
||||
{
|
||||
$port = parse_url($url, PHP_URL_PORT);
|
||||
if($url[0] == '/' || strtolower($_SERVER['HTTP_HOST']) ==
|
||||
strtolower(parse_url($url, PHP_URL_HOST) .($port ? ':'. $port : '')))
|
||||
{
|
||||
// Same host => check if same page
|
||||
$urlPath = parse_url($url, PHP_URL_PATH);
|
||||
if($_SERVER['REQUEST_URI'] == $urlPath ||
|
||||
($_SERVER['REQUEST_URI'] == '/' && $urlPath == ''))
|
||||
{
|
||||
// Yes => we don't want to link to the current URL
|
||||
return null;
|
||||
}
|
||||
// No => setup a JS popup layer
|
||||
$attr = '';
|
||||
$additional_classes = 'intern-link show-layer ';
|
||||
}
|
||||
else
|
||||
{
|
||||
$additional_classes = '';
|
||||
$attr = 'target="_blank"';
|
||||
}
|
||||
return '<a href="'. $url .'" '. $attr .' class="'. $additional_classes . $classes .'">'. $keywordValue .'</a>';
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue