remove old readme
[atutor.git] / docs / mods / _core / languages / classes / LanguageEditor.class.php
1 <?php
2 /************************************************************************/
3 /* ATutor                                                                                                                               */
4 /************************************************************************/
5 /* Copyright (c) 2002-2010                                              */
6 /* Inclusive Design Institute                                           */
7 /* http://atutor.ca                                                     */
8 /* This program is free software. You can redistribute it and/or        */
9 /* modify it under the terms of the GNU General Public License          */
10 /* as published by the Free Software Foundation.                        */
11 /************************************************************************/
12 // $Id$
13
14 /**
15 * LanguageEditor
16 * Class for adding/editing language.
17 * @access       public
18 * @author       Heidi Hazelton
19 * @author       Joel Kronenberg
20 * @package      Language
21 */
22 class LanguageEditor extends Language {
23
24         var $addslashes;
25
26         // array of missing terms
27         var $missingTerms;
28
29         // array of filters ['new', 'update']
30         var $filters;
31         
32         /**
33         * Constructor.
34         * 
35         * Initializes db and parent properties.
36         */
37         function LanguageEditor($myLang) {
38                 global $db, $addslashes, $msg;
39                 
40                 global $savant;
41                 $this->msg = $msg;
42
43                 $this->addslashes = $addslashes;
44
45                 if (isset($myLang)) {
46                         $this->Language($myLang);
47                 }
48                 $this->missingTerms = array();
49         }
50
51         /**
52         * Inserts a new language def'n into the database.
53         * @access       public
54         * @param        array $row              The language def'n fields as an assoc array.
55         * @return       boolean                 Returns TRUE if the def'n was inserted correctly, 
56         *                                                       or FALSE, otherwise.
57         * call staticly only!
58         */
59     function addLanguage($row, $db) {
60                 global $addslashes;
61                 global $msg;
62                 
63                 $row['code']         = trim($row['code']);
64                 $row['locale']       = trim($row['locale']);
65                 $row['charset']      = trim($row['charset']);
66                 $row['reg_exp']      = trim($row['reg_exp']);
67                 $row['native_name']  = trim($row['native_name']);
68                 $row['english_name'] = trim($row['english_name']);
69
70                 $missing_fields = array();
71
72                 if ($row['code'] == '') {
73                         $missing_fields[] = _AT('lang_code');
74                 }
75                 if ($row['charset'] == '') {
76                         $missing_fields[] = _AT('charset');
77                 }
78                 if ($row['reg_exp'] == '') {
79                         $missing_fields[] = _AT('reg_exp');
80                 }
81                 if ($row['native_name'] == '') {
82                         $missing_fields[] = _AT('name_in_language');
83                 }
84                 if ($row['english_name'] == '') {
85                         $missing_fields[] = _AT('name_in_english');
86                 }
87                 
88                 if ($missing_fields) {
89                         $missing_fields = implode(', ', $missing_fields);
90                         $msg->addError(array('EMPTY_FIELDS', $missing_fields));
91                 }
92
93                 if (!$msg->containsErrors()) {
94                         $row['code']         = $addslashes($row['code']);
95                         $row['locale']       = $addslashes($row['locale']);
96                         $row['charset']      = $addslashes($row['charset']);
97                         $row['direction']    = $addslashes($row['direction']);
98                         $row['reg_exp']      = $addslashes($row['reg_exp']);
99                         $row['native_name']  = $addslashes($row['native_name']);
100                         $row['english_name'] = $addslashes($row['english_name']);
101
102                         if (!empty($row['locale'])) { 
103                                 $row['code'] .= AT_LANGUAGE_LOCALE_SEP . strtolower($row['locale']);
104                         }
105
106                         $sql    = "INSERT INTO ".TABLE_PREFIX."languages VALUES ('$row[code]', '$row[charset]', '$row[direction]', '$row[reg_exp]', '$row[native_name]', '$row[english_name]', 3)";
107
108                         if (mysql_query($sql, $db)) {
109                                 return TRUE;
110                         } else {
111                                 return FALSE;
112                         }
113                 }
114
115                 return FALSE;
116     }
117
118         // public
119         // $row = the language info array
120         // $new_exists whether the new code+locale exists already
121         // returns true or false, depending on success if db update
122         // can be called staticly
123     function updateLanguage($row, $new_exists) {
124                 $missing_fields = array();
125
126                 if ($row['code'] == '') {
127                         $missing_fields[] = _AT('lang_code');
128                 }
129                 if ($row['charset'] == '') {
130                         $missing_fields[] = _AT('charset');
131                 }
132                 if ($row['reg_exp'] == '') {
133                         $missing_fields[] = _AT('reg_exp');
134                 }
135                 if ($row['native_name'] == '') {
136                         $missing_fields[] = _AT('name_in_language');
137                 }
138                 if ($row['english_name'] == '') {
139                         $missing_fields[] = _AT('name_in_english');
140                 }
141                 
142                 if ($missing_fields) {
143                         $missing_fields = implode(', ', $missing_fields);
144                         $msg->addError(array('EMPTY_FIELDS', $missing_fields));
145                 }
146
147
148                 if (!$this->msg->containsErrors()) {
149                         global $addslashes;
150                         global $db;
151
152                         $row['code']         = strtolower($addslashes($row['code']));
153                         if (!empty($row['locale'])) { 
154                                 $row['code'] .= AT_LANGUAGE_LOCALE_SEP . strtolower($addslashes($row['locale']));
155                         }
156                         $row['charset']      = strtolower($addslashes($row['charset']));
157                         $row['direction']    = strtolower($addslashes($row['direction']));
158                         $row['reg_exp']      = strtolower($addslashes($row['reg_exp']));
159                         $row['native_name']  = $addslashes($row['native_name']);
160                         $row['english_name'] = $addslashes($row['english_name']);
161                         if (isset($row['status'])) {
162                                 $row['status']       = intval($row['status']);
163                                 $status_sql = ', status='.$row['status'];
164                         } else {
165                                 $status_sql = '';
166                         }
167
168                         if ($row['old_code'] == $row['code']) {
169                                 $sql    = "UPDATE ".TABLE_PREFIX."languages SET char_set='$row[charset]', direction='$row[direction]', reg_exp='$row[reg_exp]', native_name='$row[native_name]', english_name='$row[english_name]' $status_sql WHERE language_code='$row[code]'";
170                                 mysql_query($sql, $db);
171
172                                 return TRUE;
173                         } else if ($new_exists) {
174                                 $this->msg->addError('LANG_EXISTS');
175                                 return FALSE;
176                         } else {
177                                 $sql    = "UPDATE ".TABLE_PREFIX."languages SET language_code='$row[code]', char_set='$row[charset]', direction='$row[direction]', reg_exp='$row[reg_exp]', native_name='$row[native_name]', english_name='$row[english_name]' $status_sql WHERE language_code='$row[old_code]'";
178                                 mysql_query($sql, $db);
179
180                                 $sql = "UPDATE ".TABLE_PREFIX."language_text SET language_code='$row[code]' WHERE language_code='$row[old_code]'";
181                                 mysql_query($sql, $db);
182
183                                 return TRUE;
184                         }
185
186                 }
187                 return FALSE;
188     }
189
190     function deleteLanguage() {
191                 $sql = "DELETE FROM ".TABLE_PREFIX."languages WHERE language_code='$this->code'";
192                 mysql_query($sql, $this->db);
193
194                 $sql = "DELETE FROM ".TABLE_PREFIX."language_text WHERE language_code='$this->code'";
195                 mysql_query($sql, $this->db);
196
197                 $sql = "UPDATE ".TABLE_PREFIX."members SET language='".DEFAULT_LANGUAGE."', creation_date=creation_date, last_login=last_login WHERE language='$this->code'";
198                 mysql_query($sql, $this->db);
199
200                 $sql = "UPDATE ".TABLE_PREFIX."courses SET primary_language='".DEFAULT_LANGUAGE."' WHERE primary_language='$this->code'";
201                 mysql_query($sql, $this->db);
202
203                 cache_purge('system_langs', 'system_langs');
204         }
205
206         // public
207         function updateTerm($variable, $term, $text) {
208                 $addslashes = $this->addslashes;
209
210                 $variable = $addslashes($variable);
211                 $term     = $addslashes($term);
212                 $text     = $addslashes($text);
213                 $code     = $addslashes($this->getCode());
214
215                 $sql    = "UPDATE ".TABLE_PREFIX."language_text SET text='$text', revised_date=NOW() WHERE language_code='$code' AND variable='$variable' AND term='$term'";
216
217                 /*
218                 if (mysql_query($sql, $this->db)) {
219                         return TRUE;
220                 } else {
221                         debug(mysql_error($this->db));
222                         return FALSE;
223                 }
224                 */
225         }
226
227         // public
228         function insertTerm($variable, $key, $text, $context) {
229                 $addslashes = $this->addslashes;
230
231                 $variable = $addslashes($variable);
232                 $key      = $addslashes($key);
233                 $text     = $addslashes($text);
234                 $code     = $addslashes($this->getCode());
235                 $context  = $addslashes($context);
236
237                 $sql = "INSERT INTO ".TABLE_PREFIX."language_text VALUES('$code', '$variable', '$key', '$text', NOW(), '$context')";
238         }
239
240         // public
241         function showMissingTermsFrame(){
242                 global $_base_path, $addslashes;
243                 //$terms = array_slice($this->missingTerms, 0, 20);
244                 $terms = $this->missingTerms;
245                 $terms = serialize($terms);
246                 $terms = urlencode($terms);
247
248                 echo '<div align="center"><iframe src="'.$_base_path.'mods/_core/languages/missing_language.php?terms='.$terms.SEP.'lang='.$_SESSION['lang'].'" width="99%" height="300"></div>';
249         }
250
251         // public
252         // doesn't actually check if params is one of the possible ones.
253         // possible params should be array ('new', 'update')
254         function setFilter($params){
255                 if (!is_array($params)) {
256                         return;
257                 }
258
259                 foreach($params as $param => $garbage) {
260                         $this->filters[$param] = true;
261                 }
262         }
263
264         // private
265         function checkFilter($param) {
266                 if ($this->filters[$param]) {
267                         return true;
268                 }
269                 return false;
270         }
271
272         // public
273         function printTerms($terms){
274                 global $addslashes, $languageManager; // why won't $addslashes = $this->addslashes; work?
275
276                 $counter = 0;
277
278                 $terms = unserialize(stripslashes($addslashes($terms)));
279
280                 natcasesort($terms);
281
282                 if ($this->checkFilter('new')) {
283                         $new_check = ' checked="checked"';
284                 }
285                 if ($this->checkFilter('update')) {
286                         $update_check = ' checked="checked"';
287                 }
288
289                 $fromLanguage = $languageManager->getLanguage('en');
290
291                 echo '<form method="post" action="'.htmlspecialchars($_SERVER['REQUEST_URI'], ENT_QUOTES).'">';
292                 echo '<table border="0" cellpadding="0" cellspacing="2">';
293                 echo '<tr>';
294                 echo '<td>Show: ';
295                 echo '<input name="filter_new" id="n" value="1" type="checkbox" '.$new_check.' /><label for="n">New Language</label>, ';
296                 echo '<input name="filter_update" id="u" value="1" type="checkbox" '.$update_check.' /><label for="u">Updated Language</label> ';
297                 echo '</td>';
298                 echo '</tr>';
299
300                 foreach($terms as $term => $garbage) {
301                         $to_term   = $this->getTerm($term);
302                         $from_term = $fromLanguage->getTerm($term);
303
304                         $is_new = false;
305                         if ($to_term === false) {
306                                 $is_new = true;
307                         }
308
309                         $is_old = false;
310                         if ($to_term['revised_date_unix'] < $from_term['revised_date_unix']) {
311                                 $is_old = true;
312                         }
313
314
315                         if ($this->checkFilter('new') && !$is_new) {
316                                 continue;
317                         }
318
319                         if ($this->checkFilter('update') && !$is_old) {
320                                 continue;
321                         }
322
323                         if (($counter % 10) == 0) {
324                                 echo '<tr>';
325                                 echo '<td align="center"><input type="submit" name="submit" value="Save Changes" class="button" /></td>';
326                                 echo '</tr>';
327                         }
328
329                         $style = '';
330                         if ($is_new) {
331                                 $style = 'style="background-color: white; border: red 2px solid;"';
332                         } else {
333                                 $style = 'style="background-color: white; border: yellow 1px solid;"';
334                         }
335
336                         echo '<tr>';
337                         echo '<td><strong>[ ' . $term . ' ] '.htmlspecialchars($from_term['text']).'</strong></td></tr>';
338                         echo '<tr><td><input type="text" name="'.$term.'" '.$style.' size="100" value="'.htmlspecialchars($to_term['text']).'" />';
339                         echo '<input type="hidden" name="old['.$term.']" '.$style.' size="100" value="'.htmlspecialchars($to_term['text']).'" /></td>';
340                         echo '</tr>';
341
342                         $counter++;
343                 }
344                 echo '</table>';
345                 echo '</form>';
346         }
347
348         // public
349         function updateTerms($terms) {
350                 global $addslashes;
351
352                 foreach($terms as $term => $text) {
353                         $text = $addslashes($text);
354                         $term = $addslashes($term);
355                 
356                         if (($text != '') && ($text != $_POST['old'][$term])) {
357                                 $sql = "REPLACE INTO ".TABLE_PREFIX."language_text VALUES ('".$this->getCode()."', '_template', '$term', '$text', NOW(), '')";
358                                 mysql_query($sql, $this->db);
359                         }
360                 }
361         }
362
363         // public
364         function addMissingTerm($term) {
365                 if (!isset($this->missingTerms[$term])) {
366                         $this->missingTerms[$term] = '';
367                 }
368         }
369
370
371         // this method should be called staticly: LanguageEditor::import()
372         // public
373         function import($language_sql_file) {
374                 // move sql import class from install/ to include/classes/
375                 // store the lang def'n in a .ini file and use insertLang 
376                 // after checking if it already exists
377
378                 // use the sql class to insert the language into the db
379
380                 // check if this language exists before calling this method
381
382                 require_once(AT_INCLUDE_PATH . 'classes/sqlutility.class.php');
383                 $sqlUtility = new SqlUtility();
384
385                 $sqlUtility->queryFromFile($language_sql_file, TABLE_PREFIX);
386         }
387
388         // sends the generated language pack to the browser
389         // public
390         function export($filename = '') {
391                 $search  = array('"', "'", "\x00", "\x0a", "\x0d", "\x1a"); //\x08\\x09, not required
392                 $replace = array('\"', "\'", '\0', '\n', '\r', '\Z');
393
394                 // use a function to generate the ini file
395                 // use a diff fn to generate the sql dump
396                 // use the zipfile class to package the ini file and the sql dump
397                 $sql_dump = "INSERT INTO `languages` VALUES ('$this->code', '$this->characterSet', '$this->direction', '$this->regularExpression', '$this->nativeName', '$this->englishName', $this->status);\r\n\r\n";
398
399                 $sql_dump .= "INSERT INTO `language_text` VALUES ";
400
401                 $sql    = "SELECT * FROM ".TABLE_PREFIX."language_text WHERE language_code='$this->code' ORDER BY variable, term";
402                 $result = mysql_query($sql, $this->db);
403                 if ($row = mysql_fetch_assoc($result)) {
404                         do {
405                                 $row['text']    = str_replace($search, $replace, $row['text']);
406                                 $row['context'] = str_replace($search, $replace, $row['context']);
407
408                                 $sql_dump .= "('$this->code', '$row[variable]', '$row[term]', '$row[text]', '$row[revised_date]', '$row[context]'),\r\n";
409                         } while ($row = mysql_fetch_assoc($result));
410                 } else {
411                         $this->msg->addError('LANG_EMPTY');
412                 }
413                 $sql_dump = substr($sql_dump, 0, -3) . ";";
414
415                 $readme = 'This is an ATutor language pack. Use the administrator Language section to import this language pack or manually import the contents of the SQL file into your [table_prefix]language_text table, where `table_prefix` should be replaced with your correct ATutor table prefix as defined in ./include/config.inc.php . Additional Language Packs can be found on http://atutor.ca .';
416
417                 require(AT_INCLUDE_PATH . 'classes/zipfile.class.php');
418                 $zipfile = new zipfile();
419
420                 $zipfile->add_file($sql_dump, 'language_text.sql');
421                 $zipfile->add_file($readme, 'readme.txt');
422                 $zipfile->add_file($this->getXML(), 'language.xml');  
423
424                 if ($filename) {
425                         $fp = fopen($filename, 'wb+');
426                         fwrite($fp, $zipfile->get_file(), $zipfile->get_size());
427                 } else {
428                         $version = str_replace('.','_',VERSION);
429
430                         $zipfile->send_file('atutor_' . $version . '_' . $this->code);
431                 }
432         }
433
434 }
435 ?>