TermCount::storeDocumentTermCount()   A
last analyzed

Complexity

Conditions 5
Paths 8

Size

Total Lines 25
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 18
nc 8
nop 2
dl 0
loc 25
rs 9.3554
c 0
b 0
f 0
1
<?php
2
/**
3
 * User: jensk
4
 * Date: 1-3-2017
5
 * Time: 10:22
6
 */
7
8
namespace CloudControl\Cms\search\indexer;
9
10
11
use CloudControl\Cms\search\DocumentTokenizer;
12
use CloudControl\Cms\search\Indexer;
13
use CloudControl\Cms\storage\Storage;
14
15
class TermCount
16
{
17
    /**
18
     * @var \PDO
19
     */
20
    protected $dbHandle;
21
    protected $documents;
22
    protected $filters;
23
    protected $storage;
24
25
    /**
26
     * TermCount constructor.
27
     *
28
     * @param \PDO $dbHandle
29
     * @param array $documents
30
     * @param array $filters
31
     * @param Storage $jsonStorage
32
     */
33
    public function __construct($dbHandle, $documents, $filters, $jsonStorage)
34
    {
35
        $this->dbHandle = $dbHandle;
36
        $this->documents = $documents;
37
        $this->filters = $filters;
38
        $this->storage = $jsonStorage;
39
    }
40
41
    public function execute()
42
    {
43
        $this->iterateDocumentsAndCreateTermCount($this->documents);
44
    }
45
46
    protected function applyFilters($tokens)
47
    {
48
        foreach ($this->filters as $filterName) {
49
            $filterClassName = '\CloudControl\Cms\search\filters\\' . $filterName;
50
            $filter = new $filterClassName($tokens);
51
            $tokens = $filter->getFilterResults();
52
        }
53
        return $tokens;
54
    }
55
56
    protected function storeDocumentTermCount($document, $documentTermCount)
57
    {
58
        $db = $this->dbHandle;
59
        $sqlStart = '
60
			INSERT INTO `term_count` (`documentPath`, `term`, `count`, `field`)
61
				 VALUES ';
62
        $sql = $sqlStart;
63
        $values = array();
64
        $quotedDocumentPath = $db->quote($document->path);
65
        $i = 0;
66
        foreach ($documentTermCount as $field => $countArray) {
67
            $quotedField = $db->quote($field);
68
            foreach ($countArray as $term => $count) {
69
                $values[] = $quotedDocumentPath . ', ' . $db->quote($term) . ', ' . $db->quote($count) . ', ' . $quotedField;
70
                $i += 1;
71
                if ($i >= Indexer::SQLITE_MAX_COMPOUND_SELECT) {
72
                    $this->executeStoreDocumentTermCount($values, $sql, $db);
73
                    $values = array();
74
                    $sql = $sqlStart;
75
                    $i = 0;
76
                }
77
            }
78
        }
79
        if (count($values) != 0) {
80
            $this->executeStoreDocumentTermCount($values, $sql, $db);
81
        }
82
    }
83
84
    /**
85
     * @param $values
86
     * @param $sql
87
     * @param $db
88
     *
89
     * @throws \Exception
90
     */
91
    protected function executeStoreDocumentTermCount($values, $sql, $db)
92
    {
93
        $sql .= '(' . implode('),' . PHP_EOL . '(', $values) . ');';
94
        $stmt = $db->prepare($sql);
95
        if ($stmt === false || !$stmt->execute()) {
96
            $errorInfo = $db->errorInfo();
97
            $errorMsg = $errorInfo[2];
98
            throw new \Exception('SQLite Exception: ' . $errorMsg . ' in SQL: <br /><pre>' . $sql . '</pre>');
99
        }
100
    }
101
102
    /**
103
     * @param $document
104
     */
105
    private function createTermCountForDocument($document)
106
    {
107
        $tokenizer = new DocumentTokenizer($document, $this->storage);
108
        $tokens = $tokenizer->getTokens();
109
        $documentTermCount = $this->applyFilters($tokens);
110
        $this->storeDocumentTermCount($document, $documentTermCount);
111
    }
112
113
    /**
114
     * @param $documents
115
     */
116
    private function iterateDocumentsAndCreateTermCount($documents)
117
    {
118
        foreach ($documents as $document) {
119
            if ($document->type === 'folder') {
120
                $this->iterateDocumentsAndCreateTermCount($document->content);
121
            } else {
122
                $this->createTermCountForDocument($document);
123
            }
124
        }
125
    }
126
}