diff --git a/.travis.yml b/.travis.yml index b24a0c176..5b0ba705a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,12 +30,7 @@ env: matrix: fast_finish: true include: - # PHP 5.3 only runs on Ubuntu 12.04 (precise), not 14.04 (trusty) - - php: "5.3" - dist: precise - # PHP 5.4 & 5.5 only run on Travis in 14.04 (trusty), not 16.04 (xenial) - - php: "5.4" - dist: trusty + # PHP 5.5 only runs on Travis in 14.04 (trusty), not 16.04 (xenial) - php: "5.5" dist: trusty - php: "7.2" diff --git a/CHANGELOG.md b/CHANGELOG.md index 92a941280..443302273 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,28 @@ ## 2019-XX-XX FreshRSS 1.14.4-dev +* Features + * New option to display article authors underneath the article title [#2487](https://github.com/FreshRSS/FreshRSS/pull/2487) + * Add e-mail capability [#2476](https://github.com/FreshRSS/FreshRSS/pull/2476) +* Compatibility + * Require at least PHP 5.5+ [#2495](https://github.com/FreshRSS/FreshRSS/pull/2495) +* Deployment + * Take advantage of `mod_authz_core` instead of `mod_access_compat` when running on Apache 2.4+ [#2461](https://github.com/FreshRSS/FreshRSS/pull/2461) + * Docker: Alpine image updated to 3.10 with PHP 7.3.8 and Apache 2.4.41 [#2238](https://github.com/FreshRSS/FreshRSS/pull/2238) +* Bug fixing + * Fix missing PHP `opcache` package in Docker Alpine [#2498](https://github.com/FreshRSS/FreshRSS/pull/2498) +* Security + * Fix referrer vulnerability when opening an article original link with a shortcut [#2506](https://github.com/FreshRSS/FreshRSS/pull/2506) + * Slight refactoring of access check [#2471](https://github.com/FreshRSS/FreshRSS/pull/2471) +* I18n + * Improve Dutch [#2503](https://github.com/FreshRSS/FreshRSS/pull/2503) + * Add Slovak [#2497](https://github.com/FreshRSS/FreshRSS/pull/2497) +* Extensions + * Additional hooks [#2482](https://github.com/FreshRSS/FreshRSS/pull/2482) + * New call to change the layout [#2467](https://github.com/FreshRSS/FreshRSS/pull/2467) +* Misc. + * Automatic check of CSS syntax in Travis CI [#2477](https://github.com/FreshRSS/FreshRSS/pull/2477) + * Remove support for sharing with Google+ [#2464](https://github.com/FreshRSS/FreshRSS/pull/2464) ## 2019-07-25 FreshRSS 1.14.3 diff --git a/CREDITS.md b/CREDITS.md index 81d647b84..6514aab15 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -72,6 +72,7 @@ People are sorted by name so please keep this order. * [Thomas Citharel](https://github.com/tcitworld): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:tomgue), [Web](https://www.tcit.fr/) * [Thomas Guesnon](https://github.com/patjennings): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:patjennings), [Web](http://www.thomasguesnon.fr/) * [thomas-gt](https://github.com/thomas-gt): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:thomas-gt) +* [Tibor Repček](https://github.com/tiborepcek): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:tiborepcek) * [tomgue](https://github.com/tomgue): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=tomgue) * [Twilek-de](https://github.com/Twilek-de): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:Twilek-de) * [Uncovery](https://github.com/uncovery): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:uncovery) diff --git a/Docker/Dockerfile b/Docker/Dockerfile index 8693bb0f7..1d2ead96e 100644 --- a/Docker/Dockerfile +++ b/Docker/Dockerfile @@ -49,6 +49,8 @@ RUN sed -r -i "/^\s*(CustomLog|ErrorLog|Listen) /s/^/#/" /etc/apache2/apache2.co ENV COPY_SYSLOG_TO_STDERR On ENV CRON_MIN '' +ENV FRESHRSS_ENV '' + ENTRYPOINT ["./Docker/entrypoint.sh"] EXPOSE 80 diff --git a/Docker/Dockerfile-Alpine b/Docker/Dockerfile-Alpine index ac5d74a43..3b1f1a394 100644 --- a/Docker/Dockerfile-Alpine +++ b/Docker/Dockerfile-Alpine @@ -5,7 +5,7 @@ SHELL ["/bin/ash", "-eo", "pipefail", "-c"] RUN apk add --no-cache \ apache2 php7-apache2 \ php7 php7-curl php7-gmp php7-intl php7-mbstring php7-xml php7-zip \ - php7-ctype php7-dom php7-fileinfo php7-iconv php7-json php7-session php7-simplexml php7-xmlreader php7-zlib \ + php7-ctype php7-dom php7-fileinfo php7-iconv php7-json php7-opcache php7-session php7-simplexml php7-xmlreader php7-zlib \ php7-pdo_sqlite php7-pdo_mysql php7-pdo_pgsql RUN mkdir -p /var/www/FreshRSS /run/apache2/ @@ -45,6 +45,8 @@ RUN rm -f /etc/apache2/conf.d/languages.conf /etc/apache2/conf.d/info.conf \ ENV COPY_SYSLOG_TO_STDERR On ENV CRON_MIN '' +ENV FRESHRSS_ENV '' + ENTRYPOINT ["./Docker/entrypoint.sh"] EXPOSE 80 diff --git a/Docker/Dockerfile-QEMU-ARM b/Docker/Dockerfile-QEMU-ARM index 4d81a23f0..ea1f98798 100644 --- a/Docker/Dockerfile-QEMU-ARM +++ b/Docker/Dockerfile-QEMU-ARM @@ -61,6 +61,8 @@ RUN rm /usr/bin/qemu-* /var/www/FreshRSS/Docker/qemu-* ENV COPY_SYSLOG_TO_STDERR On ENV CRON_MIN '' +ENV FRESHRSS_ENV '' + ENTRYPOINT ["./Docker/entrypoint.sh"] EXPOSE 80 diff --git a/Docker/README.md b/Docker/README.md index 32024c829..9de1d5033 100644 --- a/Docker/README.md +++ b/Docker/README.md @@ -238,6 +238,22 @@ docker run -d --restart unless-stopped --log-opt max-size=10m \ crond -f -d 6 ``` +## Development mode + +To contribute to FreshRSS development, you can use one of the Docker images to run and serve the PHP code, +while reading the source code from your local (git) directory, like the following example: + +```sh +cd /path-to-local/FreshRSS/ +docker run --rm -p 8080:80 -e TZ=Europe/Paris -e FRESHRSS_ENV=development \ + -v $(pwd):/var/www/FreshRSS \ + freshrss/freshrss:dev +``` + +This will start a server on port 8080, based on your local PHP code, which will show the logs directly in your terminal. +Press Control+c to exit. + +The `FRESHRSS_ENV=development` environment variable increases the level of logging and ensures that errors are displayed. ## More deployment options diff --git a/README.fr.md b/README.fr.md index d9b145fc4..ceee48f5b 100644 --- a/README.fr.md +++ b/README.fr.md @@ -43,7 +43,7 @@ FreshRSS n’est fourni avec aucune garantie. * Serveur modeste, par exemple sous Linux ou Windows * Fonctionne même sur un Raspberry Pi 1 avec des temps de réponse < 1s (testé sur 150 flux, 22k articles) * Serveur Web Apache2 (recommandé), ou nginx, lighttpd (non testé sur les autres) -* PHP 5.3.8+ (PHP 5.4+ recommandé, et PHP 5.5+ pour les performances, ou PHP 7+ pour d’encore meilleures performances) +* PHP 5.5+ (PHP 7+ recommandé pour de meilleures performances) * Requis : [cURL](https://secure.php.net/curl), [DOM](https://secure.php.net/dom), [XML](https://secure.php.net/xml), [session](https://secure.php.net/session), [ctype](https://secure.php.net/ctype), et [PDO_MySQL](https://secure.php.net/pdo-mysql) ou [PDO_SQLite](https://secure.php.net/pdo-sqlite) ou [PDO_PGSQL](https://secure.php.net/pdo-pgsql) * Recommandés : [JSON](https://secure.php.net/json), [GMP](https://secure.php.net/gmp) (pour accès API sur plateformes < 64 bits), [IDN](https://secure.php.net/intl.idn) (pour les noms de domaines internationalisés), [mbstring](https://secure.php.net/mbstring) (pour le texte Unicode), [iconv](https://secure.php.net/iconv) (pour conversion d’encodages), [ZIP](https://secure.php.net/zip) (pour import/export), [zlib](https://secure.php.net/zlib) (pour les flux compressés) * MySQL 5.5.3+ (recommandé) ou équivalent MariaDB, ou SQLite 3.7.4+, ou PostgreSQL 9.2+ @@ -219,7 +219,6 @@ Tout client supportant une API de type Fever ; Sélection : * [bcrypt.js](https://github.com/dcodeIO/bcrypt.js) * [phpQuery](https://github.com/phpquery/phpquery) * [Services_JSON](https://pear.php.net/pepr/pepr-proposal-show.php?id=198) -* [password_compat](https://github.com/ircmaxell/password_compat) diff --git a/README.md b/README.md index e1660a9d1..6123ae903 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ FreshRSS comes with absolutely no warranty. * Light server running Linux or Windows * It even works on Raspberry Pi 1 with response time under a second (tested with 150 feeds, 22k articles) * A web server: Apache2 (recommended), nginx, lighttpd (not tested on others) -* PHP 5.3.8+ (PHP 5.4+ recommended, and PHP 5.5+ for performance, or PHP 7 for even higher performance) +* PHP 5.5+ (PHP 7+ recommended for higher performance) * Required extensions: [cURL](https://secure.php.net/curl), [DOM](https://secure.php.net/dom), [XML](https://secure.php.net/xml), [session](https://secure.php.net/session), [ctype](https://secure.php.net/ctype), and [PDO_MySQL](https://secure.php.net/pdo-mysql) or [PDO_SQLite](https://secure.php.net/pdo-sqlite) or [PDO_PGSQL](https://secure.php.net/pdo-pgsql) * Recommended extensions: [JSON](https://secure.php.net/json), [GMP](https://secure.php.net/gmp) (for API access on 32-bit platforms), [IDN](https://secure.php.net/intl.idn) (for Internationalized Domain Names), [mbstring](https://secure.php.net/mbstring) (for Unicode strings), [iconv](https://secure.php.net/iconv) (for charset conversion), [ZIP](https://secure.php.net/zip) (for import/export), [zlib](https://secure.php.net/zlib) (for compressed feeds) * MySQL 5.5.3+ (recommended) or MariaDB equivalent, or SQLite 3.7.4+, or PostgreSQL 9.2+ @@ -219,7 +219,6 @@ Supported clients are: * [bcrypt.js](https://github.com/dcodeIO/bcrypt.js) * [phpQuery](https://github.com/phpquery/phpquery) * [Services_JSON](https://pear.php.net/pepr/pepr-proposal-show.php?id=198) -* [password_compat](https://github.com/ircmaxell/password_compat) [travis-badge]:https://travis-ci.org/FreshRSS/FreshRSS.svg?branch=master [travis-link]:https://travis-ci.org/FreshRSS/FreshRSS diff --git a/app/Controllers/authController.php b/app/Controllers/authController.php index ca44b1a96..e06a26399 100644 --- a/app/Controllers/authController.php +++ b/app/Controllers/authController.php @@ -169,10 +169,6 @@ class FreshRSS_auth_Controller extends Minz_ActionController { return; } - if (!function_exists('password_verify')) { - include_once(LIB_PATH . '/password_compat.php'); - } - $s = $conf->passwordHash; $ok = password_verify($password, $s); unset($password); diff --git a/app/Controllers/userController.php b/app/Controllers/userController.php index bf9084930..c1c27a4ab 100644 --- a/app/Controllers/userController.php +++ b/app/Controllers/userController.php @@ -9,9 +9,6 @@ class FreshRSS_user_Controller extends Minz_ActionController { const BCRYPT_COST = 9; public static function hashPassword($passwordPlain) { - if (!function_exists('password_hash')) { - include_once(LIB_PATH . '/password_compat.php'); - } $passwordHash = password_hash($passwordPlain, PASSWORD_BCRYPT, array('cost' => self::BCRYPT_COST)); $passwordPlain = ''; $passwordHash = preg_replace('/^\$2[xy]\$/', '\$2a\$', $passwordHash); //Compatibility with bcrypt.js diff --git a/app/Models/Auth.php b/app/Models/Auth.php index 6d079a01f..b7fb0e6d6 100644 --- a/app/Models/Auth.php +++ b/app/Models/Auth.php @@ -219,10 +219,6 @@ class FreshRSS_FormAuth { return false; } - if (!function_exists('password_verify')) { - include_once(LIB_PATH . '/password_compat.php'); - } - return password_verify($nonce . $hash, $challenge); } @@ -283,8 +279,7 @@ class FreshRSS_FormAuth { $cookie_duration = empty($limits['cookie_duration']) ? 2592000 : $limits['cookie_duration']; $oldest = time() - $cookie_duration; foreach (new DirectoryIterator(DATA_PATH . '/tokens/') as $file_info) { - // $extension = $file_info->getExtension(); doesn't work in PHP < 5.3.7 - $extension = pathinfo($file_info->getFilename(), PATHINFO_EXTENSION); + $extension = $file_info->getExtension(); if ($extension === 'txt' && $file_info->getMTime() < $oldest) { @unlink($file_info->getPathname()); } diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php index f2cfa044f..44a3b4cce 100644 --- a/app/Models/EntryDAO.php +++ b/app/Models/EntryDAO.php @@ -191,7 +191,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable { if ($this->hasNativeHex()) { $this->addEntryPrepared->bindParam(':hash', $valuesTmp['hash']); } else { - $valuesTmp['hashBin'] = pack('H*', $valuesTmp['hash']); //hex2bin() is PHP5.4+ + $valuesTmp['hashBin'] = hex2bin($valuesTmp['hash']); $this->addEntryPrepared->bindParam(':hash', $valuesTmp['hashBin']); } } @@ -273,7 +273,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable { if ($this->hasNativeHex()) { $this->updateEntryPrepared->bindParam(':hash', $valuesTmp['hash']); } else { - $valuesTmp['hashBin'] = pack('H*', $valuesTmp['hash']); //hex2bin() is PHP5.4+ + $valuesTmp['hashBin'] = hex2bin($valuesTmp['hash']); $this->updateEntryPrepared->bindParam(':hash', $valuesTmp['hashBin']); } diff --git a/app/i18n/en/gen.php b/app/i18n/en/gen.php index 733290c7c..655b02402 100644 --- a/app/i18n/en/gen.php +++ b/app/i18n/en/gen.php @@ -127,6 +127,7 @@ return array( 'oc' => 'Occitan', 'pt-br' => 'Português (Brasil)', 'ru' => 'Русский', + 'sk' => 'Slovenčina', 'tr' => 'Türkçe', 'zh-cn' => '简体中文', ), diff --git a/app/i18n/nl/feedback.php b/app/i18n/nl/feedback.php index 25378360b..97e1a71b8 100644 --- a/app/i18n/nl/feedback.php +++ b/app/i18n/nl/feedback.php @@ -75,7 +75,7 @@ return array( ), 'feed' => array( 'actualized' => '%s vernieuwd', - 'actualizeds' => 'RSS feeds vernieuwd', + 'actualizeds' => 'RSS-feeds vernieuwd', 'added' => 'RSS feed %s toegevoegd', 'already_subscribed' => 'Al geabonneerd op %s', 'deleted' => 'Feed verwijderd', diff --git a/app/i18n/nl/gen.php b/app/i18n/nl/gen.php index c7c97d1e0..57d68d673 100644 --- a/app/i18n/nl/gen.php +++ b/app/i18n/nl/gen.php @@ -161,23 +161,8 @@ return array( 'previous' => 'Vorige', ), 'share' => array( - 'blogotext' => 'Blogotext', - 'diaspora' => 'Diaspora*', 'email' => 'Email', - 'facebook' => 'Facebook', - 'gnusocial' => 'GNU social', - 'jdh' => 'Journal du hacker', - 'Known' => 'Known based sites', - 'linkedin' => 'LinkedIn', - 'mastodon' => 'Mastodon', - 'movim' => 'Movim', - 'pinboard' => 'Pinboard', - 'pocket' => 'Pocket', - 'print' => 'Print', - 'shaarli' => 'Shaarli', - 'twitter' => 'Twitter', - 'wallabag' => 'wallabag v1', - 'wallabagv2' => 'wallabag v2', + 'Known' => 'Known-gebaseerde sites', ), 'short' => array( 'attention' => 'Attentie!', diff --git a/app/i18n/nl/index.php b/app/i18n/nl/index.php index d202b812a..5f71a180f 100644 --- a/app/i18n/nl/index.php +++ b/app/i18n/nl/index.php @@ -7,10 +7,10 @@ return array( 'bugs_reports' => 'Rapporteer fouten', 'credits' => 'Waarderingen', 'credits_content' => 'Sommige ontwerp elementen komen van Bootstrap alhoewel FreshRSS dit raamwerk niet gebruikt. Pictogrammen komen van het GNOME project. De Open Sans font police is gemaakt door Steve Matteson. FreshRSS is gebaseerd op Minz, een PHP raamwerk. Nederlandse vertaling door Wanabo, NieuwsKop.be. Link naar de Nederlandse vertaling, FreshRSS-Dutch-translation.', - 'freshrss_description' => 'FreshRSS is een RSS feed aggregator om zelf te hosten zoals Kriss Feed of Leed. Het gebruikt weinig systeembronnen en is makkelijk te administreren terwijl het een krachtig en makkelijk te configureren programma is.', + 'freshrss_description' => 'FreshRSS is een RSS-feed aggregator om zelf te hosten, net als Kriss Feed of Leed. Het gebruikt weinig systeembronnen en is makkelijk te beheren terwijl het een krachtig en makkelijk te configureren programma is.', 'github' => 'op Github', - 'license' => 'License', - 'project_website' => 'Project website', + 'license' => 'Licentie', + 'project_website' => 'Projectwebsite', 'title' => 'Over', 'version' => 'Versie', 'website' => 'Website', @@ -18,8 +18,8 @@ return array( 'feed' => array( 'add' => 'U kunt wat feeds toevoegen.', 'empty' => 'Er is geen artikel om te laten zien.', - 'rss_of' => 'RSS feed van %s', - 'title' => 'Overzicht RSS feeds', + 'rss_of' => 'RSS-feed van %s', + 'title' => 'Overzicht RSS-feeds', 'title_global' => 'Globale weergave', 'title_fav' => 'Uw favorieten', ), @@ -48,7 +48,7 @@ return array( 'queries' => 'Gebruikers queries', 'read' => 'Laat alleen gelezen zien', 'reader_view' => 'Lees modus', - 'rss_view' => 'RSS feed', + 'rss_view' => 'RSS-feed', 'search_short' => 'Zoeken', 'starred' => 'Laat alleen favorieten zien', 'stats' => 'Statistieken', diff --git a/app/i18n/nl/sub.php b/app/i18n/nl/sub.php index b59515f42..8ceb5aa28 100644 --- a/app/i18n/nl/sub.php +++ b/app/i18n/nl/sub.php @@ -19,25 +19,25 @@ return array( 'title' => 'Titel', ), 'feed' => array( - 'add' => 'Voeg een RSS feed toe', + 'add' => 'Voeg een RSS-feed toe', 'advanced' => 'Geavanceerd', 'archiving' => 'Archiveren', 'auth' => array( 'configuration' => 'Log in', - 'help' => 'Verbinding toestaan toegang te krijgen tot HTTP beveiligde RSS feeds', + 'help' => 'Verbinding toestaan toegang te krijgen tot HTTP beveiligde RSS-feeds', 'http' => 'HTTP Authenticatie', 'password' => 'HTTP wachtwoord', 'username' => 'HTTP gebruikers naam', ), 'clear_cache' => 'Cache altijd leegmaken', - 'css_help' => 'Haalt verstoorde RSS feeds op (attentie, heeft meer tijd nodig!)', - 'css_path' => 'Artikelen CSS pad op originele website', + 'css_help' => 'Haalt onvolledige RSS-feeds op (attentie, heeft meer tijd nodig!)', + 'css_path' => 'CSS-pad van artikelen op originele website', 'description' => 'Omschrijving', 'empty' => 'Deze feed is leeg. Controleer of deze nog actueel is.', 'error' => 'Deze feed heeft problemen. Verifieer a.u.b het doeladres en actualiseer het.', 'filteractions' => array( - '_' => 'Filter actions', //TODO - Translation - 'help' => 'Write one search filter per line.', //TODO - Translation + '_' => 'Filteracties', + 'help' => 'Voer één zoekfilter per lijn in.', ), 'information' => 'Informatie', 'keep_history' => 'Minimum aantal artikelen om te houden', @@ -64,11 +64,11 @@ return array( 'think_to_add' => 'Voeg wat feeds toe.', 'timeout' => 'Time-out in seconden', 'title' => 'Titel', - 'title_add' => 'Voeg een RSS feed toe', + 'title_add' => 'Voeg een RSS-feed toe', 'ttl' => 'Vernieuw automatisch niet vaker dan', - 'url' => 'Feed URL', + 'url' => 'Feed-url', 'validator' => 'Controleer de geldigheid van de feed', - 'website' => 'Website URL', + 'website' => 'Website-url', ), 'firefox' => array( 'documentation' => 'Volg de stappen die hier beschreven worden om FreshRSS aan de Firefox-nieuwslezerlijst toe te voegen.', diff --git a/app/i18n/sk/admin.php b/app/i18n/sk/admin.php new file mode 100644 index 000000000..347204f37 --- /dev/null +++ b/app/i18n/sk/admin.php @@ -0,0 +1,199 @@ + array( + 'allow_anonymous' => 'Povoliť čítanie článkov prednastaveného používateľa (%s) bez prihlásenia.', + 'allow_anonymous_refresh' => 'Povoliť obnovenie článkov bez prihlásenia', + 'api_enabled' => 'Povoliť prístup cez API (vyžadujú mobilné aplikácie)', + 'form' => 'Webový formulár (traditičný, vyžaduje JavaScript)', + 'http' => 'HTTP (pre pokročilých používateľov s HTTPS)', + 'none' => 'Žiadny (nebezpečné)', + 'title' => 'Prihlásenie', + 'title_reset' => 'Reset prihlásenia', + 'token' => 'Token prihlásenia', + 'token_help' => 'Povoliť prístup k výstupu RSS prednastaveného používateľa bez prihlásenia:', + 'type' => 'Spôsob prihlásenia', + 'unsafe_autologin' => 'Povoliť nebezpečné automatické prihlásenie pomocou webového formulára: ', + ), + 'check_install' => array( + 'cache' => array( + 'nok' => 'Overte prístupové práva priečinka ./data/cache. HTTP server musí mať právo doň zapisovať.', + 'ok' => 'Prístupové práva priečinka pre vyrovnávaciu pamäť sú OK.', + ), + 'categories' => array( + 'nok' => 'Tabuľka kategórií je nesprávne nastavená.', + 'ok' => 'Tabuľka kategórií je OK.', + ), + 'connection' => array( + 'nok' => 'Nepodarilo sa vytvoriť pripojenie k databáze.', + 'ok' => 'Pripojenie k databáze je OK.', + ), + 'ctype' => array( + 'nok' => 'Nepodarilo sa nájsť požadovanú knižnicu na kontrolu typu znakov (php-ctype).', + 'ok' => 'Našla sa požadovaná knižnica na kontrolu typu znakov (ctype).', + ), + 'curl' => array( + 'nok' => 'Nepodarilo sa nájsť knižnicu cURL (balík php-curl).', + 'ok' => 'Našla sa knižnica cURL.', + ), + 'data' => array( + 'nok' => 'Skontrolujte oprávnenia prístupu do priečinku ./data. HTTP server musí mať právo doň zapisovať.', + 'ok' => 'Oprávnenia prístupu do priečinku údajov sú OK.', + ), + 'database' => 'Inštalácia databázy', + 'dom' => array( + 'nok' => 'Nepodarilo sa nájsť požadovanú knižnicu na prehliadanie DOM.', + 'ok' => 'Našla sa požadovaná knižnica na prehliadanie DOM.', + ), + 'entries' => array( + 'nok' => 'Tabuľka článkov je nesprávne nastavená.', + 'ok' => 'Tabuľka článkov je OK.', + ), + 'favicons' => array( + 'nok' => 'Skontrolujte oprávnenia prístupu do priečinku ./data/favicons. HTTP server musí mať právo doň zapisovať.', + 'ok' => 'Oprávnenia prístupu do priečinku ikôn obľúbených sú OK.', + ), + 'feeds' => array( + 'nok' => 'Tabuľka kanálov je nesprávne nastavená.', + 'ok' => 'Tabuľka kanálov je OK.', + ), + 'fileinfo' => array( + 'nok' => 'Nepodarilo sa nájsť knižniuc PHP fileinfo (balík fileinfo).', + 'ok' => 'Našla sa knižnica fileinfo.', + ), + 'files' => 'Inštalácia súborov', + 'json' => array( + 'nok' => 'Nepodarilo sa nájsť požadovanú knižnicu na spracovanie formátu JSON.', + 'ok' => 'Našla sa požadovaná knižnica na spracovanie formátu JSON.', + ), + 'mbstring' => array( + 'nok' => 'Nepodarilo sa nájsť požadovanú knižnicu mbstring pre Unicode.', + 'ok' => 'Našla sa požadovaná knižnica mbstring pre Unicode.', + ), + 'minz' => array( + 'nok' => 'Nepodarilo sa nájsť framework Minz.', + 'ok' => 'Našiel sa framework Minz.', + ), + 'pcre' => array( + 'nok' => 'Nepodarilo sa nájsť požadovanú knižnicu pre regulárne výrazy (php-pcre).', + 'ok' => 'Našla sa požadovaná knižnica pre regulárne výrazy (PCRE).', + ), + 'pdo' => array( + 'nok' => 'Nepodarilo sa nájsť PDO alebo niektorý z podporovaných ovládačov (pdo_mysql, pdo_sqlite, pdo_pgsql).', + 'ok' => 'Našiel sa PDO a aspoň jeden z podporovaných ovládačov (pdo_mysql, pdo_sqlite, pdo_pgsql).', + ), + 'php' => array( + '_' => 'Inštalácia PHP', + 'nok' => 'Vaša verzia PHP je %s, ale FreshRSS vyžaduje minimálne verziu %s.', + 'ok' => 'Vaša verzia PHP %s je kompatibilná s FreshRSS.', + ), + 'tables' => array( + 'nok' => 'V databáze chýba jedna alebo viacero tabuliek.', + 'ok' => 'V databáze sa nachádzajú všetky potrebné tabuľky.', + ), + 'title' => 'Kontrola inštalácie', + 'tokens' => array( + 'nok' => 'Skontrolujte oprávnenia prístupu do priečinku ./data/tokens. HTTP server musí mať právo doň zapisovať.', + 'ok' => 'Oprávnenia prístupu do priečinku tokens sú OK.', + ), + 'users' => array( + 'nok' => 'Skontrolujte oprávnenia prístupu do priečinku ./data/users. HTTP server musí mať právo doň zapisovať.', + 'ok' => 'Oprávnenia prístupu do priečinku používateľov sú OK.', + ), + 'zip' => array( + 'nok' => 'Nepodarilo sa nájsť rozšírenie ZIP (balík php-zip).', + 'ok' => 'Rozšírenie ZIP sa našlo.', + ), + ), + 'extensions' => array( + 'author' => 'Autor', + 'community' => 'Rozšírenia od komunity', + 'description' => 'Popis', + 'disabled' => 'Zakázané', + 'empty_list' => 'Žiadne nainštalované rozšírenia', + 'enabled' => 'Povolené', + 'latest' => 'Nainštalované', + 'name' => 'Názov', + 'no_configure_view' => 'Toto rozšírenie nemá nastavenia.', + 'system' => array( + '_' => 'Systémové rozšírenia', + 'no_rights' => 'Systémové rozšírenie (nemáte oprávnenia)', + ), + 'title' => 'Rozšírenia', + 'update' => 'Sú dostupné aktualizácie', + 'user' => 'Používateľské rozšírenia', + 'version' => 'Verzia', + ), + 'stats' => array( + '_' => 'Štatistiky', + 'all_feeds' => 'Všetky kanály', + 'category' => 'Kategória', + 'entry_count' => 'Počet položiek', + 'entry_per_category' => 'Položiek v kategórii', + 'entry_per_day' => 'Položiek za deň (posledných 30 dní)', + 'entry_per_day_of_week' => 'Za deň v týždni (priemer: %.2f správy)', + 'entry_per_hour' => 'Za hodinu (priemer: %.2f správy)', + 'entry_per_month' => 'Za mesiac (priemer: %.2f správy)', + 'entry_repartition' => 'Rozdelenie článkov', + 'feed' => 'Kanál', + 'feed_per_category' => 'Kanálov v kategórii', + 'idle' => 'Neaktívne kanály', + 'main' => 'Hlavné štatistiky', + 'main_stream' => 'Všetky kanály', + 'menu' => array( + 'idle' => 'Neaktívne kanály', + 'main' => 'Hlavné štatistiky', + 'repartition' => 'Rozdelenie článkov', + ), + 'no_idle' => 'Žiadne neaktívne kanály!', + 'number_entries' => 'Počet článkov: %d', + 'percent_of_total' => 'Z celkového počtu: %%', + 'repartition' => 'Rozdelenie článkov', + 'status_favorites' => 'Obľúbené', + 'status_read' => 'Prečítané', + 'status_total' => 'Spolu', + 'status_unread' => 'Neprečítané', + 'title' => 'Štatistiky', + 'top_feed' => 'Top 10 kanálov', + ), + 'system' => array( + '_' => 'Nastavenia systému', + 'auto-update-url' => 'Odkaz na aktualizačný server', + 'instance-name' => 'Názov inštancie', + 'max-categories' => 'Limit počtu kategórií pre používateľa', + 'max-feeds' => 'Limit počtu kanálov pre používateľov', + 'cookie-duration' => array( + 'help' => 'v sekundách', + 'number' => 'Dobra, počas ktorej ste prihlásený', + ), + 'registration' => array( + 'help' => '0 znamená žiadny limit počtu účtov', + 'number' => 'Maximálny počt účtov', + ), + ), + 'update' => array( + '_' => 'Aktualizácia systému', + 'apply' => 'Použiť', + 'check' => 'Skontrolovať aktualizácie', + 'current_version' => 'Vaša aktuálna verzia FreshRSS: %s', + 'last' => 'Posledná kontrola: %s', + 'none' => 'Žiadna nová aktualizácia', + 'title' => 'Aktualizácia systému', + ), + 'user' => array( + 'articles_and_size' => '%s článkov (%s)', + 'create' => 'Vytvoriť nového používateľa', + 'delete_users' => 'Zmazať používateľa', + 'language' => 'Jazyk', + 'number' => 'Je vytvorený používateľ: %d', + 'numbers' => 'Je vytvorených používateľov: %d', + 'password_form' => 'Heslo
(pre spôsob prihlásenia cez webový formulár)', + 'password_format' => 'Minimálne 7 znakov', + 'selected' => 'Označený používateľ', + 'title' => 'Správa používateľov', + 'update_users' => 'Sktualizovať používateľov', + 'user_list' => 'Zoznam používateľov', + 'username' => 'Používateľské meno', + 'users' => 'Používatelia', + ), +); diff --git a/app/i18n/sk/conf.php b/app/i18n/sk/conf.php new file mode 100644 index 000000000..f704fd4be --- /dev/null +++ b/app/i18n/sk/conf.php @@ -0,0 +1,188 @@ + array( + '_' => 'Archivovanie', + 'advanced' => 'Pokročilé', + 'delete_after' => 'Vymazať články po', + 'help' => 'Viac možností nájdete v nastaveniach kanála', + 'keep_history_by_feed' => 'Minimálny počet článkov kanála na zachovanie', + 'optimize' => 'Optimalizovať databázu', + 'optimize_help' => 'Občas vykonajte na zmenšenie veľkosti databázy', + 'purge_now' => 'Vyčistiť teraz', + 'title' => 'Archivovanie', + 'ttl' => 'Neaktualizovať častejšie ako', + ), + 'display' => array( + '_' => 'Zobrazenie', + 'icon' => array( + 'bottom_line' => 'Spodný riadok', + 'display_authors' => 'Autori', + 'entry' => 'Ikony článku', + 'publication_date' => 'Dátum zverejnenia', + 'related_tags' => 'Značky článku', + 'sharing' => 'Zdieľanie', + 'top_line' => 'Horný riadok', + ), + 'language' => 'Jazyk', + 'notif_html5' => array( + 'seconds' => 'sekundy (0 znamená bez limitu)', + 'timeout' => 'Limit HTML5 oznámenia', + ), + 'show_nav_buttons' => 'Zobraziť tlačidlá oznámenia', + 'theme' => 'Vzhľad', + 'title' => 'Zobraziť', + 'width' => array( + 'content' => 'Šírka obsahu', + 'large' => 'Veľká', + 'medium' => 'Stredná', + 'no_limit' => 'Bez obmedzenia', + 'thin' => 'Úzka', + ), + ), + 'profile' => array( + '_' => 'Správca profilu', + 'delete' => array( + '_' => 'Vymazanie účtu', + 'warn' => 'Váš účet a všetky údaje v ňom budú vymazané.', + ), + 'password_api' => 'Heslo API
(pre mobilné aplikácie)', + 'password_form' => 'Heslo
(pre spôsob prihlásenia cez webový formulár)', + 'password_format' => 'Najmenej 7 znakov', + 'title' => 'Profil', + ), + 'query' => array( + '_' => 'Dopyty používateľa', + 'deprecated' => 'Tento dopyt už nie je platný. Kategória alebo kanál boli vymazané.', + 'display' => 'Zobraziť výsledky dopytu používateľa', + 'filter' => 'Použitý filter:', + 'get_all' => 'Zobraziť všetky články', + 'get_category' => 'Zobraziť kategóriu "%s"', + 'get_favorite' => 'Zobraziť obľúbené články', + 'get_feed' => 'Zobraziť kanál "%s"', + 'no_filter' => 'Žiadny filter', + 'none' => 'Zatiaľ ste nevytvorili používateľský dopyt.', + 'number' => 'Dopyt číslo %d', + 'order_asc' => 'Zobraziť staršie články hore', + 'order_desc' => 'Zobraziť novšie články hore', + 'remove' => 'Vymazať dopyt používateľa', + 'search' => 'Vyhľadáva sa: "%s"', + 'state_0' => 'Zobraziť všetky články', + 'state_1' => 'Zobraziť prečítané články', + 'state_2' => 'Zobraziť neprečítané články', + 'state_3' => 'Zobraziť všetky články', + 'state_4' => 'Zobraziť obľúbené články', + 'state_5' => 'Zobraziť prečítané obľúbené články', + 'state_6' => 'Zobraziť neprečítané obľúbené články', + 'state_7' => 'Zobraziť obľúbené články', + 'state_8' => 'Zobraziť neobľúbené články', + 'state_9' => 'Zobraziť prečítané neobľúbené články', + 'state_10' => 'Zobraziť neprečítané neobľúbené články', + 'state_11' => 'Zobraziť neobľúbené články', + 'state_12' => 'Zobraziť všetky články', + 'state_13' => 'Zobraziť prečítané články', + 'state_14' => 'Zobraziť neprečítané články', + 'state_15' => 'Zobraziť všetky články', + 'title' => 'Používateľské dopyty', + ), + 'reading' => array( + '_' => 'Čítanie', + 'after_onread' => 'Po “Označiť všetko ako prečítané”,', + 'articles_per_page' => 'Počet článkov na jednu stranu', + 'auto_load_more' => 'Načítať ďalšie články dolu na stránke', + 'auto_remove_article' => 'Skryť články po prečítaní', + 'confirm_enabled' => 'Zobraziť potvrdzovací dialóg po kliknutí na “Označiť všetko ako prečítané”', + 'display_articles_unfolded' => 'Zobraziť články otvorené', + 'display_categories_unfolded' => 'Zobraziť kategórie otvorené', + 'hide_read_feeds' => 'Skryť kategórie a kanály s nulovým počtom neprečítaných článkov (nefunguje s nastaveným “Zobraziť všetky články”)', + 'img_with_lazyload' => 'Pre načítanie obrázkov použiť "lazy load"', + 'jump_next' => 'skočiť na ďalší neprečítaný (kanál ale kategóriu)', + 'mark_updated_article_unread' => 'Označiť aktualizované články ako neprečítané', + 'number_divided_when_reader' => 'V režime čítania predeliť na dve časti.', + 'read' => array( + 'article_open_on_website' => 'keď je článok otvorený na svojej webovej stránke', + 'article_viewed' => 'keď je článok zobrazený', + 'scroll' => 'počas skrolovania', + 'upon_reception' => 'po načítaní článku', + 'when' => 'Označiť článok ako prečítaný…', + ), + 'show' => array( + '_' => 'Článkov na zobrazenie', + 'adaptive' => 'Vyberte zobrazenie', + 'all_articles' => 'Zobraziť všetky články', + 'unread' => 'Zobraziť iba neprečítané', + ), + 'sides_close_article' => 'Po kliknutí mimo textu článku sa článok zatvorí', + 'sort' => array( + '_' => 'Poradie', + 'newer_first' => 'Novšie hore', + 'older_first' => 'Staršie hore', + ), + 'sticky_post' => 'Po otvorení posunúť článok hore', + 'title' => 'Čítanie', + 'view' => array( + 'default' => 'Prednastavené zobrazenie', + 'global' => 'Prehľadné zobrazenie', + 'normal' => 'Základné zobrazenie', + 'reader' => 'Zobrazenie na čítanie', + ), + ), + 'sharing' => array( + '_' => 'Zdieľanie', + 'add' => 'Pridať spôsob zdieľania', + 'blogotext' => 'Blogotext', + 'diaspora' => 'Diaspora*', + 'email' => 'E-mail', + 'facebook' => 'Facebook', + 'g+' => 'Google+', + 'more_information' => 'Viac informácií', + 'print' => 'Tlač', + 'remove' => 'Odstrániť spôsob zdieľania', + 'shaarli' => 'Shaarli', + 'share_name' => 'Meno pre zobrazenie', + 'share_url' => 'Zdieľaný odkaz', + 'title' => 'Zdieľanie', + 'twitter' => 'Twitter', + 'wallabag' => 'wallabag', + ), + 'shortcut' => array( + '_' => 'Skratky', + 'article_action' => 'Akcie článku', + 'auto_share' => 'Zdieľať', + 'auto_share_help' => 'Ak je nastavený iba jeden spôsob zdieľania, použije sa. Inak si spôsoby zdieľania vyberá používateľ podľa čísla.', + 'close_dropdown' => 'Zavrie menu', + 'collapse_article' => 'Zroluje článok', + 'first_article' => 'Otvorí prvý článok', + 'focus_search' => 'Vyhľadávanie', + 'global_view' => 'Prepne do prehľadného zobrazenia', + 'help' => 'Zobrazí dokumentáciu', + 'javascript' => 'JavaScript musí byť povolený, ak chcete používať skratky', + 'last_article' => 'Otvorí posledný článok', + 'load_more' => 'Načíta viac článkov', + 'mark_favorite' => 'O(d)značí ako obľúbené', + 'mark_read' => 'O(d)značí ako prečítané', + 'navigation' => 'Navigácia', + 'navigation_help' => 'Po stlačení skratky s klávesou "Shift", sa skratky navigácie vzťahujú na kanály.
Po stlačení skratky s klávesou "Alt", sa skratky navigácie vzťahujú na kategórie.', + 'navigation_no_mod_help' => 'Tieto skratky navigácie nepodporujú klávesy "Shift" a "Alt".', + 'next_article' => 'Otvorí ďalší článok', + 'normal_view' => 'Prepne do základného zobrazenia', + 'other_action' => 'Ostatné akcie', + 'previous_article' => 'Otvorí predošlý článok', + 'reading_view' => 'Prepne do zobrazenia na čítanie', + 'rss_view' => 'Otvorí zobrazenie RSS v novej záložke', + 'see_on_website' => 'Zobrazí na webovej stránke', + 'shift_for_all_read' => '+ shift na označenie všetkých článkov ako prečítaných', + 'skip_next_article' => 'Prejde na ďalší bez otvorenia', + 'skip_previous_article' => 'Prejde na predošlý bez otvorenia', + 'title' => 'Skratky', + 'user_filter' => 'Použiť používateľské filtre', + 'user_filter_help' => 'Ak je nastavený iba jeden spôsob zdieľania, použije sa. Inak si spôsoby zdieľania vyberá používateľ podľa čísla.', + 'views' => 'Zobrazenia', + ), + 'user' => array( + 'articles_and_size' => '%s článkov (%s)', + 'current' => 'Aktuálny používateľ', + 'is_admin' => 'je administrátor', + 'users' => 'Používatelia', + ), +); diff --git a/app/i18n/sk/feedback.php b/app/i18n/sk/feedback.php new file mode 100644 index 000000000..9aee79068 --- /dev/null +++ b/app/i18n/sk/feedback.php @@ -0,0 +1,116 @@ + array( + 'optimization_complete' => 'Optimalizácia dokončená', + ), + 'access' => array( + 'denied' => 'Na prístup k tejto stránke nemáte oprávnenie', + 'not_found' => 'Hľadáte stránku, ktorá neexistuje', + ), + 'auth' => array( + 'form' => array( + 'not_set' => 'Nastavl problém pri nastavovaní prihlasovacieho systému. Prosím, skúste to znova neskôr.', + 'set' => 'Webový formulár je teraz váš prednastavený prihlasovací spôsob.', + ), + 'login' => array( + 'invalid' => 'Nesprávne prihlasovacie údaje', + 'success' => 'Úspešne ste sa prihlásili', + ), + 'logout' => array( + 'success' => 'Boli ste odhlásený', + ), + 'no_password_set' => 'Heslo administrátora nebolo nastavené. Táto funkcia nie je dostupná.', + ), + 'conf' => array( + 'error' => 'Vyskytla sa chyba počas ukladania nastavaní', + 'query_created' => 'Dopyt "%s" bol vytvorený.', + 'shortcuts_updated' => 'Skratky boli aktualizované', + 'updated' => 'Nastavenia boli aktualizované', + ), + 'extensions' => array( + 'already_enabled' => '%s už je povolené', + 'disable' => array( + 'ko' => '%s sa nepodarilo nainštalovať. Prečítajte si záznamy FreshRSS, ak chcete poznať podrobnosti.', + 'ok' => '%s je teraz zakázaný', + ), + 'enable' => array( + 'ko' => '%s sa nepodarilo povoliť. Prečítajte si záznamy FreshRSS, ak chcete poznať podrobnosti.', + 'ok' => '%s je teraz povolený', + ), + 'no_access' => 'Nemáte prístup k %s', + 'not_enabled' => '%s nie je povolený', + 'not_found' => '%s neexistuje', + ), + 'import_export' => array( + 'export_no_zip_extension' => 'ZIP rozšírenie sa na vašom serveri nenachádza. Prosím, skúste exportovať súbory pojednom.', + 'feeds_imported' => 'Váš kanál bol importovaný a bude aktualizovaný', + 'feeds_imported_with_errors' => 'Vaše kanály boli importované, ale vyskytli sa chyby', + 'file_cannot_be_uploaded' => 'Súbor sa nepodarilo nahrať!', + 'no_zip_extension' => 'ZIP rozšírenie sa na vašom serveri nenachádza.', + 'zip_error' => 'Počas importovania ZIP sa vyskytla chyba.', + ), + 'profile' => array( + 'error' => 'Váš profil nie je možné upraviť', + 'updated' => 'Váš profil bol upravený', + ), + 'sub' => array( + 'actualize' => 'Aktualizácia', + 'articles' => array( + 'marked_read' => 'Vybraté články boli označené ako prečítané.', + 'marked_unread' => 'Články boli označené ako neprečítané.', + ), + 'category' => array( + 'created' => 'Kategória %s bola vytvorená.', + 'deleted' => 'Kategória bola odstránená.', + 'emptied' => 'Kategória bola vyprázdnená', + 'error' => 'Nepodarilo sa aktualizovať kategóriu', + 'name_exists' => 'Názov kategórie už existuje.', + 'no_id' => 'Musíte zadať ID kategórie.', + 'no_name' => 'Názov kategórie nemôže byť prázdny.', + 'not_delete_default' => 'Nemôžete odstrániť prednastavenú kategóriu!', + 'not_exist' => 'Kategória neexistuje!', + 'over_max' => 'Dosiahli ste limit počtu kategórií (%d)', + 'updated' => 'Kategória bola aktualizovaná.', + ), + 'feed' => array( + 'actualized' => '%s bol aktualizovaný', + 'actualizeds' => 'RSS kanál bol aktualizovaný', + 'added' => 'RSS kanál %s bol pridaný', + 'already_subscribed' => 'Tento RSS kanál už odoberáte: %s', + 'deleted' => 'Kanál bol vymazaný', + 'error' => 'Kanál sa nepodarilo aktualizovať', + 'internal_problem' => 'Kanál sa nepodarilo pridať. Prečítajte si záznamy FreshRSS, ak chcete poznať podrobnosti. Skúste pridať kanál pomocou #force_feed v odkaze (URL).', + 'invalid_url' => 'Odkaz %s je neplatný', + 'n_actualized' => 'Počet aktualizovaných kanálov: %d', + 'n_entries_deleted' => 'Počet vymazaných článkov: %d', + 'no_refresh' => 'Žiadny kanál sa neaktualizoval…', + 'not_added' => 'Kanál %s sa nepodarilo pridať', + 'over_max' => 'Dosiahli ste limit počtu kanálov (%d)', + 'updated' => 'Kanál bol aktualizovaný', + ), + 'purge_completed' => 'Čistenie ukončené. Počet vymazaných článkov: %d', + ), + 'update' => array( + 'can_apply' => 'FreshRSS sa teraz aktualizuje na verziu %s.', + 'error' => 'Počas aktualizácie sa vyskytla chyba: %s', + 'file_is_nok' => 'Je dostupná nová verzia %s, ale skontrolujte prístupové práva priečinka %s. HTTP server musí mať právo doň zapisovať.', + 'finished' => 'Aktualizácia prebehla úspešne!', + 'none' => 'Žiadne aktualizácie', + 'server_not_found' => 'Nepodarilo sa nájsť server s aktualizáciami. [%s]', + ), + 'user' => array( + 'created' => array( + '_' => 'Používateľ %s bol vytvorený', + 'error' => 'Používateľ %s nebol vytvorený', + ), + 'deleted' => array( + '_' => 'Používateľ %s bol vymazaný', + 'error' => 'Používateľ %s nebol vymazaný', + ), + 'updated' => array( + '_' => 'Používateľ %s bol aktualizovaný', + 'error' => 'Používateľ %s nebol aktualizovaný', + ), + ), +); diff --git a/app/i18n/sk/gen.php b/app/i18n/sk/gen.php new file mode 100644 index 000000000..00a03736e --- /dev/null +++ b/app/i18n/sk/gen.php @@ -0,0 +1,180 @@ + array( + 'actualize' => 'Aktualizovať', + 'back_to_rss_feeds' => '← Späť na vaše RSS kanály', + 'cancel' => 'Zrušiť', + 'create' => 'Vytvoriť', + 'disable' => 'Zakázať', + 'empty' => 'Vyprázdniť', + 'enable' => 'Povoliť', + 'export' => 'Exportovať', + 'filter' => 'Filtrovať', + 'import' => 'Importovať', + 'manage' => 'Spravovať', + 'mark_favorite' => 'Označiť ako obľúbené', + 'mark_read' => 'Označiť ako prečítané', + 'remove' => 'Odstrániť', + 'see_website' => 'Zobraziť webovú stránku', + 'submit' => 'Poslať', + 'truncate' => 'Vymazať všetky články', + 'update' => 'Aktualizovať', + ), + 'auth' => array( + 'email' => 'E-mailová adresa', + 'keep_logged_in' => 'Zostať prihlásený (počet dní: %s)', + 'login' => 'Prihlásiť', + 'logout' => 'Odhlásiť', + 'password' => array( + '_' => 'Heslo', + 'format' => 'Najmenej 7 znakov', + ), + 'registration' => array( + '_' => 'Nový účet', + 'ask' => 'Vytvoriť účet?', + 'title' => 'Vytvorenie účtu', + ), + 'reset' => 'Reset prihlásenia', + 'username' => array( + '_' => 'Používateľské meno', + 'admin' => 'Administrátorské používateľské meno', + 'format' => 'maximálne 16 alfanumerických znakov', + ), + ), + 'date' => array( + 'Apr' => '\\A\\p\\r\\í\\l', + 'apr' => 'Apr.', + 'april' => 'Apríl', + 'Aug' => '\\A\\u\\g\\u\\s\\t', + 'aug' => 'Aug.', + 'august' => 'August', + 'before_yesterday' => 'Predvčerom', + 'Dec' => '\\D\\e\\c\\e\\m\\b\\e\\r', + 'dec' => 'Dec.', + 'december' => 'December', + 'Feb' => '\\F\\e\\b\\r\\u\\á\\r', + 'feb' => 'Feb.', + 'february' => 'Február', + 'format_date' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y', + 'format_date_hour' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y \\a\\t H\\:i', + 'fri' => 'Pi', + 'Jan' => '\\J\\a\\n\\u\\á\\r', + 'jan' => 'Jan.', + 'january' => 'Január', + 'Jul' => '\\J\\ú\\l', + 'jul' => 'Júl', + 'july' => 'Júl', + 'Jun' => '\\J\\ú\\n', + 'jun' => 'Jún', + 'june' => 'Jún', + 'last_3_month' => 'Posledné 3 mesiace', + 'last_6_month' => 'Posledných 6 mesiacov', + 'last_month' => 'Posledný mesiac', + 'last_week' => 'Posledný týždeň', + 'last_year' => 'Posledný rok', + 'Mar' => '\\M\\a\\r\\e\\c', + 'mar' => 'Mar.', + 'march' => 'Marec', + 'May' => '\\M\\á\\j', + 'may' => 'Máj', + 'may_' => 'Máj', + 'mon' => 'Po', + 'month' => 'mesiace', + 'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r', + 'nov' => 'Nov.', + 'november' => 'November', + 'Oct' => '\\O\\k\\t\\ó\\b\\e\\r', + 'oct' => 'Okt.', + 'october' => 'Október', + 'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r', + 'sat' => 'So', + 'sep' => 'Sept.', + 'september' => 'September', + 'sun' => 'Ne', + 'thu' => 'Št', + 'today' => 'Dnes', + 'tue' => 'Ut', + 'wed' => 'St', + 'yesterday' => 'Včera', + ), + 'freshrss' => array( + '_' => 'FreshRSS', + 'about' => 'O FreshRSS', + ), + 'js' => array( + 'category_empty' => 'Prázdna kategória', + 'confirm_action' => 'Určite chcete vykonať túto akciu? Zmeny budú nezvratné!', + 'confirm_action_feed_cat' => 'Určite chcete vykonať túto akciu? Prídete o súvisiace obľúbené a používateľské dopyty. Zmeny budú nezvratné!', + 'feedback' => array( + 'body_new_articles' => 'Počet nových článkov v čítačke FreshRSS: %%d', + 'request_failed' => 'Nepodarilo sa spracovať váš dopyt, pravdepodobne kvôli problému s pripojením do internetu.', + 'title_new_articles' => 'FreshRSS: nové články!', + ), + 'new_article' => 'Našli sa nové články. Kliknite na obnovenie stránky.', + 'should_be_activated' => 'Musíte povoliť JavaScript', + ), + 'menu' => array( + 'about' => 'O FreshRSS', + 'admin' => 'Administrácia', + 'archiving' => 'Archivácia', + 'authentication' => 'Prihlásenie', + 'check_install' => 'Kontroloa inštalácie', + 'configuration' => 'Nastavenia', + 'display' => 'Zobrazenie', + 'extensions' => 'Rozšírenia', + 'logs' => 'Záznamy', + 'queries' => 'Používateľské dopyty', + 'reading' => 'Čítanie', + 'search' => 'Hľadajte slová alebo #značky', + 'sharing' => 'Zdieľanie', + 'shortcuts' => 'Skratky', + 'stats' => 'Štatistiky', + 'system' => 'Nastavenie systému', + 'update' => 'Aktualizácia', + 'user_management' => 'Spravovať používateľov', + 'user_profile' => 'Profil', + ), + 'pagination' => array( + 'first' => 'Prvý', + 'last' => 'Posledný', + 'load_more' => 'Načítať viac článkov', + 'mark_all_read' => 'Označiť všetko prečítané', + 'next' => 'Ďalší', + 'nothing_to_load' => 'Žiadne nové články', + 'previous' => 'Predošlý', + ), + 'share' => array( + 'blogotext' => 'Blogotext', + 'diaspora' => 'Diaspora*', + 'email' => 'E-mail', + 'facebook' => 'Facebook', + 'g+' => 'Google+', + 'gnusocial' => 'GNU social', + 'jdh' => 'Journal du hacker', + 'Known' => 'Stránky založené na Known', + 'linkedin' => 'LinkedIn', + 'mastodon' => 'Mastodon', + 'movim' => 'Movim', + 'pinboard' => 'Pinboard', + 'pocket' => 'Pocket', + 'print' => 'Print', + 'shaarli' => 'Shaarli', + 'twitter' => 'Twitter', + 'wallabag' => 'wallabag v1', + 'wallabagv2' => 'wallabag v2', + ), + 'short' => array( + 'attention' => 'Upozornenie!', + 'blank_to_disable' => 'Ak chcete zakázať, ponechajte prázdne', + 'by_author' => 'Od:', + 'by_default' => 'Prednastavené', + 'damn' => 'Sakra!', + 'default_category' => 'Bez kategórie', + 'no' => 'Nie', + 'not_applicable' => 'Nie je k dispozícii', + 'ok' => 'OK', + 'or' => 'alebo', + 'yes' => 'Áno', + ), +); diff --git a/app/i18n/sk/index.php b/app/i18n/sk/index.php new file mode 100644 index 000000000..19e63e720 --- /dev/null +++ b/app/i18n/sk/index.php @@ -0,0 +1,63 @@ + array( + '_' => 'O FreshRSS', + 'agpl3' => 'AGPL 3', + 'bugs_reports' => 'Nahlásiť chybu', + 'credits' => 'Poďakovanie', + 'credits_content' => 'Niektoré časti vzhľadu pochádzajú z Bootstrapu, aj keď FreshRSS tento framework nepoužíva. Ikony sú z GNOME project. Font Open Sans zabezpečil Steve Matteson. FreshRSS je založený na PHP frameworku Minz.', + 'freshrss_description' => 'FreshRSS je čítačka RSS kanálov, ktorú môžete nasadiť na vlastný server podobne ako Kriss Feed alebo Leed. Ide o jednoduchý a zároveň dobre nastaviteľný nástroj.', + 'github' => 'na Githube', + 'license' => 'Licencia', + 'project_website' => 'Webová stránka projektu', + 'title' => 'O FreshRSS', + 'version' => 'Verzia', + 'website' => 'Webová stránka', + ), + 'feed' => array( + 'add' => 'Môžete pridať kanály.', + 'empty' => 'Žiadne články.', + 'rss_of' => 'RSS kanál pre %s', + 'title' => 'Vaše RSS kanály', + 'title_global' => 'Prehľad', + 'title_fav' => 'Vaše obľúbené', + ), + 'log' => array( + '_' => 'Záznamy', + 'clear' => 'Vymazať záznamy', + 'empty' => 'Súbor záznamu je prázdny', + 'title' => 'Záznamy', + ), + 'menu' => array( + 'about' => 'O FreshRSS', + 'add_query' => 'Vytvoriť dopyt', + 'before_one_day' => 'Pred 1 dňom', + 'before_one_week' => 'Pred 1 týždňom', + 'favorites' => 'Obľúbené (%s)', + 'global_view' => 'Prehľad', + 'main_stream' => 'Všetky kanály', + 'mark_all_read' => 'Označiť všetko ako prečítané', + 'mark_cat_read' => 'Označiť kategóriu ako prečítanú', + 'mark_feed_read' => 'Označiť kanál ako prečítaný', + 'mark_selection_unread' => 'Označiť označené ako prečítané', + 'newer_first' => 'Novšie hore', + 'non-starred' => 'Zobraziť všetko okrem obľúbených', + 'normal_view' => 'Základné zobrazenie', + 'older_first' => 'Staršie hore', + 'queries' => 'Používateľské dopyty', + 'read' => 'Zobraziť prečítané', + 'reader_view' => 'Zobrazenie na čítanie', + 'rss_view' => 'RSS kanál', + 'search_short' => 'Hľadať', + 'starred' => 'Zobraziť obľúbené', + 'stats' => 'Štatistiky', + 'subscription' => 'Správca odberov', + 'tags' => 'Moje nálepky', + 'unread' => 'Zobraziť neprečítané', + ), + 'share' => 'Zdieľať', + 'tag' => array( + 'related' => 'Značky článku', + ), +); diff --git a/app/i18n/sk/install.php b/app/i18n/sk/install.php new file mode 100644 index 000000000..08fbfeef9 --- /dev/null +++ b/app/i18n/sk/install.php @@ -0,0 +1,123 @@ + array( + 'finish' => 'Dokončiť inštaláciu', + 'fix_errors_before' => 'Prosím, pred pokračovaním opravte chyby.', + 'keep_install' => 'Použiť predošlé nastavenia', + 'next_step' => 'Ďalší krok', + 'reinstall' => 'Preinštalovať FreshRSS', + ), + 'auth' => array( + 'form' => 'Webový formulár (tradičný, vyžaduje JavaScript)', + 'http' => 'HTTP (pre pokročilých používateľov s HTTPS)', + 'none' => 'Žiadny (nebezpečné)', + 'password_form' => 'Heslo
(pre prihlásenie cez webový formulár)', + 'password_format' => 'Najmenej 7 znakov', + 'type' => 'Spôsob prihlásenia', + ), + 'bdd' => array( + '_' => 'Databáza', + 'conf' => array( + '_' => 'Nastavenia databázy', + 'ko' => 'Skontrolovať vaše informácie o databáze.', + 'ok' => 'Nastavenia databázy boli uložené.', + ), + 'host' => 'Server', + 'password' => 'Heslo databázy', + 'prefix' => 'Predpona názvu tabuľky', + 'type' => 'Druh databázy', + 'username' => 'Používateľské meno databázy', + ), + 'check' => array( + '_' => 'Kontrola', + 'already_installed' => 'Zistilo sa, že FreshRSS je už nainštalovaný!', + 'cache' => array( + 'nok' => 'Skontrolujte oprávnenia prístupu do priečinku ./data/cache. HTTP server musí mať právo doň zapisovať.', + 'ok' => 'Oprávnenia prístupu do priečinku vyrovnávacej pamäte sú OK.', + ), + 'ctype' => array( + 'nok' => 'Nepodarilo sa nájsť požadovanú knižnicu na kontrolu typu znakov (php-ctype).', + 'ok' => 'Našla sa požadovaná knižnica na kontrolu typu znakov (ctype).', + ), + 'curl' => array( + 'nok' => 'Nepodarilo sa nájsť knižnicu cURL (balík php-curl).', + 'ok' => 'Našla sa knižnica cURL.', + ), + 'data' => array( + 'nok' => 'Skontrolujte oprávnenia prístupu do priečinku ./data. HTTP server musí mať právo doň zapisovať.', + 'ok' => 'Oprávnenia prístupu do priečinku údajov sú OK.', + ), + 'dom' => array( + 'nok' => 'Nepodarilo sa nájsť požadovanú knižnicu na prehliadanie DOM.', + 'ok' => 'Našla sa požadovaná knižnica na prehliadanie DOM.', + ), + 'favicons' => array( + 'nok' => 'Skontrolujte oprávnenia prístupu do priečinku ./data/favicons. HTTP server musí mať právo doň zapisovať.', + 'ok' => 'Oprávnenia prístupu do priečinku ikôn obľúbených sú OK.', + ), + 'fileinfo' => array( + 'nok' => 'Nepodarilo sa nájsť knižniuc PHP fileinfo (balík fileinfo).', + 'ok' => 'Našla sa knižnica fileinfo.', + ), + 'http_referer' => array( + 'nok' => 'Prosím, skontrolujte, či ste nezmenili váš HTTP REFERER.', + 'ok' => 'Váš HTTP REFERER je OK.', + ), + 'json' => array( + 'nok' => 'Nepodarilo sa nájsť požadovanú knižnicu na spracovanie formátu JSON.', + 'ok' => 'Našla sa požadovaná knižnica na spracovanie formátu JSON.', + ), + 'mbstring' => array( + 'nok' => 'Nepodarilo sa nájsť požadovanú knižnicu mbstring pre Unicode.', + 'ok' => 'Našla sa požadovaná knižnica mbstring pre Unicode.', + ), + 'minz' => array( + 'nok' => 'Nepodarilo sa nájsť framework Minz.', + 'ok' => 'Našiel sa framework Minz.', + ), + 'pcre' => array( + 'nok' => 'Nepodarilo sa nájsť požadovanú knižnicu pre regulárne výrazy (php-pcre).', + 'ok' => 'Našla sa požadovaná knižnica pre regulárne výrazy (PCRE).', + ), + 'pdo' => array( + 'nok' => 'Nepodarilo sa nájsť PDO alebo niektorý z podporovaných ovládačov (pdo_mysql, pdo_sqlite, pdo_pgsql).', + 'ok' => 'Našiel sa PDO a aspoň jeden z podporovaných ovládačov (pdo_mysql, pdo_sqlite, pdo_pgsql).', + ), + 'php' => array( + 'nok' => 'Vaša verzia PHP je %s, ale FreshRSS vyžaduje minimálne verziu %s.', + 'ok' => 'Vaša verzia PHP %s je kompatibilná s FreshRSS.', + ), + 'users' => array( + 'nok' => 'Skontrolujte oprávnenia prístupu do priečinku ./data/users. HTTP server musí mať právo doň zapisovať.', + 'ok' => 'Oprávnenia prístupu do priečinku používateľov sú OK.', + ), + 'xml' => array( + 'nok' => 'Nepodarilo sa nájsť požadovanú knižnicu na spracovanie formátu XML.', + 'ok' => 'Našla sa požadovaná knižnica na spracovanie formátu XML.', + ), + ), + 'conf' => array( + '_' => 'Hlavné nastavenia', + 'ok' => 'Hlavné nastavenia boli uložené.', + ), + 'congratulations' => 'Nastavenia!', + 'default_user' => 'Hlavné používateľské meno (najviac 16 alfanumerických znakov)', + 'delete_articles_after' => 'Vymazať články po', + 'fix_errors_before' => 'Prosím, pred pokračovaním opravte chyby.', + 'javascript_is_better' => 'FreshRSS si užijete viac, keď povolíte JavaScript', + 'js' => array( + 'confirm_reinstall' => 'Ak budete pokračovať v preinštalovaní FreshRSS, stratíte vaše predošlé nastavenia. Naozaj chcete pokračovať?', + ), + 'language' => array( + '_' => 'Jazyk', + 'choose' => 'Vyberte jazyk pre FreshRSS', + 'defined' => 'Jazyk bol nastavený.', + ), + 'not_deleted' => 'Niečo sa nepodarilo. Musíte ručne zmazať súbor %s.', + 'ok' => 'Inštalácia bola úspešná.', + 'step' => 'krok %d', + 'steps' => 'Kroky', + 'title' => 'Inštalácia · FreshRSS', + 'this_is_the_end' => 'Toto je koniec', +); diff --git a/app/i18n/sk/sub.php b/app/i18n/sk/sub.php new file mode 100644 index 000000000..4dcd09f57 --- /dev/null +++ b/app/i18n/sk/sub.php @@ -0,0 +1,100 @@ + array( + 'documentation' => 'Skopírujte tento odkaz a použite ho v inom programe.', + 'title' => 'API', + ), + 'bookmarklet' => array( + 'documentation' => 'Presunte toto tlačidlo do vašich záložiek, alebo kliknite pravým a zvoľte "Uložiť odkaz do záložiek". Potom kliknite na tlačidlo "Odoberať" na ktorejkoľvek stránke, ktorú chcete odoberať.', + 'label' => 'Odoberať', + 'title' => 'Záložka', + ), + 'category' => array( + '_' => 'Kategória', + 'add' => 'Pridať kategóriu', + 'empty' => 'Prázdna kategória', + 'information' => 'Informácia', + 'new' => 'Nová kategória', + 'title' => 'Názov', + ), + 'feed' => array( + 'add' => 'Pridať RSS kanál', + 'advanced' => 'Pokročilé', + 'archiving' => 'Archivovanie', + 'auth' => array( + 'configuration' => 'Prihlásenie', + 'help' => 'Povoliť prístup do kanálov chránených cez HTTP.', + 'http' => 'Prihlásenie cez HTTP', + 'password' => 'Heslo pre HTTP', + 'username' => 'Používateľské meno pre HTTP', + ), + 'clear_cache' => 'Vždy vymazať vyrovnávaciu pamäť', + 'css_help' => 'Stiahnuť skrátenú verziu RSS kanála (pozor, vyžaduje viac času!)', + 'css_path' => 'Pôvodný CSS súbor článku z webovej stránky', + 'description' => 'Popis', + 'empty' => 'Tento kanál je prázdny. Overte, prosím, či je ešte spravovaný autorom.', + 'error' => 'Vyskytol sa problém s týmto kanálom. Overte, prosím, či kanál stále existuje, potom ho obnovte.', + 'filteractions' => array( + '_' => 'Filtrovať akcie', + 'help' => 'Napíšte jeden výraz hľadania na riadok.', + ), + 'information' => 'Informácia', + 'keep_history' => 'Minimálny počet článkov na uchovanie', + 'moved_category_deleted' => 'Keď vymažete kategóriu, jej kanály sa automaticky zaradia pod %s.', + 'mute' => 'stíšiť', + 'no_selected' => 'Nevybrali ste kanál.', + 'number_entries' => 'Počet článkov: %d', + 'priority' => array( + '_' => 'Viditeľnosť', + 'archived' => 'Nezobrazovať (archivované)', + 'main_stream' => 'Zobraziť v prehľade kanálov', + 'normal' => 'Zobraziť vo svojej kategórii', + ), + 'websub' => 'Okamžité oznámenia cez WebSub', + 'show' => array( + 'all' => 'Zobraziť všetky kanály', + 'error' => 'Zobraziť iba kanály s chybou', + ), + 'showing' => array( + 'error' => 'Zobraziť iba kanály s chybou', + ), + 'ssl_verify' => 'Overiť bezpečnosť SSL', + 'stats' => 'Štatistiky', + 'think_to_add' => 'Mali by ste pridať kanály.', + 'timeout' => 'Doba platnosti dá v sekundách', + 'title' => 'Nadpis', + 'title_add' => 'Pridať kanál RSS', + 'ttl' => 'Automaticky neaktualizovať častejšie ako', + 'url' => 'Odkaz kanála', + 'validator' => 'Skontrolovať platnosť kanála', + 'website' => 'Odkaz webovej stránky', + ), + 'firefox' => array( + 'documentation' => 'Pridajte RSS kanály do Firefoxu pomocou tohto návodu.', + 'title' => 'RSS čítačka vo Firefoxe', + ), + 'import_export' => array( + 'export' => 'Exportovať', + 'export_opml' => 'Exportovať zoznam kanálov (OPML)', + 'export_starred' => 'Exportovať vaše obľúbené', + 'export_labelled' => 'Exportovať vaše označené články', + 'feed_list' => 'Zoznam článkov %s', + 'file_to_import' => 'Súbor na import
(OPML, JSON alebo ZIP)', + 'file_to_import_no_zip' => 'Súbor na import
(OPML alebo JSON)', + 'import' => 'Importovať', + 'starred_list' => 'Zoznam obľúbených článkov', + 'title' => 'Import / export', + ), + 'menu' => array( + 'bookmark' => 'Odoberať (záložka FreshRSS)', + 'import_export' => 'Import / export', + 'subscription_management' => 'Správa odoberaných kanálov', + 'subscription_tools' => 'Nástroje na odoberanie kanálov', + ), + 'title' => array( + '_' => 'Správa odoberaných kanálov', + 'feed_management' => 'Správa RSS kanálov', + 'subscription_tools' => 'Nástroje na odoberanie kanálov', + ), +); diff --git a/app/install.php b/app/install.php index 961a7c171..a4d1d0af9 100644 --- a/app/install.php +++ b/app/install.php @@ -61,7 +61,7 @@ function initTranslate() { } function get_best_language() { - $accept = $_SERVER['HTTP_ACCEPT_LANGUAGE']; + $accept = empty($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? '' : $_SERVER['HTTP_ACCEPT_LANGUAGE']; return strtolower(substr($accept, 0, 2)); } @@ -413,7 +413,7 @@ function printStep1() {

