HomepagePresenter.php 11.5 KB
Newer Older
Martin Gregor's avatar
Martin Gregor committed
1
2
<?php

3
4
5
use NlpTools\Stemmers\PorterStemmer;
//use Curl;

Martin Gregor's avatar
Martin Gregor committed
6
7
8
9
10
/**
 * Homepage presenter.
 */
class HomepagePresenter extends BasePresenter
{
11
    protected $sentence_id  = null;
12
13
    private $limit          = 10;
    private $exchange_count = 2;
14
15
    private $sentences      = [];
    private $words          = [];
16
    private $words_lema     = [];
17
    private $en_words       = [];
18
19
20

    public function renderDefault()
    {
21
        if (!isset($_POST['sentence_id']))
22
23
24
25
        {
            $count                  = $this->db->table('sentences')->count("*");
            $this->sentence_id      = (time() % $count) + 1;
            $current_sentence_id    = $this->sentence_id;
26

27
            $sentenceIdSession = $this->getSession('sentenceIdSession');
28

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
            // inicializacia session
            if (!is_array($sentenceIdSession->ids) || count($sentenceIdSession->ids) == $count)
            {
                $sentenceIdSession->ids = [];
            }

            // vyhladanie nezobrazenej vety
            while (in_array($current_sentence_id,$sentenceIdSession->ids))
            {
                $current_sentence_id = mt_rand(1, $count);
            }

            // ulozenie id vybranej vety a ziskanie vety z db
            $sentenceIdSession->ids[]   = $current_sentence_id;
//        else
//        {
//            $current_sentence_id = $this->sentence_id = $_POST['sentence_id'];
//        }
            $sentence                   = $this->db->table('sentences')->get($current_sentence_id);

            // rozdelenie vety na slova a inicializacia pola duplicit
            $this->words      = explode(' ', $sentence->sentence);

            // lematizacia skolskou sluzbou
53
            $this->lematize($sentence->sentence);
54
55

            // preklad kazdeho slova z vety
56
            foreach ($this->words_lema as $word)
57
58
59
60
61
62
63
            {
                $this->en_words[]     = $this->translate($word);
            }

            $this->genTranslations();

            $this->template->sentence   = $sentence->sentence;
64
        }
65
66
    }

67

68
69
70
71
    protected function createComponentTranslationForm()
    {
        $form = new Nette\Application\UI\Form();
        foreach ($this->sentences as $id => $sentence)
72
        {
Martin Gregor's avatar
Martin Gregor committed
73
74
            $label = \Nette\Utils\Html::el()->setHtml($sentence[0]);
            $form->addRadioList('sentence'.$id,$label,['correct' => 'Správne','incorrect' => 'Nesprávne']);
75
76
77
78
79
            foreach ($sentence[1] as $position => $word)
            {
                $form->addText($id.'word'.$position,'Preklad '.$word,40,100);
            }
            $form->addText('note'.$id,'Poznámka',60,500);
80
81
        }

82
83
84
85
86
        $form->addHidden('sentence_id',$this->sentence_id);
        $form->addSubmit('send','Ďalej');
        $form->onSuccess[] = $this->translationFormSucceeded;
        return $form;
    }
87

88
89
90
91
    public function translationFormSucceeded(Nette\Application\UI\Form $form)
    {
        $values = $_POST;//$form->getValues(TRUE);
        $sentences = [];
92

93
94
        foreach ($values as $id => $value)
        {
Martin Gregor's avatar
Martin Gregor committed
95
            if (strstr($id,'sentence') && $id != 'sentence_id')
96
97
98
99
100
            {
                $s_id                       = intval(str_replace('sentence','',$id));
                $sentences[$s_id]['type']   = $value;
                if ($value)
                    $this->correctTranslation($s_id,$value);
101

102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
                if ($_POST['note'.$s_id])
                    $sentences[$s_id]['note'] = $_POST['note'.$s_id];
            }
            else if (strstr($id,'word'))
            {
                $tmp = explode('word',$id);
                if ($value)
                    $sentences[intval($tmp[0])]['words'][$tmp[1]] = $value;
            }
        }

        foreach ($sentences as $id => $values)
        {
            if ($values['type'] == 'incorrect' && (isset($values['words']) || isset($values['note'])))
            {
                $tmp = $this->db->table('translations')->get($id);
                $tmp = explode(' ',$tmp->translation);
                foreach ($values['words'] as $position => $word)
                {
                    $tmp[$position] = $word;
                }
                $correction = implode(' ',$tmp);
                $this->storeCorrection($id,$correction,$values['words'],$values['note']);
            }
        }
Martin Gregor's avatar
Martin Gregor committed
127
        $this->redirect('default');
128
129
130
131
132
133
    }

