source: branches/2.1/admin/include/languages.class.php @ 8240

Last change on this file since 8240 was 8240, checked in by plg, 13 years ago

merge r8238 from trunk to branch 2.1

feature 2048 removed (and was never released): no data are sent anonymously to piwigo.org for statistics purpose

  • Property svn:eol-style set to LF
File size: 11.5 KB
Line 
1<?php
2// +-----------------------------------------------------------------------+
3// | Piwigo - a PHP based picture gallery                                  |
4// +-----------------------------------------------------------------------+
5// | Copyright(C) 2008-2010 Piwigo Team                  http://piwigo.org |
6// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
7// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
8// +-----------------------------------------------------------------------+
9// | This program is free software; you can redistribute it and/or modify  |
10// | it under the terms of the GNU General Public License as published by  |
11// | the Free Software Foundation                                          |
12// |                                                                       |
13// | This program is distributed in the hope that it will be useful, but   |
14// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
15// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
16// | General Public License for more details.                              |
17// |                                                                       |
18// | You should have received a copy of the GNU General Public License     |
19// | along with this program; if not, write to the Free Software           |
20// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
21// | USA.                                                                  |
22// +-----------------------------------------------------------------------+
23
24class languages
25{
26  var $fs_languages = array();
27  var $db_languages = array();
28  var $server_languages = array();
29
30  /**
31   * Initialize $fs_languages and $db_languages
32  */
33  function languages($target_charset = null)
34  {
35    $this->fs_languages = $this->get_fs_languages($target_charset);
36  }
37
38  /**
39   * Set tabsheet for languages pages.
40   * @param string selected page.
41   */
42  function set_tabsheet($selected)
43  {
44    include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
45
46    $link = get_root_url().'admin.php?page=';
47
48    $tabsheet = new tabsheet();
49    $tabsheet->add('languages_installed', l10n('Installed Languages'), $link.'languages_installed');
50    $tabsheet->add('languages_new', l10n('Add New Language'), $link.'languages_new');
51    $tabsheet->select($selected);
52    $tabsheet->assign();
53  }
54
55  /**
56   * Perform requested actions
57   * @param string - action
58   * @param string - language id
59   * @param array - errors
60   */
61  function perform_action($action, $language_id)
62  {
63    global $conf;
64
65    if (isset($this->db_languages[$language_id]))
66    {
67      $crt_db_language = $this->db_languages[$language_id];
68    }
69
70    $errors = array();
71
72    switch ($action)
73    {
74      case 'activate':
75        if (isset($crt_db_language))
76        {
77          array_push($errors, 'CANNOT ACTIVATE - LANGUAGE IS ALREADY ACTIVATED');
78          break;
79        }
80
81        $query = '
82INSERT INTO '.LANGUAGES_TABLE.'
83  (id, name)
84  VALUES(\''.$language_id.'\', \''.$this->fs_languages[$language_id].'\')
85;';
86        pwg_query($query);
87        break;
88
89      case 'deactivate':
90        if (!isset($crt_db_language))
91        {
92          array_push($errors, 'CANNOT DEACTIVATE - LANGUAGE IS ALREADY DEACTIVATED');
93          break;
94        }
95
96        if ($language_id == get_default_language())
97        {
98          array_push($errors, 'CANNOT DEACTIVATE - LANGUAGE IS DEFAULT LANGUAGE');
99          break;
100        }
101
102        $query = '
103DELETE
104  FROM '.LANGUAGES_TABLE.'
105  WHERE id= \''.$language_id.'\'
106;';
107        pwg_query($query);
108        break;
109
110      case 'delete':
111        if (!empty($crt_db_language))
112        {
113          array_push($errors, 'CANNOT DELETE - LANGUAGE IS ACTIVATED');
114          break;
115        }
116        if (!isset($this->fs_languages[$language_id]))
117        {
118          array_push($errors, 'CANNOT DELETE - LANGUAGE DOES NOT EXIST');
119          break;
120        }
121
122        // Set default language to user who are using this language
123        $query = '
124UPDATE '.USER_INFOS_TABLE.'
125  SET language = \''.get_default_language().'\'
126  WHERE language = \''.$language_id.'\'
127;';
128        pwg_query($query);
129
130        if (!$this->deltree(PHPWG_ROOT_PATH.'language/'.$language_id))
131        {
132          $this->send_to_trash(PHPWG_ROOT_PATH.'language/'.$language_id);
133        }
134        break;
135
136      case 'set_default':
137        $query = '
138UPDATE '.USER_INFOS_TABLE.'
139  SET language = \''.$language_id.'\'
140  WHERE user_id = '.$conf['default_user_id'].'
141;';
142        pwg_query($query);
143        break;
144    }
145    return $errors;
146  }
147
148  /**
149  *  Get languages defined in the language directory
150  */
151  function get_fs_languages($target_charset = null)
152  {
153    if ( empty($target_charset) )
154    {
155      $target_charset = get_pwg_charset();
156    }
157    $target_charset = strtolower($target_charset);
158
159    $dir = opendir(PHPWG_ROOT_PATH.'language');
160
161    while ($file = readdir($dir))
162    {
163      $path = PHPWG_ROOT_PATH.'language/'.$file;
164      if (!is_link($path) and is_dir($path) and file_exists($path.'/iso.txt'))
165      {
166        list($language_name) = @file($path.'/iso.txt');
167
168        $languages[$file] = convert_charset($language_name, 'utf-8', $target_charset);
169      }
170    }
171    closedir($dir);
172    @asort($languages);
173
174    return $languages;
175  }
176
177  function get_db_languages()
178  {
179    $query = '
180  SELECT id, name
181    FROM '.LANGUAGES_TABLE.'
182    ORDER BY name ASC
183  ;';
184    $result = pwg_query($query);
185
186    while ($row = pwg_db_fetch_assoc($result))
187    {
188      $this->db_languages[ $row['id'] ] = $row['name'];
189    }
190  }
191
192  /**
193   * Retrieve PEM server datas to $server_languages
194   */
195  function get_server_languages()
196  {
197    global $user;
198
199    $get_data = array(
200      'category_id' => 8,
201      'format' => 'php',
202    );
203
204    // Retrieve PEM versions
205    $version = PHPWG_VERSION;
206    $versions_to_check = array();
207    $url = PEM_URL . '/api/get_version_list.php';
208    if (fetchRemote($url, $result, $get_data) and $pem_versions = @unserialize($result))
209    {
210      if (!preg_match('/^\d+\.\d+\.\d+/', $version))
211      {
212        $version = $pem_versions[0]['name'];
213      }
214      $branch = substr($version, 0, strrpos($version, '.'));
215      foreach ($pem_versions as $pem_version)
216      {
217        if (strpos($pem_version['name'], $branch) === 0)
218        {
219          $versions_to_check[] = $pem_version['id'];
220        }
221      }
222    }
223    if (empty($versions_to_check))
224    {
225      return false;
226    }
227
228    // Retrieve PEM languages infos
229    $url = PEM_URL . '/api/get_revision_list.php';
230    $get_data = array_merge($get_data, array(
231      'last_revision_only' => 'true',
232      'version' => implode(',', $versions_to_check),
233      'lang' => $user['language'],
234      )
235    );
236
237    if (fetchRemote($url, $result, $get_data))
238    {
239      $pem_languages = @unserialize($result);
240      if (!is_array($pem_languages))
241      {
242        return false;
243      }
244      foreach ($pem_languages as $language)
245      {
246        if (preg_match('/^.*? \[[A-Z]{2}\]$/', $language['extension_name'])
247          and !in_array($language['extension_name'], $this->fs_languages))
248        {
249          $this->server_languages[] = $language;
250        }
251      }
252      return true;
253    }
254    return false;
255  }
256
257  /**
258   * Extract language files from archive
259   *
260   * @param string - install or upgrade
261   * @param string - remote revision identifier (numeric)
262   * @param string - language id or extension id
263   */
264  function extract_language_files($action, $revision, $dest='')
265  {
266    if ($archive = tempnam( PHPWG_ROOT_PATH.'language', 'zip'))
267    {
268      $url = PEM_URL . '/download.php';
269      $get_data = array(
270        'rid' => $revision,
271        'origin' => 'piwigo_'.$action,
272      );
273
274      if ($handle = @fopen($archive, 'wb') and fetchRemote($url, $handle, $get_data))
275      {
276        fclose($handle);
277        include(PHPWG_ROOT_PATH.'admin/include/pclzip.lib.php');
278        $zip = new PclZip($archive);
279        if ($list = $zip->listContent())
280        {
281          foreach ($list as $file)
282          {
283            // we search iso.txt in archive
284            if (basename($file['filename']) == 'iso.txt'
285              and (!isset($main_filepath)
286              or strlen($file['filename']) < strlen($main_filepath)))
287            {
288              $main_filepath = $file['filename'];
289            }
290          }
291          if (isset($main_filepath))
292          {
293            $root = basename(dirname($main_filepath)); // iso.txt path in archive
294            if (preg_match('/^[a-z]{2}_[A-Z]{2}$/', $root))
295            {
296              if ($action == 'install')
297              {
298                $dest = $root;
299              }
300              $extract_path = PHPWG_ROOT_PATH.'language/'.$dest;
301              if (
302                $result = $zip->extract(
303                  PCLZIP_OPT_PATH, $extract_path,
304                  PCLZIP_OPT_REMOVE_PATH, $root,
305                  PCLZIP_OPT_REPLACE_NEWER
306                  )
307                )
308              {
309                foreach ($result as $file)
310                {
311                  if ($file['stored_filename'] == $main_filepath)
312                  {
313                    $status = $file['status'];
314                    break;
315                  }
316                }
317                if ($status == 'ok')
318                {
319                  $this->fs_languages = $this->get_fs_languages();
320                  $this->perform_action('activate', $dest);
321                }
322                if (file_exists($extract_path.'/obsolete.list')
323                  and $old_files = file($extract_path.'/obsolete.list', FILE_IGNORE_NEW_LINES)
324                  and !empty($old_files))
325                {
326                  array_push($old_files, 'obsolete.list');
327                  foreach($old_files as $old_file)
328                  {
329                    $path = $extract_path.'/'.$old_file;
330                    if (is_file($path))
331                    {
332                      @unlink($path);
333                    }
334                    elseif (is_dir($path))
335                    {
336                      if (!$this->deltree($path))
337                      {
338                        $this->send_to_trash($path);
339                      }
340                    }
341                  }
342                }
343              }
344              else $status = 'extract_error';
345            }
346            else $status = 'archive_error';
347          }
348          else $status = 'archive_error';
349        }
350        else $status = 'archive_error';
351      }
352      else $status = 'dl_archive_error';
353    }
354    else $status = 'temp_path_error';
355
356    @unlink($archive);
357    return $status;
358  }
359
360  /**
361   * delete $path directory
362   * @param string - path
363   */
364  function deltree($path)
365  {
366    if (is_dir($path))
367    {
368      $fh = opendir($path);
369      while ($file = readdir($fh))
370      {
371        if ($file != '.' and $file != '..')
372        {
373          $pathfile = $path . '/' . $file;
374          if (is_dir($pathfile))
375          {
376            $this->deltree($pathfile);
377          }
378          else
379          {
380            @unlink($pathfile);
381          }
382        }
383      }
384      closedir($fh);
385      return @rmdir($path);
386    }
387  }
388
389  /**
390   * send $path to trash directory
391   * @param string - path
392   */
393  function send_to_trash($path)
394  {
395    $trash_path = PHPWG_ROOT_PATH . 'language/trash';
396    if (!is_dir($trash_path))
397    {
398      @mkdir($trash_path);
399      $file = @fopen($trash_path . '/.htaccess', 'w');
400      @fwrite($file, 'deny from all');
401      @fclose($file);
402    }
403    while ($r = $trash_path . '/' . md5(uniqid(rand(), true)))
404    {
405      if (!is_dir($r))
406      {
407        @rename($path, $r);
408        break;
409      }
410    }
411  }
412}
413?>
Note: See TracBrowser for help on using the repository browser.