commit
185dba88c1
72 changed files with 3055 additions and 526 deletions
@ -0,0 +1,442 @@ |
||||
# Changelog |
||||
|
||||
## 2015-05-31 FreshRSS 1.1.1 (beta) |
||||
|
||||
* Features |
||||
* New option to detect and mark updated articles as unread. |
||||
* Support for internationalized domain name (IDN). |
||||
* Improved logic for automatic deletion of old articles. |
||||
* API |
||||
* Work-around for News+ bug when there is no unread article on the server. |
||||
* UI |
||||
* New confirmation message when leaving a configuration page without saving the changes. |
||||
* Bug fixing |
||||
* Corrected bug introduced in previous beta about handling of HTTP 301 (feeds that have changed address) |
||||
* Corrected bug in FreshRSS RSS feeds. |
||||
* Security |
||||
* Sanitize HTTP request header `Host`. |
||||
* Misc. |
||||
* Attempt to better handle encoded article titles. |
||||
|
||||
|
||||
## 2015-01-31 FreshRSS 1.0.0 / 1.1.0 (beta) |
||||
|
||||
* UI |
||||
* Slider math with Dark theme |
||||
* Add a message if request failed for mark as read / favourite |
||||
* I18n |
||||
* Fix some sentences |
||||
* Add German as a supported language |
||||
* Add some indications on password format |
||||
* Bug fixing |
||||
* Some shortcuts was never saved |
||||
* Global view didn't work if set by default |
||||
* Minz_Error was badly raised |
||||
* Feed update failed if nothing had changed (MySQL only) |
||||
* CRON task failed with multiple users |
||||
* Tricky bug caused by cookie path |
||||
* Email sharing was badly supported (no urlencode()) |
||||
* Misc. |
||||
* Add a CREDIT file with contributor names |
||||
* Update lib_opml |
||||
* Default favicon is now served by HTTP code 200 |
||||
* Change calls to syslog by Minz_Log::notice |
||||
* HTTP credentials are no longer logged |
||||
|
||||
|
||||
## 2015-01-15 FreshRSS 0.9.4 (beta) |
||||
|
||||
* Feature |
||||
* Extension system (!!): some extensions are available at https://github.com/FreshRSS/Extensions |
||||
* Refactoring |
||||
* Front controller (FreshRSS class) |
||||
* Configuration system |
||||
* Sharing system |
||||
* New data files organization |
||||
* Updates |
||||
* Remove restriction of 1h for updates |
||||
* Show the current version of FreshRSS and the next one |
||||
* UI |
||||
* Remove the "sticky position" of the feed aside (moved into an extension) |
||||
* "Show password" shows the password only while the user is pressing the mouse. |
||||
|
||||
|
||||
## 2014-12-12 FreshRSS 0.9.3 (beta) |
||||
|
||||
* SimplePie |
||||
* Support for content-type application/x-rss+xml |
||||
* New force_feed option (for feeds sent with the wrong content-type / MIME) by adding #force_feed at the end of the feed URL |
||||
* Improved error messages |
||||
* Statistics |
||||
* Add information on feed repartition pages |
||||
* Add percent repartition for the bigger feeds |
||||
* UI |
||||
* New theme selector |
||||
* Update Screwdriver theme |
||||
* Add BlueLagoon theme by Mister aiR |
||||
* Misc. |
||||
* Add option to remove articles after reading them |
||||
* Add comments |
||||
* Refactor i18n system to avoid loading unnecessary strings |
||||
* Fix security issue in Minz_Error::error() method |
||||
* Fix redirection after refreshing a given feed |
||||
|
||||
|
||||
## 2014-10-31 FreshRSS 0.9.2 (beta) |
||||
|
||||
* UI |
||||
* New subscription page (introduce .box items) |
||||
* Change feed category by drag and drop |
||||
* New feed aside on the main page |
||||
* New configuration / administration organization |
||||
* Configuration |
||||
* New options in config.php for cache duration, timeout, max inactivity, max number of feeds and categories per user. |
||||
* Refactoring |
||||
* Refactor authentication system (introduce FreshRSS_Auth model) |
||||
* Refactor indexController (introduce FreshRSS_Context model) |
||||
* Use ```_t()```, ```_i()```, ```_url()```, ```Minz_Request::good()``` and ```Minz_Request::bad()``` as much as possible |
||||
* Refactor javascript_vars.phtml |
||||
* Better coding style |
||||
* I18n |
||||
* Introduce a new system for i18n keys (not finished yet) |
||||
* Misc. |
||||
* Fix global view (did not work anymore) |
||||
* Add do_post_update for update system |
||||
* Introduce ```checkInstallAction``` to test if FreshRSS installation is ok |
||||
|
||||
|
||||
## 2014-10-09 FreshRSS 0.8.1 / 0.9.1 (beta) |
||||
|
||||
* UI |
||||
* Add a space after tag icon |
||||
* Statistics |
||||
* Add an average per day on the 30-day period graph |
||||
* Add percent of total on top 10 feed |
||||
* Bug fixes |
||||
* Fix "mark as read" in global view |
||||
* Fix "read all" shortcut |
||||
* Fix categories not appearing when adding a new feed (GET action) |
||||
* Fix enclosure problem |
||||
* Fix getExtension() on PHP < 5.3.7 |
||||
|
||||
|
||||
## 2014-09-26 FreshRSS 0.8.0 / 0.9.0 (beta) |
||||
|
||||
* UI |
||||
* New interface for statistics |
||||
* Fix filter buttons |
||||
* Number of articles divided by 2 in reading view |
||||
* Redesign of bigMarkAsRead |
||||
* Features |
||||
* New automatic update system |
||||
* New reset auth system |
||||
* Security |
||||
* "Mark as read" requires POST requests for several articles |
||||
* Test HTTP REFERER in install.php |
||||
* Configuration |
||||
* New "Show all articles" / "Show only unread" / "Adjust viewing" option |
||||
* New notification timeout option |
||||
* Misc. |
||||
* Improve coding style + comments |
||||
* Fix SQLite bug "ON DELETE CASCADE" |
||||
* Improve performance when importing articles |
||||
|
||||
|
||||
## 2014-08-24 FreshRSS 0.7.4 |
||||
|
||||
* UI |
||||
* Hide categories/feeds with unread articles when showing only unread articles |
||||
* Dynamic favicon showing the number of unread articles |
||||
* New theme: Screwdriver by Mister aiR |
||||
* Statistics |
||||
* New page with article repartition |
||||
* Improvements |
||||
* Security |
||||
* Basic protection against XSRF (Cross-Site Request Forgery) based on HTTP Referer (POST requests only) |
||||
* API |
||||
* Compatible with lighttpd |
||||
* Misc. |
||||
* Changed lazyload implementation |
||||
* Support of HTML5 notifications for new upcoming articles |
||||
* Add option to stay logged in |
||||
* Bug fixes in export function, add/remove users, keyboard shortcuts, etc. |
||||
|
||||
|
||||
## 2014-07-21 FreshRSS 0.7.3 |
||||
|
||||
* New options |
||||
* Add system of user queries which are shortcuts to filter the view |
||||
* New TTL option to limit the frequency at which feeds are refreshed (by cron or manual refresh button). |
||||
It is still possible to manually refresh an individual feed at a higher frequency. |
||||
* SQL |
||||
* Add support for SQLite (beta) in addition to MySQL |
||||
* SimplePie |
||||
* Complies with HTTP "301 Moved Permanently" responses by automatically updating the URL of feeds that have changed address. |
||||
* Themes |
||||
* Flat and Dark designs are based on same template file as Origine |
||||
* Statistics |
||||
* Refactor code |
||||
* Add an idle feed page |
||||
* Misc |
||||
* Several bug fixes |
||||
* Add confirmation option when marking all articles as read |
||||
* Fix some typo |
||||
|
||||
|
||||
## 2014-06-13 FreshRSS 0.7.2 |
||||
|
||||
* API compatible with Google Reader API level 2 |
||||
* FreshRSS can now be used from e.g.: |
||||
* (Android) News+ https://play.google.com/store/apps/details?id=com.noinnion.android.newsplus.extension.google_reader |
||||
* (Android) EasyRSS https://github.com/Alkarex/EasyRSS |
||||
* Basic support for audio and video podcasts |
||||
* Searching |
||||
* New search filters date: and pubdate: accepting ISO 8601 date intervals such as `date:2013-2014` or `pubdate:P1W` |
||||
* Possibility to combine search filters, e.g. `date:2014-05 intitle:FreshRSS intitle:Open great reader #Internet` |
||||
* Change nav menu with more buttons instead of dropdown menus and add some filters |
||||
* New system of import / export |
||||
* Support OPML, Json (like Google Reader) and Zip archives |
||||
* Can export and import articles (specific option for favorites) |
||||
* Refactor "Origine" theme |
||||
* Some improvements |
||||
* Based on a template file (other themes will use it too) |
||||
|
||||
|
||||
## 2014-02-19 FreshRSS 0.7.1 |
||||
|
||||
* Mise à jour des flux plus rapide grâce à une meilleure utilisation du cache |
||||
* Utilisation d’une signature MD5 du contenu intéressant pour les flux n’implémentant pas les requêtes conditionnelles |
||||
* Modification des raccourcis |
||||
* "s" partage directement si un seul moyen de partage |
||||
* Moyens de partage accessibles par "1", "2", "3", etc. |
||||
* Premier article : Home ; Dernier article : End |
||||
* Ajout du déplacement au sein des catégories / flux (via modificateurs shift et alt) |
||||
* UI |
||||
* Séparation des descriptions des raccourcis par groupes |
||||
* Revue rapide de la page de connexion |
||||
* Amélioration de l'affichage des notifications sur mobile |
||||
* Revue du système de rafraîchissement des flux |
||||
* Meilleure gestion de la file de flux à rafraîchir en JSON |
||||
* Rafraîchissement uniquement pour les flux non rafraîchis récemment |
||||
* Possibilité donnée aux anonymes de rafraîchir les flux |
||||
* SimplePie |
||||
* Mise à jour de la lib |
||||
* Corrige fuite de mémoire |
||||
* Meilleure tolérance aux flux invalides |
||||
* Corrections divers |
||||
* Ne déplie plus l'article lors du clic sur l'icône lien externe |
||||
* Ne boucle plus à la fin de la navigation dans les articles |
||||
* Suppression du champ category.color inutile |
||||
* Corrige bug redirection infinie (Persona) |
||||
* Amélioration vérification de la requête POST |
||||
* Ajout d'un verrou lorsqu'une action mark_read ou mark_favorite est en cours |
||||
|
||||
|
||||
## 2014-01-29 FreshRSS 0.7 |
||||
|
||||
* Nouveau mode multi-utilisateur |
||||
* L’utilisateur par défaut (administrateur) peut créer et supprimer d’autres utilisateurs |
||||
* Nécessite un contrôle d’accès, soit : |
||||
* par le nouveau mode de connexion par formulaire (nom d’utilisateur + mot de passe) |
||||
* relativement sûr même sans HTTPS (le mot de passe n’est pas transmis en clair) |
||||
* requiert JavaScript et PHP 5.3+ |
||||
* par HTTP (par exemple sous Apache en créant un fichier ./p/i/.htaccess et .htpasswd) |
||||
* le nom d’utilisateur HTTP doit correspondre au nom d’utilisateur FreshRSS |
||||
* par Mozilla Persona, en renseignant l’adresse courriel des utilisateurs |
||||
* Installateur supportant les mises à jour : |
||||
* Depuis une v0.6, placer application.ini et Configuration.array.php dans le nouveau répertoire “./data/” |
||||
(voir réorganisation ci-dessous) |
||||
* Pour les versions suivantes, juste garder le répertoire “./data/” |
||||
* Rafraîchissement automatique du nombre d’articles non lus toutes les deux minutes (utilise le cache HTTP à bon escient) |
||||
* Permet aussi de conserver la session valide, surtout dans le cas de Persona |
||||
* Nouvelle page de statistiques (nombres d’articles par jour / catégorie) |
||||
* Importation OPML instantanée et plus tolérante |
||||
* Nouvelle gestion des favicons avec téléchargement en parallèle |
||||
* Nouvelles options |
||||
* Réorganisation des options |
||||
* Gestion des utilisateurs |
||||
* Améliorations partage vers Shaarli, Poche, Diaspora*, Facebook, Twitter, Google+, courriel |
||||
* Raccourci ‘s’ par défaut |
||||
* Permet la suppression de tous les articles d’un flux |
||||
* Option pour marquer les articles comme lus dès la réception |
||||
* Permet de configurer plus finement le nombre d’articles minimum à conserver par flux |
||||
* Permet de modifier la description et l’adresse d’un flux RSS ainsi que le site Web associé |
||||
* Nouveau raccourci pour ouvrir/fermer un article (‘c’ par défaut) |
||||
* Boutons pour effacer les logs et pour purger les vieux articles |
||||
* Nouveaux filtres d’affichage : seulement les articles favoris, et seulement les articles lus |
||||
* SQL : |
||||
* Nouveau moteur de recherche, aussi accessible depuis la vue mobile |
||||
* Mots clefs de recherche “intitle:”, “inurl:”, “author:” |
||||
* Les articles sont triés selon la date de leur ajout dans FreshRSS plutôt que la date déclarée (souvent erronée) |
||||
* Permet de marquer tout comme lu sans affecter les nouveaux articles arrivés en cours de lecture |
||||
* Permet une pagination efficace |
||||
* Refactorisation |
||||
* Les tables sont préfixées avec le nom d’utilisateur afin de permettre le mode multi-utilisateurs |
||||
* Amélioration des performances |
||||
* Tolère un beaucoup plus grand nombre d’articles |
||||
* Compression des données côté MySQL plutôt que côté PHP |
||||
* Incompatible avec la version 0.6 (nécessite une mise à jour grâce à l’installateur) |
||||
* Affichage de la taille de la base de données dans FreshRSS |
||||
* Correction problème de marquage de tous les favoris comme lus |
||||
* HTML5 : |
||||
* Support des balises HTML5 audio, video, et éléments associés |
||||
* Utilisation de preload="none", et réécriture correcte des adresses, aussi en HTTPS |
||||
* Protection HTML5 des iframe (sandbox="allow-scripts allow-same-origin") |
||||
* Filtrage des object et embed |
||||
* Chargement différé HTML5 (postpone="") pour iframe et video |
||||
* Chargement différé JavaScript pour iframe |
||||
* CSS : |
||||
* Nouveau thème sombre |
||||
* Chargement plus robuste des thèmes |
||||
* Meilleur support des longs titres d’articles sur des écrans étroits |
||||
* Meilleure accessibilité |
||||
* FreshRSS fonctionne aussi en mode dégradé sans images (alternatives Unicode) et/ou sans CSS |
||||
* Diverses améliorations |
||||
* PHP : |
||||
* Encore plus tolérant pour les flux comportant des erreurs |
||||
* Mise à jour automatique de l’URL du flux (en base de données) lorsque SimplePie découvre qu’elle a changé |
||||
* Meilleure gestion des caractères spéciaux dans différents cas |
||||
* Compatibilité PHP 5.5+ avec OPcache |
||||
* Amélioration des performances |
||||
* Chargement automatique des classes |
||||
* Alternative dans le cas d’absence de librairie JSON |
||||
* Pour le développement, le cache HTTP peut être désactivé en créant un fichier “./data/no-cache.txt” |
||||
* Réorganisation des fichiers et répertoires, en particulier : |
||||
* Tous les fichiers utilisateur sont dans “./data/” (y compris “cache”, “favicons”, et “log”) |
||||
* Déplacement de “./app/configuration/application.ini” vers “./data/config.php” |
||||
* Meilleure sécurité et compatibilité |
||||
* Déplacement de “./public/data/Configuration.array.php” vers “./data/*_user.php” |
||||
* Déplacement de “./public/” vers “./p/” |
||||
* Déplacement de “./public/index.php” vers “./p/i/index.php” (voir cookie ci-dessous) |
||||
* Déplacement de “./actualize_script.php” vers “./app/actualize_script.php” (pour une meilleure sécurité) |
||||
* Pensez à mettre à jour votre Cron ! |
||||
* Divers : |
||||
* Nouvelle politique de cookie de session (témoin de connexion) |
||||
* Utilise un nom poli “FreshRSS” (évite des problèmes avec certains filtres) |
||||
* Se limite au répertoire “./FreshRSS/p/i/” pour de meilleures performances HTTP |
||||
* Les images, CSS, scripts sont servis sans cookie |
||||
* Utilise “HttpOnly” pour plus de sécurité |
||||
* Nouvel “agent utilisateur” exposé lors du téléchargement des flux, par exemple : |
||||
* “FreshRSS/0.7 (Linux; http://freshrss.org) SimplePie/1.3.1” |
||||
* Script d’actualisation avec plus de messages |
||||
* Sur la sortie standard, ainsi que dans le log système (syslog) |
||||
* Affichage du numéro de version dans "À propos" |
||||
|
||||
|
||||
## 2013-11-21 FreshRSS 0.6.1 |
||||
|
||||
* Corrige bug chargement du JavaScript |
||||
* Affiche un message d’erreur plus explicite si fichier de configuration inaccessible |
||||
|
||||
|
||||
## 2013-11-17 FreshRSS 0.6 |
||||
|
||||
* Nettoyage du code JavaScript + optimisations |
||||
* Utilisation d’adresses relatives |
||||
* Amélioration des performances coté client |
||||
* Mise à jour automatique du nombre d’articles non lus |
||||
* Corrections traductions |
||||
* Mise en cache de FreshRSS |
||||
* Amélioration des retours utilisateur lorsque la configuration n’est pas bonne |
||||
* Actualisation des flux après une importation OPML |
||||
* Meilleure prise en charge des flux RSS invalides |
||||
* Amélioration de la vue globale |
||||
* Possibilité de personnaliser les icônes de lecture |
||||
* Suppression de champs lors de l’installation (base_url et sel) |
||||
* Correction bugs divers |
||||
|
||||
|
||||
## 2013-10-15 FreshRSS 0.5.1 |
||||
|
||||
* Correction bug des catégories disparues |
||||
* Correction traduction i18n/fr et i18n/en |
||||
* Suppression de certains appels à la feuille de style fallback.css |
||||
|
||||
|
||||
## 2013-10-12 FreshRSS 0.5.0 |
||||
|
||||
* Possibilité d’interdire la lecture anonyme |
||||
* Option pour garder l’historique d’un flux |
||||
* Lors d’un clic sur “Marquer tous les articles comme lus”, FreshRSS peut désormais sauter à la prochaine catégorie / prochain flux avec des articles non lus. |
||||
* Ajout d’un token pour accéder aux flux RSS générés par FreshRSS sans nécessiter de connexion |
||||
* Possibilité de partager vers Facebook, Twitter et Google+ |
||||
* Possibilité de changer de thème |
||||
* Le menu de navigation (article précédent / suivant / haut de page) a été ajouté à la vue non mobile |
||||
* La police OpenSans est désormais appliquée |
||||
* Amélioration de la page de configuration |
||||
* Une meilleure sortie pour l’imprimante |
||||
* Quelques retouches du design par défaut |
||||
* Les vidéos ne dépassent plus du cadre de l’écran |
||||
* Nouveau logo |
||||
* Possibilité d’ajouter un préfixe aux tables lors de l’installation |
||||
* Ajout d’un champ en base de données keep_history à la table feed |
||||
* Si possible, création automatique de la base de données si elle n’existe pas lors de l’installation |
||||
* L’utilisation d’UTF-8 est forcée |
||||
* Le marquage automatique au défilement de la page a été amélioré |
||||
* La vue globale a été énormément améliorée et est beaucoup plus utile |
||||
* Amélioration des requêtes SQL |
||||
* Amélioration du JavaScript |
||||
* Correction bugs divers |
||||
|
||||
|
||||
## 2013-07-02 FreshRSS 0.4.0 |
||||
|
||||
* Correction bug et ajout notification lors de la phase d’installation |
||||
* Affichage d’erreur si fichier OPML invalide |
||||
* Les tags sont maintenant cliquables pour filtrer dessus |
||||
* Amélioration vue mobile (boutons plus gros et ajout d’une barre de navigation) |
||||
* Possibilité d’ajouter directement un flux dans une catégorie dès son ajout |
||||
* Affichage des flux en erreur (injoignable par exemple) en rouge pour les différencier |
||||
* Possibilité de changer les noms des flux |
||||
* Ajout d’une option (désactivable donc) pour charger les images en lazyload permettant de ne pas charger toutes les images d’un coup |
||||
* Le framework Minz est maintenant directement inclus dans l’archive (plus besoin de passer par ./build.sh) |
||||
* Amélioration des performances pour la récupération des flux tronqués |
||||
* Possibilité d’importer des flux sans catégorie lors de l’import OPML |
||||
* Suppression de “l’API” (qui était de toute façon très basique) et de la fonctionnalité de “notes” |
||||
* Amélioration de la recherche (garde en mémoire si l’on a sélectionné une catégorie) par exemple |
||||
* Modification apparence des balises hr et pre |
||||
* Meilleure vérification des champs de formulaire |
||||
* Remise en place du mode “endless” (permettant de simplement charger les articles qui suivent plutôt que de charger une nouvelle page) |
||||
* Ajout d’une page de visualisation des logs |
||||
* Ajout d’une option pour optimiser la BDD (diminue sa taille) |
||||
* Ajout des vues lecture et globale (assez basique) |
||||
* Les vidéos YouTube ne débordent plus du cadre sur les petits écrans |
||||
* Ajout d’une option pour marquer les articles comme lus lors du défilement (et suppression de celle au chargement de la page) |
||||
|
||||
|
||||
## 2013-05-05 FreshRSS 0.3.0 |
||||
|
||||
* Fallback pour les icônes SVG (utilisation de PNG à la place) |
||||
* Fallback pour les propriétés CSS3 (utilisation de préfixes) |
||||
* Affichage des tags associés aux articles |
||||
* Internationalisation de l’application (gestion des langues anglaise et française) |
||||
* Gestion des flux protégés par authentification HTTP |
||||
* Mise en cache des favicons |
||||
* Création d’un logo *temporaire* |
||||
* Affichage des vidéos dans les articles |
||||
* Gestion de la recherche et filtre par tags pleinement fonctionnels |
||||
* Création d’un vrai script CRON permettant de mettre tous les flux à jour |
||||
* Correction bugs divers |
||||
|
||||
|
||||
## 2013-04-17 FreshRSS 0.2.0 |
||||
|
||||
* Création d’un installateur |
||||
* Actualisation des flux en Ajax |
||||
* Partage par mail et Shaarli ajouté |
||||
* Export par flux RSS |
||||
* Possibilité de vider une catégorie |
||||
* Possibilité de sélectionner les catégories en vue mobile |
||||
* Les flux peuvent être sortis du flux principal (système de priorité) |
||||
* Amélioration ajout / import / export des flux |
||||
* Amélioration actualisation (meilleure gestion des erreurs) |
||||
* Améliorations CSS |
||||
* Changements dans la base de données |
||||
* Màj de la librairie SimplePie |
||||
* Flux sans auteurs gérés normalement |
||||
* Correction bugs divers |
||||
|
||||
|
||||
## 2013-04-08 FreshRSS 0.1.0 |
||||
|
||||
* “Première” version |
@ -1,39 +0,0 @@ |
||||
This is a credit file of people who have contributed to FreshRSS with, at least, |
||||
one commit on the FreshRSS repository (at https://github.com/FreshRSS/FreshRSS). |
||||
Please note a commit on THIS specific file is not considered as a contribution |
||||
(too easy!). It's purpose is to show even the smallest contribution is important. |
||||
People are sorted by name so please keep this order. |
||||
|
||||
--- |
||||
|
||||
Alexandre Alapetite |
||||
https://github.com/Alkarex |
||||
|
||||
Alexis Degrugillier |
||||
https://github.com/aledeg |
||||
|
||||
Alwaysin |
||||
https://github.com/Alwaysin |
||||
|
||||
Amaury Carrade |
||||
https://github.com/AmauryCarrade |
||||
|
||||
ealdraed |
||||
https://github.com/ealdraed |
||||
|
||||
Luc Didry |
||||
https://github.com/ldidry |
||||
|
||||
Marien Fressinaud |
||||
dev@marienfressinaud.fr |
||||
http://marienfressinaud.fr |
||||
https://github.com/marienfressinaud |
||||
|
||||
Nicolas Elie |
||||
https://github.com/nicolaselie |
||||
|
||||
plopoyop |
||||
https://github.com/plopoyop |
||||
|
||||
tomgue |
||||
https://github.com/tomgue |
@ -0,0 +1,19 @@ |
||||
This is a credit file of people who have [contributed to FreshRSS](https://github.com/FreshRSS/FreshRSS/graphs/contributors) with, at least, |
||||
one commit on the FreshRSS repository (at https://github.com/FreshRSS/FreshRSS). |
||||
Please note a commit on THIS specific file is not considered as a contribution |
||||
(too easy!). Its purpose is to show that even the smallest contribution is important. |
||||
People are sorted by name so please keep this order. |
||||
|
||||
--- |
||||
|
||||
* [Alexandre Alapetite](https://github.com/Alkarex): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=Alkarex), [Web](http://alexandre.alapetite.fr/) |
||||
* [Alexis Degrugillier](https://github.com/aledeg): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=aledeg) |
||||
* [Alwaysin](https://github.com/Alwaysin): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=Alwaysin) |
||||
* [Amaury Carrade](https://github.com/AmauryCarrade): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=AmauryCarrade) |
||||
* [ealdraed](https://github.com/ealdraed): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=ealdraed) |
||||
* [Luc Didry](https://github.com/ldidry): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=ldidry) |
||||
* [Marien Fressinaud](https://github.com/marienfressinaud): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=marienfressinaud), [Web](http://marienfressinaud.fr/), [Email](mailto:dev@marienfressinaud.fr) |
||||
* [Melvyn Laïly](https://github.com/yaurthek): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=yaurthek) |
||||
* [Nicolas Elie](https://github.com/nicolaselie): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=nicolaselie) |
||||
* [plopoyop](https://github.com/plopoyop): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=plopoyop) |
||||
* [tomgue](https://github.com/tomgue): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=tomgue) |
@ -1,6 +1,9 @@ |
||||
<?php |
||||
|
||||
class FreshRSS_BadUrl_Exception extends FreshRSS_Feed_Exception { |
||||
|
||||
public function __construct($url) { |
||||
parent::__construct('`' . $url . '` is not a valid URL'); |
||||
} |
||||
|
||||
} |
||||
|
@ -0,0 +1,5 @@ |
||||
<?php |
||||
|
||||
class FreshRSS_DAO_Exception extends \Exception { |
||||
|
||||
} |
@ -1,7 +1,5 @@ |
||||
<?php |
||||
|
||||
class FreshRSS_EntriesGetter_Exception extends Exception { |
||||
public function __construct($message) { |
||||
parent::__construct($message); |
||||
} |
||||
class FreshRSS_EntriesGetter_Exception extends \Exception { |
||||
|
||||
} |
||||
|
@ -1,6 +1,5 @@ |
||||
<?php |
||||
class FreshRSS_Feed_Exception extends Exception { |
||||
public function __construct($message) { |
||||
parent::__construct($message); |
||||
} |
||||
|
||||
class FreshRSS_Feed_Exception extends \Exception { |
||||
|
||||
} |
||||
|
@ -0,0 +1,229 @@ |
||||
<?php |
||||
|
||||
require_once(LIB_PATH . '/lib_date.php'); |
||||
|
||||
/** |
||||
* Contains a search from the search form. |
||||
* |
||||
* It allows to extract meaningful bits of the search and store them in a |
||||
* convenient object |
||||
*/ |
||||
class FreshRSS_Search { |
||||
|
||||
// This contains the user input string |
||||
private $raw_input = ''; |
||||
// The following properties are extracted from the raw input |
||||
private $intitle; |
||||
private $min_date; |
||||
private $max_date; |
||||
private $min_pubdate; |
||||
private $max_pubdate; |
||||
private $inurl; |
||||
private $author; |
||||
private $tags; |
||||
private $search; |
||||
|
||||
public function __construct($input) { |
||||
if (strcmp($input, '') == 0) { |
||||
return; |
||||
} |
||||
$this->raw_input = $input; |
||||
$input = $this->parseIntitleSearch($input); |
||||
$input = $this->parseAuthorSearch($input); |
||||
$input = $this->parseInurlSearch($input); |
||||
$input = $this->parsePubdateSearch($input); |
||||
$input = $this->parseDateSearch($input); |
||||
$input = $this->parseTagsSeach($input); |
||||
$this->parseSearch($input); |
||||
} |
||||
|
||||
public function __toString() { |
||||
return $this->getRawInput(); |
||||
} |
||||
|
||||
public function getRawInput() { |
||||
return $this->raw_input; |
||||
} |
||||
|
||||
public function getIntitle() { |
||||
return $this->intitle; |
||||
} |
||||
|
||||
public function getMinDate() { |
||||
return $this->min_date; |
||||
} |
||||
|
||||
public function getMaxDate() { |
||||
return $this->max_date; |
||||
} |
||||
|
||||
public function getMinPubdate() { |
||||
return $this->min_pubdate; |
||||
} |
||||
|
||||
public function getMaxPubdate() { |
||||
return $this->max_pubdate; |
||||
} |
||||
|
||||
public function getInurl() { |
||||
return $this->inurl; |
||||
} |
||||
|
||||
public function getAuthor() { |
||||
return $this->author; |
||||
} |
||||
|
||||
public function getTags() { |
||||
return $this->tags; |
||||
} |
||||
|
||||
public function getSearch() { |
||||
return $this->search; |
||||
} |
||||
|
||||
/** |
||||
* Parse the search string to find intitle keyword and the search related |
||||
* to it. |
||||
* The search is the first word following the keyword. |
||||
* |
||||
* @param string $input |
||||
* @return string |
||||
*/ |
||||
private function parseIntitleSearch($input) { |
||||
if (preg_match('/intitle:(?P<delim>[\'"])(?P<search>.*)(?P=delim)/U', $input, $matches)) { |
||||
$this->intitle = $matches['search']; |
||||
return str_replace($matches[0], '', $input); |
||||
} |
||||
if (preg_match('/intitle:(?P<search>\w*)/', $input, $matches)) { |
||||
$this->intitle = $matches['search']; |
||||
return str_replace($matches[0], '', $input); |
||||
} |
||||
return $input; |
||||
} |
||||
|
||||
/** |
||||
* Parse the search string to find author keyword and the search related |
||||
* to it. |
||||
* The search is the first word following the keyword except when using |
||||
* a delimiter. Supported delimiters are single quote (') and double |
||||
* quotes ("). |
||||
* |
||||
* @param string $input |
||||
* @return string |
||||
*/ |
||||
private function parseAuthorSearch($input) { |
||||
if (preg_match('/author:(?P<delim>[\'"])(?P<search>.*)(?P=delim)/U', $input, $matches)) { |
||||
$this->author = $matches['search']; |
||||
return str_replace($matches[0], '', $input); |
||||
} |
||||
if (preg_match('/author:(?P<search>\w*)/', $input, $matches)) { |
||||
$this->author = $matches['search']; |
||||
return str_replace($matches[0], '', $input); |
||||
} |
||||
return $input; |
||||
} |
||||
|
||||
/** |
||||
* Parse the search string to find inurl keyword and the search related |
||||
* to it. |
||||
* The search is the first word following the keyword except. |
||||
* |
||||
* @param string $input |
||||
* @return string |
||||
*/ |
||||
private function parseInurlSearch($input) { |
||||
if (preg_match('/inurl:(?P<search>[^\s]*)/', $input, $matches)) { |
||||
$this->inurl = $matches['search']; |
||||
return str_replace($matches[0], '', $input); |
||||
} |
||||
return $input; |
||||
} |
||||
|
||||
/** |
||||
* Parse the search string to find date keyword and the search related |
||||
* to it. |
||||
* The search is the first word following the keyword. |
||||
* |
||||
* @param string $input |
||||
* @return string |
||||
*/ |
||||
private function parseDateSearch($input) { |
||||
if (preg_match('/date:(?P<search>[^\s]*)/', $input, $matches)) { |
||||
list($this->min_date, $this->max_date) = parseDateInterval($matches['search']); |
||||
return str_replace($matches[0], '', $input); |
||||
} |
||||
return $input; |
||||
} |
||||
|
||||
/** |
||||
* Parse the search string to find pubdate keyword and the search related |
||||
* to it. |
||||
* The search is the first word following the keyword. |
||||
* |
||||
* @param string $input |
||||
* @return string |
||||
*/ |
||||
private function parsePubdateSearch($input) { |
||||
if (preg_match('/pubdate:(?P<search>[^\s]*)/', $input, $matches)) { |
||||
list($this->min_pubdate, $this->max_pubdate) = parseDateInterval($matches['search']); |
||||
return str_replace($matches[0], '', $input); |
||||
} |
||||
return $input; |
||||
} |
||||
|
||||
/** |
||||
* Parse the search string to find tags keyword (# followed by a word) |
||||
* and the search related to it. |
||||
* The search is the first word following the #. |
||||
* |
||||
* @param string $input |
||||
* @return string |
||||
*/ |
||||
private function parseTagsSeach($input) { |
||||
if (preg_match_all('/#(?P<search>[^\s]+)/', $input, $matches)) { |
||||
$this->tags = $matches['search']; |
||||
return str_replace($matches[0], '', $input); |
||||
} |
||||
return $input; |
||||
} |
||||
|
||||
/** |
||||
* Parse the search string to find search values. |
||||
* Every word is a distinct search value, except when using a delimiter. |
||||
* Supported delimiters are single quote (') and double quotes ("). |
||||
* |
||||
* @param string $input |
||||
* @return string |
||||
*/ |
||||
private function parseSearch($input) { |
||||
$input = $this->cleanSearch($input); |
||||
if (strcmp($input, '') == 0) { |
||||
return; |
||||
} |
||||
if (preg_match_all('/(?P<delim>[\'"])(?P<search>.*)(?P=delim)/U', $input, $matches)) { |
||||
$this->search = $matches['search']; |
||||
$input = str_replace($matches[0], '', $input); |
||||
} |
||||
$input = $this->cleanSearch($input); |
||||
if (strcmp($input, '') == 0) { |
||||
return; |
||||
} |
||||
if (is_array($this->search)) { |
||||
$this->search = array_merge($this->search, explode(' ', $input)); |
||||
} else { |
||||
$this->search = explode(' ', $input); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Remove all unnecessary spaces in the search |
||||
* |
||||
* @param string $input |
||||
* @return string |
||||
*/ |
||||
private function cleanSearch($input) { |
||||
$input = preg_replace('/\s+/', ' ', $input); |
||||
return trim($input); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,6 @@ |
||||
<?php |
||||
|
||||
interface FreshRSS_Searchable { |
||||
|
||||
public function searchById($id); |
||||
} |
@ -0,0 +1,226 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* Contains the description of a user query |
||||
* |
||||
* It allows to extract the meaningful bits of the query to be manipulated in an |
||||
* easy way. |
||||
*/ |
||||
class FreshRSS_UserQuery { |
||||
|
||||
private $deprecated = false; |
||||
private $get; |
||||
private $get_name; |
||||
private $get_type; |
||||
private $name; |
||||
private $order; |
||||
private $search; |
||||
private $state; |
||||
private $url; |
||||
private $feed_dao; |
||||
private $category_dao; |
||||
|
||||
/** |
||||
* @param array $query |
||||
* @param FreshRSS_Searchable $feed_dao |
||||
* @param FreshRSS_Searchable $category_dao |
||||
*/ |
||||
public function __construct($query, FreshRSS_Searchable $feed_dao = null, FreshRSS_Searchable $category_dao = null) { |
||||
$this->category_dao = $category_dao; |
||||
$this->feed_dao = $feed_dao; |
||||
if (isset($query['get'])) { |
||||
$this->parseGet($query['get']); |
||||
} |
||||
if (isset($query['name'])) { |
||||
$this->name = $query['name']; |
||||
} |
||||
if (isset($query['order'])) { |
||||
$this->order = $query['order']; |
||||
} |
||||
if (!isset($query['search'])) { |
||||
$query['search'] = ''; |
||||
} |
||||
// linked to deeply with the search object, need to use dependency injection |
||||
$this->search = new FreshRSS_Search($query['search']); |
||||
if (isset($query['state'])) { |
||||
$this->state = $query['state']; |
||||
} |
||||
if (isset($query['url'])) { |
||||
$this->url = $query['url']; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Convert the current object to an array. |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function toArray() { |
||||
return array_filter(array( |
||||
'get' => $this->get, |
||||
'name' => $this->name, |
||||
'order' => $this->order, |
||||
'search' => $this->search->__toString(), |
||||
'state' => $this->state, |
||||
'url' => $this->url, |
||||
)); |
||||
} |
||||
|
||||
/** |
||||
* Parse the get parameter in the query string to extract its name and |
||||
* type |
||||
* |
||||
* @param string $get |
||||
*/ |
||||
private function parseGet($get) { |
||||
$this->get = $get; |
||||
if (preg_match('/(?P<type>[acfs])(_(?P<id>\d+))?/', $get, $matches)) { |
||||
switch ($matches['type']) { |
||||
case 'a': |
||||
$this->parseAll(); |
||||
break; |
||||
case 'c': |
||||
$this->parseCategory($matches['id']); |
||||
break; |
||||
case 'f': |
||||
$this->parseFeed($matches['id']); |
||||
break; |
||||
case 's': |
||||
$this->parseFavorite(); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Parse the query string when it is an "all" query |
||||
*/ |
||||
private function parseAll() { |
||||
$this->get_name = 'all'; |
||||
$this->get_type = 'all'; |
||||
} |
||||
|
||||
/** |
||||
* Parse the query string when it is a "category" query |
||||
* |
||||
* @param integer $id |
||||
* @throws FreshRSS_DAO_Exception |
||||
*/ |
||||
private function parseCategory($id) { |
||||
if (is_null($this->category_dao)) { |
||||
throw new FreshRSS_DAO_Exception('Category DAO is not loaded in UserQuery'); |
||||
} |
||||
$category = $this->category_dao->searchById($id); |
||||
if ($category) { |
||||
$this->get_name = $category->name(); |
||||
} else { |
||||
$this->deprecated = true; |
||||
} |
||||
$this->get_type = 'category'; |
||||
} |
||||
|
||||
/** |
||||
* Parse the query string when it is a "feed" query |
||||
* |
||||
* @param integer $id |
||||
* @throws FreshRSS_DAO_Exception |
||||
*/ |
||||
private function parseFeed($id) { |
||||
if (is_null($this->feed_dao)) { |
||||
throw new FreshRSS_DAO_Exception('Feed DAO is not loaded in UserQuery'); |
||||
} |
||||
$feed = $this->feed_dao->searchById($id); |
||||
if ($feed) { |
||||
$this->get_name = $feed->name(); |
||||
} else { |
||||
$this->deprecated = true; |
||||
} |
||||
$this->get_type = 'feed'; |
||||
} |
||||
|
||||
/** |
||||
* Parse the query string when it is a "favorite" query |
||||
*/ |
||||
private function parseFavorite() { |
||||
$this->get_name = 'favorite'; |
||||
$this->get_type = 'favorite'; |
||||
} |
||||
|
||||
/** |
||||
* Check if the current user query is deprecated. |
||||
* It is deprecated if the category or the feed used in the query are |
||||
* not existing. |
||||
* |
||||
* @return boolean |
||||
*/ |
||||
public function isDeprecated() { |
||||
return $this->deprecated; |
||||
} |
||||
|
||||
/** |
||||
* Check if the user query has parameters. |
||||
* If the type is 'all', it is considered equal to no parameters |
||||
* |
||||
* @return boolean |
||||
*/ |
||||
public function hasParameters() { |
||||
if ($this->get_type === 'all') { |
||||
return false; |
||||
} |
||||
if ($this->hasSearch()) { |
||||
return true; |
||||
} |
||||
if ($this->state) { |
||||
return true; |
||||
} |
||||
if ($this->order) { |
||||
return true; |
||||
} |
||||
if ($this->get) { |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* Check if there is a search in the search object |
||||
* |
||||
* @return boolean |
||||
*/ |
||||
public function hasSearch() { |
||||
return $this->search->getRawInput() != ""; |
||||
} |
||||
|
||||
public function getGet() { |
||||
return $this->get; |
||||
} |
||||
|
||||
public function getGetName() { |
||||
return $this->get_name; |
||||
} |
||||
|
||||
public function getGetType() { |
||||
return $this->get_type; |
||||
} |
||||
|
||||
public function getName() { |
||||
return $this->name; |
||||
} |
||||
|
||||
public function getOrder() { |
||||
return $this->order; |
||||
} |
||||
|
||||
public function getSearch() { |
||||
return $this->search; |
||||
} |
||||
|
||||
public function getState() { |
||||
return $this->state; |
||||
} |
||||
|
||||
public function getUrl() { |
||||
return $this->url; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,170 @@ |
||||
<?php |
||||
|
||||
return array( |
||||
'auth' => array( |
||||
'allow_anonymous' => 'Umožnit anonymně číst články výchozího uživatele (%s)', |
||||
'allow_anonymous_refresh' => 'Umožnit anonymní obnovení článků', |
||||
'api_enabled' => 'Povolit přístup k <abbr>API</abbr> <small>(vyžadováno mobilními aplikacemi)</small>', |
||||
'form' => 'Webový formulář (tradiční, vyžaduje JavaScript)', |
||||
'http' => 'HTTP (pro pokročilé uživatele s HTTPS)', |
||||
'none' => 'Žádný (nebezpečné)', |
||||
'persona' => 'Mozilla Persona (moderní, vyžaduje JavaScript)', |
||||
'title' => 'Přihlášení', |
||||
'title_reset' => 'Reset přihlášení', |
||||
'token' => 'Authentizační token', |
||||
'token_help' => 'Umožňuje přístup k RSS kanálu článků výchozího uživatele bez přihlášení:', |
||||
'type' => 'Způsob přihlášení', |
||||
'unsafe_autologin' => 'Povolit nebezpečné automatické přihlášení přes: ', |
||||
), |
||||
'check_install' => array( |
||||
'cache' => array( |
||||
'nok' => 'Zkontrolujte oprávnění adresáře <em>./data/cache</em>. HTTP server musí mít do tohoto adresáře práva zápisu', |
||||
'ok' => 'Oprávnění adresáře cache jsou v pořádku.', |
||||
), |
||||
'categories' => array( |
||||
'nok' => 'Tabulka kategorií je nastavena špatně.', |
||||
'ok' => 'Tabulka kategorií je v pořádku.', |
||||
), |
||||
'connection' => array( |
||||
'nok' => 'Nelze navázat spojení s databází.', |
||||
'ok' => 'Připojení k databázi je v pořádku.', |
||||
), |
||||
'ctype' => array( |
||||
'nok' => 'Nemáte požadovanou knihovnu pro ověřování znaků (php-ctype).', |
||||
'ok' => 'Máte požadovanou knihovnu pro ověřování znaků (ctype).', |
||||
), |
||||
'curl' => array( |
||||
'nok' => 'Nemáte cURL (balíček php5-curl).', |
||||
'ok' => 'Máte rozšíření cURL.', |
||||
), |
||||
'data' => array( |
||||
'nok' => 'Zkontrolujte oprávnění adresáře <em>./data</em>. HTTP server musí mít do tohoto adresáře práva zápisu', |
||||
'ok' => 'Oprávnění adresáře data jsou v pořádku.', |
||||
), |
||||
'database' => 'Instalace databáze', |
||||
'dom' => array( |
||||
'nok' => 'Nemáte požadovanou knihovnu pro procházení DOM (balíček php-xml).', |
||||
'ok' => 'Máte požadovanou knihovnu pro procházení DOM.', |
||||
), |
||||
'entries' => array( |
||||
'nok' => 'Tabulka článků je nastavena špatně.', |
||||
'ok' => 'Tabulka kategorií je v pořádku.', |
||||
), |
||||
'favicons' => array( |
||||
'nok' => 'Zkontrolujte oprávnění adresáře <em>./data/favicons</em>. HTTP server musí mít do tohoto adresáře práva zápisu', |
||||
'ok' => 'Oprávnění adresáře favicons jsou v pořádku.', |
||||
), |
||||
'feeds' => array( |
||||
'nok' => 'Tabulka kanálů je nastavena špatně.', |
||||
'ok' => 'Tabulka kanálů je v pořádku.', |
||||
), |
||||
'files' => 'Instalace souborů', |
||||
'json' => array( |
||||
'nok' => 'Nemáte JSON (balíček php5-json).', |
||||
'ok' => 'Máte rozšíření JSON.', |
||||
), |
||||
'minz' => array( |
||||
'nok' => 'Nemáte framework Minz.', |
||||
'ok' => 'Máte framework Minz.', |
||||
), |
||||
'pcre' => array( |
||||
'nok' => 'Nemáte požadovanou knihovnu pro regulární výrazy (php-pcre).', |
||||
'ok' => 'Máte požadovanou knihovnu pro regulární výrazy (PCRE).', |
||||
), |
||||
'pdo' => array( |
||||
'nok' => 'Nemáte PDO nebo některý z podporovaných ovladačů (pdo_mysql, pdo_sqlite).', |
||||
'ok' => 'Máte PDO a alespoň jeden z podporovaných ovladačů (pdo_mysql, pdo_sqlite).', |
||||
), |
||||
'persona' => array( |
||||
'nok' => 'Zkontrolujte oprávnění adresáře <em>./data/persona</em>. HTTP server musí mít do tohoto adresáře práva zápisu', |
||||
'ok' => 'Oprávnění adresáře Mozilla Persona jsou v pořádku.', |
||||
), |
||||
'php' => array( |
||||
'_' => 'PHP instalace', |
||||
'nok' => 'Vaše verze PHP je %s, ale FreshRSS vyžaduje alespoň verzi %s.', |
||||
'ok' => 'Vaše verze PHP je %s a je kompatibilní s FreshRSS.', |
||||
), |
||||
'tables' => array( |
||||
'nok' => 'V databázi chybí jedna nevo více tabulek.', |
||||
'ok' => 'V databázi jsou všechny tabulky.', |
||||
), |
||||
'title' => 'Kontrola instalace', |
||||
'tokens' => array( |
||||
'nok' => 'Zkontrolujte oprávnění adresáře <em>./data/tokens</em>. HTTP server musí mít do tohoto adresáře práva zápisu', |
||||
'ok' => 'Oprávnění adresáře tokens jsou v pořádku.', |
||||
), |
||||
'users' => array( |
||||
'nok' => 'Zkontrolujte oprávnění adresáře <em>./data/users</em>. HTTP server musí mít do tohoto adresáře práva zápisu', |
||||
'ok' => 'Oprávnění adresáře users jsou v pořádku.', |
||||
), |
||||
'zip' => array( |
||||
'nok' => 'Nemáte rozšíření ZIP (balíček php5-zip).', |
||||
'ok' => 'Máte rozšíření ZIP.', |
||||
), |
||||
), |
||||
'extensions' => array( |
||||
'disabled' => 'Vypnuto', |
||||
'empty_list' => 'Není naistalováno žádné rozšíření', |
||||
'enabled' => 'Zapnuto', |
||||
'no_configure_view' => 'Toto rozšíření nemá žádné možnosti nastavení.', |
||||
'system' => array( |
||||
'_' => 'Systémová rozšíření', |
||||
'no_rights' => 'Systémová rozšíření (na ně nemáte oprávnění)', |
||||
), |
||||
'title' => 'Rozšíření', |
||||
'user' => 'Uživatelská rozšíření', |
||||
), |
||||
'stats' => array( |
||||
'_' => 'Statistika', |
||||
'all_feeds' => 'Všechny kanály', |
||||
'category' => 'Kategorie', |
||||
'entry_count' => 'Počet článků', |
||||
'entry_per_category' => 'Článků na kategorii', |
||||
'entry_per_day' => 'Článků za den (posledních 30 dní)', |
||||
'entry_per_day_of_week' => 'Za den v týdnu (průměr: %.2f zprávy)', |
||||
'entry_per_hour' => 'Za hodinu (průměr: %.2f zprávy)', |
||||
'entry_per_month' => 'Za měsíc (průměr: %.2f zprávy)', |
||||
'entry_repartition' => 'Rozdělení článků', |
||||
'feed' => 'Kanál', |
||||
'feed_per_category' => 'Článků na kategorii', |
||||
'idle' => 'Neaktivní kanály', |
||||
'main' => 'Přehled', |
||||
'main_stream' => 'Všechny kanály', |
||||
'menu' => array( |
||||
'idle' => 'Neaktivní kanály', |
||||
'main' => 'Přehled', |
||||
'repartition' => 'Rozdělení článků', |
||||
), |
||||
'no_idle' => 'Žádné neaktivní kanály!', |
||||
'number_entries' => '%d článků', |
||||
'percent_of_total' => '%% ze všech', |
||||
'repartition' => 'Rozdělení článků', |
||||
'status_favorites' => 'Oblíbené', |
||||
'status_read' => 'Přečtené', |
||||
'status_total' => 'Celkem', |
||||
'status_unread' => 'Nepřečtené', |
||||
'title' => 'Statistika', |
||||
'top_feed' => 'Top ten kanálů', |
||||
), |
||||
'update' => array( |
||||
'_' => 'Aktualizace systému', |
||||
'apply' => 'Použít', |
||||
'check' => 'Zkontrolovat aktualizace', |
||||
'current_version' => 'Vaše instalace FreshRSS je verze %s.', |
||||
'last' => 'Poslední kontrola: %s', |
||||
'none' => 'Žádné nové aktualizace', |
||||
'title' => 'Aktualizovat systém', |
||||
), |
||||
'user' => array( |
||||
'articles_and_size' => '%s článků (%s)', |
||||
'create' => 'Vytvořit nového uživatele', |
||||
'email_persona' => 'Email pro přihlášení<br /><small>(pro <a href="https://persona.org/" rel="external">Mozilla Persona</a>)</small>', |
||||
'language' => 'Jazyk', |
||||
'password_form' => 'Heslo<br /><small>(pro přihlášení webovým formulářem)</small>', |
||||
'password_format' => 'Alespoň 7 znaků', |
||||
'title' => 'Správa uživatelů', |
||||
'user_list' => 'Seznam uživatelů', |
||||
'username' => 'Přihlašovací jméno', |
||||
'users' => 'Uživatelé', |
||||
), |
||||
); |
@ -0,0 +1,169 @@ |
||||
<?php |
||||
|
||||
return array( |
||||
'archiving' => array( |
||||
'_' => 'Archivace', |
||||
'advanced' => 'Pokročilé', |
||||
'delete_after' => 'Smazat články starší než', |
||||
'help' => 'Více možností je dostupných v nastavení jednotlivých kanálů', |
||||
'keep_history_by_feed' => 'Zachovat tento minimální počet článků v každém kanálu', |
||||
'optimize' => 'Optimalizovat databázi', |
||||
'optimize_help' => 'Občasná údržba zmenší velikost databáze', |
||||
'purge_now' => 'Vyčistit nyní', |
||||
'title' => 'Archivace', |
||||
'ttl' => 'Neaktualizovat častěji než', |
||||
), |
||||
'display' => array( |
||||
'_' => 'Zobrazení', |
||||
'icon' => array( |
||||
'bottom_line' => 'Spodní řádek', |
||||
'entry' => 'Ikony článků', |
||||
'publication_date' => 'Datum vydání', |
||||
'related_tags' => 'Související tagy', |
||||
'sharing' => 'Sdílení', |
||||
'top_line' => 'Horní řádek', |
||||
), |
||||
'language' => 'Jazyk', |
||||
'notif_html5' => array( |
||||
'seconds' => 'sekund (0 znamená žádný timeout)', |
||||
'timeout' => 'Timeout HTML5 notifikací', |
||||
), |
||||
'theme' => 'Vzhled', |
||||
'title' => 'Zobrazení', |
||||
'width' => array( |
||||
'content' => 'Šířka obsahu', |
||||
'large' => 'Velká', |
||||
'medium' => 'Střední', |
||||
'no_limit' => 'Bez limitu', |
||||
'thin' => 'Tenká', |
||||
), |
||||
), |
||||
'query' => array( |
||||
'_' => 'Uživatelské dotazy', |
||||
'deprecated' => 'Tento dotaz již není platný. Odkazovaná kategorie nebo kanál byly smazány.', |
||||
'filter' => 'Filtr aplikován:', |
||||
'get_all' => 'Zobrazit všechny články', |
||||
'get_category' => 'Zobrazit "%s" kategorii', |
||||
'get_favorite' => 'Zobrazit oblíbené články', |
||||
'get_feed' => 'Zobrazit "%s" článkek', |
||||
'no_filter' => 'Zrušit filtr', |
||||
'none' => 'Ještě jste nevytvořil žádný uživatelský dotaz.', |
||||
'number' => 'Dotaz n°%d', |
||||
'order_asc' => 'Zobrazit nejdříve nejstarší články', |
||||
'order_desc' => 'Zobrazit nejdříve nejnovější články', |
||||
'search' => 'Hledat "%s"', |
||||
'state_0' => 'Zobrazit všechny články', |
||||
'state_1' => 'Zobrazit přečtené články', |
||||
'state_2' => 'Zobrazit nepřečtené články', |
||||
'state_3' => 'Zobrazit všechny články', |
||||
'state_4' => 'Zobrazit oblíbené články', |
||||
'state_5' => 'Zobrazit oblíbené přečtené články', |
||||
'state_6' => 'Zobrazit oblíbené nepřečtené články', |
||||
'state_7' => 'Zobrazit oblíbené články', |
||||
'state_8' => 'Zobrazit všechny články vyjma oblíbených', |
||||
'state_9' => 'Zobrazit všechny přečtené články vyjma oblíbených', |
||||
'state_10' => 'Zobrazit všechny nepřečtené články vyjma oblíbených', |
||||
'state_11' => 'Zobrazit všechny články vyjma oblíbených', |
||||
'state_12' => 'Zobrazit všechny články', |
||||
'state_13' => 'Zobrazit přečtené články', |
||||
'state_14' => 'Zobrazit nepřečtené články', |
||||
'state_15' => 'Zobrazit všechny články', |
||||
'title' => 'Uživatelské dotazy', |
||||
), |
||||
'profile' => array( |
||||
'_' => 'Správa profilu', |
||||
'email_persona' => 'Email pro přihlášení<br /><small>(pro <a href="https://persona.org/" rel="external">Mozilla Persona</a>)</small>', |
||||
'password_api' => 'Password API<br /><small>(tzn. pro mobilní aplikace)</small>', |
||||
'password_form' => 'Heslo<br /><small>(pro přihlášení webovým formulářem)</small>', |
||||
'password_format' => 'Alespoň 7 znaků', |
||||
'title' => 'Profil', |
||||
), |
||||
'reading' => array( |
||||
'_' => 'Čtení', |
||||
'after_onread' => 'Po “označit vše jako přečtené”,', |
||||
'articles_per_page' => 'Počet článků na stranu', |
||||
'auto_load_more' => 'Načítat další články dole na stránce', |
||||
'auto_remove_article' => 'Po přečtení články schovat', |
||||
'confirm_enabled' => 'Vyžadovat potvrzení pro akci “označit vše jako přečtené”', |
||||
'display_articles_unfolded' => 'Ve výchozím stavu zobrazovat články otevřené', |
||||
'display_categories_unfolded' => 'Ve výchozím stavu zobrazovat kategorie zavřené', |
||||
'hide_read_feeds' => 'Schovat kategorie a kanály s nulovým počtem nepřečtených článků (nefunguje s nastavením “Zobrazit všechny články”)', |
||||
'img_with_lazyload' => 'Použít "lazy load" mód pro načítaní obrázků', |
||||
'jump_next' => 'skočit na další nepřečtený (kanál nebo kategorii)', |
||||
'number_divided_when_reader' => 'V režimu “Čtení” děleno dvěma.', |
||||
'read' => array( |
||||
'article_open_on_website' => 'když je otevřen původní web s článkem', |
||||
'article_viewed' => 'během čtení článku', |
||||
'scroll' => 'během skrolování', |
||||
'upon_reception' => 'po načtení článku', |
||||
'when' => 'Označit článek jako přečtený…', |
||||
), |
||||
'show' => array( |
||||
'_' => 'Počet zobrazených článků', |
||||
'adaptive' => 'Vyberte zobrazení', |
||||
'all_articles' => 'Zobrazit všechny články', |
||||
'unread' => 'Zobrazit jen nepřečtené', |
||||
), |
||||
'sort' => array( |
||||
'_' => 'Řazení', |
||||
'newer_first' => 'Nejdříve nejnovější', |
||||
'older_first' => 'Nejdříve nejstarší', |
||||
), |
||||
'sticky_post' => 'Při otevření posunout článek nahoru', |
||||
'title' => 'Čtení', |
||||
'view' => array( |
||||
'default' => 'Výchozí', |
||||
'global' => 'Přehled', |
||||
'normal' => 'Normální', |
||||
'reader' => 'Čtení', |
||||
), |
||||
), |
||||
'sharing' => array( |
||||
'_' => 'Sdílení', |
||||
'blogotext' => 'Blogotext', |
||||
'diaspora' => 'Diaspora*', |
||||
'email' => 'Email', |
||||
'facebook' => 'Facebook', |
||||
'g+' => 'Google+', |
||||
'more_information' => 'Více informací', |
||||
'print' => 'Tisk', |
||||
'shaarli' => 'Shaarli', |
||||
'share_name' => 'Jméno pro zobrazení', |
||||
'share_url' => 'Jakou URL použít pro sdílení', |
||||
'title' => 'Sdílení', |
||||
'twitter' => 'Twitter', |
||||
'wallabag' => 'wallabag', |
||||
), |
||||
'shortcut' => array( |
||||
'_' => 'Zkratky', |
||||
'article_action' => 'Články - akce', |
||||
'auto_share' => 'Sdílet', |
||||
'auto_share_help' => 'Je-li nastavena pouze jedna možnost sdílení, bude použita. Další možnosti jsou dostupné pomocí jejich čísla.', |
||||
'close_dropdown' => 'Zavřít menu', |
||||
'collapse_article' => 'Srolovat', |
||||
'first_article' => 'Skočit na první článek', |
||||
'focus_search' => 'Hledání', |
||||
'help' => 'Zobrazit documentaci', |
||||
'javascript' => 'Pro použití zkratek musí být povolen JavaScript', |
||||
'last_article' => 'Skočit na poslední článek', |
||||
'load_more' => 'Načíst více článků', |
||||
'mark_read' => 'Označit jako přečtené', |
||||
'mark_favorite' => 'Označit jako oblíbené', |
||||
'navigation' => 'Navigace', |
||||
'navigation_help' => 'Pomocí přepínače "Shift" fungují navigační zkratky v rámci kanálů.<br/>Pomocí přepínače "Alt" fungují v rámci kategorií.', |
||||
'next_article' => 'Skočit na další článek', |
||||
'other_action' => 'Ostatní akce', |
||||
'previous_article' => 'Skočit na předchozí článek', |
||||
'see_on_website' => 'Navštívit původní webovou stránku', |
||||
'shift_for_all_read' => '+ <code>shift</code> označí vše jako přečtené', |
||||
'title' => 'Zkratky', |
||||
'user_filter' => 'Aplikovat uživatelské filtry', |
||||
'user_filter_help' => 'Je-li nastaven pouze jeden filtr, bude použit. Další filtry jsou dostupné pomocí jejich čísla.', |
||||
), |
||||
'user' => array( |
||||
'articles_and_size' => '%s článků (%s)', |
||||
'current' => 'Aktuální uživatel', |
||||
'is_admin' => 'je administrátor', |
||||
'users' => 'Uživatelé', |
||||
), |
||||
); |
@ -0,0 +1,110 @@ |
||||
<?php |
||||
|
||||
return array( |
||||
'admin' => array( |
||||
'optimization_complete' => 'Optimalizace dokončena', |
||||
), |
||||
'access' => array( |
||||
'denied' => 'Nemáte oprávnění přistupovat na tuto stránku', |
||||
'not_found' => 'Tato stránka neexistuje', |
||||
), |
||||
'auth' => array( |
||||
'form' => array( |
||||
'not_set' => 'Nastal problém s konfigurací přihlašovacího systému. Zkuste to prosím později.', |
||||
'set' => 'Webový formulář je nyní výchozí přihlašovací systém.', |
||||
), |
||||
'login' => array( |
||||
'invalid' => 'Login není platný', |
||||
'success' => 'Jste přihlášen', |
||||
), |
||||
'logout' => array( |
||||
'success' => 'Jste odhlášen', |
||||
), |
||||
'no_password_set' => 'Heslo administrátora nebylo nastaveno. Tato funkce není k dispozici.', |
||||
'not_persona' => 'Resetovat lze pouze systém Persona.', |
||||
), |
||||
'conf' => array( |
||||
'error' => 'Během ukládání nastavení došlo k chybě', |
||||
'query_created' => 'Dotaz "%s" byl vytvořen.', |
||||
'shortcuts_updated' => 'Zkratky byly aktualizovány', |
||||
'updated' => 'Nastavení bylo aktualizováno', |
||||
), |
||||
'extensions' => array( |
||||
'already_enabled' => '%s je již zapnut', |
||||
'disable' => array( |
||||
'ko' => '%s nelze vypnout. Pro více detailů <a href="%s">zkontrolujte logy FressRSS</a>.', |
||||
'ok' => '%s je nyní vypnut', |
||||
), |
||||
'enable' => array( |
||||
'ko' => '%s nelze zapnout. Pro více detailů <a href="%s">zkontrolujte logy FressRSS</a>.', |
||||
'ok' => '%s je nyní zapnut', |
||||
), |
||||
'no_access' => 'Nemáte přístup k %s', |
||||
'not_enabled' => '%s není ještě zapnut', |
||||
'not_found' => '%s neexistuje', |
||||
), |
||||
'import_export' => array( |
||||
'export_no_zip_extension' => 'Na serveru není naistalována podpora zip. Zkuste prosím exportovat soubory jeden po druhém.', |
||||
'feeds_imported' => 'Vaše kanály byly naimportovány a nyní budou aktualizovány', |
||||
'feeds_imported_with_errors' => 'Vaše kanály byly naimportovány, došlo ale k nějakým chybám', |
||||
'file_cannot_be_uploaded' => 'Soubor nelze nahrát!', |
||||
'no_zip_extension' => 'Na serveru není naistalována podpora zip.', |
||||
'zip_error' => 'Během importu zip souboru došlo k chybě.', |
||||
), |
||||
'sub' => array( |
||||
'actualize' => 'Aktualizovat', |
||||
'category' => array( |
||||
'created' => 'Kategorie %s byla vytvořena.', |
||||
'deleted' => 'Kategorie byla smazána.', |
||||
'emptied' => 'Kategorie byla vyprázdněna', |
||||
'error' => 'Kategorii nelze aktualizovat', |
||||
'name_exists' => 'Název kategorie již existuje.', |
||||
'no_id' => 'Musíte upřesnit id kategorie.', |
||||
'no_name' => 'Název kategorie nemůže být prázdný.', |
||||
'not_delete_default' => 'Nelze smazat výchozí kategorii!', |
||||
'not_exist' => 'Tato kategorie neexistuje!', |
||||
'over_max' => 'Dosáhl jste maximálního počtu kategorií (%d)', |
||||
'updated' => 'Kategorie byla aktualizována.', |
||||
), |
||||
'feed' => array( |
||||
'actualized' => '<em>%s</em> bylo aktualizováno', |
||||
'actualizeds' => 'RSS kanály byly aktualizovány', |
||||
'added' => 'RSS kanál <em>%s</em> byl přidán', |
||||
'already_subscribed' => 'Již jste přihlášen k odběru <em>%s</em>', |
||||
'deleted' => 'Kanál byl smazán', |
||||
'error' => 'Kanál nelze aktualizovat', |
||||
'internal_problem' => 'RSS kanál nelze přidat. Pro detaily <a href="%s">zkontrolujte logy FressRSS</a>.', |
||||
'invalid_url' => 'URL <em>%s</em> není platné', |
||||
'marked_read' => 'Kanály byly označeny jako přečtené', |
||||
'n_actualized' => '%d kanálů bylo aktualizováno', |
||||
'n_entries_deleted' => '%d článků bylo smazáno', |
||||
'no_refresh' => 'Nelze obnovit žádné kanály…', |
||||
'not_added' => '<em>%s</em> nemůže být přidán', |
||||
'over_max' => 'Dosáhl jste maximálního počtu kanálů (%d)', |
||||
'updated' => 'Kanál byl aktualizován', |
||||
), |
||||
'purge_completed' => 'Vyprázdněno (smazáno %d článků)', |
||||
), |
||||
'update' => array( |
||||
'can_apply' => 'FreshRSS bude nyní upgradováno na <strong>verzi %s</strong>.', |
||||
'error' => 'Během upgrade došlo k chybě: %s', |
||||
'file_is_nok' => 'Zkontrolujte oprávnění adresáře <em>%s</em>. HTTP server musí mít do tohoto adresáře práva zápisu', |
||||
'finished' => 'Upgrade hotov!', |
||||
'none' => 'Novější verze není k dispozici', |
||||
'server_not_found' => 'Nelze nalézt server s instalačním souborem. [%s]', |
||||
), |
||||
'user' => array( |
||||
'created' => array( |
||||
'_' => 'Uživatel %s byl vytvořen', |
||||
'error' => 'Uživatele %s nelze vytvořit', |
||||
), |
||||
'deleted' => array( |
||||
'_' => 'Uživatel %s byl smazán', |
||||
'error' => 'Uživatele %s nelze smazat', |
||||
), |
||||
), |
||||
'profile' => array( |
||||
'error' => 'Váš profil nelze změnit', |
||||
'updated' => 'Váš profil byl změněn', |
||||
), |
||||
); |
@ -0,0 +1,164 @@ |
||||
<?php |
||||
|
||||
return array( |
||||
'action' => array( |
||||
'actualize' => 'Aktualizovat', |
||||
'back_to_rss_feeds' => '← Zpět na seznam RSS kanálů', |
||||
'cancel' => 'Zrušit', |
||||
'create' => 'Vytvořit', |
||||
'disable' => 'Zakázat', |
||||
'empty' => 'Vyprázdnit', |
||||
'enable' => 'Povolit', |
||||
'export' => 'Export', |
||||
'filter' => 'Filtrovat', |
||||
'import' => 'Import', |
||||
'manage' => 'Spravovat', |
||||
'mark_read' => 'Označit jako přečtené', |
||||
'mark_favorite' => 'Označit jako oblíbené', |
||||
'remove' => 'Odstranit', |
||||
'see_website' => 'Navštívit WWW stránku', |
||||
'submit' => 'Odeslat', |
||||
'truncate' => 'Smazat všechny články', |
||||
), |
||||
'auth' => array( |
||||
'keep_logged_in' => 'Zapamatovat přihlášení <small>(1 měsíc)</small>', |
||||
'login' => 'Login', |
||||
'login_persona' => 'Přihlášení pomocí Persona', |
||||
'login_persona_problem' => 'Problém s připojením k Persona?', |
||||
'logout' => 'Odhlášení', |
||||
'password' => 'Heslo', |
||||
'reset' => 'Reset přihlášení', |
||||
'username' => 'Uživatel', |
||||
'username_admin' => 'Název administrátorského účtu', |
||||
'will_reset' => 'Přihlašovací systém bude vyresetován: místo sytému Persona bude použito přihlášení formulářem.', |
||||
), |
||||
'date' => array( |
||||
'Apr' => '\\D\\u\\b\\e\\n', |
||||
'Aug' => '\\S\\r\\p\\e\\n', |
||||
'Dec' => '\\P\\r\\o\\s\\i\\n\\e\\c', |
||||
'Feb' => '\\Ú\\n\\o\\r', |
||||
'Jan' => '\\L\\e\\d\\e\\n', |
||||
'Jul' => '\\Č\\e\\r\\v\\e\\n\\e\\c', |
||||
'Jun' => '\\Č\\e\\r\\v\\e\\n', |
||||
'Mar' => '\\B\\ř\\e\\z\\e\\n', |
||||
'May' => '\\K\\v\\ě\\t\\e\\n', |
||||
'Nov' => '\\L\\i\\s\\t\\o\\p\\a\\d', |
||||
'Oct' => '\\Ř\\í\\j\\e\\n', |
||||
'Sep' => '\\Z\\á\\ř\\í', |
||||
'apr' => 'dub', |
||||
'april' => 'Dub', |
||||
'aug' => 'srp', |
||||
'august' => 'Srp', |
||||
'before_yesterday' => 'Předevčírem', |
||||
'dec' => 'pro', |
||||
'december' => 'Pro', |
||||
'feb' => 'úno', |
||||
'february' => 'Úno', |
||||
'format_date' => 'j\\. %s Y', |
||||
'format_date_hour' => 'j\\. %s Y \\v H\\:i', |
||||
'fri' => 'Pá', |
||||
'jan' => 'led', |
||||
'january' => 'Led', |
||||
'jul' => 'čvn', |
||||
'july' => 'Čvn', |
||||
'jun' => 'čer', |
||||
'june' => 'Čer', |
||||
'last_3_month' => 'Minulé tři měsíce', |
||||
'last_6_month' => 'Minulých šest měsíců', |
||||
'last_month' => 'Minulý měsíc', |
||||
'last_week' => 'Minulý týden', |
||||
'last_year' => 'Minulý rok', |
||||
'mar' => 'bře', |
||||
'march' => 'Bře', |
||||
'may' => 'Kvě', |
||||
'mon' => 'Po', |
||||
'month' => 'měsíce', |
||||
'nov' => 'lis', |
||||
'november' => 'Lis', |
||||
'oct' => 'říj', |
||||
'october' => 'Říj', |
||||
'sat' => 'So', |
||||
'sep' => 'zář', |
||||
'september' => 'Zář', |
||||
'sun' => 'Ne', |
||||
'thu' => 'Čt', |
||||
'today' => 'Dnes', |
||||
'tue' => 'Út', |
||||
'wed' => 'St', |
||||
'yesterday' => 'Včera', |
||||
), |
||||
'freshrss' => array( |
||||
'_' => 'FreshRSS', |
||||
'about' => 'O FreshRSS', |
||||
), |
||||
'js' => array( |
||||
'category_empty' => 'Prázdná kategorie', |
||||
'confirm_action' => 'Jste si jist, že chcete provést tuto akci? Změny nelze vrátit zpět!', |
||||
'confirm_action_feed_cat' => 'Jste si jist, že chcete provést tuto akci? Přijdete o související oblíbené položky a uživatelské dotazy. Změny nelze vrátit zpět!', |
||||
'feedback' => array( |
||||
'body_new_articles' => 'Je \\d nových článků k přečtení v FreshRSS.', |
||||
'request_failed' => 'Požadavek selhal, což může být způsobeno problémy s připojení k internetu.', |
||||
'title_new_articles' => 'FreshRSS: nové články!', |
||||
), |
||||
'new_article' => 'Jsou k dispozici nové články, stránku obnovíte kliknutím zde.', |
||||
'should_be_activated' => 'JavaScript musí být povolen', |
||||
), |
||||
'lang' => array( |
||||
'de' => 'Deutsch', |
||||
'en' => 'English', |
||||
'fr' => 'Français', |
||||
'cz' => 'Čeština', |
||||
), |
||||
'menu' => array( |
||||
'about' => 'O aplikaci', |
||||
'admin' => 'Administrace', |
||||
'archiving' => 'Archivace', |
||||
'authentication' => 'Přihlášení', |
||||
'check_install' => 'Ověření instalace', |
||||
'configuration' => 'Nastavení', |
||||
'display' => 'Zobrazení', |
||||
'extensions' => 'Rozšíření', |
||||
'logs' => 'Logy', |
||||
'queries' => 'Uživatelské dotazy', |
||||
'reading' => 'Čtení', |
||||
'search' => 'Hledat výraz nebo #tagy', |
||||
'sharing' => 'Sdílení', |
||||
'shortcuts' => 'Zkratky', |
||||
'stats' => 'Statistika', |
||||
'update' => 'Aktualizace', |
||||
'user_management' => 'Správa uživatelů', |
||||
'user_profile' => 'Profil', |
||||
), |
||||
'pagination' => array( |
||||
'first' => 'První', |
||||
'last' => 'Poslední', |
||||
'load_more' => 'Načíst více článků', |
||||
'mark_all_read' => 'Označit vše jako přečtené', |
||||
'next' => 'Další', |
||||
'nothing_to_load' => 'Žádné nové články', |
||||
'previous' => 'Předchozí', |
||||
), |
||||
'share' => array( |
||||
'blogotext' => 'Blogotext', |
||||
'diaspora' => 'Diaspora*', |
||||
'email' => 'Email', |
||||
'facebook' => 'Facebook', |
||||
'g+' => 'Google+', |
||||
'print' => 'Tisk', |
||||
'shaarli' => 'Shaarli', |
||||
'twitter' => 'Twitter', |
||||
'wallabag' => 'wallabag', |
||||
), |
||||
'short' => array( |
||||
'attention' => 'Upozornění!', |
||||
'blank_to_disable' => 'Zakázat - ponechte prázdné', |
||||
'by_author' => 'Od <em>%s</em>', |
||||
'by_default' => 'Výchozí', |
||||
'damn' => 'Sakra!', |
||||
'default_category' => 'Nezařazeno', |
||||
'no' => 'Ne', |
||||
'ok' => 'Ok!', |
||||
'or' => 'nebo', |
||||
'yes' => 'Ano', |
||||
), |
||||
); |
@ -0,0 +1,61 @@ |
||||
<?php |
||||
|
||||
return array( |
||||
'about' => array( |
||||
'_' => 'O FreshRSS', |
||||
'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>', |
||||
'bugs_reports' => 'Hlášení chyb', |
||||
'credits' => 'Poděkování', |
||||
'credits_content' => 'Některé designové prvky pocházejí z <a href="http://twitter.github.io/bootstrap/">Bootstrap</a>, FreshRSS ale tuto platformu nevyužívá. <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">Ikony</a> pocházejí z <a href="https://www.gnome.org/">GNOME projektu</a>. Font <em>Open Sans</em> vytvořil <a href="https://www.google.com/webfonts/specimen/Open+Sans">Steve Matteson</a>. Favicony jsou shromažďovány pomocí <a href="https://getfavicon.appspot.com/">getFavicon API</a>. FreshRSS je založen na PHP framework <a href="https://github.com/marienfressinaud/MINZ">Minz</a>.', |
||||
'freshrss_description' => 'FreshRSS je čtečka RSS kanálů určená k provozu na vlastním serveru, podobná <a href="http://tontof.net/kriss/feed/">Kriss Feed</a> nebo <a href="http://projet.idleman.fr/leed/">Leed</a>. Je to nenáročný a jednoduchý, zároveň ale mocný a konfigurovatelný nástroj.', |
||||
'github' => '<a href="https://github.com/FreshRSS/FreshRSS/issues">na Github</a>', |
||||
'license' => 'Licence', |
||||
'project_website' => 'Stránka projektu', |
||||
'title' => 'O FreshRSS', |
||||
'version' => 'Verze', |
||||
'website' => 'Webové stránka', |
||||
), |
||||
'feed' => array( |
||||
'add' => 'Můžete přidat kanály.', |
||||
'empty' => 'Žádné články k zobrazení.', |
||||
'rss_of' => 'RSS kanál %s', |
||||
'title' => 'RSS kanály', |
||||
'title_global' => 'Přehled', |
||||
'title_fav' => 'Oblíbené', |
||||
), |
||||
'log' => array( |
||||
'_' => 'Logy', |
||||
'clear' => 'Vymazat logy', |
||||
'empty' => 'Log je prázdný', |
||||
'title' => 'Logy', |
||||
), |
||||
'menu' => array( |
||||
'about' => 'O FreshRSS', |
||||
'add_query' => 'Vytvořit dotaz', |
||||
'before_one_day' => 'Den nazpět', |
||||
'before_one_week' => 'Před týdnem', |
||||
'favorites' => 'Oblíbené (%s)', |
||||
'global_view' => 'Přehled', |
||||
'main_stream' => 'Všechny kanály', |
||||
'mark_all_read' => 'Označit vše jako přečtené', |
||||
'mark_cat_read' => 'Označit kategorii jako přečtenou', |
||||
'mark_feed_read' => 'Označit kanál jako přečtený', |
||||
'newer_first' => 'Nové nejdříve', |
||||
'non-starred' => 'Zobrazit vše vyjma oblíbených', |
||||
'normal_view' => 'Normální', |
||||
'older_first' => 'Nejstarší nejdříve', |
||||
'queries' => 'Uživatelské dotazy', |
||||
'read' => 'Zobrazovat přečtené', |
||||
'reader_view' => 'Čtení', |
||||
'rss_view' => 'RSS kanál', |
||||
'search_short' => 'Hledat', |
||||
'starred' => 'Zobrazit oblíbené', |
||||
'stats' => 'Statistika', |
||||
'subscription' => 'Správa subskripcí', |
||||
'unread' => 'Zobrazovat nepřečtené', |
||||
), |
||||
'share' => 'Sdílet', |
||||
'tag' => array( |
||||
'related' => 'Související tagy', |
||||
), |
||||
); |
@ -0,0 +1,107 @@ |
||||
<?php |
||||
|
||||
return array( |
||||
'action' => array( |
||||
'finish' => 'Dokončit instalaci', |
||||
'fix_errors_before' => 'Chyby prosím před přechodem na další krok opravte.', |
||||
'next_step' => 'Přejít na další krok', |
||||
), |
||||
'auth' => array( |
||||
'email_persona' => 'Email pro přihlášení<br /><small>(pro <a href="https://persona.org/" rel="external">Mozilla Persona</a>)</small>', |
||||
'form' => 'Webový formulář (tradiční, vyžaduje JavaScript)', |
||||
'http' => 'HTTP (pro pokročilé uživatele s HTTPS)', |
||||
'none' => 'Žádný (nebezpečné)', |
||||
'password_form' => 'Heslo<br /><small>(pro přihlášení webovým formulářem)</small>', |
||||
'password_format' => 'Alespoň 7 znaků', |
||||
'persona' => 'Mozilla Persona (moderní, vyžaduje JavaScript)', |
||||
'type' => 'Způsob přihlášení', |
||||
), |
||||
'bdd' => array( |
||||
'_' => 'Databáze', |
||||
'conf' => array( |
||||
'_' => 'Nastavení databáze', |
||||
'ko' => 'Ověřte informace o databázi.', |
||||
'ok' => 'Nastavení databáze bylo uloženo.', |
||||
), |
||||
'host' => 'Hostitel', |
||||
'prefix' => 'Prefix tabulky', |
||||
'password' => 'Heslo', |
||||
'type' => 'Typ databáze', |
||||
'username' => 'Uživatel', |
||||
), |
||||
'check' => array( |
||||
'_' => 'Kontrola', |
||||
'cache' => array( |
||||
'nok' => 'Zkontrolujte oprávnění adresáře <em>./data/cache</em>. HTTP server musí mít do tohoto adresáře práva zápisu', |
||||
'ok' => 'Oprávnění adresáře cache jsou v pořádku.', |
||||
), |
||||
'ctype' => array( |
||||
'nok' => 'Není nainstalována požadovaná knihovna pro ověřování znaků (php-ctype).', |
||||
'ok' => 'Je nainstalována požadovaná knihovna pro ověřování znaků (ctype).', |
||||
), |
||||
'curl' => array( |
||||
'nok' => 'Nemáte cURL (balíček php5-curl).', |
||||
'ok' => 'Máte rozšíření cURL.', |
||||
), |
||||
'data' => array( |
||||
'nok' => 'Zkontrolujte oprávnění adresáře <em>./data</em>. HTTP server musí mít do tohoto adresáře práva zápisu', |
||||
'ok' => 'Oprávnění adresáře data jsou v pořádku.', |
||||
), |
||||
'dom' => array( |
||||
'nok' => 'Nemáte požadovanou knihovnu pro procházení DOM (balíček php-xml).', |
||||
'ok' => 'Máte požadovanou knihovnu pro procházení DOM.', |
||||
), |
||||
'favicons' => array( |
||||
'nok' => 'Zkontrolujte oprávnění adresáře <em>./data/favicons</em>. HTTP server musí mít do tohoto adresáře práva zápisu', |
||||
'ok' => 'Oprávnění adresáře favicons jsou v pořádku.', |
||||
), |
||||
'http_referer' => array( |
||||
'nok' => 'Zkontrolujte prosím že neměníte HTTP REFERER.', |
||||
'ok' => 'Váš HTTP REFERER je znám a odpovídá Vašemu serveru.', |
||||
), |
||||
'minz' => array( |
||||
'nok' => 'Nemáte framework Minz.', |
||||
'ok' => 'Máte framework Minz.', |
||||
), |
||||
'pcre' => array( |
||||
'nok' => 'Nemáte požadovanou knihovnu pro regulární výrazy (php-pcre).', |
||||
'ok' => 'Máte požadovanou knihovnu pro regulární výrazy (PCRE).', |
||||
), |
||||
'pdo' => array( |
||||
'nok' => 'Nemáte PDO nebo některý z podporovaných ovladačů (pdo_mysql, pdo_sqlite).', |
||||
'ok' => 'Máte PDO a alespoň jeden z podporovaných ovladačů (pdo_mysql, pdo_sqlite).', |
||||
), |
||||
'persona' => array( |
||||
'nok' => 'Zkontrolujte oprávnění adresáře <em>./data/persona</em>. HTTP server musí mít do tohoto adresáře práva zápisu', |
||||
'ok' => 'Oprávnění adresáře Mozilla Persona jsou v pořádku.', |
||||
), |
||||
'php' => array( |
||||
'nok' => 'Vaše verze PHP je %s, ale FreshRSS vyžaduje alespoň verzi %s.', |
||||
'ok' => 'Vaše verze PHP je %s a je kompatibilní s FreshRSS.', |
||||
), |
||||
'users' => array( |
||||
'nok' => 'Zkontrolujte oprávnění adresáře <em>./data/users</em>. HTTP server musí mít do tohoto adresáře práva zápisu', |
||||
'ok' => 'Oprávnění adresáře users jsou v pořádku.', |
||||
), |
||||
), |
||||
'conf' => array( |
||||
'_' => 'Obecná nastavení', |
||||
'ok' => 'Nastavení bylo uloženo.', |
||||
), |
||||
'congratulations' => 'Gratulujeme!', |
||||
'default_user' => 'Jméno výchozího uživatele <small>(maximálně 16 alfanumerických znaků)</small>', |
||||
'delete_articles_after' => 'Smazat články starší než', |
||||
'fix_errors_before' => 'Chyby prosím před přechodem na další krok opravte.', |
||||
'javascript_is_better' => 'Práce s FreshRSS je příjemnější se zapnutým JavaScriptem', |
||||
'language' => array( |
||||
'_' => 'Jazyk', |
||||
'choose' => 'Vyberte jazyk FreshRSS', |
||||
'defined' => 'Jazyk byl nastaven.', |
||||
), |
||||
'not_deleted' => 'Nastala chyba, soubor <em>%s</em> musíte smazat ručně.', |
||||
'ok' => 'Instalace byla úspěšná.', |
||||
'step' => 'krok %d', |
||||
'steps' => 'Kroky', |
||||
'title' => 'Instalace · FreshRSS', |
||||
'this_is_the_end' => 'Konec', |
||||
); |
@ -0,0 +1,61 @@ |
||||
<?php |
||||
|
||||
return array( |
||||
'category' => array( |
||||
'_' => 'Kategorie', |
||||
'add' => 'Přidat kategorii', |
||||
'empty' => 'Vyprázdit kategorii', |
||||
'new' => 'Nová kategorie', |
||||
), |
||||
'feed' => array( |
||||
'add' => 'Přidat RSS kanál', |
||||
'advanced' => 'Pokročilé', |
||||
'archiving' => 'Archivace', |
||||
'auth' => array( |
||||
'configuration' => 'Přihlášení', |
||||
'help' => 'Umožní přístup k RSS kanálům chráneným HTTP autentizací', |
||||
'http' => 'HTTP přihlášení', |
||||
'password' => 'Heslo', |
||||
'username' => 'Přihlašovací jméno', |
||||
), |
||||
'css_help' => 'Stáhne zkrácenou verzi RSS kanálů (pozor, náročnější na čas!)', |
||||
'css_path' => 'Původní CSS soubor článku z webových stránek', |
||||
'description' => 'Popis', |
||||
'empty' => 'Kanál je prázdný. Ověřte prosím zda je ještě autorem udržován.', |
||||
'error' => 'Vyskytl se problém s kanálem. Ověřte že je vždy dostupný, prosím, a poté jej aktualizujte.', |
||||
'in_main_stream' => 'Zobrazit ve “Všechny kanály”', |
||||
'informations' => 'Informace', |
||||
'keep_history' => 'Zachovat tento minimální počet článků', |
||||
'moved_category_deleted' => 'Po smazání kategorie budou v ní obsažené kanály automaticky přesunuty do <em>%s</em>.', |
||||
'no_selected' => 'Nejsou označeny žádné kanály.', |
||||
'number_entries' => '%d článků', |
||||
'stats' => 'Statistika', |
||||
'think_to_add' => 'Můžete přidat kanály.', |
||||
'title' => 'Název', |
||||
'title_add' => 'Přidat RSS kanál', |
||||
'ttl' => 'Neobnovovat častěji než', |
||||
'url' => 'URL kanálu', |
||||
'validator' => 'Zkontrolovat platnost kanálu', |
||||
'website' => 'URL webové stránky', |
||||
), |
||||
'import_export' => array( |
||||
'export' => 'Export', |
||||
'export_opml' => 'Exportovat seznam kanálů (OPML)', |
||||
'export_starred' => 'Exportovat oblíbené', |
||||
'feed_list' => 'Seznam %s článků', |
||||
'file_to_import' => 'Soubor k importu<br />(OPML, Json nebo Zip)', |
||||
'file_to_import_no_zip' => 'Soubor k importu<br />(OPML nebo Json)', |
||||
'import' => 'Import', |
||||
'starred_list' => 'Seznam oblíbených článků', |
||||
'title' => 'Import / export', |
||||
), |
||||
'menu' => array( |
||||
'bookmark' => 'Přihlásit (FreshRSS bookmark)', |
||||
'import_export' => 'Import / export', |
||||
'subscription_management' => 'Správa subskripcí', |
||||
), |
||||
'title' => array( |
||||
'_' => 'Správa subskripcí', |
||||
'feed_management' => 'Správa RSS kanálů', |
||||
), |
||||
); |
@ -1,31 +1,104 @@ |
||||
<?php |
||||
|
||||
# Do not modify this file, which is only a template. |
||||
# See `config.php` after the install process is completed. |
||||
return array( |
||||
|
||||
# Set to `development` to get additional error messages, |
||||
# or to `production` to get only the most important messages. |
||||
'environment' => 'production', |
||||
|
||||
# Used to make crypto more unique. Generated during install. |
||||
'salt' => '', |
||||
|
||||
# Leave empty for most cases. |
||||
# Ability to override the address of the FreshRSS instance, |
||||
# used when building absolute URLs. |
||||
'base_url' => '', |
||||
|
||||
# Natural language of the user interface, e.g. `en`, `fr`. |
||||
'language' => 'en', |
||||
|
||||
# Title of this FreshRSS instance in the Web user interface. |
||||
'title' => 'FreshRSS', |
||||
|
||||
# Name of the user that has administration rights. |
||||
'default_user' => '_', |
||||
|
||||
# Allow or not visitors without login to see the articles |
||||
# of the default user. |
||||
'allow_anonymous' => false, |
||||
|
||||
# Allow or not anonymous users to start the refresh process. |
||||
'allow_anonymous_refresh' => false, |
||||
|
||||
# Login method: |
||||
# `none` is without password and shows only the default user; |
||||
# `form` is a conventional Web login form; |
||||
# `persona` is the email-based login by Mozilla; |
||||
# `http_auth` is an access controled by the HTTP Web server (e.g. `/FreshRSS/p/i/.htaccess` for Apache) |
||||
# if you use `http_auth`, remember to protect only `/FreshRSS/p/i/`, |
||||
# and in particular not protect `/FreshRSS/p/api/` if you would like to use the API (different login system). |
||||
'auth_type' => 'none', |
||||
|
||||
# Allow or not the use of the API, used for mobile apps. |
||||
# End-point is http://example.net/FreshRSS/p/api/greader.php |
||||
# You need to set the user's API password. |
||||
'api_enabled' => false, |
||||
|
||||
# Allow or not the use of an unsafe login, |
||||
# by providing username and password in the login URL: |
||||
# http://example.net/FreshRSS/p/i/?c=auth&a=login&u=alice&p=1234 |
||||
'unsafe_autologin_enabled' => false, |
||||
|
||||
# Enable or not the use of syslog to log the activity of |
||||
# SimplePie, which is retrieving RSS feeds via HTTP requests. |
||||
'simplepie_syslog_enabled' => true, |
||||
|
||||
'limits' => array( |
||||
|
||||
# Duration in seconds of the SimplePie cache, |
||||
# during which a query to the RSS feed will return the local cached version. |
||||
# Especially important for multi-user setups. |
||||
'cache_duration' => 800, |
||||
|
||||
# SimplePie HTTP request timeout in seconds. |
||||
'timeout' => 10, |
||||
|
||||
# If a user has not used FreshRSS for more than x seconds, |
||||
# then its feeds are not refreshed anymore. |
||||
'max_inactivity' => PHP_INT_MAX, |
||||
|
||||
# Max number of feeds for a user. |
||||
'max_feeds' => 16384, |
||||
|
||||
# Max number of categories for a user. |
||||
'max_categories' => 16384, |
||||
|
||||
), |
||||
|
||||
'db' => array( |
||||
|
||||
# Type of database: `sqlite` or `mysql`. |
||||
'type' => 'sqlite', |
||||
|
||||
# MySQL host. |
||||
'host' => '', |
||||
|
||||
# MySQL user. |
||||
'user' => '', |
||||
|
||||
# MySQL password. |
||||
'password' => '', |
||||
|
||||
# MySQL database. |
||||
'base' => '', |
||||
|
||||
# MySQL table prefix. |
||||
'prefix' => '', |
||||
|
||||
), |
||||
|
||||
# List of enabled FreshRSS extensions. |
||||
'extensions_enabled' => array(), |
||||
); |
||||
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,5 @@ |
||||
<?php |
||||
|
||||
class ContextTest extends \PHPUnit_Framework_TestCase { |
||||
|
||||
} |
@ -0,0 +1,293 @@ |
||||
<?php |
||||
|
||||
require_once(LIB_PATH . '/lib_date.php'); |
||||
|
||||
class SearchTest extends \PHPUnit_Framework_TestCase { |
||||
|
||||
/** |
||||
* @dataProvider provideEmptyInput |
||||
* @param string|null $input |
||||
*/ |
||||
public function test__construct_whenInputIsEmpty_getsOnlyNullValues($input) { |
||||
$search = new FreshRSS_Search($input); |
||||
$this->assertEquals('', $search->getRawInput()); |
||||
$this->assertNull($search->getIntitle()); |
||||
$this->assertNull($search->getMinDate()); |
||||
$this->assertNull($search->getMaxDate()); |
||||
$this->assertNull($search->getMinPubdate()); |
||||
$this->assertNull($search->getMaxPubdate()); |
||||
$this->assertNull($search->getAuthor()); |
||||
$this->assertNull($search->getTags()); |
||||
$this->assertNull($search->getSearch()); |
||||
} |
||||
|
||||
/** |
||||
* Return an array of values for the search object. |
||||
* Here is the description of the values |
||||
* @return array |
||||
*/ |
||||
public function provideEmptyInput() { |
||||
return array( |
||||
array(''), |
||||
array(null), |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* @dataProvider provideIntitleSearch |
||||
* @param string $input |
||||
* @param string $intitle_value |
||||
* @param string|null $search_value |
||||
*/ |
||||
public function test__construct_whenInputContainsIntitle_setsIntitlePropery($input, $intitle_value, $search_value) { |
||||
$search = new FreshRSS_Search($input); |
||||
$this->assertEquals($intitle_value, $search->getIntitle()); |
||||
$this->assertEquals($search_value, $search->getSearch()); |
||||
} |
||||
|
||||
/** |
||||
* @return array |
||||
*/ |
||||
public function provideIntitleSearch() { |
||||
return array( |
||||
array('intitle:word1', 'word1', null), |
||||
array('intitle:word1 word2', 'word1', array('word2')), |
||||
array('intitle:"word1 word2"', 'word1 word2', null), |
||||
array("intitle:'word1 word2'", 'word1 word2', null), |
||||
array('word1 intitle:word2', 'word2', array('word1')), |
||||
array('word1 intitle:word2 word3', 'word2', array('word1', 'word3')), |
||||
array('word1 intitle:"word2 word3"', 'word2 word3', array('word1')), |
||||
array("word1 intitle:'word2 word3'", 'word2 word3', array('word1')), |
||||
array('intitle:word1 intitle:word2', 'word1', array('intitle:word2')), |
||||
array('intitle: word1 word2', null, array('word1', 'word2')), |
||||
array('intitle:123', '123', null), |
||||
array('intitle:"word1 word2" word3"', 'word1 word2', array('word3"')), |
||||
array("intitle:'word1 word2' word3'", 'word1 word2', array("word3'")), |
||||
array('intitle:"word1 word2\' word3"', "word1 word2' word3", null), |
||||
array("intitle:'word1 word2\" word3'", 'word1 word2" word3', null), |
||||
array("intitle:word1 'word2 word3' word4", 'word1', array('word2 word3', 'word4')), |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* @dataProvider provideAuthorSearch |
||||
* @param string $input |
||||
* @param string $author_value |
||||
* @param string|null $search_value |
||||
*/ |
||||
public function test__construct_whenInputContainsAuthor_setsAuthorValue($input, $author_value, $search_value) { |
||||
$search = new FreshRSS_Search($input); |
||||
$this->assertEquals($author_value, $search->getAuthor()); |
||||
$this->assertEquals($search_value, $search->getSearch()); |
||||
} |
||||
|
||||
/** |
||||
* @return array |
||||
*/ |
||||
public function provideAuthorSearch() { |
||||
return array( |
||||
array('author:word1', 'word1', null), |
||||
array('author:word1 word2', 'word1', array('word2')), |
||||
array('author:"word1 word2"', 'word1 word2', null), |
||||
array("author:'word1 word2'", 'word1 word2', null), |
||||
array('word1 author:word2', 'word2', array('word1')), |
||||
array('word1 author:word2 word3', 'word2', array('word1', 'word3')), |
||||
array('word1 author:"word2 word3"', 'word2 word3', array('word1')), |
||||
array("word1 author:'word2 word3'", 'word2 word3', array('word1')), |
||||
array('author:word1 author:word2', 'word1', array('author:word2')), |
||||
array('author: word1 word2', null, array('word1', 'word2')), |
||||
array('author:123', '123', null), |
||||
array('author:"word1 word2" word3"', 'word1 word2', array('word3"')), |
||||
array("author:'word1 word2' word3'", 'word1 word2', array("word3'")), |
||||
array('author:"word1 word2\' word3"', "word1 word2' word3", null), |
||||
array("author:'word1 word2\" word3'", 'word1 word2" word3', null), |
||||
array("author:word1 'word2 word3' word4", 'word1', array('word2 word3', 'word4')), |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* @dataProvider provideInurlSearch |
||||
* @param string $input |
||||
* @param string $inurl_value |
||||
* @param string|null $search_value |
||||
*/ |
||||
public function test__construct_whenInputContainsInurl_setsInurlValue($input, $inurl_value, $search_value) { |
||||
$search = new FreshRSS_Search($input); |
||||
$this->assertEquals($inurl_value, $search->getInurl()); |
||||
$this->assertEquals($search_value, $search->getSearch()); |
||||
} |
||||
|
||||
/** |
||||
* @return array |
||||
*/ |
||||
public function provideInurlSearch() { |
||||
return array( |
||||
array('inurl:word1', 'word1', null), |
||||
array('inurl: word1', null, array('word1')), |
||||
array('inurl:123', '123', null), |
||||
array('inurl:word1 word2', 'word1', array('word2')), |
||||
array('inurl:"word1 word2"', '"word1', array('word2"')), |
||||
array("inurl:word1 'word2 word3' word4", 'word1', array('word2 word3', 'word4')), |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* @dataProvider provideDateSearch |
||||
* @param string $input |
||||
* @param string $min_date_value |
||||
* @param string $max_date_value |
||||
*/ |
||||
public function test__construct_whenInputContainsDate_setsDateValues($input, $min_date_value, $max_date_value) { |
||||
$search = new FreshRSS_Search($input); |
||||
$this->assertEquals($min_date_value, $search->getMinDate()); |
||||
$this->assertEquals($max_date_value, $search->getMaxDate()); |
||||
} |
||||
|
||||
/** |
||||
* @return array |
||||
*/ |
||||
public function provideDateSearch() { |
||||
return array( |
||||
array('date:2007-03-01T13:00:00Z/2008-05-11T15:30:00Z', '1172754000', '1210519800'), |
||||
array('date:2007-03-01T13:00:00Z/P1Y2M10DT2H30M', '1172754000', '1210516199'), |
||||
array('date:P1Y2M10DT2H30M/2008-05-11T15:30:00Z', '1172757601', '1210519800'), |
||||
array('date:2007-03-01/2008-05-11', '1172725200', '1210564799'), |
||||
array('date:2007-03-01/', '1172725200', ''), |
||||
array('date:/2008-05-11', '', '1210564799'), |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* @dataProvider providePubdateSearch |
||||
* @param string $input |
||||
* @param string $min_pubdate_value |
||||
* @param string $max_pubdate_value |
||||
*/ |
||||
public function test__construct_whenInputContainsPubdate_setsPubdateValues($input, $min_pubdate_value, $max_pubdate_value) { |
||||
$search = new FreshRSS_Search($input); |
||||
$this->assertEquals($min_pubdate_value, $search->getMinPubdate()); |
||||
$this->assertEquals($max_pubdate_value, $search->getMaxPubdate()); |
||||
} |
||||
|
||||
/** |
||||
* @return array |
||||
*/ |
||||
public function providePubdateSearch() { |
||||
return array( |
||||
array('pubdate:2007-03-01T13:00:00Z/2008-05-11T15:30:00Z', '1172754000', '1210519800'), |
||||
array('pubdate:2007-03-01T13:00:00Z/P1Y2M10DT2H30M', '1172754000', '1210516199'), |
||||
array('pubdate:P1Y2M10DT2H30M/2008-05-11T15:30:00Z', '1172757601', '1210519800'), |
||||
array('pubdate:2007-03-01/2008-05-11', '1172725200', '1210564799'), |
||||
array('pubdate:2007-03-01/', '1172725200', ''), |
||||
array('pubdate:/2008-05-11', '', '1210564799'), |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* @dataProvider provideTagsSearch |
||||
* @param string $input |
||||
* @param string $tags_value |
||||
* @param string|null $search_value |
||||
*/ |
||||
public function test__construct_whenInputContainsTags_setsTagsValue($input, $tags_value, $search_value) { |
||||
$search = new FreshRSS_Search($input); |
||||
$this->assertEquals($tags_value, $search->getTags()); |
||||
$this->assertEquals($search_value, $search->getSearch()); |
||||
} |
||||
|
||||
/** |
||||
* @return array |
||||
*/ |
||||
public function provideTagsSearch() { |
||||
return array( |
||||
array('#word1', array('word1'), null), |
||||
array('# word1', null, array('#', 'word1')), |
||||
array('#123', array('123'), null), |
||||
array('#word1 word2', array('word1'), array('word2')), |
||||
array('#"word1 word2"', array('"word1'), array('word2"')), |
||||
array('#word1 #word2', array('word1', 'word2'), null), |
||||
array("#word1 'word2 word3' word4", array('word1'), array('word2 word3', 'word4')), |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* @dataProvider provideMultipleSearch |
||||
* @param string $input |
||||
* @param string $author_value |
||||
* @param string $min_date_value |
||||
* @param string $max_date_value |
||||
* @param string $intitle_value |
||||
* @param string $inurl_value |
||||
* @param string $min_pubdate_value |
||||
* @param string $max_pubdate_value |
||||
* @param array $tags_value |
||||
* @param string|null $search_value |
||||
*/ |
||||
public function test__construct_whenInputContainsMultipleKeywords_setsValues($input, $author_value, $min_date_value, $max_date_value, $intitle_value, $inurl_value, $min_pubdate_value, $max_pubdate_value, $tags_value, $search_value) { |
||||
$search = new FreshRSS_Search($input); |
||||
$this->assertEquals($author_value, $search->getAuthor()); |
||||
$this->assertEquals($min_date_value, $search->getMinDate()); |
||||
$this->assertEquals($max_date_value, $search->getMaxDate()); |
||||
$this->assertEquals($intitle_value, $search->getIntitle()); |
||||
$this->assertEquals($inurl_value, $search->getInurl()); |
||||
$this->assertEquals($min_pubdate_value, $search->getMinPubdate()); |
||||
$this->assertEquals($max_pubdate_value, $search->getMaxPubdate()); |
||||
$this->assertEquals($tags_value, $search->getTags()); |
||||
$this->assertEquals($search_value, $search->getSearch()); |
||||
$this->assertEquals($input, $search->getRawInput()); |
||||
} |
||||
|
||||
public function provideMultipleSearch() { |
||||
return array( |
||||
array( |
||||
'author:word1 date:2007-03-01/2008-05-11 intitle:word2 inurl:word3 pubdate:2007-03-01/2008-05-11 #word4 #word5', |
||||
'word1', |
||||
'1172725200', |
||||
'1210564799', |
||||
'word2', |
||||
'word3', |
||||
'1172725200', |
||||
'1210564799', |
||||
array('word4', 'word5'), |
||||
null, |
||||
), |
||||
array( |
||||
'word6 intitle:word2 inurl:word3 pubdate:2007-03-01/2008-05-11 #word4 author:word1 #word5 date:2007-03-01/2008-05-11', |
||||
'word1', |
||||
'1172725200', |
||||
'1210564799', |
||||
'word2', |
||||
'word3', |
||||
'1172725200', |
||||
'1210564799', |
||||
array('word4', 'word5'), |
||||
array('word6'), |
||||
), |
||||
array( |
||||
'word6 intitle:word2 inurl:word3 pubdate:2007-03-01/2008-05-11 #word4 author:word1 #word5 word7 date:2007-03-01/2008-05-11', |
||||
'word1', |
||||
'1172725200', |
||||
'1210564799', |
||||
'word2', |
||||
'word3', |
||||
'1172725200', |
||||
'1210564799', |
||||
array('word4', 'word5'), |
||||
array('word6', 'word7'), |
||||
), |
||||
array( |
||||
'word6 intitle:word2 inurl:word3 pubdate:2007-03-01/2008-05-11 #word4 author:word1 #word5 "word7 word8" date:2007-03-01/2008-05-11', |
||||
'word1', |
||||
'1172725200', |
||||
'1210564799', |
||||
'word2', |
||||
'word3', |
||||
'1172725200', |
||||
'1210564799', |
||||
array('word4', 'word5'), |
||||
array('word7 word8', 'word6'), |
||||
), |
||||
); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,229 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* Description of UserQueryTest |
||||
*/ |
||||
class UserQueryTest extends \PHPUnit_Framework_TestCase { |
||||
|
||||
public function test__construct_whenAllQuery_storesAllParameters() { |
||||
$query = array('get' => 'a'); |
||||
$user_query = new FreshRSS_UserQuery($query); |
||||
$this->assertEquals('all', $user_query->getGetName()); |
||||
$this->assertEquals('all', $user_query->getGetType()); |
||||
} |
||||
|
||||
public function test__construct_whenFavoriteQuery_storesFavoriteParameters() { |
||||
$query = array('get' => 's'); |
||||
$user_query = new FreshRSS_UserQuery($query); |
||||
$this->assertEquals('favorite', $user_query->getGetName()); |
||||
$this->assertEquals('favorite', $user_query->getGetType()); |
||||
} |
||||
|
||||
/** |
||||
* @expectedException Exceptions/FreshRSS_DAO_Exception |
||||
* @expectedExceptionMessage Category DAO is not loaded in UserQuery |
||||
*/ |
||||
public function test__construct_whenCategoryQueryAndNoDao_throwsException() { |
||||
$this->markTestIncomplete('There is a problem with the exception autoloading. We need to make a better autoloading process'); |
||||
$query = array('get' => 'c_1'); |
||||
new FreshRSS_UserQuery($query); |
||||
} |
||||
|
||||
public function test__construct_whenCategoryQuery_storesCategoryParameters() { |
||||
$category_name = 'some category name'; |
||||
$cat = $this->getMock('FreshRSS_Category'); |
||||
$cat->expects($this->atLeastOnce()) |
||||
->method('name') |
||||
->withAnyParameters() |
||||
->willReturn($category_name); |
||||
$cat_dao = $this->getMock('FreshRSS_Searchable'); |
||||
$cat_dao->expects($this->atLeastOnce()) |
||||
->method('searchById') |
||||
->withAnyParameters() |
||||
->willReturn($cat); |
||||
$query = array('get' => 'c_1'); |
||||
$user_query = new FreshRSS_UserQuery($query, null, $cat_dao); |
||||
$this->assertEquals($category_name, $user_query->getGetName()); |
||||
$this->assertEquals('category', $user_query->getGetType()); |
||||
} |
||||
|
||||
/** |
||||
* @expectedException Exceptions/FreshRSS_DAO_Exception |
||||
* @expectedExceptionMessage Feed DAO is not loaded in UserQuery |
||||
*/ |
||||
public function test__construct_whenFeedQueryAndNoDao_throwsException() { |
||||
$this->markTestIncomplete('There is a problem with the exception autoloading. We need to make a better autoloading process'); |
||||
$query = array('get' => 'c_1'); |
||||
new FreshRSS_UserQuery($query); |
||||
} |
||||
|
||||
public function test__construct_whenFeedQuery_storesFeedParameters() { |
||||
$feed_name = 'some feed name'; |
||||
$feed = $this->getMock('FreshRSS_Feed', array(), array('', false)); |
||||
$feed->expects($this->atLeastOnce()) |
||||
->method('name') |
||||
->withAnyParameters() |
||||
->willReturn($feed_name); |
||||
$feed_dao = $this->getMock('FreshRSS_Searchable'); |
||||
$feed_dao->expects($this->atLeastOnce()) |
||||
->method('searchById') |
||||
->withAnyParameters() |
||||
->willReturn($feed); |
||||
$query = array('get' => 'f_1'); |
||||
$user_query = new FreshRSS_UserQuery($query, $feed_dao, null); |
||||
$this->assertEquals($feed_name, $user_query->getGetName()); |
||||
$this->assertEquals('feed', $user_query->getGetType()); |
||||
} |
||||
|
||||
public function test__construct_whenUnknownQuery_doesStoreParameters() { |
||||
$query = array('get' => 'q'); |
||||
$user_query = new FreshRSS_UserQuery($query); |
||||
$this->assertNull($user_query->getGetName()); |
||||
$this->assertNull($user_query->getGetType()); |
||||
} |
||||
|
||||
public function test__construct_whenName_storesName() { |
||||
$name = 'some name'; |
||||
$query = array('name' => $name); |
||||
$user_query = new FreshRSS_UserQuery($query); |
||||
$this->assertEquals($name, $user_query->getName()); |
||||
} |
||||
|
||||
public function test__construct_whenOrder_storesOrder() { |
||||
$order = 'some order'; |
||||
$query = array('order' => $order); |
||||
$user_query = new FreshRSS_UserQuery($query); |
||||
$this->assertEquals($order, $user_query->getOrder()); |
||||
} |
||||
|
||||
public function test__construct_whenState_storesState() { |
||||
$state = 'some state'; |
||||
$query = array('state' => $state); |
||||
$user_query = new FreshRSS_UserQuery($query); |
||||
$this->assertEquals($state, $user_query->getState()); |
||||
} |
||||
|
||||
public function test__construct_whenUrl_storesUrl() { |
||||
$url = 'some url'; |
||||
$query = array('url' => $url); |
||||
$user_query = new FreshRSS_UserQuery($query); |
||||
$this->assertEquals($url, $user_query->getUrl()); |
||||
} |
||||
|
||||
public function testToArray_whenNoData_returnsEmptyArray() { |
||||
$user_query = new FreshRSS_UserQuery(array()); |
||||
$this->assertInternalType('array', $user_query->toArray()); |
||||
$this->assertCount(0, $user_query->toArray()); |
||||
} |
||||
|
||||
public function testToArray_whenData_returnsArray() { |
||||
$query = array( |
||||
'get' => 's', |
||||
'name' => 'some name', |
||||
'order' => 'some order', |
||||
'search' => 'some search', |
||||
'state' => 'some state', |
||||
'url' => 'some url', |
||||
); |
||||
$user_query = new FreshRSS_UserQuery($query); |
||||
$this->assertInternalType('array', $user_query->toArray()); |
||||
$this->assertCount(6, $user_query->toArray()); |
||||
$this->assertEquals($query, $user_query->toArray()); |
||||
} |
||||
|
||||
public function testHasSearch_whenSearch_returnsTrue() { |
||||
$query = array( |
||||
'search' => 'some search', |
||||
); |
||||
$user_query = new FreshRSS_UserQuery($query); |
||||
$this->assertTrue($user_query->hasSearch()); |
||||
} |
||||
|
||||
public function testHasSearch_whenNoSearch_returnsFalse() { |
||||
$user_query = new FreshRSS_UserQuery(array()); |
||||
$this->assertFalse($user_query->hasSearch()); |
||||
} |
||||
|
||||
public function testHasParameters_whenAllQuery_returnsFalse() { |
||||
$query = array('get' => 'a'); |
||||
$user_query = new FreshRSS_UserQuery($query); |
||||
$this->assertFalse($user_query->hasParameters()); |
||||
} |
||||
|
||||
public function testHasParameters_whenNoParameter_returnsFalse() { |
||||
$query = array(); |
||||
$user_query = new FreshRSS_UserQuery($query); |
||||
$this->assertFalse($user_query->hasParameters()); |
||||
} |
||||
|
||||
public function testHasParameters_whenParameter_returnTrue() { |
||||
$query = array('get' => 's'); |
||||
$user_query = new FreshRSS_UserQuery($query); |
||||
$this->assertTrue($user_query->hasParameters()); |
||||
} |
||||
|
||||
public function testIsDeprecated_whenCategoryExists_returnFalse() { |
||||
$cat = $this->getMock('FreshRSS_Category'); |
||||
$cat_dao = $this->getMock('FreshRSS_Searchable'); |
||||
$cat_dao->expects($this->atLeastOnce()) |
||||
->method('searchById') |
||||
->withAnyParameters() |
||||
->willReturn($cat); |
||||
$query = array('get' => 'c_1'); |
||||
$user_query = new FreshRSS_UserQuery($query, null, $cat_dao); |
||||
$this->assertFalse($user_query->isDeprecated()); |
||||
} |
||||
|
||||
public function testIsDeprecated_whenCategoryDoesNotExist_returnTrue() { |
||||
$cat_dao = $this->getMock('FreshRSS_Searchable'); |
||||
$cat_dao->expects($this->atLeastOnce()) |
||||
->method('searchById') |
||||
->withAnyParameters() |
||||
->willReturn(null); |
||||
$query = array('get' => 'c_1'); |
||||
$user_query = new FreshRSS_UserQuery($query, null, $cat_dao); |
||||
$this->assertTrue($user_query->isDeprecated()); |
||||
} |
||||
|
||||
public function testIsDeprecated_whenFeedExists_returnFalse() { |
||||
$feed = $this->getMock('FreshRSS_Feed', array(), array('', false)); |
||||
$feed_dao = $this->getMock('FreshRSS_Searchable'); |
||||
$feed_dao->expects($this->atLeastOnce()) |
||||
->method('searchById') |
||||
->withAnyParameters() |
||||
->willReturn($feed); |
||||
$query = array('get' => 'f_1'); |
||||
$user_query = new FreshRSS_UserQuery($query, $feed_dao, null); |
||||
$this->assertFalse($user_query->isDeprecated()); |
||||
} |
||||
|
||||
public function testIsDeprecated_whenFeedDoesNotExist_returnTrue() { |
||||
$feed_dao = $this->getMock('FreshRSS_Searchable'); |
||||
$feed_dao->expects($this->atLeastOnce()) |
||||
->method('searchById') |
||||
->withAnyParameters() |
||||
->willReturn(null); |
||||
$query = array('get' => 'f_1'); |
||||
$user_query = new FreshRSS_UserQuery($query, $feed_dao, null); |
||||
$this->assertTrue($user_query->isDeprecated()); |
||||
} |
||||
|
||||
public function testIsDeprecated_whenAllQuery_returnFalse() { |
||||
$query = array('get' => 'a'); |
||||
$user_query = new FreshRSS_UserQuery($query); |
||||
$this->assertFalse($user_query->isDeprecated()); |
||||
} |
||||
|
||||
public function testIsDeprecated_whenFavoriteQuery_returnFalse() { |
||||
$query = array('get' => 's'); |
||||
$user_query = new FreshRSS_UserQuery($query); |
||||
$this->assertFalse($user_query->isDeprecated()); |
||||
} |
||||
|
||||
public function testIsDeprecated_whenUnknownQuery_returnFalse() { |
||||
$query = array('get' => 'q'); |
||||
$user_query = new FreshRSS_UserQuery($query); |
||||
$this->assertFalse($user_query->isDeprecated()); |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue