1<?php
2/* vim: set expandtab sw=4 ts=4 sts=4: */
3/**
4 * User preferences management page
5 *
6 * @package PhpMyAdmin
7 */
8use PhpMyAdmin\Config\ConfigFile;
9use PhpMyAdmin\Config\Forms\User\UserFormList;
10use PhpMyAdmin\Core;
11use PhpMyAdmin\File;
12use PhpMyAdmin\Message;
13use PhpMyAdmin\Response;
14use PhpMyAdmin\Sanitize;
15use PhpMyAdmin\ThemeManager;
16use PhpMyAdmin\Url;
17use PhpMyAdmin\UserPreferences;
18use PhpMyAdmin\Util;
19
20/**
21 * Gets some core libraries and displays a top message if required
22 */
23require_once 'libraries/common.inc.php';
24
25$userPreferences = new UserPreferences();
26
27$cf = new ConfigFile($GLOBALS['PMA_Config']->base_settings);
28$userPreferences->pageInit($cf);
29$response = Response::getInstance();
30
31$error = '';
32if (isset($_POST['submit_export'])
33    && isset($_POST['export_type'])
34    && $_POST['export_type'] == 'text_file'
35) {
36    // export to JSON file
37    $response->disable();
38    $filename = 'phpMyAdmin-config-' . urlencode(Core::getenv('HTTP_HOST')) . '.json';
39    Core::downloadHeader($filename, 'application/json');
40    $settings = $userPreferences->load();
41    echo json_encode($settings['config_data'], JSON_PRETTY_PRINT);
42    exit;
43} elseif (isset($_POST['submit_export'])
44    && isset($_POST['export_type'])
45    && $_POST['export_type'] == 'php_file'
46) {
47    // export to JSON file
48    $response->disable();
49    $filename = 'phpMyAdmin-config-' . urlencode(Core::getenv('HTTP_HOST')) . '.php';
50    Core::downloadHeader($filename, 'application/php');
51    $settings = $userPreferences->load();
52    echo '/* ' . __('phpMyAdmin configuration snippet') . " */\n\n";
53    echo '/* ' . __('Paste it to your config.inc.php') . " */\n\n";
54    foreach ($settings['config_data'] as $key => $val) {
55        echo '$cfg[\'' . str_replace('/', '\'][\'', $key) . '\'] = ';
56        echo var_export($val, true) . ";\n";
57    }
58    exit;
59} elseif (isset($_POST['submit_get_json'])) {
60    $settings = $userPreferences->load();
61    $response->addJSON('prefs', json_encode($settings['config_data']));
62    $response->addJSON('mtime', $settings['mtime']);
63    exit;
64} elseif (isset($_POST['submit_import'])) {
65    // load from JSON file
66    $json = '';
67    if (isset($_POST['import_type'])
68        && $_POST['import_type'] == 'text_file'
69        && isset($_FILES['import_file'])
70        && $_FILES['import_file']['error'] == UPLOAD_ERR_OK
71        && is_uploaded_file($_FILES['import_file']['tmp_name'])
72    ) {
73        $import_handle = new File($_FILES['import_file']['tmp_name']);
74        $import_handle->checkUploadedFile();
75        if ($import_handle->isError()) {
76            $error = $import_handle->getError();
77        } else {
78            // read JSON from uploaded file
79            $json = $import_handle->getRawContent();
80        }
81    } else {
82        // read from POST value (json)
83        $json = isset($_POST['json']) ? $_POST['json'] : null;
84    }
85
86    // hide header message
87    $_SESSION['userprefs_autoload'] = true;
88
89    $config = json_decode($json, true);
90    $return_url = isset($_POST['return_url']) ? $_POST['return_url'] : null;
91    if (! is_array($config)) {
92        if (! isset($error)) {
93            $error = __('Could not import configuration');
94        }
95    } else {
96        // sanitize input values: treat them as though
97        // they came from HTTP POST request
98        $form_display = new UserFormList($cf);
99        $new_config = $cf->getFlatDefaultConfig();
100        if (!empty($_POST['import_merge'])) {
101            $new_config = array_merge($new_config, $cf->getConfigArray());
102        }
103        $new_config = array_merge($new_config, $config);
104        $_POST_bak = $_POST;
105        foreach ($new_config as $k => $v) {
106            $_POST[str_replace('/', '-', $k)] = $v;
107        }
108        $cf->resetConfigData();
109        $all_ok = $form_display->process(true, false);
110        $all_ok = $all_ok && !$form_display->hasErrors();
111        $_POST = $_POST_bak;
112
113        if (!$all_ok && isset($_POST['fix_errors'])) {
114            $form_display->fixErrors();
115            $all_ok = true;
116        }
117        if (!$all_ok) {
118            // mimic original form and post json in a hidden field
119            include 'libraries/user_preferences.inc.php';
120            $msg = Message::error(
121                __('Configuration contains incorrect data for some fields.')
122            );
123            $msg->display();
124            echo '<div class="config-form">';
125            echo $form_display->displayErrors();
126            echo '</div>';
127            echo '<form action="prefs_manage.php" method="post" class="disableAjax">';
128            echo Url::getHiddenInputs() , "\n";
129            echo '<input type="hidden" name="json" value="'
130                , htmlspecialchars($json) , '" />';
131            echo '<input type="hidden" name="fix_errors" value="1" />';
132            if (! empty($_POST['import_merge'])) {
133                echo '<input type="hidden" name="import_merge" value="1" />';
134            }
135            if ($return_url) {
136                echo '<input type="hidden" name="return_url" value="'
137                    , htmlspecialchars($return_url) , '" />';
138            }
139            echo '<p>';
140            echo __('Do you want to import remaining settings?');
141            echo '</p>';
142            echo '<input type="submit" name="submit_import" value="'
143                , __('Yes') , '" />';
144            echo '<input type="submit" name="submit_ignore" value="'
145                , __('No') , '" />';
146            echo '</form>';
147            exit;
148        }
149
150        // check for ThemeDefault
151        $params = array();
152        $tmanager = ThemeManager::getInstance();
153        if (isset($config['ThemeDefault'])
154            && $tmanager->theme->getId() != $config['ThemeDefault']
155            && $tmanager->checkTheme($config['ThemeDefault'])
156        ) {
157            $tmanager->setActiveTheme($config['ThemeDefault']);
158            $tmanager->setThemeCookie();
159        }
160        if (isset($config['lang'])
161            && $config['lang'] != $GLOBALS['lang']
162        ) {
163            $params['lang'] = $config['lang'];
164        }
165
166        // save settings
167        $result = $userPreferences->save($cf->getConfigArray());
168        if ($result === true) {
169            if ($return_url) {
170                $query =  PhpMyAdmin\Util::splitURLQuery($return_url);
171                $return_url = parse_url($return_url, PHP_URL_PATH);
172
173                foreach ($query as $q) {
174                    $pos = mb_strpos($q, '=');
175                    $k = mb_substr($q, 0, $pos);
176                    if ($k == 'token') {
177                        continue;
178                    }
179                    $params[$k] = mb_substr($q, $pos + 1);
180                }
181            } else {
182                $return_url = 'prefs_manage.php';
183            }
184            // reload config
185            $GLOBALS['PMA_Config']->loadUserPreferences();
186            $userPreferences->redirect($return_url, $params);
187            exit;
188        } else {
189            $error = $result;
190        }
191    }
192} elseif (isset($_POST['submit_clear'])) {
193    $result = $userPreferences->save(array());
194    if ($result === true) {
195        $params = array();
196        $GLOBALS['PMA_Config']->removeCookie('pma_collaction_connection');
197        $GLOBALS['PMA_Config']->removeCookie('pma_lang');
198        $userPreferences->redirect('prefs_manage.php', $params);
199        exit;
200    } else {
201        $error = $result;
202    }
203    exit;
204}
205
206$response = Response::getInstance();
207$header   = $response->getHeader();
208$scripts = $header->getScripts();
209$scripts->addFile('config.js');
210
211require 'libraries/user_preferences.inc.php';
212if ($error) {
213    if (!$error instanceof Message) {
214        $error = Message::error($error);
215    }
216    $error->display();
217}
218?>
219<script type="text/javascript">
220<?php
221Sanitize::printJsValue("PMA_messages['strSavedOn']", __('Saved on: @DATE@'));
222?>
223</script>
224<div id="maincontainer">
225    <div id="main_pane_left">
226        <div class="group">
227<?php
228echo '<h2>' , __('Import') , '</h2>'
229    , '<form class="group-cnt prefs-form disableAjax" name="prefs_import"'
230    , ' action="prefs_manage.php" method="post" enctype="multipart/form-data">'
231    , Util::generateHiddenMaxFileSize($GLOBALS['max_upload_size'])
232    , Url::getHiddenInputs()
233    , '<input type="hidden" name="json" value="" />'
234    , '<input type="radio" id="import_text_file" name="import_type"'
235    , ' value="text_file" checked="checked" />'
236    , '<label for="import_text_file">' . __('Import from file') . '</label>'
237    , '<div id="opts_import_text_file" class="prefsmanage_opts">'
238    , '<label for="input_import_file">' , __('Browse your computer:') , '</label>'
239    , '<input type="file" name="import_file" id="input_import_file" />'
240    , '</div>'
241    , '<input type="radio" id="import_local_storage" name="import_type"'
242    , ' value="local_storage" disabled="disabled" />'
243    , '<label for="import_local_storage">'
244    , __('Import from browser\'s storage') , '</label>'
245    , '<div id="opts_import_local_storage" class="prefsmanage_opts disabled">'
246    , '<div class="localStorage-supported">'
247    , __('Settings will be imported from your browser\'s local storage.')
248    , '<br />'
249    , '<div class="localStorage-exists">'
250    , __('Saved on: @DATE@')
251    , '</div>'
252    , '<div class="localStorage-empty">';
253Message::notice(__('You have no saved settings!'))->display();
254echo  '</div>'
255    , '</div>'
256    , '<div class="localStorage-unsupported">';
257Message::notice(
258    __('This feature is not supported by your web browser')
259)->display();
260echo '</div>'
261    , '</div>'
262    , '<input type="checkbox" id="import_merge" name="import_merge" />'
263    , '<label for="import_merge">'
264    , __('Merge with current configuration') . '</label>'
265    , '<br /><br />'
266    , '<input type="submit" name="submit_import" value="'
267    , __('Go') . '" />'
268    , '</form>'
269    , '</div>';
270if (@file_exists('setup/index.php') && ! @file_exists(CONFIG_FILE)) {
271            // show only if setup script is available, allows to disable this message
272            // by simply removing setup directory
273            // Also do not show in config exists (and setup would refuse to work)
274            ?>
275            <div class="group">
276            <h2><?php echo __('More settings') ?></h2>
277            <div class="group-cnt">
278                <?php
279                echo sprintf(
280                    __(
281                        'You can set more settings by modifying config.inc.php, eg. '
282                        . 'by using %sSetup script%s.'
283                    ), '<a href="setup/index.php" target="_blank">', '</a>'
284                ) , PhpMyAdmin\Util::showDocu('setup', 'setup-script');
285                ?>
286            </div>
287            </div>
288        <?php
289}
290        ?>
291    </div>
292    <div id="main_pane_right">
293        <div class="group">
294            <h2><?php echo __('Export'); ?></h2>
295            <div class="click-hide-message group-cnt hide">
296                <?php
297                Message::rawSuccess(
298                    __('Configuration has been saved.')
299                )->display();
300                ?>
301            </div>
302            <form class="group-cnt prefs-form disableAjax" name="prefs_export"
303                  action="prefs_manage.php" method="post">
304                <?php echo Url::getHiddenInputs(); ?>
305                <div style="padding-bottom:0.5em">
306                    <input type="radio" id="export_text_file" name="export_type"
307                           value="text_file" checked="checked" />
308                    <label for="export_text_file">
309                        <?php echo __('Save as JSON file'); ?>
310                    </label><br />
311                    <input type="radio" id="export_php_file" name="export_type"
312                           value="php_file" />
313                    <label for="export_php_file">
314                        <?php echo __('Save as PHP file'); ?>
315                    </label><br />
316                    <input type="radio" id="export_local_storage" name="export_type"
317                           value="local_storage" disabled="disabled" />
318                    <label for="export_local_storage">
319                        <?php echo __('Save to browser\'s storage'); ?></label>
320                </div>
321                <div id="opts_export_local_storage"
322                     class="prefsmanage_opts disabled">
323                    <span class="localStorage-supported">
324                        <?php
325                        echo __(
326                            'Settings will be saved in your browser\'s local '
327                            . 'storage.'
328                        );
329                        ?>
330                        <div class="localStorage-exists">
331                            <b>
332                                <?php
333                                echo __(
334                                    'Existing settings will be overwritten!'
335                                );
336                                ?>
337                            </b>
338                        </div>
339                    </span>
340                    <div class="localStorage-unsupported">
341                        <?php
342                        Message::notice(
343                            __('This feature is not supported by your web browser')
344                        )->display();
345                        ?>
346                    </div>
347                </div>
348                <br />
349                <?php
350                echo '<input type="submit" name="submit_export" value="' , __(
351                    'Go'
352                ) , '" />';
353                ?>
354            </form>
355        </div>
356        <div class="group">
357            <h2><?php echo __('Reset'); ?></h2>
358            <form class="group-cnt prefs-form disableAjax" name="prefs_reset"
359                  action="prefs_manage.php" method="post">
360                <?php
361                echo Url::getHiddenInputs() , __(
362                    'You can reset all your settings and restore them to default '
363                    . 'values.'
364                );
365                ?>
366                <br /><br />
367                <input type="submit" name="submit_clear"
368                       value="<?php echo __('Reset'); ?>"/>
369            </form>
370        </div>
371    </div>
372    <br class="clearfloat" />
373</div>
374
375<?php
376if ($response->isAjax()) {
377    $response->addJSON('_disableNaviSettings', true);
378} else {
379    define('PMA_DISABLE_NAVI_SETTINGS', true);
380}
381