-

+

diff --git a/app/views/helpers/export/articles.phtml b/app/views/helpers/export/articles.phtml index 2d1fcd133..0bbfb86ec 100644 --- a/app/views/helpers/export/articles.phtml +++ b/app/views/helpers/export/articles.phtml @@ -1,10 +1,7 @@ = 0) { - $options = JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE; -} +$options = JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE; $articles = array( 'id' => 'user/' . str_replace('/', '', $username) . '/state/org.freshrss/' . $this->type, diff --git a/app/views/update/checkInstall.phtml b/app/views/update/checkInstall.phtml index 33d78cbe7..e719e53dd 100644 --- a/app/views/update/checkInstall.phtml +++ b/app/views/update/checkInstall.phtml @@ -9,7 +9,7 @@

Required (32-bit only): GMP
Recommanded: JSON, Zlib, mbstring, iconv, ZipArchive
*For the whole modules list see [Dockerfile](https://github.com/FreshRSS/FreshRSS/blob/744a9e8cf00aef7dec0acfa5f90f0dcfa2ef8837/Docker/Dockerfile-Alpine#L7-L9)* | | +| PHP | **PHP 7+** | PHP 5.5+ | +| PHP modules | Required: libxml, cURL, PDO_MySQL, PCRE and ctype.
Required (32-bit only): GMP
Recommanded: JSON, Zlib, mbstring, iconv, ZipArchive
*For the whole modules list see [Dockerfile](https://github.com/FreshRSS/FreshRSS/blob/master/Docker/Dockerfile-Alpine#L7-L9)* | | | Database | **MySQL 5.5.3+** | SQLite 3.7.4+ | | Browser | **Firefox** | Chrome, Opera, Safari, or IE11+ | -## Important notice - -FreshRSS **CAN** work with PHP 5.3.8+. To do so, we are using specific functions available in the [''password_compat'' library](https://github.com/ircmaxell/password_compat#requirements) for the form authentication. - # Getting the appropriate version of FreshRSS diff --git a/docs/en/developers/01_First_steps.md b/docs/en/developers/01_First_steps.md index adca4495b..fef27cb39 100644 --- a/docs/en/developers/01_First_steps.md +++ b/docs/en/developers/01_First_steps.md @@ -148,26 +148,9 @@ abstract class ClassName {} Files must be encoded with UTF-8 character set. -## PHP 5.3 compatibility +## PHP compatibility -Do not get an array item directly from a function or a method. Use a variable. - -```php -// code with PHP 5.3 compatibility -$my_variable = function_returning_an_array(); -echo $my_variable[0]; -// code without PHP 5.3 compatibility -echo function_returning_an_array()[0]; -``` - -Do not use short array declaration. - -```php -// code with PHP 5.3 compatibility -$variable = array(); -// code without PHP 5.3 compatibility -$variable = []; -``` +Ensure that your code is working with a PHP version as old as what FreshRSS officially supports. ## Miscellaneous diff --git a/docs/en/users/06_Mobile_access.md b/docs/en/users/06_Mobile_access.md index 13dba828d..be4d0ded2 100644 --- a/docs/en/users/06_Mobile_access.md +++ b/docs/en/users/06_Mobile_access.md @@ -29,7 +29,7 @@ See the [page about the Fever compatible API](06_Fever_API.md) for another possi * If you get *Service Unavailable!*, then check from step 1 again. * With __Apache__: * If you get *FAIL getallheaders!*, the combination of your PHP version and your Web server does not provide access to [`getallheaders`](http://php.net/getallheaders) - * Update to PHP 5.4+, or use PHP as module instead of CGI. Otherwise turn on Apache `mod_setenvif` (often enabled by default), or `mod_rewrite` with the following procedure: + * Turn on Apache `mod_setenvif` (often enabled by default), or `mod_rewrite` with the following procedure: * Allow [`FileInfo` in `.htaccess`](http://httpd.apache.org/docs/trunk/mod/core.html#allowoverride): see the [server setup](../admins/02_Installation.md) again. * Enable [`mod_rewrite`](http://httpd.apache.org/docs/trunk/mod/mod_rewrite.html): * With Debian / Ubuntu: `sudo a2enmod rewrite` diff --git a/docs/fr/developers/01_First_steps.md b/docs/fr/developers/01_First_steps.md index d2bf9d315..dd38bcb3f 100644 --- a/docs/fr/developers/01_First_steps.md +++ b/docs/fr/developers/01_First_steps.md @@ -148,26 +148,9 @@ abstract class NomDeLaClasse {} Les fichiers doivent être encodés en UTF-8. -## Compatibilité avec PHP 5.3 +## Compatibilité PHP -Il ne faut pas demander l'indice d'un tableau qui est retourné par une fonction ou une méthode. Il faut passer par une variable intermédiaire. - -```php -// code compatible avec PHP 5.3 -$ma_variable = fonction_qui_retourne_un_tableau(); -echo $ma_variable[0]; -// code incompatible avec PHP 5.3 -echo fonction_qui_retourne_un_tableau()[0]; -``` - -Il ne faut pas utiliser la déclaration raccourcie des tableaux. - -```php -// code compatible avec PHP 5.3 -$variable = array(); -// code incompatible avec PHP 5.3 -$variable = []; -``` +Assurez-vous que votre code fonctionne avec une version de PHP aussi ancienne que celle que FreshRSS supporte officiellement. ## Divers diff --git a/docs/fr/users/01_Installation.md b/docs/fr/users/01_Installation.md index a6495d2fd..f90d52c54 100644 --- a/docs/fr/users/01_Installation.md +++ b/docs/fr/users/01_Installation.md @@ -7,15 +7,11 @@ Il est toutefois de votre responsabilité de vérifier que votre hébergement pe | Logiciel | Recommandé | Fonctionne aussi avec | | -------- | ----------- | --------------------- | | Serveur web | **Apache 2** | Nginx | - | PHP | **PHP 5.5+** | PHP 5.3.8+ | - | Modules PHP | Requis : libxml, cURL, PDO_MySQL, PCRE et ctype
Requis (32 bits seulement) : GMP
Recommandé : JSON, Zlib, mbstring et iconv, ZipArchive
*Pour une liste complète des modules nécessaires voir le [Dockerfile](https://github.com/FreshRSS/FreshRSS/blob/744a9e8cf00aef7dec0acfa5f90f0dcfa2ef8837/Docker/Dockerfile-Alpine#L7-L9)* | | + | PHP | **PHP 7+** | PHP 5.5+ | + | Modules PHP | Requis : libxml, cURL, PDO_MySQL, PCRE et ctype
Requis (32 bits seulement) : GMP
Recommandé : JSON, Zlib, mbstring et iconv, ZipArchive
*Pour une liste complète des modules nécessaires voir le [Dockerfile](https://github.com/FreshRSS/FreshRSS/blob/master/Docker/Dockerfile-Alpine#L7-L9)* | | | Base de données | **MySQL 5.5.3+** | SQLite 3.7.4+ | | Navigateur | **Firefox** | Chrome, Opera, Safari, or IE 11+ | -## Note importante - -FreshRSS **PEUT** fonctionner sur la version de PHP 5.3.8+. En effet, nous utilisons des fonctions spécifiques pour la connexion par formulaire et notamment la [bibliothèque ''password_compat''](https://github.com/ircmaxell/password_compat#requirements). - # Choisir la bonne version de FreshRSS FreshRSS possède trois versions différentes (nous parlons de branches) qui sortent à des fréquences plus ou moins rapides. Aussi prenez le temps de comprendre à quoi correspond chacune de ces versions. diff --git a/docs/fr/users/06_Mobile_access.md b/docs/fr/users/06_Mobile_access.md index 7bce9eea3..225c55c7c 100644 --- a/docs/fr/users/06_Mobile_access.md +++ b/docs/fr/users/06_Mobile_access.md @@ -29,7 +29,7 @@ Voir la [page sur l’API compatible Fever](06_Fever_API.md) pour une autre poss * Si vous obtenez *Service Unavailable!*, retourner à l’étape 6. * Avec __Apache__: * Si vous obtenez *FAIL getallheaders!*, alors la combinaison de votre version de PHP et de votre serveur Web ne permet pas l’accès à [`getallheaders`](http://php.net/getallheaders) - * Utilisez au moins PHP 5.4+, ou utilisez PHP en tant que module plutôt que CGI. Sinon, activer Apache `mod_setenvif` (souvent activé par défault), ou `mod_rewrite` avec la procédure suivante : + * Activer Apache `mod_setenvif` (souvent activé par défault), ou `mod_rewrite` avec la procédure suivante : * Autoriser [`FileInfo` dans `.htaccess`](http://httpd.apache.org/docs/trunk/mod/core.html#allowoverride) : revoir [l’installation du serveur](01_Installation.md). * Activer [`mod_rewrite`](http://httpd.apache.org/docs/trunk/mod/mod_rewrite.html) : * Sur Debian / Ubuntu : `sudo a2enmod rewrite` diff --git a/lib/Minz/Configuration.php b/lib/Minz/Configuration.php index aae3accc6..93f6b494c 100644 --- a/lib/Minz/Configuration.php +++ b/lib/Minz/Configuration.php @@ -198,7 +198,7 @@ class Minz_Configuration { return false; } - // Clear PHP 5.5+ cache for include + // Clear PHP cache for include if (function_exists('opcache_invalidate')) { opcache_invalidate($this->config_filename); } diff --git a/lib/Minz/FrontController.php b/lib/Minz/FrontController.php index 066278b7c..e09b022fc 100644 --- a/lib/Minz/FrontController.php +++ b/lib/Minz/FrontController.php @@ -115,21 +115,26 @@ class Minz_FrontController { } private function setReporting() { - $conf = Minz_Configuration::get('system'); - switch($conf->environment) { - case 'production': - error_reporting(E_ALL); - ini_set('display_errors', 'Off'); - ini_set('log_errors', 'On'); - break; - case 'development': - error_reporting(E_ALL); - ini_set('display_errors', 'On'); - ini_set('log_errors', 'On'); - break; - case 'silent': - error_reporting(0); - break; + $envType = getenv('FRESHRSS_ENV'); + if ($envType == '') { + $conf = Minz_Configuration::get('system'); + $envType = $conf->environment; + } + switch ($envType) { + case 'development': + error_reporting(E_ALL); + ini_set('display_errors', 'On'); + ini_set('log_errors', 'On'); + break; + case 'silent': + error_reporting(0); + break; + case 'production': + default: + error_reporting(E_ALL); + ini_set('display_errors', 'Off'); + ini_set('log_errors', 'On'); + break; } } } diff --git a/lib/Minz/ModelArray.php b/lib/Minz/ModelArray.php index 1ac2b313d..4938f4b1d 100644 --- a/lib/Minz/ModelArray.php +++ b/lib/Minz/ModelArray.php @@ -48,7 +48,7 @@ class Minz_ModelArray { throw new Minz_PermissionDeniedException($this->filename); } if (function_exists('opcache_invalidate')) { - opcache_invalidate($this->filename); //Clear PHP 5.5+ cache for include + opcache_invalidate($this->filename); //Clear PHP cache for include } return true; } diff --git a/lib/Minz/ModelPdo.php b/lib/Minz/ModelPdo.php index bf226842a..9aa4d90d6 100644 --- a/lib/Minz/ModelPdo.php +++ b/lib/Minz/ModelPdo.php @@ -111,7 +111,7 @@ class Minz_ModelPdo { $this->bd->beginTransaction(); } public function inTransaction() { - return $this->bd->inTransaction(); //requires PHP >= 5.3.3 + return $this->bd->inTransaction(); } public function commit() { $this->bd->commit(); diff --git a/lib/lib_install.php b/lib/lib_install.php index 6e4df4e9c..6b9b33240 100644 --- a/lib/lib_install.php +++ b/lib/lib_install.php @@ -6,7 +6,7 @@ Minz_Configuration::register('default_system', join_path(FRESHRSS_PATH, 'config. Minz_Configuration::register('default_user', join_path(FRESHRSS_PATH, 'config-user.default.php')); function checkRequirements($dbType = '') { - $php = version_compare(PHP_VERSION, '5.3.8') >= 0; + $php = version_compare(PHP_VERSION, '5.5.0') >= 0; $minz = file_exists(join_path(LIB_PATH, 'Minz')); $curl = extension_loaded('curl'); $pdo_mysql = extension_loaded('pdo_mysql'); diff --git a/lib/lib_rss.php b/lib/lib_rss.php index c0ea23989..2706ff606 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -1,9 +1,9 @@ = 0) { - $htmlEntitiesOnly = array_flip(array_diff( - get_html_translation_table(HTML_ENTITIES, ENT_NOQUOTES, 'UTF-8'), //Decode HTML entities - get_html_translation_table(HTML_SPECIALCHARS, ENT_NOQUOTES, 'UTF-8') //Preserve XML entities - )); - } else { - $htmlEntitiesOnly = array_map('utf8_encode', array_flip(array_diff( - get_html_translation_table(HTML_ENTITIES, ENT_NOQUOTES), //Decode HTML entities - get_html_translation_table(HTML_SPECIALCHARS, ENT_NOQUOTES) //Preserve XML entities - ))); - } + $htmlEntitiesOnly = array_flip(array_diff( + get_html_translation_table(HTML_ENTITIES, ENT_NOQUOTES, 'UTF-8'), //Decode HTML entities + get_html_translation_table(HTML_SPECIALCHARS, ENT_NOQUOTES, 'UTF-8') //Preserve XML entities + )); } return strtr($text, $htmlEntitiesOnly); } @@ -428,7 +414,7 @@ function check_install_php() { $pdo_pgsql = extension_loaded('pdo_pgsql'); $pdo_sqlite = extension_loaded('pdo_sqlite'); return array( - 'php' => version_compare(PHP_VERSION, '5.3.8') >= 0, + 'php' => version_compare(PHP_VERSION, '5.5.0') >= 0, 'minz' => file_exists(LIB_PATH . '/Minz'), 'curl' => extension_loaded('curl'), 'pdo' => $pdo_mysql || $pdo_sqlite || $pdo_pgsql, diff --git a/lib/password_compat.php b/lib/password_compat.php deleted file mode 100644 index e8ec02885..000000000 --- a/lib/password_compat.php +++ /dev/null @@ -1,279 +0,0 @@ - - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @copyright 2012 The Authors - */ - -namespace { - -if (!defined('PASSWORD_DEFAULT')) { - - define('PASSWORD_BCRYPT', 1); - define('PASSWORD_DEFAULT', PASSWORD_BCRYPT); - - /** - * Hash the password using the specified algorithm - * - * @param string $password The password to hash - * @param int $algo The algorithm to use (Defined by PASSWORD_* constants) - * @param array $options The options for the algorithm to use - * - * @return string|false The hashed password, or false on error. - */ - function password_hash($password, $algo, array $options = array()) { - if (!function_exists('crypt')) { - trigger_error("Crypt must be loaded for password_hash to function", E_USER_WARNING); - return null; - } - if (!is_string($password)) { - trigger_error("password_hash(): Password must be a string", E_USER_WARNING); - return null; - } - if (!is_int($algo)) { - trigger_error("password_hash() expects parameter 2 to be long, " . gettype($algo) . " given", E_USER_WARNING); - return null; - } - $resultLength = 0; - switch ($algo) { - case PASSWORD_BCRYPT: - // Note that this is a C constant, but not exposed to PHP, so we don't define it here. - $cost = 10; - if (isset($options['cost'])) { - $cost = $options['cost']; - if ($cost < 4 || $cost > 31) { - trigger_error(sprintf("password_hash(): Invalid bcrypt cost parameter specified: %d", $cost), E_USER_WARNING); - return null; - } - } - // The length of salt to generate - $raw_salt_len = 16; - // The length required in the final serialization - $required_salt_len = 22; - $hash_format = sprintf("$2y$%02d$", $cost); - // The expected length of the final crypt() output - $resultLength = 60; - break; - default: - trigger_error(sprintf("password_hash(): Unknown password hashing algorithm: %s", $algo), E_USER_WARNING); - return null; - } - $salt_requires_encoding = false; - if (isset($options['salt'])) { - switch (gettype($options['salt'])) { - case 'NULL': - case 'boolean': - case 'integer': - case 'double': - case 'string': - $salt = (string) $options['salt']; - break; - case 'object': - if (method_exists($options['salt'], '__tostring')) { - $salt = (string) $options['salt']; - break; - } - case 'array': - case 'resource': - default: - trigger_error('password_hash(): Non-string salt parameter supplied', E_USER_WARNING); - return null; - } - if (PasswordCompat\binary\_strlen($salt) < $required_salt_len) { - trigger_error(sprintf("password_hash(): Provided salt is too short: %d expecting %d", PasswordCompat\binary\_strlen($salt), $required_salt_len), E_USER_WARNING); - return null; - } elseif (0 == preg_match('#^[a-zA-Z0-9./]+$#D', $salt)) { - $salt_requires_encoding = true; - } - } else { - $buffer = ''; - $buffer_valid = false; - if (function_exists('mcrypt_create_iv') && !defined('PHALANGER')) { - $buffer = mcrypt_create_iv($raw_salt_len, MCRYPT_DEV_URANDOM); - if ($buffer) { - $buffer_valid = true; - } - } - if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) { - $buffer = openssl_random_pseudo_bytes($raw_salt_len); - if ($buffer) { - $buffer_valid = true; - } - } - if (!$buffer_valid && @is_readable('/dev/urandom')) { - $f = fopen('/dev/urandom', 'r'); - $read = PasswordCompat\binary\_strlen($buffer); - while ($read < $raw_salt_len) { - $buffer .= fread($f, $raw_salt_len - $read); - $read = PasswordCompat\binary\_strlen($buffer); - } - fclose($f); - if ($read >= $raw_salt_len) { - $buffer_valid = true; - } - } - if (!$buffer_valid || PasswordCompat\binary\_strlen($buffer) < $raw_salt_len) { - $bl = PasswordCompat\binary\_strlen($buffer); - for ($i = 0; $i < $raw_salt_len; $i++) { - if ($i < $bl) { - $buffer[$i] = $buffer[$i] ^ chr(mt_rand(0, 255)); - } else { - $buffer .= chr(mt_rand(0, 255)); - } - } - } - $salt = $buffer; - $salt_requires_encoding = true; - } - if ($salt_requires_encoding) { - // encode string with the Base64 variant used by crypt - $base64_digits = - 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - $bcrypt64_digits = - './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; - - $base64_string = base64_encode($salt); - $salt = strtr(rtrim($base64_string, '='), $base64_digits, $bcrypt64_digits); - } - $salt = PasswordCompat\binary\_substr($salt, 0, $required_salt_len); - - $hash = $hash_format . $salt; - - $ret = crypt($password, $hash); - - if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != $resultLength) { - return false; - } - - return $ret; - } - - /** - * Get information about the password hash. Returns an array of the information - * that was used to generate the password hash. - * - * array( - * 'algo' => 1, - * 'algoName' => 'bcrypt', - * 'options' => array( - * 'cost' => 10, - * ), - * ) - * - * @param string $hash The password hash to extract info from - * - * @return array The array of information about the hash. - */ - function password_get_info($hash) { - $return = array( - 'algo' => 0, - 'algoName' => 'unknown', - 'options' => array(), - ); - if (PasswordCompat\binary\_substr($hash, 0, 4) == '$2y$' && PasswordCompat\binary\_strlen($hash) == 60) { - $return['algo'] = PASSWORD_BCRYPT; - $return['algoName'] = 'bcrypt'; - list($cost) = sscanf($hash, "$2y$%d$"); - $return['options']['cost'] = $cost; - } - return $return; - } - - /** - * Determine if the password hash needs to be rehashed according to the options provided - * - * If the answer is true, after validating the password using password_verify, rehash it. - * - * @param string $hash The hash to test - * @param int $algo The algorithm used for new password hashes - * @param array $options The options array passed to password_hash - * - * @return boolean True if the password needs to be rehashed. - */ - function password_needs_rehash($hash, $algo, array $options = array()) { - $info = password_get_info($hash); - if ($info['algo'] != $algo) { - return true; - } - switch ($algo) { - case PASSWORD_BCRYPT: - $cost = isset($options['cost']) ? $options['cost'] : 10; - if ($cost != $info['options']['cost']) { - return true; - } - break; - } - return false; - } - - /** - * Verify a password against a hash using a timing attack resistant approach - * - * @param string $password The password to verify - * @param string $hash The hash to verify against - * - * @return boolean If the password matches the hash - */ - function password_verify($password, $hash) { - if (!function_exists('crypt')) { - trigger_error("Crypt must be loaded for password_verify to function", E_USER_WARNING); - return false; - } - $ret = crypt($password, $hash); - if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != PasswordCompat\binary\_strlen($hash) || PasswordCompat\binary\_strlen($ret) <= 13) { - return false; - } - - $status = 0; - for ($i = 0; $i < PasswordCompat\binary\_strlen($ret); $i++) { - $status |= (ord($ret[$i]) ^ ord($hash[$i])); - } - - return $status === 0; - } -} - -} - -namespace PasswordCompat\binary { - /** - * Count the number of bytes in a string - * - * We cannot simply use strlen() for this, because it might be overwritten by the mbstring extension. - * In this case, strlen() will count the number of *characters* based on the internal encoding. A - * sequence of bytes might be regarded as a single multibyte character. - * - * @param string $binary_string The input string - * - * @internal - * @return int The number of bytes - */ - function _strlen($binary_string) { - if (function_exists('mb_strlen')) { - return mb_strlen($binary_string, '8bit'); - } - return strlen($binary_string); - } - - /** - * Get a substring based on byte limits - * - * @see _strlen() - * - * @param string $binary_string The input string - * @param int $start - * @param int $length - * - * @internal - * @return string The substring - */ - function _substr($binary_string, $start, $length) { - if (function_exists('mb_substr')) { - return mb_substr($binary_string, $start, $length, '8bit'); - } - return substr($binary_string, $start, $length); - } - -} diff --git a/p/api/greader.php b/p/api/greader.php index 3d628c855..4cf1b7b20 100644 --- a/p/api/greader.php +++ b/p/api/greader.php @@ -43,11 +43,7 @@ if (PHP_INT_SIZE < 8) { //32-bit } } -if (version_compare(PHP_VERSION, '5.4.0') >= 0) { - define('JSON_OPTIONS', JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); -} else { - define('JSON_OPTIONS', 0); -} +define('JSON_OPTIONS', JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); function headerVariable($headerName, $varName) { $header = ''; @@ -182,10 +178,6 @@ function authorizationToUser() { function clientLogin($email, $pass) { //http://web.archive.org/web/20130604091042/http://undoc.in/clientLogin.html if (FreshRSS_user_Controller::checkUsername($email)) { - if (!function_exists('password_verify')) { - include_once(LIB_PATH . '/password_compat.php'); - } - FreshRSS_Context::$user_conf = get_user_configuration($email); if (FreshRSS_Context::$user_conf == null) { Minz_Log::warning('Invalid API user ' . $email . ': configuration cannot be found.'); diff --git a/p/scripts/main.js b/p/scripts/main.js index 4fd91235e..3a9d8a52a 100644 --- a/p/scripts/main.js +++ b/p/scripts/main.js @@ -720,8 +720,14 @@ function init_shortcuts() { return true; } - const s = context.shortcuts, - k = (ev.key.trim() || ev.code).toUpperCase(); + const s = context.shortcuts; + let k = (ev.key.trim() || ev.code || 'Space').toUpperCase(); + + //IE11 + if (k === 'SPACEBAR') k = 'SPACE'; + else if (k === 'DEL') k = 'DELETE'; + else if (k === 'ESC') k = 'ESCAPE'; + if (location.hash.match(/^#dropdown-/)) { const n = parseInt(k); if (n) { @@ -803,7 +809,11 @@ function init_shortcuts() { if (context.auto_mark_site) { mark_read(document.querySelector('.flux.current'), true, false); } - window.open(document.querySelector('.flux.current a.go_website').href); + const newWindow = window.open(); + if (newWindow) { + newWindow.opener = null; + newWindow.location = document.querySelector('.flux.current a.go_website').href; + } return false; } if (k === s.skip_next_entry) { next_entry(true); return false; } diff --git a/phpcs.xml b/phpcs.xml index c30ad54f6..8234aced8 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -10,7 +10,6 @@ ./lib/http-conditional.php ./lib/JSON.php ./lib/lib_phpQuery.php - ./lib/password_compat.php