Add basic title edition

Fix #218
I mean basic, because there is no javascript at all. It could be a nice edit-in-place. But for the moment, it is simple.
This commit is contained in:
Jeremy Benoist 2015-06-02 18:54:34 +02:00
parent 51d9699fa1
commit 82d6d9cb06
8 changed files with 147 additions and 13 deletions

View file

@ -7,7 +7,8 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Wallabag\CoreBundle\Entity\Entry; use Wallabag\CoreBundle\Entity\Entry;
use Wallabag\CoreBundle\Service\Extractor; use Wallabag\CoreBundle\Service\Extractor;
use Wallabag\CoreBundle\Form\Type\EntryType; use Wallabag\CoreBundle\Form\Type\NewEntryType;
use Wallabag\CoreBundle\Form\Type\EditEntryType;
class EntryController extends Controller class EntryController extends Controller
{ {
@ -22,7 +23,7 @@ class EntryController extends Controller
{ {
$entry = new Entry($this->getUser()); $entry = new Entry($this->getUser());
$form = $this->createForm(new EntryType(), $entry); $form = $this->createForm(new NewEntryType(), $entry);
$form->handleRequest($request); $form->handleRequest($request);
@ -49,6 +50,42 @@ class EntryController extends Controller
)); ));
} }
/**
* Edit an entry content.
*
* @param Request $request
* @param Entry $entry
*
* @Route("/edit/{id}", requirements={"id" = "\d+"}, name="edit")
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function editEntryAction(Request $request, Entry $entry)
{
$this->checkUserAction($entry);
$form = $this->createForm(new EditEntryType(), $entry);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entry);
$em->flush();
$this->get('session')->getFlashBag()->add(
'notice',
'Entry updated'
);
return $this->redirect($this->generateUrl('view', array('id' => $entry->getId())));
}
return $this->render('WallabagCoreBundle:Entry:edit.html.twig', array(
'form' => $form->createView(),
));
}
/** /**
* Shows unread entries for current user. * Shows unread entries for current user.
* *
@ -212,7 +249,7 @@ class EntryController extends Controller
private function checkUserAction(Entry $entry) private function checkUserAction(Entry $entry)
{ {
if ($this->getUser()->getId() != $entry->getUser()->getId()) { if ($this->getUser()->getId() != $entry->getUser()->getId()) {
throw $this->createAccessDeniedException('You can not use this entry.'); throw $this->createAccessDeniedException('You can not access this entry.');
} }
} }
} }

View file

@ -390,7 +390,7 @@ class Entry
/** /**
* @param bool $isPublic * @param bool $isPublic
*/ */
public function setPublic($isPublic) public function setIsPublic($isPublic)
{ {
$this->isPublic = $isPublic; $this->isPublic = $isPublic;
} }

View file

