Xataface Translation Memory Module 0.1
Translation Memory for Xataface Applications
/Applications/XAMPP/xamppfiles/htdocs/recipedb/modules/tm/lib/XFTranslationMemory.php
Go to the documentation of this file.
00001 <?php
00002 /*
00003  * Xataface Translation Memory Module
00004  * Copyright (C) 2011  Steve Hannah <steve@weblite.ca>
00005  * 
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Library General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2 of the License, or (at your option) any later version.
00010  * 
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Library General Public License for more details.
00015  * 
00016  * You should have received a copy of the GNU Library General Public
00017  * License along with this library; if not, write to the
00018  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
00019  * Boston, MA  02110-1301, USA.
00020  *
00021  */
00022 require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'TMTools.php');
00023 
00028 class XFTranslationMemory {
00029 
00030         const TRANSLATION_REJECTED=1;
00031         //const TRANSLATION_VOTE_DOWN=2;
00032         const TRANSLATION_SUBMITTED=3;
00033         //const TRANSLATION_VOTE_UP=4;
00034         const TRANSLATION_APPROVED=5;
00035 
00041         private $_rec;
00042         
00043 
00049         public function __construct(Dataface_Record $rec){
00050                 $this->_rec = $rec;
00051         }
00052         
00057         public function getRecord(){
00058                 return $this->_rec;
00059         }
00060         
00065         public function getSourceLanguage(){
00066                 return $this->_rec->val('source_language');
00067         }
00068         
00069         
00074         public function getDestinationLanguage(){
00075                 return $this->_rec->val('destination_language');
00076         }
00077 
00078         
00084         private static $defaultTranslationMemories = null;
00085         
00086         
00098         public static function getDefaultTranslationMemory($source, $dest, $secure=false){
00099                 $source = strtolower($source);
00100                 $dest = strtolower($dest);
00101                 if ( !isset(self::$defaultTranslationMemories) ){
00102                         self::$defaultTranslationMemories = array();
00103                 }
00104                 
00105                 if ( !isset(self::$defaultTranslationMemories[$source]) ){
00106                         self::$defaultTranslationMemories[$source] = array();
00107                 }
00108                 
00109                 if ( !isset(self::$defaultTranslationMemories[$source][$dest]) ){
00110                         $rec = df_get_record('xf_tm_records',
00111                                 array(
00112                                         'record_id'=>'=*',
00113                                         'source_language'=>'='.$source,
00114                                         'destination_language'=>'='.$dest
00115                                 )
00116                         );
00117                         
00118                         if ( $rec ){
00119                         
00120                                 self::$defaultTranslationMemories[$source][$dest] = self::loadTranslationMemoryById($rec->val('translation_memory_id'));
00121                                 
00122                         }
00123                 }
00124                 
00125                 if ( !isset(self::$defaultTranslationMemories[$source][$dest]) ){
00126                         $tm = self::createTranslationMemory('Default '.$source.'=>'.$dest, $source, $dest, $secure);
00127                         $tm->assignTo('*');
00128                         self::$defaultTranslationMemories[$source][$dest] = $tm;
00129                 }
00130                 return self::$defaultTranslationMemories[$source][$dest];
00131         }
00132         
00148         private static function createTranslationMemory($name, $source, $dest, $secure=false){
00149                 $source = strtolower($source); $dest = strtolower($dest);
00150                 if ( !preg_match('/^[a-z0-9]{2}$/', $source) ){
00151                         throw new Exception("Invalid source language code inserting a translation memory: $source");
00152                 }
00153                 if ( !preg_match('/^[a-z0-9]{2}$/', $dest) ){
00154                         throw new Exception("Invalid destination language code inserting a translation memory: $dest");
00155                 }
00156                 
00157                 $rec = new Dataface_Record('xf_tm_translation_memories',array());
00158                 $rec->setValues(array(
00159                         'translation_memory_name'=>$name,
00160                         'source_language'=>$source,
00161                         'destination_language'=>$dest
00162                 ));
00163                 $res = $rec->save($secure);
00164                 if ( PEAR::isError($res) ){
00165                         throw new Exception("Failed to create translation memory ".$res->getMessage(), $res->getCode());
00166                 }
00167                 
00168                 $tm = new XFTranslationMemory($rec);
00169                 
00170                 return $tm;     
00171         }
00172         
00173         
00174         
00184         public function assignTo($recid, $secure = false){
00185                 $rec = new Dataface_Record('xf_tm_records', array());
00186                 $rec->setValues(array(
00187                         'record_id'=>$recid,
00188                         'translation_memory_id'=>$this->_rec->val('translation_memory_id')
00189                 ));
00190                 $res = $rec->save($secure);
00191                 if ( PEAR::isError($res) ){
00192                         throw new Exception("Failed to assign the translation memory to the record with id ".$recid);
00193                         
00194                 }
00195                 
00196         }
00197 
00203         public static function loadTranslationMemoryById($id){
00204                 $tmrec  = df_get_record('xf_tm_translation_memories', array('translation_memory_id'=>'='.$id));
00205                 if ( !$tmrec ) return null;
00206                 return new XFTranslationMemory($tmrec);
00207         }
00208 
00209 
00218         public static function loadTranslationMemoryFor(Dataface_Record $record, $source, $dest){
00219                 $rec = df_get_record('xf_tm_records', 
00220                         array(
00221                                 'record_id'=>'='.$record->getId(),
00222                                 'source_language'=>'='.$source,
00223                                 'destination_language'=>'='.$dest
00224                         )
00225                 );
00226                 if ( !$rec ){
00227                         return self::getDefaultTranslationMemory($source, $dest);
00228                 }
00229                 
00230                 if ( !$rec->val('translation_memory_id') ){
00231                         return null;
00232                 }
00233                 
00234                 return self::loadTranslationMemoryById($rec->val('translation_memory_id'));
00235         }
00236         
00250         public function addTranslation($string, $translation, $username=null, $secure=false){
00251                 if ( !$username ) $username = Dataface_AuthenticationTool::getInstance()->getLoggedInUserName();
00252                 $strid = null;
00253                 if ( is_int($string) ){
00254                         $strid = $string;
00255                 }
00256                 
00257                 if ( !$strid ){
00258                         $strRec = self::findString($string, $this->getSourceLanguage());
00259                         if ( !$strRec ){
00260                                 $strRec = self::addString($string, $this->getSourceLanguage(), $secure);
00261                                 
00262                         }
00263                         if ( !$strRec ){
00264                                 throw new Exception("Failed to add string $string");
00265                         }
00266                         $strid = intval($strRec->val('string_id'));
00267                         
00268                 }
00269                 
00270                 
00271                 $trec = $this->findTranslation($strid, $translation);
00272                 if ( !$trec ){
00273                         
00274                         $normalized = TMTools::normalize($translation);
00275                         $hash = md5($normalized);
00276                         $trec = new Dataface_Record('xf_tm_translations', array());
00277                         $trec->setValues(array(
00278                                 'string_id'=>$strid,
00279                                 'translation_value'=>$translation,
00280                                 'normalized_translation_value'=> $normalized,
00281                                 'language'=> $this->getDestinationLanguage(),
00282                                 'translation_hash'=>$hash,
00283                                 'created_by' => $username
00284                         ));
00285                         $res = $trec->save($secure);
00286                         if ( PEAR::isError($res) ){
00287                                 throw new Exception('Failed to add translation "$translation": '.$res->getMessage(), $res->getCode());
00288                         }
00289                 }
00290                 
00291                 // Now add this translation to the translation memory
00292                 $res = mysql_query("insert ignore into xf_tm_translation_memory_translations 
00293                         (translation_memory_id,translation_id)
00294                         values
00295                         ('".addslashes($this->_rec->val('translation_memory_id'))."',
00296                          '".addslashes($trec->val('translation_id'))."'
00297                          )", df_db());
00298                 if ( !$res ) throw new Exception(mysql_error(df_db()));
00299                 
00300                 
00301                 return $trec;
00302                         
00303                 
00304                 
00305                 
00306         }
00307         
00315         public function containsTranslation($string, $translation){
00316                 $tr = $this->findTranslation($string, $translation);
00317                 if ( !$tr ) return false;
00318                 $tm = df_get_record('xf_tm_translation_memory_translations', 
00319                         array(
00320                                 'translation_memory_id'=>'='.$this->_rec->val('translation_memory_id'),
00321                                 'translation_id'=>'='.$tr->val('translation_id')
00322                         )
00323                 );
00324                 if ( !$tm ) return false;
00325                 else return true;
00326         }
00327         
00328         
00334         public static function findString($string, $language){
00335                 $normalized = TMTools::normalize($string);
00336                 $hash = md5($normalized);
00337                 $strRec = df_get_record('xf_tm_strings', 
00338                         array(
00339                                 'normalized_value'=>'='.$normalized, 
00340                                 'hash'=>'='.$hash,
00341                                 'language'=>'='.$language));
00342                 if ( !$strRec ) return null;
00343                 return $strRec;
00344         }
00345         
00346         
00355         public static function addString($string, $language, $secure=false){
00356                 
00357                 $str = self::findString($string, $language);
00358                 if ( !$str ){
00359                         $app = Dataface_Application::getInstance();
00360                         $strRec = new Dataface_Record('xf_tm_strings', array());
00361                         $normalized = TMTools::normalize($string);
00362                         $hash = md5($normalized);
00363                         $strRec->setValues(array(
00364                                 'language'=>$language,
00365                                 'string_value'=>$string,
00366                                 'normalized_value'=>$normalized,
00367                                 'hash'=> $hash
00368                         ));
00369                         $res = $strRec->save($secure);
00370                         if ( PEAR::isError($res) ){
00371                                 
00372                                 throw new Exception($res->getMessage());
00373                         }
00374                         return $strRec;
00375                                 
00376                 }
00377                 return $str;
00378         }
00379         
00380         
00389         public function findTranslation($string, $translation){
00390                 $strid = null;
00391                 if ( is_int($string) ) $strid = $string;
00392                 
00393                 if ( !$strid ){
00394                         
00395                         $strRec = self::findString($string, $this->getSourceLanguage());
00396                         if ( $strRec ){
00397                                 $strid = intval($strRec->val('string_id'));
00398                         }
00399                         
00400                 }
00401                 if ( !$strid ) return null;
00402                 
00403                 $normalizedTranslation = TMTools::normalize($translation);
00404                 $hashTranslation = md5($normalizedTranslation);
00405                 
00406                 $trRec = df_get_record('xf_tm_translations', 
00407                         array(
00408                                 'string_id'=>'='.$strid,
00409                                 'normalized_translation_value'=>'='.$normalizedTranslation,
00410                                 'translation_hash'=>'='.$hashTranslation,
00411                                 'language'=>'='.$this->getDestinationLanguage()
00412                                 
00413                         )
00414                 );
00415                 
00416                 if ( !$trRec ) return null;
00417                 
00418                 return $trRec;
00419                 
00420                 
00421         }
00422         
00435         public function scoreTranslation($string, $translation, $score, $username=null, $secure=false){
00436                 
00437                 if ( !$username ) $username = Dataface_AuthenticationTool::getInstance()->getLoggedInUserName();
00438                 $trec = $this->findTranslation($string, $translation);
00439                 
00440                 if ( !$trec ){
00441                         $trec = $this->addTranslation($string, $translation, $username, $secure);
00442                 }
00443                 
00444                 if ( !$trec ){
00445                         throw new Exception("Could not find matching translation and failed to add one.");
00446                 }
00447                 
00448                 $arec = new Dataface_Record('xf_tm_translations_score', array());
00449                 $arec->setValues(array(
00450                         'translation_id'=>$trec->val('translation_id'),
00451                         'translation_memory_id'=>$this->_rec->val('translation_memory_id'),
00452                         'username'=>$username,
00453                         'score'=>$score
00454                 ));
00455                 $res = $arec->save($secure);
00456                 if ( PEAR::isError($res) ){
00457                         throw new Exception("Failed to approve translation: ".$res->getMessage());
00458                         
00459                 }
00460                 return $arec;
00461                 
00462         }
00463         
00464         
00479         public function setTranslationStatus($string, $translation, $status, $username=null, $secure=false){
00480                 if ( !$username ) $username = Dataface_AuthenticationTool::getInstance()->getLoggedInUserName();
00481                 $trec = $this->findTranslation($string, $translation);
00482                 
00483                 if ( !$trec ){
00484                         $trec = $this->addTranslation($string, $translation, $username, $secure);
00485                 }
00486                 
00487                 if ( !$trec ){
00488                         throw new Exception("Could not find matching translation and failed to add one.");
00489                 }
00490                 
00491                 $arec = new Dataface_Record('xf_tm_translations_status', array());
00492                 $arec->setValues(array(
00493                         'translation_id'=>$trec->val('translation_id'),
00494                         'translation_memory_id'=>$this->_rec->val('translation_memory_id'),
00495                         'username'=>$username,
00496                         'status_id'=>$status
00497                 ));
00498                 $res = $arec->save($secure);
00499                 if ( PEAR::isError($res) ){
00500                         throw new Exception("Failed to approve translation: ".$res->getMessage());
00501                         
00502                 }
00503                 return $arec;
00504         }
00505         
00506         
00515         public function addTranslationComment($string, $translation, $comment, $username=null, $secure=false){
00516                 if ( !$username ) $username = Dataface_AuthenticationTool::getInstance()->getLoggedInUserName();
00517                 $trec = $this->findTranslation($string, $translation);
00518                 
00519                 if ( !$trec ){
00520                         $trec = $this->addTranslation($string, $translation, $username, $secure);
00521                 }
00522                 
00523                 if ( !$trec ){
00524                         throw new Exception("Could not find matching translation and failed to add one.");
00525                 }
00526                 
00527                 $arec = new Dataface_Record('xf_tm_translations_comments', array());
00528                 $arec->setValues(array(
00529                         'translation_id'=>$trec->val('translation_id'),
00530                         'translation_memory_id'=>$this->_rec->val('translation_memory_id'),
00531                         'posted_by'=>$username,
00532                         'comments'=>$comment
00533                 ));
00534                 $res = $arec->save($secure);
00535                 if ( PEAR::isError($res) ){
00536                         throw new Exception("Failed to approve translation: ".$res->getMessage());
00537                         
00538                 }
00539                 return $arec;
00540         }
00541         
00548         public function getTranslations(array $sources, $minStatus=3, $maxStatus=5){
00549                 $out = array();
00550                 $normalized = array();
00551                 $hashed = array();
00552                 $hashIndex = array();
00553                 $disqualified = array();
00554                 foreach ($sources as $k=>$src){
00555                         $normalized[$k] = TMTools::normalize($src);
00556                         $hashed[$k] = md5($normalized[$k]);
00557                         $hashIndex[$hashed[$k]] = $k;
00558                         $out[$k] = null;
00559                 }
00560                 
00561                 $hashesStr = "'".implode("','", $hashed)."'";
00562                 if ( !$hashesStr ) $hashesStr = '0';
00563                 $hashesStr = '('.$hashesStr.')';
00564                 
00565                 
00566                 $sql = "select 
00567                         s.`hash`,
00568                         t.translation_value,
00569                         tts.status_id
00570                         from 
00571                                 xf_tm_translations t
00572                                 inner join xf_tm_translations_status tts on t.translation_id=tts.translation_id and tts.translation_memory_id='".addslashes($this->_rec->val('translation_memory_id'))."'
00573                                 inner join xf_tm_strings s on t.string_id=s.string_id
00574                         where 
00575                                 tts.translation_memory_id='".addslashes($this->_rec->val('translation_memory_id'))."'
00576                                 and s.`hash` in $hashesStr
00577                                 
00578                         order by tts.date_created desc";
00579                 $res  = mysql_query($sql, df_db());
00580                 if ( !$res ) throw new Exception(mysql_error(df_db()));
00581                 
00582                 while ($row = mysql_fetch_assoc($res) ){
00583                         $k = $hashIndex[$row['hash']];
00584                         if ( !isset($k) ){
00585                                 throw new Exception("Invalid hash returned");
00586                         }
00587                         if ( !isset($out[$k]) ){
00588                                 if ( $row['status_id'] < $minStatus or $row['status_id'] > $maxStatus ){
00589                                         $disqualified[$k] = true;
00590                                 } else if ( !@$disqualified[$k] ){
00591                                         $out[$k] = $row['translation_value'];
00592                                 }
00593                         }
00594                 }
00595                 @mysql_free_result($res);
00596                 return $out;
00597                 
00598                         
00599                         
00600         }
00601         
00602         
00603         
00604 }
 All Data Structures Files Functions Variables