diff options
Diffstat (limited to 'classes/pref/prefs.php')
-rw-r--r-- | classes/pref/prefs.php | 306 |
1 files changed, 141 insertions, 165 deletions
diff --git a/classes/pref/prefs.php b/classes/pref/prefs.php index 98bd99a04..aeaf5285b 100644 --- a/classes/pref/prefs.php +++ b/classes/pref/prefs.php @@ -24,24 +24,24 @@ class Pref_Prefs extends Handler_Protected { $this->pref_help = array( "ALLOW_DUPLICATE_POSTS" => array(__("Allow duplicate articles"), ""), "BLACKLISTED_TAGS" => array(__("Blacklisted tags"), __("When auto-detecting tags in articles these tags will not be applied (comma-separated list).")), - "CDM_AUTO_CATCHUP" => array(__("Automatically mark articles as read"), __("This option enables marking articles as read automatically while you scroll article list.")), + "CDM_AUTO_CATCHUP" => array(__("Automatically mark articles as read"), __("Mark articles as read while you scroll")), "CDM_EXPANDED" => array(__("Automatically expand articles in combined mode"), ""), - "COMBINED_DISPLAY_MODE" => array(__("Combined feed display"), __("Display expanded list of feed articles, instead of separate displays for headlines and article content")), + "COMBINED_DISPLAY_MODE" => array(__("Combined feed display"), __("Show combined list of articles, instead of separate panels")), "CONFIRM_FEED_CATCHUP" => array(__("Confirm marking feed as read"), ""), "DEFAULT_ARTICLE_LIMIT" => array(__("Amount of articles to display at once"), ""), - "DEFAULT_UPDATE_INTERVAL" => array(__("Default feed update interval"), __("Shortest interval at which a feed will be checked for updates regardless of update method")), + "DEFAULT_UPDATE_INTERVAL" => array(__("Default feed update interval")), "DIGEST_CATCHUP" => array(__("Mark articles in e-mail digest as read"), ""), - "DIGEST_ENABLE" => array(__("Enable e-mail digest"), __("This option enables sending daily digest of new (and unread) headlines on your configured e-mail address")), - "DIGEST_PREFERRED_TIME" => array(__("Try to send digests around specified time"), __("Uses UTC timezone")), + "DIGEST_ENABLE" => array(__("Enable e-mail digest"), __("Send daily digest of new (and unread) headlines to your e-mail address")), + "DIGEST_PREFERRED_TIME" => array(__("Try to send digests around specified time"), __("Time in UTC")), "ENABLE_API_ACCESS" => array(__("Enable API access"), __("Allows external clients to access this account through the API")), "ENABLE_FEED_CATS" => array(__("Enable feed categories"), ""), "FEEDS_SORT_BY_UNREAD" => array(__("Sort feeds by unread articles count"), ""), "FRESH_ARTICLE_MAX_AGE" => array(__("Maximum age of fresh articles (in hours)"), ""), "HIDE_READ_FEEDS" => array(__("Hide feeds with no unread articles"), ""), "HIDE_READ_SHOWS_SPECIAL" => array(__("Show special feeds when hiding read feeds"), ""), - "LONG_DATE_FORMAT" => array(__("Long date format"), __("The syntax used is identical to the PHP <a href='http://php.net/manual/function.date.php'>date()</a> function.")), - "ON_CATCHUP_SHOW_NEXT_FEED" => array(__("On catchup show next feed"), __("Automatically open next feed with unread articles after marking one as read")), - "PURGE_OLD_DAYS" => array(__("Purge articles after this number of days (0 - disables)"), ""), + "LONG_DATE_FORMAT" => array(__("Long date format"), __("Syntax is identical to PHP <a href='http://php.net/manual/function.date.php'>date()</a> function.")), + "ON_CATCHUP_SHOW_NEXT_FEED" => array(__("On catchup show next feed"), __("Automatically opens next unread feed after marking one as read")), + "PURGE_OLD_DAYS" => array(__("Purge articles older than"), "<strong>days</strong> (0 disables purging)"), "PURGE_UNREAD_ARTICLES" => array(__("Purge unread articles"), ""), "REVERSE_HEADLINES" => array(__("Reverse headline order (oldest first)"), ""), "SHORT_DATE_FORMAT" => array(__("Short date format"), ""), @@ -50,11 +50,11 @@ class Pref_Prefs extends Handler_Protected { "SSL_CERT_SERIAL" => array(__("Login with an SSL certificate"), __("Click to register your SSL client certificate with tt-rss")), "STRIP_IMAGES" => array(__("Do not embed media in articles"), ""), "STRIP_UNSAFE_TAGS" => array(__("Strip unsafe tags from articles"), __("Strip all but most common HTML tags when reading articles.")), - "USER_STYLESHEET" => array(__("Customize stylesheet"), __("Customize CSS stylesheet to your liking")), + "USER_STYLESHEET" => array(__("Customize stylesheet")), "USER_TIMEZONE" => array(__("Time zone"), ""), "VFEED_GROUP_BY_FEED" => array(__("Group headlines in virtual feeds"), __("Special feeds, labels, and categories are grouped by originating feeds")), "USER_LANGUAGE" => array(__("Language")), - "USER_CSS_THEME" => array(__("Theme"), __("Select one of the available CSS themes")) + "USER_CSS_THEME" => array(__("Theme")) ); } @@ -178,13 +178,16 @@ class Pref_Prefs extends Handler_Protected { $_SESSION["prefs_op_result"] = ""; - print "<div dojoType=\"dijit.layout.AccordionContainer\" region=\"center\">"; - print "<div dojoType=\"dijit.layout.AccordionPane\" + print "<div dojoType='dijit.layout.AccordionContainer' region='center'>"; + print "<div dojoType='dijit.layout.AccordionPane' title=\"<i class='material-icons'>person</i> ".__('Personal data / Authentication')."\">"; - print "<form dojoType=\"dijit.form.Form\" id=\"changeUserdataForm\">"; + print "<div dojoType='dijit.layout.TabContainer'>"; + print "<div dojoType='dijit.layout.ContentPane' title=\"".__('Personal data')."\">"; - print "<script type=\"dojo/method\" event=\"onSubmit\" args=\"evt\"> + print "<form dojoType='dijit.form.Form' id='changeUserdataForm'>"; + + print "<script type='dojo/method' event='onSubmit' args='evt'> evt.preventDefault(); if (this.validate()) { Notify.progress('Saving data...', true); @@ -198,10 +201,6 @@ class Pref_Prefs extends Handler_Protected { } </script>"; - print "<table width=\"100%\" class=\"prefPrefsList\">"; - - print "<h2>" . __("Personal data") . "</h2>"; - $sth = $this->pdo->prepare("SELECT email,full_name,otp_enabled, access_level FROM ttrss_users WHERE id = ?"); @@ -212,30 +211,38 @@ class Pref_Prefs extends Handler_Protected { $full_name = htmlspecialchars($row["full_name"]); $otp_enabled = sql_bool_to_bool($row["otp_enabled"]); - print "<tr><td width=\"40%\">".__('Full name')."</td>"; - print "<td class=\"prefValue\"><input dojoType=\"dijit.form.ValidationTextBox\" name=\"full_name\" required=\"1\" - value=\"$full_name\"></td></tr>"; + print "<fieldset>"; + print "<label>".__('Full name:')."</label>"; + print "<input dojoType='dijit.form.ValidationTextBox' name='full_name' required='1' value='$full_name'>"; + print "</fieldset>"; - print "<tr><td width=\"40%\">".__('E-mail')."</td>"; - print "<td class=\"prefValue\"><input dojoType=\"dijit.form.ValidationTextBox\" name=\"email\" required=\"1\" value=\"$email\"></td></tr>"; + print "<fieldset>"; + print "<label>".__('E-mail:')."</label>"; + print "<input dojoType='dijit.form.ValidationTextBox' name='email' required='1' value='$email'>"; + print "</fieldset>"; if (!SINGLE_USER_MODE && !$_SESSION["hide_hello"]) { $access_level = $row["access_level"]; - print "<tr><td width=\"40%\">".__('Access level')."</td>"; - print "<td>" . $access_level_names[$access_level] . "</td></tr>"; + print "<fieldset>"; + print "<label>".__('Access level:')."</label>"; + print $access_level_names[$access_level]; + print "</fieldset>"; } - print "</table>"; - print_hidden("op", "pref-prefs"); print_hidden("method", "changeemail"); - print "<p><button dojoType=\"dijit.form.Button\" type=\"submit\" class=\"alt-primary\">". + print "<hr/>"; + + print "<button dojoType='dijit.form.Button' type='submit' class='alt-primary'>". __("Save data")."</button>"; print "</form>"; + print "</div>"; # content pane + print "<div dojoType='dijit.layout.ContentPane' title=\"".__('Password')."\">"; + if ($_SESSION["auth_module"]) { $authenticator = PluginHost::getInstance()->get_plugin($_SESSION["auth_module"]); } else { @@ -244,13 +251,11 @@ class Pref_Prefs extends Handler_Protected { if ($authenticator && method_exists($authenticator, "change_password")) { - print "<h2>" . __("Password") . "</h2>"; - print "<div style='display : none' id='pwd_change_infobox'></div>"; - print "<form dojoType=\"dijit.form.Form\">"; + print "<form dojoType='dijit.form.Form'>"; - print "<script type=\"dojo/method\" event=\"onSubmit\" args=\"evt\"> + print "<script type='dojo/method' event='onSubmit' args='evt'> evt.preventDefault(); if (this.validate()) { Notify.progress('Changing password...', true); @@ -283,92 +288,91 @@ class Pref_Prefs extends Handler_Protected { print_notice(__("Changing your current password will disable OTP.")); } - print "<table width=\"100%\" class=\"prefPrefsList\">"; - - print "<tr><td width=\"40%\">".__("Old password")."</td>"; - print "<td class=\"prefValue\"><input dojoType=\"dijit.form.ValidationTextBox\" type=\"password\" required=\"1\" name=\"old_password\"></td></tr>"; - - print "<tr><td width=\"40%\">".__("New password")."</td>"; + print "<fieldset>"; + print "<label>".__("Old password:")."</label>"; + print "<input dojoType='dijit.form.ValidationTextBox' type='password' required='1' name='old_password'>"; + print "</fieldset>"; - print "<td class=\"prefValue\"><input dojoType=\"dijit.form.ValidationTextBox\" type=\"password\" required=\"1\" - name=\"new_password\"></td></tr>"; + print "<fieldset>"; + print "<label>".__("New password:")."</label>"; + print "<input dojoType='dijit.form.ValidationTextBox' type='password' required='1' name='new_password'>"; + print "</fieldset>"; - print "<tr><td width=\"40%\">".__("Confirm password")."</td>"; - - print "<td class=\"prefValue\"><input dojoType=\"dijit.form.ValidationTextBox\" type=\"password\" required=\"1\" name=\"confirm_password\"></td></tr>"; - - print "</table>"; + print "<fieldset>"; + print "<label>".__("Confirm password:")."</label>"; + print "<input dojoType='dijit.form.ValidationTextBox' type='password' required='1' name='confirm_password'>"; + print "</fieldset>"; print_hidden("op", "pref-prefs"); print_hidden("method", "changepassword"); - print "<p><button dojoType=\"dijit.form.Button\" type=\"submit\" class=\"alt-primary\">". + print "<hr/>"; + + print "<button dojoType='dijit.form.Button' type='submit' class='alt-primary'>". __("Change password")."</button>"; print "</form>"; - if ($_SESSION["auth_module"] == "auth_internal") { + print "</div>"; # content pane + print "<div dojoType='dijit.layout.ContentPane' title=\"".__('One time passwords / Authenticator')."\">"; - print "<h2>" . __("One time passwords / Authenticator") . "</h2>"; + if ($_SESSION["auth_module"] == "auth_internal") { if ($otp_enabled) { - print_notice(__("One time passwords are currently enabled. Enter your current password below to disable.")); - - print "<form dojoType=\"dijit.form.Form\">"; - - print "<script type=\"dojo/method\" event=\"onSubmit\" args=\"evt\"> - evt.preventDefault(); - if (this.validate()) { - Notify.progress('Disabling OTP', true); - - new Ajax.Request('backend.php', { - parameters: dojo.objectToQuery(this.getValues()), - onComplete: function(transport) { - Notify.close(); - if (transport.responseText.indexOf('ERROR: ') == 0) { - Notify.error(transport.responseText.replace('ERROR: ', '')); - } else { - window.location.reload(); - } - }}); - this.reset(); - } - </script>"; + print_warning("One time passwords are currently enabled. Enter your current password below to disable."); - print "<table width=\"100%\" class=\"prefPrefsList\">"; + print "<form dojoType='dijit.form.Form'>"; - print "<tr><td width=\"40%\">".__("Enter your password")."</td>"; + print "<script type='dojo/method' event='onSubmit' args='evt'> + evt.preventDefault(); + if (this.validate()) { + Notify.progress('Disabling OTP', true); + + new Ajax.Request('backend.php', { + parameters: dojo.objectToQuery(this.getValues()), + onComplete: function(transport) { + Notify.close(); + if (transport.responseText.indexOf('ERROR: ') == 0) { + Notify.error(transport.responseText.replace('ERROR: ', '')); + } else { + window.location.reload(); + } + }}); + this.reset(); + } + </script>"; - print "<td class=\"prefValue\"><input dojoType=\"dijit.form.ValidationTextBox\" type=\"password\" required=\"1\" - name=\"password\"></td></tr>"; + print "<fieldset>"; + print "<label>".__("Your password:")."</label>"; + print "<input dojoType='dijit.form.ValidationTextBox' type='password' required='1' name='password'>"; + print "</fieldset>"; - print "</table>"; + print_hidden("op", "pref-prefs"); + print_hidden("method", "otpdisable"); - print_hidden("op", "pref-prefs"); - print_hidden("method", "otpdisable"); + print "<hr/>"; - print "<p><button dojoType=\"dijit.form.Button\" type=\"submit\">". - __("Disable OTP")."</button>"; + print "<button dojoType='dijit.form.Button' type='submit'>". + __("Disable OTP")."</button>"; - print "</form>"; + print "</form>"; } else if (function_exists("imagecreatefromstring")) { - print "<p>" . __("You will need a compatible Authenticator to use this. Changing your password would automatically disable OTP.") . "</p>"; - - print "<p>".__("Scan the following code by the Authenticator application:")."</p>"; + print_warning("You will need a compatible Authenticator to use this. Changing your password would automatically disable OTP."); + print_notice("Scan the following code by the Authenticator application:"); $csrf_token = $_SESSION["csrf_token"]; - print "<img src=\"backend.php?op=pref-prefs&method=otpqrcode&csrf_token=$csrf_token\">"; + print "<img alt='otp qr-code' src='backend.php?op=pref-prefs&method=otpqrcode&csrf_token=$csrf_token'>"; - print "<form dojoType=\"dijit.form.Form\" id=\"changeOtpForm\">"; + print "<form dojoType='dijit.form.Form' id='changeOtpForm'>"; print_hidden("op", "pref-prefs"); print_hidden("method", "otpenable"); - print "<script type=\"dojo/method\" event=\"onSubmit\" args=\"evt\"> + print "<script type='dojo/method' event='onSubmit' args='evt'> evt.preventDefault(); if (this.validate()) { Notify.progress('Saving data...', true); @@ -387,38 +391,32 @@ class Pref_Prefs extends Handler_Protected { } </script>"; - print "<table width=\"100%\" class=\"prefPrefsList\">"; - - print "<tr><td width=\"40%\">".__("Enter your password")."</td>"; - - print "<td class=\"prefValue\"><input dojoType=\"dijit.form.ValidationTextBox\" type=\"password\" required=\"1\" - name=\"password\"></td></tr>"; - - print "<tr><td width=\"40%\">".__("Enter the generated one time password")."</td>"; + print "<fieldset>"; + print "<label>".__("Your password:")."</label>"; + print "<input dojoType='dijit.form.ValidationTextBox' type='password' required='1' + name='password'>"; + print "</fieldset>"; - print "<td class=\"prefValue\"><input dojoType=\"dijit.form.ValidationTextBox\" autocomplete=\"off\" - required=\"1\" - name=\"otp\"></td></tr>"; + print "<fieldset>"; + print "<label>".__("One time password:")."</label>"; + print "<input dojoType='dijit.form.ValidationTextBox' autocomplete='off' + required='1' name='otp'>"; + print "</fieldset>"; - print "<tr><td colspan=\"2\">"; - - print "</td></tr><tr><td colspan=\"2\">"; - - print "</td></tr>"; - print "</table>"; - - print "<p><button dojoType=\"dijit.form.Button\" type=\"submit\" class=\"alt-primary\">". + print "<hr/>"; + print "<button dojoType='dijit.form.Button' type='submit' class='alt-primary'>". __("Enable OTP")."</button>"; print "</form>"; } else { - - print_notice(__("PHP GD functions are required for OTP support.")); - + print_notice("PHP GD functions are required for OTP support."); } - } + + print "</div>"; # content pane + print "</div>"; # tab container + } PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION, @@ -426,12 +424,12 @@ class Pref_Prefs extends Handler_Protected { print "</div>"; #pane - print "<div dojoType=\"dijit.layout.AccordionPane\" selected=\"true\" + print "<div dojoType='dijit.layout.AccordionPane' selected='true' title=\"<i class='material-icons'>settings</i> ".__('Preferences')."\">"; - print "<form dojoType=\"dijit.form.Form\" id=\"changeSettingsForm\">"; + print "<form dojoType='dijit.form.Form' id='changeSettingsForm'>"; - print "<script type=\"dojo/method\" event=\"onSubmit\" args=\"evt, quit\"> + print "<script type='dojo/method' event='onSubmit' args='evt, quit'> if (evt) evt.preventDefault(); if (this.validate()) { console.log(dojo.objectToQuery(this.getValues())); @@ -480,8 +478,6 @@ class Pref_Prefs extends Handler_Protected { ORDER BY ttrss_prefs_sections.order_id,pref_name"); $sth->execute([":uid" => $_SESSION['uid'], ":profile" => $profile]); - $lnum = 0; - $active_section = ""; $listed_boolean_prefs = array(); @@ -508,32 +504,17 @@ class Pref_Prefs extends Handler_Protected { if ($active_section != $line["section_id"]) { - if ($active_section != "") { - print "</table>"; - } - - print "<table width=\"100%\" class=\"prefPrefsList\">"; - $active_section = $line["section_id"]; - print "<tr><td colspan=\"3\"><h2>".$section_name."</h2></td></tr>"; - - $lnum = 0; + print "<h2>".$section_name."</h2>"; } - print "<tr>"; + print "<fieldset class='prefs-set'>"; - print "<td width=\"40%\" class=\"prefName\" id=\"$pref_name\">"; - print "<label for='CB_$pref_name'>"; - print $short_desc; + print "<label for='CB_$pref_name' style='width : 300px'>"; + print "$short_desc:"; print "</label>"; - if ($help_text) print "<div class=\"prefHelp\">".__($help_text)."</div>"; - - print "</td>"; - - print "<td class=\"prefValue\">"; - if ($pref_name == "USER_LANGUAGE") { print_select_hash($pref_name, $value, get_translations(), "style='width : 220px; margin : 0px' dojoType='dijit.form.Select'"); @@ -569,7 +550,6 @@ class Pref_Prefs extends Handler_Protected { print "</select>"; - } else if ($pref_name == "DEFAULT_UPDATE_INTERVAL") { global $update_intervals_nodefault; @@ -605,9 +585,14 @@ class Pref_Prefs extends Handler_Protected { $disabled = ""; } - print "<input dojoType=\"dijit.form.ValidationTextBox\" - required=\"1\" $regexp $disabled - name=\"$pref_name\" value=\"$value\">"; + if ($type_name == 'integer') + print "<input dojoType=\"dijit.form.NumberSpinner\" + required=\"1\" $disabled + name=\"$pref_name\" value=\"$value\">"; + else + print "<input dojoType=\"dijit.form.TextBox\" + required=\"1\" $regexp $disabled + name=\"$pref_name\" value=\"$value\">"; } else if ($pref_name == "SSL_CERT_SERIAL") { @@ -618,21 +603,20 @@ class Pref_Prefs extends Handler_Protected { $cert_serial = htmlspecialchars(get_ssl_certificate_id()); $has_serial = ($cert_serial) ? "false" : "true"; - print "<br/>"; - - print " <button dojoType=\"dijit.form.Button\" disabled=\"$has_serial\" + print " <button dojoType='dijit.form.Button' class='alt-primary' disabled=\"$has_serial\" onclick=\"dijit.byId('SSL_CERT_SERIAL').attr('value', '$cert_serial')\">" . __('Register') . "</button>"; - print " <button dojoType=\"dijit.form.Button\" + print " <button dojoType='dijit.form.Button' class='alt-danger' onclick=\"dijit.byId('SSL_CERT_SERIAL').attr('value', '')\">" . __('Clear') . "</button>"; } else if ($pref_name == 'DIGEST_PREFERRED_TIME') { print "<input dojoType=\"dijit.form.ValidationTextBox\" id=\"$pref_name\" regexp=\"[012]?\d:\d\d\" placeHolder=\"12:00\" - name=\"$pref_name\" value=\"$value\"><div class=\"insensitive\">". - T_sprintf("Current server time: %s (UTC)", date("H:i")) . "</div>"; + name=\"$pref_name\" value=\"$value\">"; + //<div class='help-text insensitive'>" . T_sprintf("Server time: %s (UTC)", date("H:i")) . "</div>"; + $help_text .= ". " . T_sprintf("Current server time: %s", date("H:i")); } else { $regexp = ($type_name == 'integer') ? 'regexp="^\d*$"' : ''; @@ -641,15 +625,11 @@ class Pref_Prefs extends Handler_Protected { name=\"$pref_name\" value=\"$value\">"; } - print "</td>"; - - print "</tr>"; + if ($help_text) print "<div class='help-text insensitive'><label for='CB_$pref_name'>".__($help_text)."</label></div>"; - $lnum++; + print "</fieldset>"; } - print "</table>"; - $listed_boolean_prefs = htmlspecialchars(join(",", $listed_boolean_prefs)); print_hidden("boolean_prefs", "$listed_boolean_prefs"); @@ -727,12 +707,12 @@ class Pref_Prefs extends Handler_Protected { format_notice(__("System plugins are enabled in <strong>config.php</strong> for all users.")). "</td></tr>"; - print "<tr class=\"title\"> - <td width=\"5%\"> </td> - <td width='10%'>".__('Plugin')."</td> - <td width=''>".__('Description')."</td> - <td width='5%'>".__('Version')."</td> - <td width='10%'>".__('Author')."</td></tr>"; + print "<tr> + <th width=\"5%\"> </th> + <th width='10%'>".__('Plugin')."</th> + <th width=''>".__('Description')."</th> + <th width='5%'>".__('Version')."</th> + <th width='10%'>".__('Author')."</th></tr>"; $system_enabled = array_map("trim", explode(",", PLUGINS)); $user_enabled = array_map("trim", explode(",", get_pref("_ENABLED_PLUGINS"))); @@ -783,12 +763,12 @@ class Pref_Prefs extends Handler_Protected { print "<tr><td colspan='4'><h2>".__("User plugins")."</h2></td></tr>"; - print "<tr class=\"title\"> - <td width=\"5%\"> </td> - <td width='10%'>".__('Plugin')."</td> - <td width=''>".__('Description')."</td> - <td width='5%'>".__('Version')."</td> - <td width='10%'>".__('Author')."</td></tr>"; + print "<tr> + <th width=\"5%\"> </th> + <th width='10%'>".__('Plugin')."</th> + <th width=''>".__('Description')."</th> + <th width='5%'>".__('Version')."</th> + <th width='10%'>".__('Author')."</th></tr>"; foreach ($tmppluginhost->get_plugins() as $name => $plugin) { @@ -1051,8 +1031,6 @@ class Pref_Prefs extends Handler_Protected { print "</tr>"; - $lnum = 1; - while ($line = $sth->fetch()) { $profile_id = $line["id"]; @@ -1087,8 +1065,6 @@ class Pref_Prefs extends Handler_Protected { </span> $is_active</td>"; print "</tr>"; - - ++$lnum; } print "</table>"; |