diff options
Diffstat (limited to 'src')
24 files changed, 327 insertions, 128 deletions
diff --git a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadTaggingRuleData.php b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadTaggingRuleData.php index 7efe6356..55abd63c 100644 --- a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadTaggingRuleData.php +++ b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadTaggingRuleData.php | |||
@@ -36,6 +36,13 @@ class LoadTaggingRuleData extends AbstractFixture implements OrderedFixtureInter | |||
36 | 36 | ||
37 | $manager->persist($tr3); | 37 | $manager->persist($tr3); |
38 | 38 | ||
39 | $tr4 = new TaggingRule(); | ||
40 | $tr4->setRule('content notmatches "basket"'); | ||
41 | $tr4->setTags(['foot']); | ||
42 | $tr4->setConfig($this->getReference('admin-config')); | ||
43 | |||
44 | $manager->persist($tr4); | ||
45 | |||
39 | $manager->flush(); | 46 | $manager->flush(); |
40 | } | 47 | } |
41 | 48 | ||
diff --git a/src/Wallabag/CoreBundle/Entity/TaggingRule.php b/src/Wallabag/CoreBundle/Entity/TaggingRule.php index 72651b19..84e11e26 100644 --- a/src/Wallabag/CoreBundle/Entity/TaggingRule.php +++ b/src/Wallabag/CoreBundle/Entity/TaggingRule.php | |||
@@ -31,7 +31,7 @@ class TaggingRule | |||
31 | * @Assert\Length(max=255) | 31 | * @Assert\Length(max=255) |
32 | * @RulerZAssert\ValidRule( | 32 | * @RulerZAssert\ValidRule( |
33 | * allowed_variables={"title", "url", "isArchived", "isStared", "content", "language", "mimetype", "readingTime", "domainName"}, | 33 | * allowed_variables={"title", "url", "isArchived", "isStared", "content", "language", "mimetype", "readingTime", "domainName"}, |
34 | * allowed_operators={">", "<", ">=", "<=", "=", "is", "!=", "and", "not", "or", "matches"} | 34 | * allowed_operators={">", "<", ">=", "<=", "=", "is", "!=", "and", "not", "or", "matches", "notmatches"} |
35 | * ) | 35 | * ) |
36 | * @ORM\Column(name="rule", type="string", nullable=false) | 36 | * @ORM\Column(name="rule", type="string", nullable=false) |
37 | */ | 37 | */ |
@@ -87,7 +87,7 @@ class TaggingRule | |||
87 | /** | 87 | /** |
88 | * Set tags. | 88 | * Set tags. |
89 | * | 89 | * |
90 | * @param array<string> $tags | 90 | * @param array <string> $tags |
91 | * | 91 | * |
92 | * @return TaggingRule | 92 | * @return TaggingRule |
93 | */ | 93 | */ |
diff --git a/src/Wallabag/CoreBundle/Operator/Doctrine/NotMatches.php b/src/Wallabag/CoreBundle/Operator/Doctrine/NotMatches.php new file mode 100644 index 00000000..b7f9da57 --- /dev/null +++ b/src/Wallabag/CoreBundle/Operator/Doctrine/NotMatches.php | |||
@@ -0,0 +1,25 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Operator\Doctrine; | ||
4 | |||
5 | /** | ||
6 | * Provides a "notmatches" operator used for tagging rules. | ||
7 | * | ||
8 | * It asserts that a given pattern is not contained in a subject, in a | ||
9 | * case-insensitive way. | ||
10 | * | ||
11 | * This operator will be used to compile tagging rules in DQL, usable | ||
12 | * by Doctrine ORM. | ||
13 | * It's registered in RulerZ using a service (wallabag.operator.doctrine.notmatches); | ||
14 | */ | ||
15 | class NotMatches | ||
16 | { | ||
17 | public function __invoke($subject, $pattern) | ||
18 | { | ||
19 | if ($pattern[0] === "'") { | ||
20 | $pattern = sprintf("'%%%s%%'", substr($pattern, 1, -1)); | ||
21 | } | ||
22 | |||
23 | return sprintf('UPPER(%s) NOT LIKE UPPER(%s)', $subject, $pattern); | ||
24 | } | ||
25 | } | ||
diff --git a/src/Wallabag/CoreBundle/Operator/PHP/NotMatches.php b/src/Wallabag/CoreBundle/Operator/PHP/NotMatches.php new file mode 100644 index 00000000..68b2676f --- /dev/null +++ b/src/Wallabag/CoreBundle/Operator/PHP/NotMatches.php | |||
@@ -0,0 +1,21 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Operator\PHP; | ||
4 | |||
5 | /** | ||
6 | * Provides a "notmatches" operator used for tagging rules. | ||
7 | * | ||
8 | * It asserts that a given pattern is not contained in a subject, in a | ||
9 | * case-insensitive way. | ||
10 | * | ||
11 | * This operator will be used to compile tagging rules in PHP, usable | ||
12 | * directly on Entry objects for instance. | ||
13 | * It's registered in RulerZ using a service (wallabag.operator.array.notmatches); | ||
14 | */ | ||
15 | class NotMatches | ||
16 | { | ||
17 | public function __invoke($subject, $pattern) | ||
18 | { | ||
19 | return stripos($subject, $pattern) === false; | ||
20 | } | ||
21 | } | ||
diff --git a/src/Wallabag/CoreBundle/Resources/config/services.yml b/src/Wallabag/CoreBundle/Resources/config/services.yml index 51d6ab47..bccb2e19 100644 --- a/src/Wallabag/CoreBundle/Resources/config/services.yml +++ b/src/Wallabag/CoreBundle/Resources/config/services.yml | |||
@@ -125,6 +125,16 @@ services: | |||
125 | tags: | 125 | tags: |
126 | - { name: rulerz.operator, target: doctrine, operator: matches, inline: true } | 126 | - { name: rulerz.operator, target: doctrine, operator: matches, inline: true } |
127 | 127 | ||
128 | wallabag.operator.array.notmatches: | ||
129 | class: Wallabag\CoreBundle\Operator\PHP\NotMatches | ||
130 | tags: | ||
131 | - { name: rulerz.operator, target: native, operator: notmatches } | ||
132 | |||
133 | wallabag.operator.doctrine.notmatches: | ||
134 | class: Wallabag\CoreBundle\Operator\Doctrine\NotMatches | ||
135 | tags: | ||
136 | - { name: rulerz.operator, target: doctrine, operator: notmatches, inline: true } | ||
137 | |||
128 | wallabag_core.helper.redirect: | 138 | wallabag_core.helper.redirect: |
129 | class: Wallabag\CoreBundle\Helper\Redirect | 139 | class: Wallabag\CoreBundle\Helper\Redirect |
130 | arguments: | 140 | arguments: |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml index 72493fe3..57319af7 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml | |||
@@ -155,7 +155,7 @@ config: | |||
155 | # or: 'One rule OR another' | 155 | # or: 'One rule OR another' |
156 | # and: 'One rule AND another' | 156 | # and: 'One rule AND another' |
157 | # matches: 'Tests that a <i>subject</i> is matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>' | 157 | # matches: 'Tests that a <i>subject</i> is matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>' |
158 | 158 | # notmatches: 'Tests that a <i>subject</i> is not matches a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' | |
159 | entry: | 159 | entry: |
160 | page_titles: | 160 | page_titles: |
161 | # unread: 'Unread entries' | 161 | # unread: 'Unread entries' |
@@ -512,6 +512,8 @@ user: | |||
512 | # delete: Delete | 512 | # delete: Delete |
513 | # delete_confirm: Are you sure? | 513 | # delete_confirm: Are you sure? |
514 | # back_to_list: Back to list | 514 | # back_to_list: Back to list |
515 | search: | ||
516 | # placeholder: Filter by username or email | ||
515 | 517 | ||
516 | error: | 518 | error: |
517 | # page_title: An error occurred | 519 | # page_title: An error occurred |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml index dbad8b16..a7bcecc6 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml | |||
@@ -155,6 +155,7 @@ config: | |||
155 | or: 'Eine Regel ODER die andere' | 155 | or: 'Eine Regel ODER die andere' |
156 | and: 'Eine Regel UND eine andere' | 156 | and: 'Eine Regel UND eine andere' |
157 | matches: 'Testet, ob eine <i>Variable</i> auf eine <i>Suche</i> zutrifft (Groß- und Kleinschreibung wird nicht berücksichtigt).<br />Beispiel: <code>title matches "Fußball"</code>' | 157 | matches: 'Testet, ob eine <i>Variable</i> auf eine <i>Suche</i> zutrifft (Groß- und Kleinschreibung wird nicht berücksichtigt).<br />Beispiel: <code>title matches "Fußball"</code>' |
158 | # notmatches: 'Tests that a <i>subject</i> is not matches a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' | ||
158 | 159 | ||
159 | entry: | 160 | entry: |
160 | page_titles: | 161 | page_titles: |
@@ -512,6 +513,8 @@ user: | |||
512 | delete: Löschen | 513 | delete: Löschen |
513 | delete_confirm: Bist du sicher? | 514 | delete_confirm: Bist du sicher? |
514 | back_to_list: Zurück zur Liste | 515 | back_to_list: Zurück zur Liste |
516 | search: | ||
517 | # placeholder: Filter by username or email | ||
515 | 518 | ||
516 | error: | 519 | error: |
517 | page_title: Ein Fehler ist aufgetreten | 520 | page_title: Ein Fehler ist aufgetreten |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml index 7da9fe6b..1ef2874d 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml | |||
@@ -155,6 +155,7 @@ config: | |||
155 | or: 'One rule OR another' | 155 | or: 'One rule OR another' |
156 | and: 'One rule AND another' | 156 | and: 'One rule AND another' |
157 | matches: 'Tests that a <i>subject</i> is matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>' | 157 | matches: 'Tests that a <i>subject</i> is matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>' |
158 | notmatches: 'Tests that a <i>subject</i> is not matches a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' | ||
158 | 159 | ||
159 | entry: | 160 | entry: |
160 | page_titles: | 161 | page_titles: |
@@ -361,7 +362,7 @@ quickstart: | |||
361 | developer: | 362 | developer: |
362 | title: 'Developers' | 363 | title: 'Developers' |
363 | description: 'We also thought to the developers: Docker, API, translations, etc.' | 364 | description: 'We also thought to the developers: Docker, API, translations, etc.' |
364 | create_application: 'Create your third application' | 365 | create_application: 'Create your third-party application' |
365 | use_docker: 'Use Docker to install wallabag' | 366 | use_docker: 'Use Docker to install wallabag' |
366 | docs: | 367 | docs: |
367 | title: 'Full documentation' | 368 | title: 'Full documentation' |
@@ -512,6 +513,8 @@ user: | |||
512 | delete: Delete | 513 | delete: Delete |
513 | delete_confirm: Are you sure? | 514 | delete_confirm: Are you sure? |
514 | back_to_list: Back to list | 515 | back_to_list: Back to list |
516 | search: | ||
517 | placeholder: Filter by username or email | ||
515 | 518 | ||
516 | error: | 519 | error: |
517 | page_title: An error occurred | 520 | page_title: An error occurred |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml index 6e21614e..6cd079b0 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml | |||
@@ -155,6 +155,7 @@ config: | |||
155 | or: 'Una regla U otra' | 155 | or: 'Una regla U otra' |
156 | and: 'Una regla Y la otra' | 156 | and: 'Una regla Y la otra' |
157 | matches: 'Prueba si un <i>sujeto</i> corresponde a una <i>búsqueda</i> (insensible a mayusculas).<br />Ejemplo : <code>title matches "fútbol"</code>' | 157 | matches: 'Prueba si un <i>sujeto</i> corresponde a una <i>búsqueda</i> (insensible a mayusculas).<br />Ejemplo : <code>title matches "fútbol"</code>' |
158 | # notmatches: 'Tests that a <i>subject</i> is not matches a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' | ||
158 | 159 | ||
159 | entry: | 160 | entry: |
160 | page_titles: | 161 | page_titles: |
@@ -512,6 +513,8 @@ user: | |||
512 | delete: Eliminar | 513 | delete: Eliminar |
513 | delete_confirm: ¿Estás seguro? | 514 | delete_confirm: ¿Estás seguro? |
514 | back_to_list: Volver a la lista | 515 | back_to_list: Volver a la lista |
516 | search: | ||
517 | # placeholder: Filter by username or email | ||
515 | 518 | ||
516 | error: | 519 | error: |
517 | page_title: Ha ocurrido un error | 520 | page_title: Ha ocurrido un error |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml index b938c80a..fb6e315e 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml | |||
@@ -155,6 +155,7 @@ config: | |||
155 | # or: 'One rule OR another' | 155 | # or: 'One rule OR another' |
156 | # and: 'One rule AND another' | 156 | # and: 'One rule AND another' |
157 | # matches: 'Tests that a <i>subject</i> is matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>' | 157 | # matches: 'Tests that a <i>subject</i> is matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>' |
158 | # notmatches: 'Tests that a <i>subject</i> is not matches a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' | ||
158 | 159 | ||
159 | entry: | 160 | entry: |
160 | page_titles: | 161 | page_titles: |
@@ -512,6 +513,8 @@ user: | |||
512 | # delete: Delete | 513 | # delete: Delete |
513 | # delete_confirm: Are you sure? | 514 | # delete_confirm: Are you sure? |
514 | # back_to_list: Back to list | 515 | # back_to_list: Back to list |
516 | search: | ||
517 | # placeholder: Filter by username or email | ||
515 | 518 | ||
516 | error: | 519 | error: |
517 | # page_title: An error occurred | 520 | # page_title: An error occurred |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml index 9abcda45..ad886363 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml | |||
@@ -46,7 +46,7 @@ footer: | |||
46 | social: "Social" | 46 | social: "Social" |
47 | powered_by: "propulsé par" | 47 | powered_by: "propulsé par" |
48 | about: "À propos" | 48 | about: "À propos" |
49 | stats: Depuis le %user_creation%, vous avez lu %nb_archives% articles. Ce qui fait %per_day% par jour ! | 49 | stats: "Depuis le %user_creation%, vous avez lu %nb_archives% articles. Ce qui fait %per_day% par jour !" |
50 | 50 | ||
51 | config: | 51 | config: |
52 | page_title: "Configuration" | 52 | page_title: "Configuration" |
@@ -71,16 +71,16 @@ config: | |||
71 | 300_word: "Je lis environ 300 mots par minute" | 71 | 300_word: "Je lis environ 300 mots par minute" |
72 | 400_word: "Je lis environ 400 mots par minute" | 72 | 400_word: "Je lis environ 400 mots par minute" |
73 | action_mark_as_read: | 73 | action_mark_as_read: |
74 | label: 'Où souhaitez-vous être redirigé après avoir marqué un article comme lu ?' | 74 | label: "Où souhaitez-vous être redirigé après avoir marqué un article comme lu ?" |
75 | redirect_homepage: "À la page d'accueil" | 75 | redirect_homepage: "À la page d’accueil" |
76 | redirect_current_page: 'À la page courante' | 76 | redirect_current_page: "À la page courante" |
77 | pocket_consumer_key_label: Clé d’authentification Pocket pour importer les données | 77 | pocket_consumer_key_label: "Clé d’authentification Pocket pour importer les données" |
78 | android_configuration: Configurez votre application Android | 78 | android_configuration: "Configurez votre application Android" |
79 | help_theme: "L'affichage de wallabag est personnalisable. C'est ici que vous choisissez le thème que vous préférez." | 79 | help_theme: "L’affichage de wallabag est personnalisable. C’est ici que vous choisissez le thème que vous préférez." |
80 | help_items_per_page: "Vous pouvez définir le nombre d'articles affichés sur chaque page." | 80 | help_items_per_page: "Vous pouvez définir le nombre d’articles affichés sur chaque page." |
81 | help_reading_speed: "wallabag calcule une durée de lecture pour chaque article. Vous pouvez définir ici, grâce à cette liste déroulante, si vous lisez plus ou moins vite. wallabag recalculera la durée de lecture de chaque article." | 81 | help_reading_speed: "wallabag calcule une durée de lecture pour chaque article. Vous pouvez définir ici, grâce à cette liste déroulante, si vous lisez plus ou moins vite. wallabag recalculera la durée de lecture de chaque article." |
82 | help_language: "Vous pouvez définir la langue de l'interface de wallabag." | 82 | help_language: "Vous pouvez définir la langue de l’interface de wallabag." |
83 | help_pocket_consumer_key: "Nécessaire pour l'import depuis Pocket. Vous pouvez le créer depuis votre compte Pocket." | 83 | help_pocket_consumer_key: "Nécessaire pour l’import depuis Pocket. Vous pouvez le créer depuis votre compte Pocket." |
84 | form_rss: | 84 | form_rss: |
85 | description: "Les flux RSS fournis par wallabag vous permettent de lire vos articles sauvegardés dans votre lecteur de flux préféré. Pour pouvoir les utiliser, vous devez d’abord créer un jeton." | 85 | description: "Les flux RSS fournis par wallabag vous permettent de lire vos articles sauvegardés dans votre lecteur de flux préféré. Pour pouvoir les utiliser, vous devez d’abord créer un jeton." |
86 | token_label: "Jeton RSS" | 86 | token_label: "Jeton RSS" |
@@ -100,18 +100,18 @@ config: | |||
100 | twoFactorAuthentication_label: "Double authentification" | 100 | twoFactorAuthentication_label: "Double authentification" |
101 | help_twoFactorAuthentication: "Si vous activez 2FA, à chaque tentative de connexion à wallabag, vous recevrez un code par email." | 101 | help_twoFactorAuthentication: "Si vous activez 2FA, à chaque tentative de connexion à wallabag, vous recevrez un code par email." |
102 | delete: | 102 | delete: |
103 | title: Supprimer mon compte (attention danger !) | 103 | title: "Supprimer mon compte (attention danger !)" |
104 | description: Si vous confirmez la suppression de votre compte, TOUS les articles, TOUS les tags, TOUTES les annotations et votre compte seront DÉFINITIVEMENT supprimé (c'est IRRÉVERSIBLE). Vous serez ensuite déconnecté. | 104 | description: "Si vous confirmez la suppression de votre compte, TOUS les articles, TOUS les tags, TOUTES les annotations et votre compte seront DÉFINITIVEMENT supprimé (c’est IRRÉVERSIBLE). Vous serez ensuite déconnecté." |
105 | confirm: Vous êtes vraiment sûr ? (C'EST IRRÉVERSIBLE) | 105 | confirm: "Vous êtes vraiment sûr ? (C’EST IRRÉVERSIBLE)" |
106 | button: 'Supprimer mon compte' | 106 | button: "Supprimer mon compte" |
107 | reset: | 107 | reset: |
108 | title: Réinitialisation (attention danger !) | 108 | title: "Réinitialisation (attention danger !)" |
109 | description: En cliquant sur les boutons ci-dessous vous avez la possibilité de supprimer certaines informations de votre compte. Attention, ces actions sont IRRÉVERSIBLES ! | 109 | description: "En cliquant sur les boutons ci-dessous vous avez la possibilité de supprimer certaines informations de votre compte. Attention, ces actions sont IRRÉVERSIBLES !" |
110 | annotations: Supprimer TOUTES les annotations | 110 | annotations: "Supprimer TOUTES les annotations" |
111 | tags: Supprimer TOUS les tags | 111 | tags: "Supprimer TOUS les tags" |
112 | entries: Supprimer TOUS les articles | 112 | entries: "Supprimer TOUS les articles" |
113 | archived: Supprimer TOUS les articles archivés | 113 | archived: "Supprimer TOUS les articles archivés" |
114 | confirm: Êtes-vous vraiment vraiment sûr ? (C'EST IRRÉVERSIBLE) | 114 | confirm: "Êtes-vous vraiment vraiment sûr ? (C’EST IRRÉVERSIBLE)" |
115 | form_password: | 115 | form_password: |
116 | description: "Vous pouvez changer ici votre mot de passe. Le mot de passe doit contenir au moins 8 caractères." | 116 | description: "Vous pouvez changer ici votre mot de passe. Le mot de passe doit contenir au moins 8 caractères." |
117 | old_password_label: "Mot de passe actuel" | 117 | old_password_label: "Mot de passe actuel" |
@@ -155,6 +155,7 @@ config: | |||
155 | or: "Une règle OU l’autre" | 155 | or: "Une règle OU l’autre" |
156 | and: "Une règle ET l’autre" | 156 | and: "Une règle ET l’autre" |
157 | matches: "Teste si un <i>sujet</i> correspond à une <i>recherche</i> (non sensible à la casse).<br />Exemple : <code>title matches \"football\"</code>" | 157 | matches: "Teste si un <i>sujet</i> correspond à une <i>recherche</i> (non sensible à la casse).<br />Exemple : <code>title matches \"football\"</code>" |
158 | notmatches: "Teste si un <i>sujet</i> ne correspond pas à une <i>recherche</i> (non sensible à la casse).<br />Exemple : <code>title notmatches \"football\"</code>" | ||
158 | 159 | ||
159 | entry: | 160 | entry: |
160 | page_titles: | 161 | page_titles: |
@@ -163,7 +164,7 @@ entry: | |||
163 | archived: "Articles lus" | 164 | archived: "Articles lus" |
164 | filtered: "Articles filtrés" | 165 | filtered: "Articles filtrés" |
165 | filtered_tags: "Articles filtrés par tags :" | 166 | filtered_tags: "Articles filtrés par tags :" |
166 | filtered_search: 'Articles filtrés par recherche :' | 167 | filtered_search: "Articles filtrés par recherche :" |
167 | untagged: "Article sans tag" | 168 | untagged: "Article sans tag" |
168 | list: | 169 | list: |
169 | number_on_the_page: "{0} Il n’y a pas d’article.|{1} Il y a un article.|]1,Inf[ Il y a %count% articles." | 170 | number_on_the_page: "{0} Il n’y a pas d’article.|{1} Il y a un article.|]1,Inf[ Il y a %count% articles." |
@@ -187,7 +188,7 @@ entry: | |||
187 | preview_picture_label: "A une photo" | 188 | preview_picture_label: "A une photo" |
188 | preview_picture_help: "Photo" | 189 | preview_picture_help: "Photo" |
189 | language_label: "Langue" | 190 | language_label: "Langue" |
190 | http_status_label: 'Statut HTTP' | 191 | http_status_label: "Statut HTTP" |
191 | reading_time: | 192 | reading_time: |
192 | label: "Durée de lecture en minutes" | 193 | label: "Durée de lecture en minutes" |
193 | from: "de" | 194 | from: "de" |
@@ -297,32 +298,32 @@ howto: | |||
297 | bookmarklet: | 298 | bookmarklet: |
298 | description: "Glissez et déposez ce lien dans votre barre de favoris :" | 299 | description: "Glissez et déposez ce lien dans votre barre de favoris :" |
299 | shortcuts: | 300 | shortcuts: |
300 | page_description: Voici les raccourcis disponibles dans wallabag. | 301 | page_description: "Voici les raccourcis disponibles dans wallabag." |
301 | shortcut: Raccourci | 302 | shortcut: "Raccourci" |
302 | action: Action | 303 | action: "Action" |
303 | all_pages_title: Raccourcis disponibles dans toutes les pages | 304 | all_pages_title: "Raccourcis disponibles dans toutes les pages" |
304 | go_unread: Afficher les articles non lus | 305 | go_unread: "Afficher les articles non lus" |
305 | go_starred: Afficher les articles favoris | 306 | go_starred: "Afficher les articles favoris" |
306 | go_archive: Afficher les articles lus | 307 | go_archive: "Afficher les articles lus" |
307 | go_all: Afficher tous les articles | 308 | go_all: "Afficher tous les articles" |
308 | go_tags: Afficher les tags | 309 | go_tags: "Afficher les tags" |
309 | go_config: Aller à la configuration | 310 | go_config: "Aller à la configuration" |
310 | go_import: Aller aux imports | 311 | go_import: "Aller aux imports" |
311 | go_developers: Aller à la section Développeurs | 312 | go_developers: "Aller à la section Développeurs" |
312 | go_howto: Afficher l'aide (cette page !) | 313 | go_howto: "Afficher l’aide (cette page !)" |
313 | go_logout: Se déconnecter | 314 | go_logout: "Se déconnecter" |
314 | list_title: Raccourcis disponibles dans les pages de liste | 315 | list_title: "Raccourcis disponibles dans les pages de liste" |
315 | search: Afficher le formulaire de recherche | 316 | search: "Afficher le formulaire de recherche" |
316 | article_title: Raccourcis disponibles quand on affiche un article | 317 | article_title: "Raccourcis disponibles quand on affiche un article" |
317 | open_original: Ouvrir l'URL originale de l'article | 318 | open_original: "Ouvrir l’URL originale de l’article" |
318 | toggle_favorite: Changer le statut Favori de l'article | 319 | toggle_favorite: "Changer le statut Favori de l’article" |
319 | toggle_archive: Changer le status Lu de l'article | 320 | toggle_archive: "Changer le status Lu de l’article" |
320 | delete: Supprimer l'article | 321 | delete: "Supprimer l’article" |
321 | material_title: Raccourcis disponibles avec le thème Material uniquement | 322 | material_title: "Raccourcis disponibles avec le thème Material uniquement" |
322 | add_link: Ajouter un nouvel article | 323 | add_link: "Ajouter un nouvel article" |
323 | hide_form: Masquer le formulaire courant (recherche ou nouvel article) | 324 | hide_form: "Masquer le formulaire courant (recherche ou nouvel article)" |
324 | arrows_navigation: Naviguer à travers les articles | 325 | arrows_navigation: "Naviguer à travers les articles" |
325 | open_article: Afficher l'article sélectionné | 326 | open_article: "Afficher l’article sélectionné" |
326 | 327 | ||
327 | quickstart: | 328 | quickstart: |
328 | page_title: "Pour bien débuter" | 329 | page_title: "Pour bien débuter" |
@@ -384,8 +385,8 @@ tag: | |||
384 | number_on_the_page: "{0} Il n’y a pas de tag.|{1} Il y a un tag.|]1,Inf[ Il y a %count% tags." | 385 | number_on_the_page: "{0} Il n’y a pas de tag.|{1} Il y a un tag.|]1,Inf[ Il y a %count% tags." |
385 | see_untagged_entries: "Voir les articles sans tag" | 386 | see_untagged_entries: "Voir les articles sans tag" |
386 | new: | 387 | new: |
387 | add: 'Ajouter' | 388 | add: "Ajouter" |
388 | placeholder: 'Vous pouvez ajouter plusieurs tags, séparés par une virgule.' | 389 | placeholder: "Vous pouvez ajouter plusieurs tags, séparés par une virgule." |
389 | 390 | ||
390 | import: | 391 | import: |
391 | page_title: "Importer" | 392 | page_title: "Importer" |
@@ -419,7 +420,7 @@ import: | |||
419 | how_to: "Choisissez le fichier de votre export Readability et cliquez sur le bouton ci-dessous pour l’importer." | 420 | how_to: "Choisissez le fichier de votre export Readability et cliquez sur le bouton ci-dessous pour l’importer." |
420 | worker: | 421 | worker: |
421 | enabled: "Les imports sont asynchrones. Une fois l’import commencé un worker externe traitera les messages un par un. Le service activé est :" | 422 | enabled: "Les imports sont asynchrones. Une fois l’import commencé un worker externe traitera les messages un par un. Le service activé est :" |
422 | download_images_warning: "Vous avez configuré le téléchagement des images pour vos articles. Combiné à l'import classique, cette opération peut être très très longue (voire échouer). Nous vous conseillons <strong>vivement</strong> d'activer les imports asynchrones." | 423 | download_images_warning: "Vous avez configuré le téléchagement des images pour vos articles. Combiné à l’import classique, cette opération peut être très très longue (voire échouer). Nous vous conseillons <strong>vivement</strong> d’activer les imports asynchrones." |
423 | firefox: | 424 | firefox: |
424 | page_title: "Import > Firefox" | 425 | page_title: "Import > Firefox" |
425 | description: "Cet outil va vous permettre d’importer tous vos marques-pages de Firefox. Ouvrez le panneau des marques-pages (Ctrl+Maj+O), puis dans « Importation et sauvegarde », choisissez « Sauvegarde… ». Vous allez récupérer un fichier .json. </p>" | 426 | description: "Cet outil va vous permettre d’importer tous vos marques-pages de Firefox. Ouvrez le panneau des marques-pages (Ctrl+Maj+O), puis dans « Importation et sauvegarde », choisissez « Sauvegarde… ». Vous allez récupérer un fichier .json. </p>" |
@@ -488,16 +489,16 @@ developer: | |||
488 | back: "Retour" | 489 | back: "Retour" |
489 | 490 | ||
490 | user: | 491 | user: |
491 | page_title: Gestion des utilisateurs | 492 | page_title: "Gestion des utilisateurs" |
492 | new_user: Créer un nouvel utilisateur | 493 | new_user: "Créer un nouvel utilisateur" |
493 | edit_user: Éditer un utilisateur existant | 494 | edit_user: "Éditer un utilisateur existant" |
494 | description: Ici vous pouvez gérer vos utilisateurs (création, mise à jour et suppression) | 495 | description: "Ici vous pouvez gérer vos utilisateurs (création, mise à jour et suppression)" |
495 | list: | 496 | list: |
496 | actions: Actions | 497 | actions: "Actions" |
497 | edit_action: Éditer | 498 | edit_action: "Éditer" |
498 | yes: Oui | 499 | yes: "Oui" |
499 | no: Non | 500 | no: "Non" |
500 | create_new_one: Créer un nouvel utilisateur | 501 | create_new_one: "Créer un nouvel utilisateur" |
501 | form: | 502 | form: |
502 | username_label: "Nom d’utilisateur" | 503 | username_label: "Nom d’utilisateur" |
503 | name_label: "Nom" | 504 | name_label: "Nom" |
@@ -512,9 +513,11 @@ user: | |||
512 | delete: "Supprimer" | 513 | delete: "Supprimer" |
513 | delete_confirm: "Voulez-vous vraiment ?" | 514 | delete_confirm: "Voulez-vous vraiment ?" |
514 | back_to_list: "Revenir à la liste" | 515 | back_to_list: "Revenir à la liste" |
516 | search: | ||
517 | placeholder: "Filtrer par nom d’utilisateur ou email" | ||
515 | 518 | ||
516 | error: | 519 | error: |
517 | page_title: Une erreur est survenue | 520 | page_title: "Une erreur est survenue" |
518 | 521 | ||
519 | flashes: | 522 | flashes: |
520 | config: | 523 | config: |
@@ -527,10 +530,10 @@ flashes: | |||
527 | tagging_rules_updated: "Règles mises à jour" | 530 | tagging_rules_updated: "Règles mises à jour" |
528 | tagging_rules_deleted: "Règle supprimée" | 531 | tagging_rules_deleted: "Règle supprimée" |
529 | rss_token_updated: "Jeton RSS mis à jour" | 532 | rss_token_updated: "Jeton RSS mis à jour" |
530 | annotations_reset: Annotations supprimées | 533 | annotations_reset: "Annotations supprimées" |
531 | tags_reset: Tags supprimés | 534 | tags_reset: "Tags supprimés" |
532 | entries_reset: Articles supprimés | 535 | entries_reset: "Articles supprimés" |
533 | archived_reset: Articles archivés supprimés | 536 | archived_reset: "Articles archivés supprimés" |
534 | entry: | 537 | entry: |
535 | notice: | 538 | notice: |
536 | entry_already_saved: "Article déjà sauvegardé le %date%" | 539 | entry_already_saved: "Article déjà sauvegardé le %date%" |
@@ -562,6 +565,6 @@ flashes: | |||
562 | client_deleted: "Client %name% supprimé" | 565 | client_deleted: "Client %name% supprimé" |
563 | user: | 566 | user: |
564 | notice: | 567 | notice: |
565 | added: 'Utilisateur "%username%" ajouté' | 568 | added: "Utilisateur \"%username%\" ajouté" |
566 | updated: 'Utilisateur "%username%" mis à jour' | 569 | updated: "Utilisateur \"%username%\" mis à jour" |
567 | deleted: 'Utilisateur "%username%" supprimé' | 570 | deleted: "Utilisateur \"%username%\" supprimé" |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml index 58d0962a..5a9605ff 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml | |||
@@ -155,6 +155,7 @@ config: | |||
155 | or: "Una regola O un'altra" | 155 | or: "Una regola O un'altra" |
156 | and: "Una regola E un'altra" | 156 | and: "Una regola E un'altra" |
157 | matches: 'Verifica che un <i>oggetto</i> risulti in una <i>ricerca</i> (case-insensitive).<br />Esempio: <code>titolo contiene "football"</code>' | 157 | matches: 'Verifica che un <i>oggetto</i> risulti in una <i>ricerca</i> (case-insensitive).<br />Esempio: <code>titolo contiene "football"</code>' |
158 | # notmatches: 'Tests that a <i>subject</i> is not matches a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' | ||
158 | 159 | ||
159 | entry: | 160 | entry: |
160 | page_titles: | 161 | page_titles: |
@@ -512,6 +513,8 @@ user: | |||
512 | # delete: Delete | 513 | # delete: Delete |
513 | # delete_confirm: Are you sure? | 514 | # delete_confirm: Are you sure? |
514 | # back_to_list: Back to list | 515 | # back_to_list: Back to list |
516 | search: | ||
517 | # placeholder: Filter by username or email | ||
515 | 518 | ||
516 | error: | 519 | error: |
517 | # page_title: An error occurred | 520 | # page_title: An error occurred |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml index 825a0efd..942bc257 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml | |||
@@ -155,6 +155,7 @@ config: | |||
155 | or: "Una règla O l'autra" | 155 | or: "Una règla O l'autra" |
156 | and: "Una règla E l'autra" | 156 | and: "Una règla E l'autra" |
157 | matches: 'Teste se un <i>subjècte</i> correspond a una <i>recerca</i> (non sensibla a la cassa).<br />Exemple : <code>title matches \"football\"</code>' | 157 | matches: 'Teste se un <i>subjècte</i> correspond a una <i>recerca</i> (non sensibla a la cassa).<br />Exemple : <code>title matches \"football\"</code>' |
158 | # notmatches: 'Tests that a <i>subject</i> is not matches a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' | ||
158 | 159 | ||
159 | entry: | 160 | entry: |
160 | page_titles: | 161 | page_titles: |
@@ -512,6 +513,8 @@ user: | |||
512 | delete: 'Suprimir' | 513 | delete: 'Suprimir' |
513 | delete_confirm: 'Sètz segur ?' | 514 | delete_confirm: 'Sètz segur ?' |
514 | back_to_list: 'Tornar a la lista' | 515 | back_to_list: 'Tornar a la lista' |
516 | search: | ||
517 | # placeholder: Filter by username or email | ||
515 | 518 | ||
516 | error: | 519 | error: |
517 | page_title: Una error s'es produsida | 520 | page_title: Una error s'es produsida |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml index b02aa4ec..fea90440 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml | |||
@@ -155,6 +155,7 @@ config: | |||
155 | or: 'Jedna reguła LUB inna' | 155 | or: 'Jedna reguła LUB inna' |
156 | and: 'Jedna reguła I inna' | 156 | and: 'Jedna reguła I inna' |
157 | matches: 'Sprawdź czy <i>temat</i> pasuje <i>szukaj</i> (duże lub małe litery).<br />Przykład: <code>tytuł zawiera "piłka nożna"</code>' | 157 | matches: 'Sprawdź czy <i>temat</i> pasuje <i>szukaj</i> (duże lub małe litery).<br />Przykład: <code>tytuł zawiera "piłka nożna"</code>' |
158 | # notmatches: 'Tests that a <i>subject</i> is not matches a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' | ||
158 | 159 | ||
159 | entry: | 160 | entry: |
160 | page_titles: | 161 | page_titles: |
@@ -512,6 +513,8 @@ user: | |||
512 | delete: Usuń | 513 | delete: Usuń |
513 | delete_confirm: JesteÅ› pewien? | 514 | delete_confirm: JesteÅ› pewien? |
514 | back_to_list: Powrót do listy | 515 | back_to_list: Powrót do listy |
516 | search: | ||
517 | # placeholder: Filter by username or email | ||
515 | 518 | ||
516 | error: | 519 | error: |
517 | page_title: Wystąpił błąd | 520 | page_title: Wystąpił błąd |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml index 8aa7e5af..c59991f8 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml | |||
@@ -155,6 +155,7 @@ config: | |||
155 | or: 'Uma regra OU outra' | 155 | or: 'Uma regra OU outra' |
156 | and: 'Uma regra E outra' | 156 | and: 'Uma regra E outra' |
157 | matches: 'Testa que um <i>assunto</i> corresponde a uma <i>pesquisa</i> (maiúscula ou minúscula).<br />Exemplo: <code>tÃtulo corresponde a "futebol"</code>' | 157 | matches: 'Testa que um <i>assunto</i> corresponde a uma <i>pesquisa</i> (maiúscula ou minúscula).<br />Exemplo: <code>tÃtulo corresponde a "futebol"</code>' |
158 | # notmatches: 'Tests that a <i>subject</i> is not matches a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' | ||
158 | 159 | ||
159 | entry: | 160 | entry: |
160 | page_titles: | 161 | page_titles: |
@@ -512,6 +513,8 @@ user: | |||
512 | delete: 'Apagar' | 513 | delete: 'Apagar' |
513 | delete_confirm: 'Tem certeza?' | 514 | delete_confirm: 'Tem certeza?' |
514 | back_to_list: 'Voltar para a lista' | 515 | back_to_list: 'Voltar para a lista' |
516 | search: | ||
517 | # placeholder: Filter by username or email | ||
515 | 518 | ||
516 | error: | 519 | error: |
517 | # page_title: An error occurred | 520 | # page_title: An error occurred |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml index ce8d8d52..5846b7cc 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml | |||
@@ -155,6 +155,7 @@ config: | |||
155 | # or: 'One rule OR another' | 155 | # or: 'One rule OR another' |
156 | # and: 'One rule AND another' | 156 | # and: 'One rule AND another' |
157 | # matches: 'Tests that a <i>subject</i> is matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>' | 157 | # matches: 'Tests that a <i>subject</i> is matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>' |
158 | # notmatches: 'Tests that a <i>subject</i> is not matches a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' | ||
158 | 159 | ||
159 | entry: | 160 | entry: |
160 | page_titles: | 161 | page_titles: |
@@ -512,6 +513,8 @@ user: | |||
512 | # delete: Delete | 513 | # delete: Delete |
513 | # delete_confirm: Are you sure? | 514 | # delete_confirm: Are you sure? |
514 | # back_to_list: Back to list | 515 | # back_to_list: Back to list |
516 | search: | ||
517 | # placeholder: Filter by username or email | ||
515 | 518 | ||
516 | error: | 519 | error: |
517 | # page_title: An error occurred | 520 | # page_title: An error occurred |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml index d8903608..430fb96b 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml | |||
@@ -155,6 +155,7 @@ config: | |||
155 | or: 'Bir kural veya birbaşkası' | 155 | or: 'Bir kural veya birbaşkası' |
156 | and: 'Bir kural ve diÄŸeri' | 156 | and: 'Bir kural ve diÄŸeri' |
157 | # matches: 'Tests that a <i>subject</i> is matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>' | 157 | # matches: 'Tests that a <i>subject</i> is matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>' |
158 | # notmatches: 'Tests that a <i>subject</i> is not matches a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' | ||
158 | 159 | ||
159 | entry: | 160 | entry: |
160 | page_titles: | 161 | page_titles: |
@@ -512,6 +513,8 @@ user: | |||
512 | # delete: Delete | 513 | # delete: Delete |
513 | # delete_confirm: Are you sure? | 514 | # delete_confirm: Are you sure? |
514 | # back_to_list: Back to list | 515 | # back_to_list: Back to list |
516 | search: | ||
517 | # placeholder: Filter by username or email | ||
515 | 518 | ||
516 | error: | 519 | error: |
517 | # page_title: An error occurred | 520 | # page_title: An error occurred |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig index 708ff951..d6e414e9 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig | |||
@@ -413,8 +413,8 @@ | |||
413 | <tr> | 413 | <tr> |
414 | <td>domainName</td> | 414 | <td>domainName</td> |
415 | <td>{{ 'config.form_rules.faq.variable_description.domainName'|trans }}</td> | 415 | <td>{{ 'config.form_rules.faq.variable_description.domainName'|trans }}</td> |
416 | <td>matches</td> | 416 | <td>matches<br />notmaches</td> |
417 | <td>{{ 'config.form_rules.faq.operator_description.matches'|trans|raw }}</td> | 417 | <td>{{ 'config.form_rules.faq.operator_description.matches'|trans|raw }}<br />{{ 'config.form_rules.faq.operator_description.notmatches'|trans|raw }}</td> |
418 | </tr> | 418 | </tr> |
419 | </tbody> | 419 | </tbody> |
420 | </table> | 420 | </table> |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entry.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entry.html.twig index 8be5fd0d..3c4ad024 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entry.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entry.html.twig | |||
@@ -12,6 +12,11 @@ | |||
12 | <div class="nav-wrapper cyan darken-1"> | 12 | <div class="nav-wrapper cyan darken-1"> |
13 | <ul> | 13 | <ul> |
14 | <li> | 14 | <li> |
15 | <a href="#" data-activates="slide-out" class="button-collapse"> | ||
16 | <i class="material-icons">menu</i> | ||
17 | </a> | ||
18 | </li> | ||
19 | <li> | ||
15 | <a class="waves-effect" href="{{ path('homepage') }}"> | 20 | <a class="waves-effect" href="{{ path('homepage') }}"> |
16 | <i class="material-icons">exit_to_app</i> | 21 | <i class="material-icons">exit_to_app</i> |
17 | </a> | 22 | </a> |
@@ -28,11 +33,6 @@ | |||
28 | <i class="material-icons small">{% if entry.isStarred == 0 %}star_outline{% else %}star{% endif %}</i> | 33 | <i class="material-icons small">{% if entry.isStarred == 0 %}star_outline{% else %}star{% endif %}</i> |
29 | </a> | 34 | </a> |
30 | </li> | 35 | </li> |
31 | <li> | ||
32 | <a href="#" data-activates="slide-out" class="button-collapse right"> | ||
33 | <i class="material-icons">menu</i> | ||
34 | </a> | ||
35 | </li> | ||
36 | </ul> | 36 | </ul> |
37 | </div> | 37 | </div> |
38 | </nav> | 38 | </nav> |
diff --git a/src/Wallabag/ImportBundle/Command/ImportCommand.php b/src/Wallabag/ImportBundle/Command/ImportCommand.php index 28d01715..ce72837a 100644 --- a/src/Wallabag/ImportBundle/Command/ImportCommand.php +++ b/src/Wallabag/ImportBundle/Command/ImportCommand.php | |||
@@ -15,10 +15,11 @@ class ImportCommand extends ContainerAwareCommand | |||
15 | $this | 15 | $this |
16 | ->setName('wallabag:import') | 16 | ->setName('wallabag:import') |
17 | ->setDescription('Import entries from a JSON export') | 17 | ->setDescription('Import entries from a JSON export') |
18 | ->addArgument('userId', InputArgument::REQUIRED, 'User ID to populate') | 18 | ->addArgument('username', InputArgument::REQUIRED, 'User to populate') |
19 | ->addArgument('filepath', InputArgument::REQUIRED, 'Path to the JSON file') | 19 | ->addArgument('filepath', InputArgument::REQUIRED, 'Path to the JSON file') |
20 | ->addOption('importer', null, InputArgument::OPTIONAL, 'The importer to use: v1, v2, instapaper, pinboard, readability, firefox or chrome', 'v1') | 20 | ->addOption('importer', null, InputArgument::OPTIONAL, 'The importer to use: v1, v2, instapaper, pinboard, readability, firefox or chrome', 'v1') |
21 | ->addOption('markAsRead', null, InputArgument::OPTIONAL, 'Mark all entries as read', false) | 21 | ->addOption('markAsRead', null, InputArgument::OPTIONAL, 'Mark all entries as read', false) |
22 | ->addOption('useUserId', null, InputArgument::OPTIONAL, 'Use user id instead of username to find account', false) | ||
22 | ; | 23 | ; |
23 | } | 24 | } |
24 | 25 | ||
@@ -34,10 +35,14 @@ class ImportCommand extends ContainerAwareCommand | |||
34 | // Turning off doctrine default logs queries for saving memory | 35 | // Turning off doctrine default logs queries for saving memory |
35 | $em->getConnection()->getConfiguration()->setSQLLogger(null); | 36 | $em->getConnection()->getConfiguration()->setSQLLogger(null); |
36 | 37 | ||
37 | $user = $em->getRepository('WallabagUserBundle:User')->findOneById($input->getArgument('userId')); | 38 | if ($input->getOption('useUserId')) { |
39 | $user = $em->getRepository('WallabagUserBundle:User')->findOneById($input->getArgument('username')); | ||
40 | } else { | ||
41 | $user = $em->getRepository('WallabagUserBundle:User')->findOneByUsername($input->getArgument('username')); | ||
42 | } | ||
38 | 43 | ||
39 | if (!is_object($user)) { | 44 | if (!is_object($user)) { |
40 | throw new Exception(sprintf('User with id "%s" not found', $input->getArgument('userId'))); | 45 | throw new Exception(sprintf('User "%s" not found', $input->getArgument('username'))); |
41 | } | 46 | } |
42 | 47 | ||
43 | switch ($input->getOption('importer')) { | 48 | switch ($input->getOption('importer')) { |
diff --git a/src/Wallabag/UserBundle/Controller/ManageController.php b/src/Wallabag/UserBundle/Controller/ManageController.php index 92ee2b41..1c5c86d4 100644 --- a/src/Wallabag/UserBundle/Controller/ManageController.php +++ b/src/Wallabag/UserBundle/Controller/ManageController.php | |||
@@ -4,12 +4,15 @@ namespace Wallabag\UserBundle\Controller; | |||
4 | 4 | ||
5 | use FOS\UserBundle\Event\UserEvent; | 5 | use FOS\UserBundle\Event\UserEvent; |
6 | use FOS\UserBundle\FOSUserEvents; | 6 | use FOS\UserBundle\FOSUserEvents; |
7 | use Pagerfanta\Adapter\DoctrineORMAdapter; | ||
8 | use Pagerfanta\Exception\OutOfRangeCurrentPageException; | ||
9 | use Pagerfanta\Pagerfanta; | ||
7 | use Symfony\Component\HttpFoundation\Request; | 10 | use Symfony\Component\HttpFoundation\Request; |
8 | use Symfony\Bundle\FrameworkBundle\Controller\Controller; | 11 | use Symfony\Bundle\FrameworkBundle\Controller\Controller; |
9 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; | 12 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; |
10 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; | 13 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; |
11 | use Wallabag\UserBundle\Entity\User; | 14 | use Wallabag\UserBundle\Entity\User; |
12 | use Wallabag\CoreBundle\Entity\Config; | 15 | use Wallabag\UserBundle\Form\SearchUserType; |
13 | 16 | ||
14 | /** | 17 | /** |
15 | * User controller. | 18 | * User controller. |
@@ -17,23 +20,6 @@ use Wallabag\CoreBundle\Entity\Config; | |||
17 | class ManageController extends Controller | 20 | class ManageController extends Controller |
18 | { | 21 | { |
19 | /** | 22 | /** |
20 | * Lists all User entities. | ||
21 | * | ||
22 | * @Route("/", name="user_index") | ||
23 | * @Method("GET") | ||
24 | */ | ||
25 | public function indexAction() | ||
26 | { | ||
27 | $em = $this->getDoctrine()->getManager(); | ||
28 | |||
29 | $users = $em->getRepository('WallabagUserBundle:User')->findAll(); | ||
30 | |||
31 | return $this->render('WallabagUserBundle:Manage:index.html.twig', array( | ||
32 | 'users' => $users, | ||
33 | )); | ||
34 | } | ||
35 | |||
36 | /** | ||
37 | * Creates a new User entity. | 23 | * Creates a new User entity. |
38 | * | 24 | * |
39 | * @Route("/new", name="user_new") | 25 | * @Route("/new", name="user_new") |
@@ -146,4 +132,49 @@ class ManageController extends Controller | |||
146 | ->getForm() | 132 | ->getForm() |
147 | ; | 133 | ; |
148 | } | 134 | } |
135 | |||
136 | /** | ||
137 | * @param Request $request | ||
138 | * @param int $page | ||
139 | * | ||
140 | * @Route("/list/{page}", name="user_index", defaults={"page" = 1}) | ||
141 | * | ||
142 | * Default parameter for page is hardcoded (in duplication of the defaults from the Route) | ||
143 | * because this controller is also called inside the layout template without any page as argument | ||
144 | * | ||
145 | * @return \Symfony\Component\HttpFoundation\Response | ||
146 | */ | ||
147 | public function searchFormAction(Request $request, $page = 1) | ||
148 | { | ||
149 | $em = $this->getDoctrine()->getManager(); | ||
150 | $qb = $em->getRepository('WallabagUserBundle:User')->createQueryBuilder('u'); | ||
151 | |||
152 | $form = $this->createForm(SearchUserType::class); | ||
153 | $form->handleRequest($request); | ||
154 | |||
155 | if ($form->isSubmitted() && $form->isValid()) { | ||
156 | $this->get('logger')->info('searching users'); | ||
157 | |||
158 | $searchTerm = (isset($request->get('search_user')['term']) ? $request->get('search_user')['term'] : ''); | ||
159 | |||
160 | $qb = $em->getRepository('WallabagUserBundle:User')->getQueryBuilderForSearch($searchTerm); | ||
161 | } | ||
162 | |||
163 | $pagerAdapter = new DoctrineORMAdapter($qb->getQuery(), true, false); | ||
164 | $pagerFanta = new Pagerfanta($pagerAdapter); | ||
165 | $pagerFanta->setMaxPerPage(50); | ||
166 | |||
167 | try { | ||
168 | $pagerFanta->setCurrentPage($page); | ||
169 | } catch (OutOfRangeCurrentPageException $e) { | ||
170 | if ($page > 1) { | ||
171 | return $this->redirect($this->generateUrl('user_index', ['page' => $pagerFanta->getNbPages()]), 302); | ||
172 | } | ||
173 | } | ||
174 | |||
175 | return $this->render('WallabagUserBundle:Manage:index.html.twig', [ | ||
176 | 'searchForm' => $form->createView(), | ||
177 | 'users' => $pagerFanta, | ||
178 | ]); | ||
179 | } | ||
149 | } | 180 | } |
diff --git a/src/Wallabag/UserBundle/Form/SearchUserType.php b/src/Wallabag/UserBundle/Form/SearchUserType.php new file mode 100644 index 00000000..9ce46ee1 --- /dev/null +++ b/src/Wallabag/UserBundle/Form/SearchUserType.php | |||
@@ -0,0 +1,29 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\UserBundle\Form; | ||
4 | |||
5 | use Symfony\Component\Form\AbstractType; | ||
6 | use Symfony\Component\Form\Extension\Core\Type\TextType; | ||
7 | use Symfony\Component\Form\FormBuilderInterface; | ||
8 | use Symfony\Component\OptionsResolver\OptionsResolver; | ||
9 | |||
10 | class SearchUserType extends AbstractType | ||
11 | { | ||
12 | public function buildForm(FormBuilderInterface $builder, array $options) | ||
13 | { | ||
14 | $builder | ||
15 | ->setMethod('GET') | ||
16 | ->add('term', TextType::class, [ | ||
17 | 'required' => true, | ||
18 | 'label' => 'user.new.form_search.term_label', | ||
19 | ]) | ||
20 | ; | ||
21 | } | ||
22 | |||
23 | public function configureOptions(OptionsResolver $resolver) | ||
24 | { | ||
25 | $resolver->setDefaults([ | ||
26 | 'csrf_protection' => false, | ||
27 | ]); | ||
28 | } | ||
29 | } | ||
diff --git a/src/Wallabag/UserBundle/Repository/UserRepository.php b/src/Wallabag/UserBundle/Repository/UserRepository.php index f913f52d..6adbe329 100644 --- a/src/Wallabag/UserBundle/Repository/UserRepository.php +++ b/src/Wallabag/UserBundle/Repository/UserRepository.php | |||
@@ -52,4 +52,17 @@ class UserRepository extends EntityRepository | |||
52 | ->getQuery() | 52 | ->getQuery() |
53 | ->getSingleScalarResult(); | 53 | ->getSingleScalarResult(); |
54 | } | 54 | } |
55 | |||
56 | /** | ||
57 | * Retrieves users filtered with a search term. | ||
58 | * | ||
59 | * @param string $term | ||
60 | * | ||
61 | * @return QueryBuilder | ||
62 | */ | ||
63 | public function getQueryBuilderForSearch($term) | ||
64 | { | ||
65 | return $this->createQueryBuilder('u') | ||
66 | ->andWhere('lower(u.username) LIKE lower(:term) OR lower(u.email) LIKE lower(:term) OR lower(u.name) LIKE lower(:term)')->setParameter('term', '%'.$term.'%'); | ||
67 | } | ||
55 | } | 68 | } |
diff --git a/src/Wallabag/UserBundle/Resources/views/Manage/index.html.twig b/src/Wallabag/UserBundle/Resources/views/Manage/index.html.twig index daba29e4..15002632 100644 --- a/src/Wallabag/UserBundle/Resources/views/Manage/index.html.twig +++ b/src/Wallabag/UserBundle/Resources/views/Manage/index.html.twig | |||
@@ -7,37 +7,60 @@ | |||
7 | <div class="row"> | 7 | <div class="row"> |
8 | <div class="col s12"> | 8 | <div class="col s12"> |
9 | <div class="card-panel"> | 9 | <div class="card-panel"> |
10 | {% if users.getNbPages > 1 %} | ||
11 | {{ pagerfanta(users, 'twitter_bootstrap_translated', {'proximity': 1}) }} | ||
12 | {% endif %} | ||
10 | <div class="row"> | 13 | <div class="row"> |
11 | <div class="input-field col s12"> | 14 | <div class="col s6"> |
12 | <p class="help">{{ 'user.description'|trans|raw }}</p> | 15 | <p class="help">{{ 'user.description'|trans|raw }}</p> |
16 | </div> | ||
17 | <div class="col s6"> | ||
18 | <div class="input-field"> | ||
19 | <form name="search_users" method="GET" action="{{ path('user_index')}}"> | ||
20 | {% if form_errors(searchForm) %} | ||
21 | <span class="black-text">{{ form_errors(searchForm) }}</span> | ||
22 | {% endif %} | ||
23 | |||
24 | {% if form_errors(searchForm.term) %} | ||
25 | <span class="black-text">{{ form_errors(searchForm.term) }}</span> | ||
26 | {% endif %} | ||
13 | 27 | ||
14 | <table class="bordered"> | 28 | {{ form_widget(searchForm.term, { 'attr': {'autocomplete': 'off', 'placeholder': 'user.search.placeholder'} }) }} |
15 | <thead> | 29 | |
16 | <tr> | 30 | {{ form_rest(searchForm) }} |
17 | <th>{{ 'user.form.username_label'|trans }}</th> | 31 | </form> |
18 | <th>{{ 'user.form.email_label'|trans }}</th> | 32 | </div> |
19 | <th>{{ 'user.form.last_login_label'|trans }}</th> | ||
20 | <th>{{ 'user.list.actions'|trans }}</th> | ||
21 | </tr> | ||
22 | </thead> | ||
23 | <tbody> | ||
24 | {% for user in users %} | ||
25 | <tr> | ||
26 | <td>{{ user.username }}</td> | ||
27 | <td>{{ user.email }}</td> | ||
28 | <td>{% if user.lastLogin %}{{ user.lastLogin|date('Y-m-d H:i:s') }}{% endif %}</td> | ||
29 | <td> | ||
30 | <a href="{{ path('user_edit', { 'id': user.id }) }}">{{ 'user.list.edit_action'|trans }}</a> | ||
31 | </td> | ||
32 | </tr> | ||
33 | {% endfor %} | ||
34 | </tbody> | ||
35 | </table> | ||
36 | <br /> | ||
37 | <p> | ||
38 | <a href="{{ path('user_new') }}" class="waves-effect waves-light btn">{{ 'user.list.create_new_one'|trans }}</a> | ||
39 | </p> | ||
40 | </div> | 33 | </div> |
34 | |||
35 | <table class="bordered"> | ||
36 | <thead> | ||
37 | <tr> | ||
38 | <th>{{ 'user.form.username_label'|trans }}</th> | ||
39 | <th>{{ 'user.form.email_label'|trans }}</th> | ||
40 | <th>{{ 'user.form.last_login_label'|trans }}</th> | ||
41 | <th>{{ 'user.list.actions'|trans }}</th> | ||
42 | </tr> | ||
43 | </thead> | ||
44 | <tbody> | ||
45 | {% for user in users %} | ||
46 | <tr> | ||
47 | <td>{{ user.username }}</td> | ||
48 | <td>{{ user.email }}</td> | ||
49 | <td>{% if user.lastLogin %}{{ user.lastLogin|date('Y-m-d H:i:s') }}{% endif %}</td> | ||
50 | <td> | ||
51 | <a href="{{ path('user_edit', { 'id': user.id }) }}">{{ 'user.list.edit_action'|trans }}</a> | ||
52 | </td> | ||
53 | </tr> | ||
54 | {% endfor %} | ||
55 | </tbody> | ||
56 | </table> | ||
57 | <br /> | ||
58 | <p> | ||
59 | <a href="{{ path('user_new') }}" class="waves-effect waves-light btn">{{ 'user.list.create_new_one'|trans }}</a> | ||
60 | </p> | ||
61 | {% if users.getNbPages > 1 %} | ||
62 | {{ pagerfanta(users, 'twitter_bootstrap_translated', {'proximity': 1}) }} | ||
63 | {% endif %} | ||
41 | </div> | 64 | </div> |
42 | </div> | 65 | </div> |
43 | </div> | 66 | </div> |