    private function correctTranslation($id, $value)
    {
        if ($value == 'correct')
        {
Martin Gregor's avatar
Martin Gregor committed
134
135
            $correct_count = $this->db->table('translations')->where(['id' => $id])->select('correct_count')->fetch()->correct_count;
            $this->db->table('translations')->where(['id' => $id])->update(['correct_count' => $correct_count + 1]);
136
137
138
        }
        else
        {
Martin Gregor's avatar
Martin Gregor committed
139
140
            $incorrect_count = $this->db->table('translations')->where(['id' => $id])->select('incorrect_count')->fetch()->incorrect_count;
            $this->db->table('translations')->where(['id' => $id])->update(['incorrect_count' => $incorrect_count + 1]);
141
142
143
144
145
146
147
        }
    }

    private function storeCorrection($trans_id,$correction,$words,$comment)
    {
        $correction_id = $this->db->table('corrections')->select('id')->where(['translation_id' => $trans_id,'correction' => $correction])->fetch();
        if ($correction_id)
148
        {
Martin Gregor's avatar
Martin Gregor committed
149
150
151
            $correction_id = $correction_id->id;
            $use_count = $this->db->table('corrections')->select('use_count')->where(["id" => $correction_id])->fetch()->use_count;
            $this->table('corrections')->where(['id' => $correction_id])->update(['use_count' => $use_count + 1,'updated_at' => date('Y-m-d H:i:s',time())]);
152
        }
153
154
155
156
157
        else
        {
            $this->db->table('corrections')->insert(['use_count' => 1, 'translation_id' => $trans_id,
            'correction' => $correction,'correction_count' => count($words)]);
            $correction_id = $this->db->lastInsertId();
158

159
160
161
162
163
164
165
166
            foreach ($words as $position => $word)
            {
                $word_en_id = $this->db->table('word_en')->select('id')->where(['word_en' => $word])->fetch();
                if (!$word_en_id)
                {
                    $this->db->table('word_en')->insert(['word_en' => $word]);
                    $word_en_id = $this->db->lastInsertId();
                }
Martin Gregor's avatar
Martin Gregor committed
167
168
169
170
                else
                {
                    $word_en_id = $word_en_id->word_en_id;
                }
171
172
                $word_sk_id = $this->db->table('word_translation')->select('word_sk_id')
                    ->where(['translation_id' => $trans_id,'word_position' => $position])->fetch();
Martin Gregor's avatar
Martin Gregor committed
173
174
                if ($word_sk_id->word_sk_id)
                    $this->db->table('word_correction')->insert(['correction_id' => $correction_id,'word_sk_id' => $word_sk_id->word_sk_id, 'word_en_id' => $word_en_id]);
175
176
            }
        }
177

178
179
180
181
        if ($comment)
        {
            $this->db->table('comments')->insert(['correction_id' => $correction_id,'comment' => $comment]);
        }
182
    }
Martin Gregor's avatar
Martin Gregor committed
183

184
185
186
187
188
189
190
191
192
193
    private function translate($word)
    {
        $word_en = $this->db->query('SELECT dict_en.word as word, dict_en.rank3 as rank, dict_sk_en.type as type'.
        ' FROM dict_sk_en LEFT JOIN dict_sk ON dict_sk_en.sk_id = dict_sk.id JOIN dict_en ON dict_en.id = dict_sk_en.en_id'.
        ' WHERE dict_sk.word = ? ORDER BY original_pos',$word)->fetch();
        if ($word_en)
            return $word_en;
        else
            return null;
    }
194
195
196
197
198
199
200
201
202
203

    private function generateTransRekurzive($words,$position,$level,$s_words = [])
    {
        if ($position == count($words))
            return;

        $this->generateTransRekurzive($words,$position + 1,$level,$s_words);

        if ($this->en_words[$position] != null)
        {
Martin Gregor's avatar
Martin Gregor committed
204
205
            $words[$position] = '<span class="translation"><span class="en-word">'.$this->en_words[$position]->word
                .'</span><span class="sk-word" style="display: none;">'.$this->words[$position].'</span></span>';
206
207
208
            $sentence = implode(' ',$words);
            if (!isset($this->sentences[$sentence]))
            {
Martin Gregor's avatar
Martin Gregor committed
209
                $s_words[$position] = $this->en_words[$position]->word;
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
                $this->sentences[$sentence] = $s_words;
            }
        }
        if ($level < $this->exchange_count)
        {
            $this->generateTransRekurzive($words, $position + 1,$level + 1,$s_words);
        }
    }

