Skip to content

Commit

Permalink
Merge pull request #1 from luyadev/word-highlight
Browse files Browse the repository at this point in the history
transliterate
  • Loading branch information
nadar authored Mar 17, 2021
2 parents 7967443 + 6870a6a commit dfe04f0
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 18 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).

## 1.1.0 (17. March 2021)

+ [#1](https://github.com/luyadev/yii-helpers/pull/1) Highlight word function works with text transliteration.

## 1.0.0 (2. February 2021)

+ First stable release
65 changes: 48 additions & 17 deletions src/helpers/StringHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -295,38 +295,69 @@ public static function truncateMiddle($content, $word, $length, $affix = '..', $
/**
* Highlight a word within a content.
*
* Since version 1.0.14 an array of words to highlight is possible.
* Since version 1.0.14 its possible to provide an array with words to highlight
*
* > This function IS NOT case sensitive!
*
*
*
* ```php
* StringHelper::highlightWord('Hello John!', 'john');
* ```
*
* The above example would return `Hello <b>John</b>!`.
*
* @param string $content The content to find the word.
* @param string $word The word to find within the content.
* @param string $markup The markup used wrap the word to highlight.
*/
public static function highlightWord($content, $word, $markup = '<b>%s</b>')
{
$word = (array) $word;
$content = strip_tags($content);
$latest = null;
foreach ($word as $needle) {
preg_match_all("/".preg_quote($needle, '/')."+/i", $content, $matches);
if (is_array($matches[0]) && count($matches[0]) >= 1) {
foreach ($matches[0] as $match) {
// ensure if a word is found twice we don't replace again.
if ($latest === $match) {
continue;
}
$content = str_replace($match, sprintf($markup, $match), $content);
$latest = $match;
}
$transliterateContent = Inflector::transliterate($content);
$highlights = [];
foreach ((array) $word as $word) {
// search in content
preg_match_all("/".preg_quote($word, '/')."+/i", $content, $matches);
foreach ($matches[0] as $word) {
$highlights[] = $word;
// if the word is covered already, do not process further in foreach and break here
break;
}

// search in transliated content if not yet breaked from previous results
preg_match_all("/".preg_quote($word, '/')."+/i", $transliterateContent, $matches);
foreach ($matches[0] as $word) {
$highlights[] = self::sliceTransliteratedWord($word, $transliterateContent, $content);
}
}

foreach (array_unique($highlights) as $highlight) {
$content = str_replace($highlight, sprintf($markup, $highlight), $content);
}

return $content;
}

/**
* Search a word within a transliterated text and cut out the original word in the original text.
*
* For example when you search for the transliaterad word in text and want to return the original:
*
* ```php
* StringHelper::sliceTransliteratedWord('frederic', 'Hello frederic', 'Hello fréderic');
* ```
*
* The above example would return `fréderic`
*
* @param string $word
* @param string $transliteratedText
* @param string $originalText
* @return string
* @since 1.1.0
*/
public static function sliceTransliteratedWord($word, $transliteratedText, $originalText)
{
return mb_substr($originalText, mb_strpos($transliteratedText, $word), mb_strlen($word));
}

/**
* Multibyte-safe str_split funciton.
*
Expand Down
13 changes: 12 additions & 1 deletion tests/helpers/StringHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ public function testCut()
$this->assertSame('..oo ABC ba..', StringHelper::truncateMiddle('foo ABC bar', 'abc', 3));
$this->assertSame('foo abc..', StringHelper::truncateMiddle('foo abc bar', 'notfound', 4));
}

public function testHighlightWord()
{
$this->assertSame('foo <b>bar</b> foo', StringHelper::highlightWord('foo bar foo', 'bar'));
Expand All @@ -155,6 +154,18 @@ public function testHighlightWord()

$this->assertStringContainsString(' unsere <b>kompetent</b>en und <b>motiviert</b>en', StringHelper::highlightWord($str, ['Kompetent', 'Motiviert']));
$this->assertStringContainsString('vor <b>Ort</b> angebot', StringHelper::highlightWord($str, 'ort'));
$this->assertSame('test <b>référents</b>', StringHelper::highlightWord('test référents', 'referents'));
$this->assertSame('test <b>référents</b>', StringHelper::highlightWord('test référents', 'REFERENTS'));
$this->assertSame('test <b>référents</b>', StringHelper::highlightWord('test référents', 'référents'));
$this->assertSame('test <b>référents</b>', StringHelper::highlightWord('test référents', 'Référents'));
$this->assertSame('<b>foo</b> bar <b>foo</b> bar', StringHelper::highlightWord('foo bar foo bar', 'foo'));
$this->assertSame('<b>féé</b> bar <b>fee</b> bar', StringHelper::highlightWord('féé bar fee bar', 'fee'));
}

public function testTransliteratedWordSlice()
{
$this->assertSame('foo', StringHelper::sliceTransliteratedWord('foo', 'hello foo bar', 'hello foo bar'));
$this->assertSame('féé', StringHelper::sliceTransliteratedWord('fee', 'hello fee bar', 'hello féé bar'));
}

public function testCutAndHighlightWord()
Expand Down

0 comments on commit dfe04f0

Please sign in to comment.