commit 4b592357a1af4231c3f25697f451ee495d18f183
Author: Jan Šedivý <honza.seeda@gmail.com>
Date:   Fri Apr 26 22:04:55 2019 +0200

    Re #7328 Zobrazování okolních řádek ve výsledcích vyhledávání

diff --git a/app/FrontModule/component/Transliteration/TransliterationSearchResultList.latte b/app/FrontModule/component/Transliteration/TransliterationSearchResultList.latte
index 2d5f887..72ec9be 100644
--- a/app/FrontModule/component/Transliteration/TransliterationSearchResultList.latte
+++ b/app/FrontModule/component/Transliteration/TransliterationSearchResultList.latte
@@ -58,13 +58,29 @@
     {foreach $resultRows as $result}
         <hr>
 
-        <a href="{plink Transliteration:view $result->id}">
+        <a href="{plink Transliteration:view $result->id}" class="transliteration-link">
             {$result->book_abrev}, {$result->chapter}
         </a>
+        {ifset $result['adjacentLines']['linesBefore']}
+            {foreach $result['adjacentLines']['linesBefore'] as $lineBefore}
+                <div>
+                    <span>{$lineBefore->line_number}.</span>
+                    <span>{$lineBefore->transliteration}</span>
+                </div>
+            {/foreach}
+        {/ifset}
         <div>
             <span class="linefound">{$result->line_number}.</span>
             <span>{$result->transliteration|noescape}</span>
         </div>
+        {ifset $result['adjacentLines']['linesAfter']}
+            {foreach $result['adjacentLines']['linesAfter'] as $linesAfter}
+                <div>
+                    <span>{$linesAfter->line_number}.</span>
+                    <span>{$linesAfter->transliteration}</span>
+                </div>
+            {/foreach}
+        {/ifset}
 
     {/foreach}
 
diff --git a/app/FrontModule/component/Transliteration/TransliterationSearchResultList.php b/app/FrontModule/component/Transliteration/TransliterationSearchResultList.php
index 3f6c732..983e278 100644
--- a/app/FrontModule/component/Transliteration/TransliterationSearchResultList.php
+++ b/app/FrontModule/component/Transliteration/TransliterationSearchResultList.php
@@ -5,6 +5,8 @@ namespace App\FrontModule\Components;
 
 use App\Enum\EAdjacentLines;
 use App\Enum\EPageLimit;
+use App\Enum\ESearchFormOperators;
+use App\Model\Repository\LineRepository;
 use App\Model\Repository\TransliterationRepository;
 use App\Model\TransliterationSearchModel;
 use App\Utils\Form;
@@ -19,6 +21,9 @@ class TransliterationSearchResultList extends Control
     /** @var TransliterationRepository */
     private $transliterationRepository;
 
+    /** @var LineRepository */
+    private $lineRepository;
+
     /** @var Paginator */
     private $paginator;
 
@@ -31,20 +36,49 @@ class TransliterationSearchResultList extends Control
     private $resultRows;
     private $totalCount;
 
-    private $adjacentLines;
+    /**
+     * @persistent
+     */
+    public $adjacentLines;
+
+    /**
+     * @persistent
+     */
+    public $page;
+
+    /**
+     * @persistent
+     */
+    public $limit;
 
     /**
      * TransliterationSearchResultList constructor.
      * @param TransliterationSearchModel $transliterationSearchModel
      * @param TransliterationRepository $transliterationRepository
+     * @param LineRepository $lineRepository
      * @throws \Nette\Application\AbortException
      */
