diff options
Diffstat (limited to 'src')
9 files changed, 186 insertions, 2 deletions
diff --git a/src/Wallabag/CoreBundle/Controller/TagController.php b/src/Wallabag/CoreBundle/Controller/TagController.php index a342ec0b..fd2069e0 100644 --- a/src/Wallabag/CoreBundle/Controller/TagController.php +++ b/src/Wallabag/CoreBundle/Controller/TagController.php | |||
@@ -4,10 +4,60 @@ namespace Wallabag\CoreBundle\Controller; | |||
4 | 4 | ||
5 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; | 5 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; |
6 | use Symfony\Bundle\FrameworkBundle\Controller\Controller; | 6 | use Symfony\Bundle\FrameworkBundle\Controller\Controller; |
7 | use Symfony\Component\HttpFoundation\Request; | ||
8 | use Wallabag\CoreBundle\Form\Type\NewTagType; | ||
9 | use Wallabag\CoreBundle\Entity\Tag; | ||
10 | use Wallabag\CoreBundle\Entity\Entry; | ||
7 | 11 | ||
8 | class TagController extends Controller | 12 | class TagController extends Controller |
9 | { | 13 | { |
10 | /** | 14 | /** |
15 | * @param Request $request | ||
16 | * | ||
17 | * @Route("/new-tag/{entry}", requirements={"entry" = "\d+"}, name="new_tag") | ||
18 | * | ||
19 | * @return \Symfony\Component\HttpFoundation\Response | ||
20 | */ | ||
21 | public function addTagFormAction(Request $request, Entry $entry) | ||
22 | { | ||
23 | $tag = new Tag($this->getUser()); | ||
24 | $form = $this->createForm(new NewTagType(), $tag); | ||
25 | $form->handleRequest($request); | ||
26 | |||
27 | if ($form->isValid()) { | ||
28 | $existingTag = $this->getDoctrine() | ||
29 | ->getRepository('WallabagCoreBundle:Tag') | ||
30 | ->findOneByLabelAndUserId($tag->getLabel(), $this->getUser()->getId()); | ||
31 | |||
32 | $em = $this->getDoctrine()->getManager(); | ||
33 | |||
34 | if (is_null($existingTag)) { | ||
35 | $entry->addTag($tag); | ||
36 | $em->persist($tag); | ||
37 | } else { | ||
38 | if (!$existingTag->hasEntry($entry)) { | ||
39 | $entry->addTag($existingTag); | ||
40 | $em->persist($existingTag); | ||
41 | } | ||
42 | } | ||
43 | |||
44 | $em->flush(); | ||
45 | |||
46 | $this->get('session')->getFlashBag()->add( | ||
47 | 'notice', | ||
48 | 'Tag added' | ||
49 | ); | ||
50 | |||
51 | return $this->redirect($this->generateUrl('view', array('id' => $entry->getId()))); | ||
52 | } | ||
53 | |||
54 | return $this->render('WallabagCoreBundle:Tag:new_form.html.twig', array( | ||
55 | 'form' => $form->createView(), | ||
56 | 'entry' => $entry, | ||
57 | )); | ||
58 | } | ||
59 | |||
60 | /** | ||
11 | * Shows tags for current user. | 61 | * Shows tags for current user. |
12 | * | 62 | * |
13 | * @Route("/tag/list", name="tag") | 63 | * @Route("/tag/list", name="tag") |
diff --git a/src/Wallabag/CoreBundle/Entity/Tag.php b/src/Wallabag/CoreBundle/Entity/Tag.php index 6f005314..97c4579f 100644 --- a/src/Wallabag/CoreBundle/Entity/Tag.php +++ b/src/Wallabag/CoreBundle/Entity/Tag.php | |||
@@ -96,6 +96,11 @@ class Tag | |||
96 | $this->entries[] = $entry; | 96 | $this->entries[] = $entry; |
97 | } | 97 | } |
98 | 98 | ||
99 | public function hasEntry($entry) | ||
100 | { | ||
101 | return $this->entries->contains($entry); | ||
102 | } | ||
103 | |||
99 | /** | 104 | /** |
100 | * @return User | 105 | * @return User |
101 | */ | 106 | */ |
diff --git a/src/Wallabag/CoreBundle/Form/Type/NewTagType.php b/src/Wallabag/CoreBundle/Form/Type/NewTagType.php new file mode 100644 index 00000000..8e4ab649 --- /dev/null +++ b/src/Wallabag/CoreBundle/Form/Type/NewTagType.php | |||
@@ -0,0 +1,30 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Form\Type; | ||
4 | |||
5 | use Symfony\Component\Form\AbstractType; | ||
6 | use Symfony\Component\Form\FormBuilderInterface; | ||
7 | use Symfony\Component\OptionsResolver\OptionsResolver; | ||
8 | |||
9 | class NewTagType extends AbstractType | ||
10 | { | ||
11 | public function buildForm(FormBuilderInterface $builder, array $options) | ||
12 | { | ||
13 | $builder | ||
14 | ->add('label', 'text', array('required' => true)) | ||
15 | ->add('save', 'submit') | ||
16 | ; | ||
17 | } | ||
18 | |||
19 | public function configureOptions(OptionsResolver $resolver) | ||
20 | { | ||
21 | $resolver->setDefaults(array( | ||
22 | 'data_class' => 'Wallabag\CoreBundle\Entity\Tag', | ||
23 | )); | ||
24 | } | ||
25 | |||
26 | public function getName() | ||
27 | { | ||
28 | return 'tag'; | ||
29 | } | ||
30 | } | ||
diff --git a/src/Wallabag/CoreBundle/Repository/TagRepository.php b/src/Wallabag/CoreBundle/Repository/TagRepository.php index 9c409607..ac3145a1 100644 --- a/src/Wallabag/CoreBundle/Repository/TagRepository.php +++ b/src/Wallabag/CoreBundle/Repository/TagRepository.php | |||
@@ -24,4 +24,21 @@ class TagRepository extends EntityRepository | |||
24 | 24 | ||
25 | return new Pagerfanta($pagerAdapter); | 25 | return new Pagerfanta($pagerAdapter); |
26 | } | 26 | } |
27 | |||
28 | /** | ||
29 | * Find a tag by its label and its owner. | ||
30 | * | ||
31 | * @param string $label | ||
32 | * @param int $userId | ||
33 | * | ||
34 | * @return Tag|null | ||
35 | */ | ||
36 | public function findOneByLabelAndUserId($label, $userId) | ||
37 | { | ||
38 | return $this->createQueryBuilder('t') | ||
39 | ->where('t.label = :label')->setParameter('label', $label) | ||
40 | ->andWhere('t.user = :user_id')->setParameter('user_id', $userId) | ||
41 | ->getQuery() | ||
42 | ->getOneOrNullResult(); | ||
43 | } | ||
27 | } | 44 | } |
diff --git a/src/Wallabag/CoreBundle/Resources/views/Entry/entry.html.twig b/src/Wallabag/CoreBundle/Resources/views/Entry/entry.html.twig index 00480d1a..18cfd59d 100644 --- a/src/Wallabag/CoreBundle/Resources/views/Entry/entry.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/Entry/entry.html.twig | |||
@@ -28,7 +28,8 @@ | |||
28 | <h1>{{ entry.title|raw }} <a href="{{ path('edit', { 'id': entry.id }) }}" title="{% trans %}Edit tags{% endtrans %}">✎</a></h1> | 28 | <h1>{{ entry.title|raw }} <a href="{{ path('edit', { 'id': entry.id }) }}" title="{% trans %}Edit tags{% endtrans %}">✎</a></h1> |
29 | </header> | 29 | </header> |
30 | <aside class="tags"> | 30 | <aside class="tags"> |
31 | tags: {% for tag in entry.tags %}<a href="./?view=tag&id={{ tag.id }}">{{ tag.label }}</a> {% endfor %}<a href="./?view=edit-tags&id={{ entry.id }}" title="{% trans %}Edit tags{% endtrans %}">✎</a> | 31 | {% for tag in entry.tags %}<span class="mdi-action-label-outline">{{ tag.label }}</span>{% endfor %} |
32 | {{ render(controller( "WallabagCoreBundle:Tag:addTagForm", { 'id': entry.id } )) }} | ||
32 | </aside> | 33 | </aside> |
33 | <article> | 34 | <article> |
34 | {{ entry.content | raw }} | 35 | {{ entry.content | raw }} |
diff --git a/src/Wallabag/CoreBundle/Resources/views/Tag/new_form.html.twig b/src/Wallabag/CoreBundle/Resources/views/Tag/new_form.html.twig new file mode 100644 index 00000000..0b5a530d --- /dev/null +++ b/src/Wallabag/CoreBundle/Resources/views/Tag/new_form.html.twig | |||
@@ -0,0 +1,15 @@ | |||
1 | <form name="tag" method="post" action="{{ path('new_tag', { 'entry': entry.id })}}"> | ||
2 | |||
3 | {% if form_errors(form) %} | ||
4 | <span class="black-text">{{ form_errors(form) }}</span> | ||
5 | {% endif %} | ||
6 | |||
7 | {% if form_errors(form.label) %} | ||
8 | <span class="black-text">{{ form_errors(form.label) }}</span> | ||
9 | {% endif %} | ||
10 | |||
11 | {{ form_widget(form.label, { 'attr': {'autocomplete': 'off'} }) }} | ||
12 | {{ form_widget(form.save, { 'attr': {'class': 'btn waves-effect waves-light'}, 'label': 'add tag' }) }} | ||
13 | |||
14 | <div class="hidden">{{ form_rest(form) }}</div> | ||
15 | </form> | ||
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 b92c41b6..31b2c664 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 | |||
@@ -137,7 +137,8 @@ main { | |||
137 | <a href="{{ entry.url|e }}" target="_blank" title="{% trans %}original{% endtrans %} : {{ entry.title|e }}" class="tool link"><span>{{ entry.domainName }}</span></a> | 137 | <a href="{{ entry.url|e }}" target="_blank" title="{% trans %}original{% endtrans %} : {{ entry.title|e }}" class="tool link"><span>{{ entry.domainName }}</span></a> |
138 | </header> | 138 | </header> |
139 | <aside class="tags"> | 139 | <aside class="tags"> |
140 | tags: {% for tag in entry.tags %}<a href="./?view=tag&id={{ tag.id }}">{{ tag.label }}</a> {% endfor %}<a href="./?view=edit-tags&id={{ entry.id }}" title="{% trans %}Edit tags{% endtrans %}">✎</a> | 140 | {% for tag in entry.tags %}<span class="mdi-action-label-outline">{{ tag.label }}</span>{% endfor %} |
141 | {{ render(controller( "WallabagCoreBundle:Tag:addTagForm", { 'id': entry.id } )) }} | ||
141 | </aside> | 142 | </aside> |
142 | <article> | 143 | <article> |
143 | {{ entry.content | raw }} | 144 | {{ entry.content | raw }} |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Tag/new_form.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Tag/new_form.html.twig new file mode 100644 index 00000000..0b5a530d --- /dev/null +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Tag/new_form.html.twig | |||
@@ -0,0 +1,15 @@ | |||
1 | <form name="tag" method="post" action="{{ path('new_tag', { 'entry': entry.id })}}"> | ||
2 | |||
3 | {% if form_errors(form) %} | ||
4 | <span class="black-text">{{ form_errors(form) }}</span> | ||
5 | {% endif %} | ||
6 | |||
7 | {% if form_errors(form.label) %} | ||
8 | <span class="black-text">{{ form_errors(form.label) }}</span> | ||
9 | {% endif %} | ||
10 | |||
11 | {{ form_widget(form.label, { 'attr': {'autocomplete': 'off'} }) }} | ||
12 | {{ form_widget(form.save, { 'attr': {'class': 'btn waves-effect waves-light'}, 'label': 'add tag' }) }} | ||
13 | |||
14 | <div class="hidden">{{ form_rest(form) }}</div> | ||
15 | </form> | ||
diff --git a/src/Wallabag/CoreBundle/Tests/Controller/TagControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/TagControllerTest.php index 4a43e049..af39d6ce 100644 --- a/src/Wallabag/CoreBundle/Tests/Controller/TagControllerTest.php +++ b/src/Wallabag/CoreBundle/Tests/Controller/TagControllerTest.php | |||
@@ -15,4 +15,54 @@ class TagControllerTest extends WallabagCoreTestCase | |||
15 | 15 | ||
16 | $this->assertEquals(200, $client->getResponse()->getStatusCode()); | 16 | $this->assertEquals(200, $client->getResponse()->getStatusCode()); |
17 | } | 17 | } |
18 | |||
19 | public function testAddTagToEntry() | ||
20 | { | ||
21 | $this->logInAs('admin'); | ||
22 | $client = $this->getClient(); | ||
23 | |||
24 | $entry = $client->getContainer() | ||
25 | ->get('doctrine.orm.entity_manager') | ||
26 | ->getRepository('WallabagCoreBundle:Entry') | ||
27 | ->findOneByIsArchived(false); | ||
28 | |||
29 | $crawler = $client->request('GET', '/view/'.$entry->getId()); | ||
30 | |||
31 | $form = $crawler->filter('button[id=tag_save]')->form(); | ||
32 | |||
33 | $data = array( | ||
34 | 'tag[label]' => 'opensource', | ||
35 | ); | ||
36 | |||
37 | $client->submit($form, $data); | ||
38 | $this->assertEquals(302, $client->getResponse()->getStatusCode()); | ||
39 | |||
40 | $this->assertEquals(1, count($entry->getTags())); | ||
41 | |||
42 | # tag already exists and already assigned | ||
43 | $client->submit($form, $data); | ||
44 | $this->assertEquals(302, $client->getResponse()->getStatusCode()); | ||
45 | |||
46 | $newEntry = $client->getContainer() | ||
47 | ->get('doctrine.orm.entity_manager') | ||
48 | ->getRepository('WallabagCoreBundle:Entry') | ||
49 | ->findOneById($entry->getId()); | ||
50 | |||
51 | $this->assertEquals(1, count($newEntry->getTags())); | ||
52 | |||
53 | # tag already exists but still not assigned to this entry | ||
54 | $data = array( | ||
55 | 'tag[label]' => 'foo', | ||
56 | ); | ||
57 | |||
58 | $client->submit($form, $data); | ||
59 | $this->assertEquals(302, $client->getResponse()->getStatusCode()); | ||
60 | |||
61 | $newEntry = $client->getContainer() | ||
62 | ->get('doctrine.orm.entity_manager') | ||
63 | ->getRepository('WallabagCoreBundle:Entry') | ||
64 | ->findOneById($entry->getId()); | ||
65 | |||
66 | $this->assertEquals(2, count($newEntry->getTags())); | ||
67 | } | ||
18 | } | 68 | } |