XarayaTranslationMemory  1.6
TranslationBackend.php
Go to the documentation of this file.
1 <?php
2 
3 /***************************************************************************
4  * Copyright (C) 2005-2020 by Ferenc Veres *
5  * lion@netngine.hu *
6  * *
7  * This program is free software; you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation; either version 3 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License *
18  * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19  ***************************************************************************/
20 include_once('config.inc.php');
21 include_once('lib/Common.php');
22 
23 $DB = NewADOConnection(GetConfigVar('db_software'));
24 $DB->Connect(GetConfigVar('db_host'), GetConfigVar('db_username') , GetConfigVar('db_password'), GetConfigVar('db_database'));
25 $DB->Execute("SET NAMES utf8");
26 CacheIndexes();
27 
28 define('LOCATE_CURR', 0);
29 define('LOCATE_NEXT', 1);
30 define('LOCATE_NEXTMISSING', 2);
31 define('LOCATE_PREV', 3);
32 define('LOCATE_PREVMISSING', 4);
33 
43 {
44  public $Event;
46  // CONTROLS
47 
48  public $txtFindText;
49  public $ddlSearchType;
50  public $ddlFindPercent;
51  public $ddlLocaleID;
52  public $xOldLocaleID;
53  public $xStringID;
54  public $xProjectID;
55  public $xActiveRootID;
56  public $xDelStringID;
57  public $txtEditString;
59  // OUTPUT
60 
61  public $Translations;
62  public $LocatedString;
65  public $ChildProjects;
66  public $CurrentStrings;
67  public $RootProjects;
69  // PRIVATE
70 
71  private $String;
80  function __construct()
81  {
82  // Get and use default locale
83  $localeName = GetConfigVar('default_locale');
84  $localeID = TranslationProject::$LocaleIDCache[$localeName];
85  if(empty($localeID))
86  {
87  throw new Exception("Invalid default locale in the configuration: $localeName");
88  }
89 
90  // Create a new translation string handler class
91  $this->String = new TranslationString();
92  $this->DB = GetDbConn();
93  $this->Tables = GetTables();
94 
95  $this->txtFindText = "";
96  $this->ddlSearchType = 0;
97  $this->ddlFindPercent = 60;
98  $this->ddlLocaleID = $localeID;
99  $this->xOldLocaleID = $localeID;
100  $this->xStringID = 0;
101  $this->xProjectID = 0;
102 
103  $this->RootProjects = TranslationProject::GetRoots($this->ddlLocaleID);
104  if(count($this->RootProjects) == 0)
105  {
106  throw new Exception("Cannot initialze backend for $this->ddlLocaleID locale. No roots.");
107  }
108 
109  $this->InitLanguage();
110  }
111 
116  public function InitLanguage()
117  {
118  // Find a legal root project
119  $proj = new TranslationProject();
120 
121  // Reset to first project's root if no root selected yet
122  if(!$this->xActiveRootID)
123  {
124  $this->xActiveRootID = array_keys($this->RootProjects)[0];
125  }
126 
127  // Reset system to select the root project
128  $this->xProjectID = $this->RootProjects[$this->xActiveRootID]->GetID();
129  $this->FindProjectPath();
130  }
131 
147  function FindStrings()
148  {
149  switch($this->ddlSearchType)
150  {
151 
152  case 1:
153  // Find in Original as part of the string
154  $this->Translations = $this->String->FindText($this->txtFindText, $this->ddlLocaleID, true);
155  break;
156 
157  case 2:
158  // Find in Translation as part of the string
159  $this->Translations = $this->String->FindText($this->txtFindText, $this->ddlLocaleID, false);
160  break;
161 
162  default:
163  // Similarity matching
164  $this->Translations = $this->String->FindSimilar($this->txtFindText, $this->ddlLocaleID, $this->ddlFindPercent);
165  break;
166  }
167  }
168 
181  function LocateString($locate = LOCATE_CURR)
182  {
183  // Load string details
184  switch($locate)
185  {
186  case LOCATE_CURR:
187  $this->LocatedString = new TranslationString($this->xStringID);
188  break;
189 
190  case LOCATE_NEXT:
191  case LOCATE_NEXTMISSING:
192  $this->LocateStringNext( ($locate == LOCATE_NEXTMISSING) );
193  break;
194  }
195  }
196 
201  private function LocateStringNext($missingOnly)
202  {
203  unset($this->LocatedString);
204 
205  // Skip string-in-project search if xStringID is empty:
206  // which means there were no strings in this project
207 
208  if($this->xStringID != 0)
209  {
210  // Take current string and an iterator for it's siblings
211  $currentString = new TranslationString($this->xStringID);
212  $stringIter = new StringIterator($currentString->GetProjectID());
213 
214  // FLAT SEARCH - STRINGS OF THE CURRENT PROJECT
215 
216  // Find current and then take next. If we are last, this will end with false.
217  $takeString = false;
218  foreach($stringIter as $str)
219  {
220  if($takeString)
221  {
222  $this->LocatedString = new TranslationString($str->GetStringID());
223 
224  // If we find Missing Strings, ignore non-empty results!
225  if($missingOnly && $this->LocatedString->GetTranslation() != "")
226  {
227  // Need to search a missing one, drop that result
228  unset($this->LocatedString);
229  }
230  else
231  {
232  // Found, break!
233  $this->xStringID = $str->GetStringID();
234  break;
235  }
236  }
237 
238  // If reached the current string, note to take the next one
239  if($str->GetStringID() == $currentString->GetStringID())
240  {
241  $takeString = true;
242  }
243  }
244  }
245 
246  // RECURSIVE SEARCH - UPWARDS AND DOWNWARDS
247 
248  // If this was a "last string" in the project, we will search across projects!
249  $currentProject = new TranslationProject($this->xProjectID);
250 
251  // Stop variable for reaching root
252  $rootHit = false;
253 
254  // Search next string across projects!
255  while(empty($this->LocatedString) && !$rootHit)
256  {
257  $takeProject = false;
258 
259  // Start an iterator on sibling and subprojects
260  $parentProjects = new RecursiveIteratorIterator(
261  new ProjectIterator($currentProject->GetParentID(), $this->ddlLocaleID, true),
262  RecursiveIteratorIterator::SELF_FIRST);
263 
264  // Loop on the projects and find the current one (which hit last string above!)
265  foreach($parentProjects as $proj)
266  {
267  // This happens after the "last-string-hit" project, take next project:
268  if($takeProject)
269  {
270  // Get strings of all next projects and see if there are any strings.
271  $stringIter = new StringIterator($proj->GetID());
272 
273  // There are strings, take the first and we are done! (in not missing ok)
274  if(!$missingOnly)
275  {
276  // Any strings? If yes, found, break!
277  if($stringIter->valid())
278  {
279  $this->xStringID = $stringIter->current()->GetStringID();
280  $this->LocatedString = new TranslationString($this->xStringID);
281  break;
282  }
283  }
284  else
285  {
286  $foundEmpty = false;
287  // Missing only, so loop on all strings
288  // If we find Missing Strings, ignore non-empty results!
289  foreach($stringIter as $str)
290  {
291  if($str->GetTranslation() == "")
292  {
293  $this->xStringID = $str->GetStringID();
294  $this->LocatedString = new TranslationString($this->xStringID);
295  $foundEmpty = true;
296  break;
297  }
298  }
299 
300  // If iterator not finished, we found the result
301  if($foundEmpty)
302  {
303  break;
304  }
305  }
306  }
307 
308  // Found the "last-string-hit" project?
309  if($proj->GetID() == $this->xProjectID)
310  {
311  $takeProject = true;
312  }
313  }
314 
315  // Stop working if taking parent would result in looping on root!
316  $rootHit = ($currentProject->GetParentID() == 0);
317 
318  // If not root and not found a string, recurse UPWARDS
319  if($currentProject->GetParentID() != 0 && empty($this->LocatedString))
320  {
321  $currentProject = new TranslationProject($currentProject->GetParentID());
322  }
323 
324  }
325  }
340  function FindProjectPath()
341  {
342  unset ($this->LocatedProjects);
343  unset ($this->SiblingProjects);
344  unset ($this->ChildProjects);
345 
346  $pid = $this->xProjectID;
347 
348  // Loop and collect projects until reaching the end
349  while($pid != 0)
350  {
351  $proj = new TranslationProject($pid);
352  $this->LocatedProjects[] = $proj;
353  $pid = $proj->GetParentID();
354  }
355 
356  // Make a new project Iterators with current parent to see if there are children
357  $this->ChildProjects = new ProjectIterator($this->xProjectID, $this->ddlLocaleID, true);
358  $this->SiblingProjects = new ProjectIterator($this->GetProject()->GetParentID(), $this->ddlLocaleID, true);
359  }
360 
369  function SaveString()
370  {
371  // Load our string from the DB, change it and save changes
372  $string = new TranslationString($this->xStringID);
373  $string->SetTranslation($this->txtEditString);
374  $string->Save();
375  }
376 
381  function DeleteString()
382  {
383  // Load our string
384  $string = new TranslationString($this->xDelStringID);
385  $string->DestroyData();
386  }
387 
394  function DeleteProject($projectID)
395  {
396  $project = new TranslationProject($projectID);
397  $parent = $project->GetParentID();
398  $project->DestroyData();
399  return $parent;
400  }
401 
407  {
408  $this->CurrentStrings = new StringIterator($this->xProjectID);
409  }
410 
415  function GetProject()
416  {
417  if(count($this->LocatedProjects) > 0)
418  {
419  return $this->LocatedProjects[0];
420  }
421  return null;
422  }
423 }
424 
425 ?>
CacheIndexes()
Definition: Common.php:94
& GetTables()
Definition: Common.php:71
const LOCATE_NEXT
& GetDbConn()
Definition: Common.php:61
const LOCATE_NEXTMISSING
const LOCATE_CURR
GetConfigVar($varName)
Definition: Common.php:84
LocateStringNext($missingOnly)
static GetRoots($localeID)
LocateString($locate=LOCATE_CURR)