    private function genTranslations()
    {
        $sentences = [];
        $this->generateTransRekurzive($this->words,0,1);

        if (count($this->sentences) >= $this->limit)
        {
              $sentences = array_rand($this->sentences, $this->limit);
        }

        $this->storeTranslation($sentences);
    }

    private function storeTranslation($sentences)
    {
234
        $tmp_sentences = [];
235
236
        foreach ($sentences as $sentence)
        {
Martin Gregor's avatar
Martin Gregor committed
237
            $translation_id = $this->db->table('translations')->where(['sentence_id' => $this->sentence_id,'translation' => $sentence])->select('id')->fetch();
238
239
240

            if ($translation_id)
            {
Martin Gregor's avatar
Martin Gregor committed
241
242
243
                $translation_id = $translation_id->id;
                $view_count = $this->db->table('translations')->select('view_count')->where(['id' => $translation_id])->fetch()->view_count;
                $this->db->table('translations')->where(['id' => $translation_id])->update(['view_count' => $view_count + 1,'updated_at' => date('Y-m-d H:i:s',time())]);
Martin Gregor's avatar
Martin Gregor committed
244
245

                $this->storeWords($this->sentences[$sentence],$translation_id);
246
247
248
            }
            else
            {
249
                $this->db->table('translations')->insert(['sentence_id' => $this->sentence_id,'translation' => $sentence, 'lemas' => implode(' ',$this->words_lema),
250
251
252
253
                                                          'correct_count' => 0, 'incorrect_count' => 0, 'view_count' => 1,
                                                          'translated_word_count' => count($this->sentences[$sentence])]);
                $translation_id = $this->db->lastInsertId();
                $this->storeWords($this->sentences[$sentence],$translation_id);
254
            }
255
256

            $tmp_sentences[$translation_id] = [$sentence,$this->sentences[$sentence]];
Martin Gregor's avatar
Martin Gregor committed
257
        }
258
        $this->sentences = $tmp_sentences;
Martin Gregor's avatar
Martin Gregor committed
259
260
261
262
263
264
265
    }

    private function storeWords($words, $translation_id)
    {
        foreach ($words as $position => $word)
        {
            $word_en_id = $this->db->table('word_en')->where(['word_en' => $word])->select('id')->fetch();
266
            $word_sk_id = $this->db->table('word_sk')->where(['word_sk' => $this->words[$position],'word_lema' => $this->words_lema[$position]])->select('id')->fetch();
Martin Gregor's avatar
Martin Gregor committed
267
268
269
            if (!$word_en_id)
                $word_en_id = $this->db->table('word_en')->insert(['word_en' => $word]);
            if (!$word_sk_id)
270
                $word_sk_id = $this->db->table('word_sk')->insert(['word_sk' => $this->words[$position], 'word_lema' => $this->words_lema[$position]]);
271

Martin Gregor's avatar
Martin Gregor committed
272
273
            $exists = $this->db->table('word_translation')->where(['word_en_id' => $word_en_id->id, 'word_sk_id' => $word_sk_id->id, 'translation_id' => $translation_id])->count('*');
            if (!$exists)
Martin Gregor's avatar
Martin Gregor committed
274
            {
Martin Gregor's avatar
Martin Gregor committed
275
                $this->db->table('word_translation')->insert(['word_en_id' => $word_en_id->id, 'word_sk_id' => $word_sk_id->id, 'translation_id' => $translation_id, 'word_position' => $position]);
Martin Gregor's avatar
Martin Gregor committed
276
            }
277
        }
Martin Gregor's avatar
Martin Gregor committed
278
279
280
281
282
283
284
285
286
    }

    private function lematize($sentence)
    {
        $curl = new Curl();

        $curl->headers = [
            'Content-Type' => 'text/plain'
        ];
287

Martin Gregor's avatar
Martin Gregor committed
288
        $result = $curl->post('http://text.fiit.stuba.sk:8080/lematizer/services/lemmatizer/lemmatize/fast',$sentence);
289

290
        $this->words_lema = explode(' ',$result->body);
291
    }
Martin Gregor's avatar
Martin Gregor committed
292
}