* {"name"="perPage", "dataType"="integer", "required"=false, "format"="default'30'", "description"="results per page."},
* {"name"="tags", "dataType"="string", "required"=false, "format"="api,rest", "description"="a list of tags url encoded. Will returns entries that matches ALL tags."},
* {"name"="since", "dataType"="integer", "required"=false, "format"="default '0'", "description"="The timestamp since when you want entries updated."},
+ * {"name"="public", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by entries with a public link"},
* }
* )
*
$isArchived = (null === $request->query->get('archive')) ? null : (bool) $request->query->get('archive');
$isStarred = (null === $request->query->get('starred')) ? null : (bool) $request->query->get('starred');
+ $isPublic = (null === $request->query->get('public')) ? null : (bool) $request->query->get('public');
$sort = $request->query->get('sort', 'created');
$order = $request->query->get('order', 'desc');
$page = (int) $request->query->get('page', 1);
$since = $request->query->get('since', 0);
/** @var \Pagerfanta\Pagerfanta $pager */
- $pager = $this->getDoctrine()
- ->getRepository('WallabagCoreBundle:Entry')
- ->findEntries($this->getUser()->getId(), $isArchived, $isStarred, $sort, $order, $since, $tags);
+ $pager = $this->get('wallabag_core.entry_repository')->findEntries(
+ $this->getUser()->getId(),
+ $isArchived,
+ $isStarred,
+ $isPublic,
+ $sort,
+ $order,
+ $since,
+ $tags
+ );
$pager->setMaxPerPage($perPage);
$pager->setCurrentPage($page);
[
'archive' => $isArchived,
'starred' => $isStarred,
+ 'public' => $isPublic,
'sort' => $sort,
'order' => $order,
'page' => $page,
* {"name"="preview_picture", "dataType"="string", "required"=false, "description"="Preview picture of the entry"},
* {"name"="published_at", "dataType"="datetime|integer", "format"="YYYY-MM-DDTHH:II:SS+TZ or a timestamp", "required"=false, "description"="Published date of the entry"},
* {"name"="authors", "dataType"="string", "format"="Name Firstname,author2,author3", "required"=false, "description"="Authors of the entry"},
+ * {"name"="public", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="will generate a public link for the entry"},
* }
* )
*
* {"name"="preview_picture", "dataType"="string", "required"=false, "description"="Preview picture of the entry"},
* {"name"="published_at", "dataType"="datetime|integer", "format"="YYYY-MM-DDTHH:II:SS+TZ or a timestamp", "required"=false, "description"="Published date of the entry"},
* {"name"="authors", "dataType"="string", "format"="Name Firstname,author2,author3", "required"=false, "description"="Authors of the entry"},
+ * {"name"="public", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="will generate a public link for the entry"},
* }
* )
*
$tags = $request->request->get('tags', []);
$isArchived = $request->request->get('archive');
$isStarred = $request->request->get('starred');
+ $isPublic = $request->request->get('public');
$content = $request->request->get('content');
$language = $request->request->get('language');
$picture = $request->request->get('preview_picture');
$this->get('wallabag_core.tags_assigner')->assignTagsToEntry($entry, $tags);
}
+ if (!is_null($isPublic)) {
+ if (true === (bool) $isPublic && null === $entry->getUid()) {
+ $entry->generateUid();
+ } elseif (false === (bool) $isPublic) {
+ $entry->cleanUid();
+ }
+ }
+
$em = $this->getDoctrine()->getManager();
$em->persist($entry);
$em->flush();
$this->uid = null;
}
+ /**
+ * Used in the entries filter so it's more explicit for the end user than the uid.
+ * Also used in the API.
+ *
+ * @VirtualProperty
+ * @SerializedName("is_public")
+ * @Groups({"entries_for_user"})
+ *
+ * @return bool
+ */
+ public function isPublic()
+ {
+ return null !== $this->uid;
+ }
+
/**
* @return string
*/
},
'label' => 'entry.filters.preview_picture_label',
])
+ ->add('isPublic', CheckboxFilterType::class, [
+ 'apply_filter' => function (QueryInterface $filterQuery, $field, $values) {
+ if (false === $values['value']) {
+ return;
+ }
+
+ // is_public isn't a real field
+ // we should use the "uid" field to determine if the entry has been made public
+ $expression = $filterQuery->getExpr()->isNotNull($values['alias'].'.uid');
+
+ return $filterQuery->createCondition($expression);
+ },
+ 'label' => 'entry.filters.is_public_label',
+ ])
->add('language', ChoiceFilterType::class, [
'choices' => array_flip($this->repository->findDistinctLanguageByUser($this->user->getId())),
'label' => 'entry.filters.language_label',
* @param int $userId
* @param bool $isArchived
* @param bool $isStarred
+ * @param bool $isPublic
* @param string $sort
* @param string $order
* @param int $since
*
* @return array
*/
- public function findEntries($userId, $isArchived = null, $isStarred = null, $sort = 'created', $order = 'ASC', $since = 0, $tags = '')
+ public function findEntries($userId, $isArchived = null, $isStarred = null, $isPublic = null, $sort = 'created', $order = 'ASC', $since = 0, $tags = '')
{
$qb = $this->createQueryBuilder('e')
->leftJoin('e.tags', 't')
->where('e.user =:userId')->setParameter('userId', $userId);
if (null !== $isArchived) {
- $qb->andWhere('e.isArchived =:isArchived')->setParameter('isArchived', (bool) $isArchived);
+ $qb->andWhere('e.isArchived = :isArchived')->setParameter('isArchived', (bool) $isArchived);
}
if (null !== $isStarred) {
- $qb->andWhere('e.isStarred =:isStarred')->setParameter('isStarred', (bool) $isStarred);
+ $qb->andWhere('e.isStarred = :isStarred')->setParameter('isStarred', (bool) $isStarred);
+ }
+
+ if (null !== $isPublic) {
+ $qb->andWhere('e.uid IS '.(true === $isPublic ? 'NOT' : '').' NULL');
}
if ($since > 0) {
unread_label: 'Ulæst'
preview_picture_label: 'Har et vist billede'
preview_picture_help: 'Forhåndsvis billede'
+ # is_public_label: 'Has a public link'
+ # is_public_help: 'Public link'
language_label: 'Sprog'
# http_status_label: 'HTTP status'
reading_time:
unread_label: 'Ungelesene'
preview_picture_label: 'Vorschaubild vorhanden'
preview_picture_help: 'Vorschaubild'
+ # is_public_label: 'Has a public link'
+ # is_public_help: 'Public link'
language_label: 'Sprache'
http_status_label: 'HTTP-Status'
reading_time:
unread_label: 'Unread'
preview_picture_label: 'Has a preview picture'
preview_picture_help: 'Preview picture'
+ is_public_label: 'Has a public link'
+ is_public_help: 'Public link'
language_label: 'Language'
http_status_label: 'HTTP status'
reading_time:
unread_label: 'Sin leer'
preview_picture_label: 'Tiene imagen de previsualización'
preview_picture_help: 'Imagen de previsualización'
+ # is_public_label: 'Has a public link'
+ # is_public_help: 'Public link'
language_label: 'Idioma'
http_status_label: 'Código de estado HTTP'
reading_time:
unread_label: 'خواندهنشده'
preview_picture_label: 'دارای عکس پیشنمایش'
preview_picture_help: 'پیشنمایش عکس'
+ # is_public_label: 'Has a public link'
+ # is_public_help: 'Public link'
language_label: 'زبان'
# http_status_label: 'HTTP status'
reading_time:
unread_label: "Non lus"
preview_picture_label: "A une photo"
preview_picture_help: "Photo"
+ is_public_label: 'A un lien public'
+ is_public_help: 'Lien public'
language_label: "Langue"
http_status_label: "Statut HTTP"
reading_time:
# unread_label: 'Unread'
preview_picture_label: "Ha un'immagine di anteprima"
preview_picture_help: 'Immagine di anteprima'
+ # is_public_label: 'Has a public link'
+ # is_public_help: 'Public link'
language_label: 'Lingua'
# http_status_label: 'HTTP status'
reading_time:
unread_label: 'Pas legits'
preview_picture_label: 'A un imatge'
preview_picture_help: 'Imatge'
+ # is_public_label: 'Has a public link'
+ # is_public_help: 'Public link'
language_label: 'Lenga'
http_status_label: 'Estatut HTTP'
reading_time:
unread_label: 'Nieprzeczytane'
preview_picture_label: 'Posiada podgląd obrazu'
preview_picture_help: 'Podgląd obrazu'
+ # is_public_label: 'Has a public link'
+ # is_public_help: 'Public link'
language_label: 'Język'
http_status_label: 'Status HTTP'
reading_time:
unread_label: 'Não Lido'
preview_picture_label: 'Possui uma imagem de preview'
preview_picture_help: 'Imagem de preview'
+ # is_public_label: 'Has a public link'
+ # is_public_help: 'Public link'
language_label: 'Idioma'
# http_status_label: 'HTTP status'
reading_time:
unread_label: 'Necitite'
preview_picture_label: 'Are o imagine de previzualizare'
preview_picture_help: 'Previzualizare imagine'
+ # is_public_label: 'Has a public link'
+ # is_public_help: 'Public link'
language_label: 'Limbă'
# http_status_label: 'HTTP status'
reading_time:
{{ form_widget(form.previewPicture) }}
{{ form_label(form.previewPicture) }}
</div>
+
+ <div class="input-field">
+ {{ form_widget(form.isPublic) }}
+ {{ form_label(form.isPublic) }}
+ </div>
</div>
<div id="filter-language" class="filter-group">
{{ form_label(form.previewPicture) }}
</div>
+ <div class="col s12">
+ <label>{{ 'entry.filters.is_public_help'|trans }}</label>
+ </div>
+
+ <div class="input-field col s12 with-checkbox">
+ {{ form_widget(form.isPublic) }}
+ {{ form_label(form.isPublic) }}
+ </div>
+
<div class="col s12">
{{ form_label(form.language) }}
</div>
<div class="col s12">
{{ form_label(form.readingTime) }}
</div>
+
<div class="input-field col s6">
{{ form_widget(form.readingTime.left_number, {'type': 'number'}) }}
<label for="entry_filter_readingTime_left_number">{{ 'entry.filters.reading_time.from'|trans }}</label>
</div>
+
<div class="input-field col s6">
{{ form_widget(form.readingTime.right_number, {'type': 'number'}) }}
<label for="entry_filter_readingTime_right_number">{{ 'entry.filters.reading_time.to'|trans }}</label>
'perPage' => 2,
'tags' => 'foo',
'since' => 1443274283,
+ 'public' => 0,
]);
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());
$this->assertContains('order=asc', $content['_links'][$link]['href']);
$this->assertContains('tags=foo', $content['_links'][$link]['href']);
$this->assertContains('since=1443274283', $content['_links'][$link]['href']);
+ $this->assertContains('public=0', $content['_links'][$link]['href']);
+ }
+
+ $this->assertEquals('application/json', $this->client->getResponse()->headers->get('Content-Type'));
+ }
+
+ public function testGetEntriesPublicOnly()
+ {
+ $entry = $this->client->getContainer()
+ ->get('doctrine.orm.entity_manager')
+ ->getRepository('WallabagCoreBundle:Entry')
+ ->findOneByUser(1);
+
+ if (!$entry) {
+ $this->markTestSkipped('No content found in db.');
+ }
+
+ // generate at least one public entry
+ $entry->generateUid();
+
+ $em = $this->client->getContainer()->get('doctrine.orm.entity_manager');
+ $em->persist($entry);
+ $em->flush();
+
+ $this->client->request('GET', '/api/entries', [
+ 'public' => 1,
+ ]);
+
+ $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+ $content = json_decode($this->client->getResponse()->getContent(), true);
+
+ $this->assertGreaterThanOrEqual(1, count($content));
+ $this->assertArrayHasKey('items', $content['_embedded']);
+ $this->assertGreaterThanOrEqual(1, $content['total']);
+ $this->assertEquals(1, $content['page']);
+ $this->assertEquals(30, $content['limit']);
+ $this->assertGreaterThanOrEqual(1, $content['pages']);
+
+ $this->assertArrayHasKey('_links', $content);
+ $this->assertArrayHasKey('self', $content['_links']);
+ $this->assertArrayHasKey('first', $content['_links']);
+ $this->assertArrayHasKey('last', $content['_links']);
+
+ foreach (['self', 'first', 'last'] as $link) {
+ $this->assertArrayHasKey('href', $content['_links'][$link]);
+ $this->assertContains('public=1', $content['_links'][$link]['href']);
}
$this->assertEquals('application/json', $this->client->getResponse()->headers->get('Content-Type'));
'language' => 'de',
'published_at' => '2016-09-08T11:55:58+0200',
'authors' => 'bob,helen',
+ 'public' => 1,
]);
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());
$this->assertCount(2, $content['published_by']);
$this->assertContains('bob', $content['published_by']);
$this->assertContains('helen', $content['published_by']);
+ $this->assertTrue($content['is_public'], 'A public link has been generated for that entry');
}
public function testPostSameEntry()
'preview_picture' => 'http://preview.io/picture.jpg',
'authors' => 'bob,sponge',
'content' => 'awesome',
+ 'public' => 0,
]);
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());
$this->assertContains('sponge', $content['published_by']);
$this->assertContains('bob', $content['published_by']);
$this->assertEquals('awesome', $content['content']);
+ $this->assertFalse($content['is_public'], 'Entry is no more shared');
}
public function testPatchEntryWithoutQuotes()
$this->assertCount(1, $crawler->filter('div[class=entry]'));
}
+ public function testFilterOnIsPublic()
+ {
+ $this->logInAs('admin');
+ $this->useTheme('baggy');
+ $client = $this->getClient();
+
+ $crawler = $client->request('GET', '/unread/list');
+ $form = $crawler->filter('button[id=submit-filter]')->form();
+ $form['entry_filter[isPublic]']->tick();
+
+ $crawler = $client->submit($form);
+ $this->assertCount(0, $crawler->filter('div[class=entry]'));
+ }
+
public function testPreviewPictureFilter()
{
$this->logInAs('admin');