-    public function __construct(TransliterationSearchModel $transliterationSearchModel, TransliterationRepository $transliterationRepository)
+    public function __construct(
+        TransliterationSearchModel $transliterationSearchModel,
+        TransliterationRepository $transliterationRepository,
+        LineRepository $lineRepository
+    )
     {
         parent::__construct();
         $this->transliterationSearchModel = $transliterationSearchModel;
         $this->transliterationRepository = $transliterationRepository;
-        $this->paginator = new Paginator(1, 10);
+        $this->lineRepository = $lineRepository;
+
+        if(!$this->page)
+        {
+            $this->page = 1;
+        }
+
+        if(!$this->limit)
+        {
+            $this->limit = EPageLimit::$defaultLimit;
+        }
+        $this->paginator = new Paginator($this->page, $this->limit);
 
         $this->searchTerms = $this->transliterationSearchModel->getSearchTerms();
         $this->totalCount = $this->transliterationRepository->getTransliterationsFulltextSearchTotalCount($this->searchTerms);
@@ -67,7 +101,15 @@ class TransliterationSearchResultList extends Control
 
         $this->resultRows = $this->transliterationRepository->transliterationsFulltextSearch($this->searchTerms, $this->paginator->getOffset(), $this->paginator->getPageSize())->fetchAll();
         $this->paginator->setPageCount($this->totalCount);
+
         $this->highlight();
+        if(in_array($this->adjacentLines, EAdjacentLines::$lines) && $this->adjacentLines > 0)
+        {
+            foreach ($this->resultRows as &$row)
+            {
+                $row['adjacentLines'] = $this->lineRepository->getAdjacentLines($row['line_id'], $row['surface_id'], $this->adjacentLines);
+            }
+        }
 
         $this->template->resultRows = $this->resultRows;
         $this->template->paginator = $this->paginator;
@@ -78,37 +120,41 @@ class TransliterationSearchResultList extends Control
     {
         foreach ($this->resultRows as $resultRow)
         {
-            $resultRow->transliteration = str_replace("<", "&lt;", $resultRow->transliteration);
-            $resultRow->transliteration = str_replace(">", "&gt;", $resultRow->transliteration);
+            //nejprve escape html znaků, které chceme nechat zobrazovat,
+            //jelikož následně přidáváme html tagy pro vyznačení a výstup v latte nemůže být escapovaný
+            $resultRow->transliteration = htmlspecialchars($resultRow->transliteration);
 
             $resultRow->transliteration = preg_replace(
                 "/" . $this->transliterationRepository->prepareSearchRegExp($this->searchTerms['word1']) . "/",
                 "<span class='found'>$0</span>",
                 $resultRow->transliteration);
 
-            //TODO: dořešit označování slov, když se zadají slova co se překrývají tak se tagy mezi sebou ruší,
-            // viz např. vyhledávání slov 'šu' a 'as'
-
-//            if($this->searchTerms['word2_condition'] === ESearchFormOperators::AND || $this->searchTerms['word2_condition'] === ESearchFormOperators::OR )
-//            {
-//                $resultRow->transliteration = preg_replace(
-//                    "/" . $this->transliterationRepository->prepareSearchRegExp($this->searchTerms['word2']) . "/",
-//                    "<span class='found'>$0</span>",
-//                    $resultRow->transliteration);
-//            }
-//
-//            if($this->searchTerms['word3_condition'] === ESearchFormOperators::AND || $this->searchTerms['word3_condition'] === ESearchFormOperators::OR )
-//            {
-//                $resultRow->transliteration = preg_replace(
-//                    "/" . $this->transliterationRepository->prepareSearchRegExp($this->searchTerms['word3']) . "/",
-//                    "<span class='found'>$0</span>",
-//                    $resultRow->transliteration);
-//            }
+            /**
+             * TODO: dořešit označování slov, když se zadají slova co se překrývají tak se tagy mezi sebou ruší,
+             * viz např. vyhledávání slov 'šu' a 'as'
+             */
+            if($this->searchTerms['word2_condition'] === ESearchFormOperators::AND || $this->searchTerms['word2_condition'] === ESearchFormOperators::OR )
+            {
+                $resultRow->transliteration = preg_replace(
+                    "/" . $this->transliterationRepository->prepareSearchRegExp($this->searchTerms['word2']) . "/",
+                    "<span class='found'>$0</span>",
+                    $resultRow->transliteration);
+            }
+
+            if($this->searchTerms['word3_condition'] === ESearchFormOperators::AND || $this->searchTerms['word3_condition'] === ESearchFormOperators::OR )
+            {
+                $resultRow->transliteration = preg_replace(
+                    "/" . $this->transliterationRepository->prepareSearchRegExp($this->searchTerms['word3']) . "/",
+                    "<span class='found'>$0</span>",
+                    $resultRow->transliteration);
+            }
         }
     }
 
     public function handleChangePage($page, $limit)
     {
+        $this->page = $page;
+        $this->limit = $limit;
         $this->paginator = new Paginator($page, $limit);
         $this->redrawControl('resultList');
     }
@@ -149,6 +195,8 @@ class TransliterationSearchResultList extends Control
             if($lines !== null)
             {
                 $this->adjacentLines = $lines;
+                $this->paginator = new Paginator($this->page, $this->limit);
+
                 $this['searchSettingsForm']->setDefaults(array('lines' => $lines));
                 $this->redrawControl('resultList');
 
diff --git a/app/model/repository/LineRepository.php b/app/model/repository/LineRepository.php
index a9c1af6..5940e6a 100644
--- a/app/model/repository/LineRepository.php
+++ b/app/model/repository/LineRepository.php
@@ -39,4 +39,40 @@ class LineRepository extends Repository
             $transliterationId
         );
     }