@ -51,6 +51,12 @@ class Tag
$this->user = $user; $this->user = $user;
$this->entries = new ArrayCollection(); $this->entries = new ArrayCollection();
} }
public function __toString()
{
return $this->label;
}
/** /**
* Get id. * Get id.
* *

View file

@ -0,0 +1,36 @@
<?php
namespace Wallabag\CoreBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class EditEntryType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', 'text', array('required' => true))
->add('is_public', 'checkbox', array('required' => false))
// @todo: add autocomplete
// ->add('tags', 'entity', array(
// 'class' => 'Wallabag\CoreBundle\Entity\Tag',
// 'choice_translation_domain' => true,
// ))
->add('save', 'submit')
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Wallabag\CoreBundle\Entity\Entry',
));
}
public function getName()
{
return 'entry';
}
}

View file

@ -6,7 +6,7 @@ use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface; use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class EntryType extends AbstractType class NewEntryType extends AbstractType
{ {
public function buildForm(FormBuilderInterface $builder, array $options) public function buildForm(FormBuilderInterface $builder, array $options)
{ {

View file

@ -0,0 +1,7 @@
{% extends "WallabagCoreBundle::layout.html.twig" %}
{% block title %}{% trans %}Edit an entry{% endtrans %}{% endblock %}
{% block content %}
{{ form(form) }}
{% endblock %}

View file

@ -17,18 +17,18 @@
{# {% if flattr %}{% if flattr.status == flattrable %}<li><a href="http://flattr.com/submit/auto?url={{ entry.url }}" class="tool flattr icon icon-flattr" target="_blank" title="{% trans %}flattr{% endtrans %}"><span>{% trans %}flattr{% endtrans %}</span></a></li>{% elseif flattr.status == flattred %}<li><a href="{{ flattr.flattrItemURL }}" class="tool flattr icon icon-flattr" target="_blank" title="{% trans %}flattr{% endtrans %}><span>{% trans %}flattr{% endtrans %}</span> ({{ flattr.numFlattrs }})</a></li>{% endif %}{% endif %} #} {# {% if flattr %}{% if flattr.status == flattrable %}<li><a href="http://flattr.com/submit/auto?url={{ entry.url }}" class="tool flattr icon icon-flattr" target="_blank" title="{% trans %}flattr{% endtrans %}"><span>{% trans %}flattr{% endtrans %}</span></a></li>{% elseif flattr.status == flattred %}<li><a href="{{ flattr.flattrItemURL }}" class="tool flattr icon icon-flattr" target="_blank" title="{% trans %}flattr{% endtrans %}><span>{% trans %}flattr{% endtrans %}</span> ({{ flattr.numFlattrs }})</a></li>{% endif %}{% endif %} #}
{% if carrot %}<li><a href="https://secure.carrot.org/GiveAndGetBack.do?url={{ entry.url|url_encode }}&title={{ entry.title|url_encode }}" class="tool carrot icon-image icon-image--carrot" target="_blank" title="{% trans %}carrot{% endtrans %}"><span>Carrot</span></a></li>{% endif %} {% if carrot %}<li><a href="https://secure.carrot.org/GiveAndGetBack.do?url={{ entry.url|url_encode }}&title={{ entry.title|url_encode }}" class="tool carrot icon-image icon-image--carrot" target="_blank" title="{% trans %}carrot{% endtrans %}"><span>Carrot</span></a></li>{% endif %}
{% if show_printlink %}<li><a title="{% trans %}Print{% endtrans %}" class="tool icon icon-print" href="javascript: window.print();"><span>{% trans %}Print{% endtrans %}</span></a></li>{% endif %} {% if show_printlink %}<li><a title="{% trans %}Print{% endtrans %}" class="tool icon icon-print" href="javascript: window.print();"><span>{% trans %}Print{% endtrans %}</span></a></li>{% endif %}
{% if export_epub %}<li><a href="?epub&amp;method=id&amp;value={{ entry.id|e }}" title="Generate ePub file">EPUB</a></li>{% endif %} {% if export_epub %}<li><a href="?epub&amp;method=id&amp;value={{ entry.id }}" title="Generate ePub file">EPUB</a></li>{% endif %}
{% if export_mobi %}<li><a href="?mobi&amp;method=id&amp;value={{ entry.id|e }}" title="Generate Mobi file">MOBI</a></li>{% endif %} {% if export_mobi %}<li><a href="?mobi&amp;method=id&amp;value={{ entry.id }}" title="Generate Mobi file">MOBI</a></li>{% endif %}
{% if export_pdf %}<li><a href="?pdf&amp;method=id&amp;value={{ entry.id|e }}" title="Generate PDF file">PDF</a></li>{% endif %} {% if export_pdf %}<li><a href="?pdf&amp;method=id&amp;value={{ entry.id }}" title="Generate PDF file">PDF</a></li>{% endif %}
<li><a href="mailto:hello@wallabag.org?subject=Wrong%20display%20in%20wallabag&amp;body={{ entry.url|url_encode }}" title="{% trans %}Does this article appear wrong?{% endtrans %}" class="tool bad-display icon icon-delete"><span>{% trans %}Does this article appear wrong?{% endtrans %}</span></a></li> <li><a href="mailto:hello@wallabag.org?subject=Wrong%20display%20in%20wallabag&amp;body={{ entry.url|url_encode }}" title="{% trans %}Does this article appear wrong?{% endtrans %}" class="tool bad-display icon icon-delete"><span>{% trans %}Does this article appear wrong?{% endtrans %}</span></a></li>
</ul> </ul>
</div> </div>
<div id="article"> <div id="article">
<header class="mbm"> <header class="mbm">
<h1>{{ entry.title|raw }}</h1> <h1>{{ entry.title|raw }} <a href="{{ path('edit', { 'id': entry.id }) }}" title="{% trans %}Edit tags{% endtrans %}">✎</a></h1>
</header> </header>
<aside class="tags"> <aside class="tags">
tags: {# {% for tag in tags %}<a href="./?view=tag&amp;id={{ tag.id }}">{{ tag.value }}</a> {% endfor %}<a href="./?view=edit-tags&amp;id={{ entry.id|e }}" title="{% trans %}Edit tags{% endtrans %}">✎</a> #} tags: {% for tag in entry.tags %}<a href="./?view=tag&amp;id={{ tag.id }}">{{ tag.label }}</a> {% endfor %}<a href="./?view=edit-tags&amp;id={{ entry.id }}" title="{% trans %}Edit tags{% endtrans %}">✎</a>
</aside> </aside>
<article> <article>
{{ entry.content | raw }} {{ entry.content | raw }}
@ -87,13 +87,13 @@
var docHeight = $(document).height(); var docHeight = $(document).height();
var scrollPercent = (scrollTop) / (docHeight); var scrollPercent = (scrollTop) / (docHeight);
var scrollPercentRounded = Math.round(scrollPercent*100)/100; var scrollPercentRounded = Math.round(scrollPercent*100)/100;
savePercent({{ entry.id|e }}, scrollPercentRounded); savePercent({{ entry.id }}, scrollPercentRounded);
}); });
retrievePercent({{ entry.id|e }}); retrievePercent({{ entry.id }});
$(window).resize(function(){ $(window).resize(function(){
retrievePercent({{ entry.id|e }}); retrievePercent({{ entry.id }});
}); });
}); });
</script> </script>

View file

@ -109,6 +109,54 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->assertContains($content->getTitle(), $client->getResponse()->getContent()); $this->assertContains($content->getTitle(), $client->getResponse()->getContent());
} }
public function testEdit()
{
$this->logInAs('admin');
$client = $this->getClient();
$content = $client->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('WallabagCoreBundle:Entry')
->findOneByIsArchived(false);
$crawler = $client->request('GET', '/edit/'.$content->getId());
$this->assertEquals(200, $client->getResponse()->getStatusCode());
$this->assertCount(1, $crawler->filter('input[id=entry_title]'));
$this->assertCount(1, $crawler->filter('button[id=entry_save]'));
}
public function testEditUpdate()
{
$this->logInAs('admin');
$client = $this->getClient();
$content = $client->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('WallabagCoreBundle:Entry')
->findOneByIsArchived(false);
$crawler = $client->request('GET', '/edit/'.$content->getId());
$this->assertEquals(200, $client->getResponse()->getStatusCode());
$form = $crawler->filter('button[type=submit]')->form();
$data = array(
'entry[title]' => 'My updated title hehe :)',
);
$client->submit($form, $data);
$this->assertEquals(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$this->assertGreaterThan(1, $alert = $crawler->filter('div[id=article] h1')->extract(array('_text')));
$this->assertContains('My updated title hehe :)', $alert[0]);
}
public function testToggleArchive() public function testToggleArchive()
{ {
$this->logInAs('admin'); $this->logInAs('admin');