+
+    /**
+     * Returns lines of a surface adjacent to passed line by id
+     * @param $lineId
+     * @param $surfaceId
+     * @param $numberOfLines number of adjacent lines
+     * @return array of arrays of lines before and lines after
+     */
+    public function getAdjacentLines($lineId, $surfaceId, $numberOfLines)
+    {
+        $adjacentLines['linesBefore'] = [];
+        $adjacentLines['linesAfter'] = [];
+        if($numberOfLines < 1)
+        {
+            return $adjacentLines;
+        }
+
+        $linesBefore = $this->getTable()
+            ->select('line_number, transliteration')
+            ->where('id_surface = ? AND id_line < ?', $surfaceId, $lineId)
+            ->limit($numberOfLines)
+            ->order('id_line DESC')
+            ->fetchAll();
+        $adjacentLines['linesBefore'] = array_reverse($linesBefore);
+
+        $linesAfter = $this->getTable()
+            ->select('line_number, transliteration')
+            ->where('id_surface = ? AND id_line > ?', $surfaceId, $lineId)
+            ->limit($numberOfLines)
+            ->order('id_line ASC')
+            ->fetchAll();
+        $adjacentLines['linesAfter'] = $linesAfter;
+
+        return $adjacentLines;
+    }
+
 }
\ No newline at end of file
diff --git a/app/model/repository/TransliterationRepository.php b/app/model/repository/TransliterationRepository.php
index 9d3e188..5190904 100644
--- a/app/model/repository/TransliterationRepository.php
+++ b/app/model/repository/TransliterationRepository.php
@@ -118,10 +118,12 @@ class TransliterationRepository extends Repository
         }
 
         $query = "SELECT 
-                    t.id_transliteration as id, 
+                    t.id_transliteration as id,
+                    s.id_surface as surface_id, 
                     b.book_abrev, 
                     t.chapter, 
                     l.transliteration, 
+                    l.id_line as line_id,
                     l.line_number 
                   FROM transliteration t
                   LEFT JOIN surface s ON s.id_transliteration = t.id_transliteration
diff --git a/www/css/front/style.css b/www/css/front/style.css
index 02ae8fd..ae0a470 100644
--- a/www/css/front/style.css
+++ b/www/css/front/style.css
@@ -66,12 +66,13 @@ body {
 }
 
 .linefound {
+    color: #003dc7;
     font-weight: 600;
 }
 
 .found {
     font-weight: 600;
-    color: #003366;
+    color: #003dc7;
 }
 
 .search-settings-select {
@@ -84,4 +85,21 @@ body {
 
 .results-found {
     margin-bottom: 0.2em;
+}
+
+.page-link {
+    color: #003dc7;
+}
+
+.page-item.active .page-link {
+    background-color: #003366;
+    border-color: #003366;
+}
+
+.transliteration-link {
+    font-weight: 400;
+}
+
+a {
+    color: #003dc7;
 }
\ No newline at end of file
