2016-10-28 12:46:30 +00:00
< ? php
namespace Wallabag\ApiBundle\Controller ;
use Hateoas\Configuration\Route ;
use Hateoas\Representation\Factory\PagerfantaFactory ;
2017-06-28 06:15:06 +00:00
use JMS\Serializer\SerializationContext ;
2016-10-28 12:46:30 +00:00
use Nelmio\ApiDocBundle\Annotation\ApiDoc ;
use Symfony\Component\HttpFoundation\JsonResponse ;
2017-07-01 07:52:38 +00:00
use Symfony\Component\HttpFoundation\Request ;
2017-07-29 20:51:50 +00:00
use Symfony\Component\HttpFoundation\Response ;
2017-07-01 07:52:38 +00:00
use Symfony\Component\HttpKernel\Exception\HttpException ;
2016-10-28 12:46:30 +00:00
use Symfony\Component\Routing\Generator\UrlGeneratorInterface ;
use Wallabag\CoreBundle\Entity\Entry ;
use Wallabag\CoreBundle\Entity\Tag ;
2016-11-03 15:41:29 +00:00
use Wallabag\CoreBundle\Event\EntryDeletedEvent ;
2017-07-01 07:52:38 +00:00
use Wallabag\CoreBundle\Event\EntrySavedEvent ;
2016-10-28 12:46:30 +00:00
class EntryRestController extends WallabagRestController
{
/**
* Check if an entry exist by url .
2017-06-23 06:30:23 +00:00
* Return ID if entry ( ies ) exist ( and if you give the return_id parameter ) .
* Otherwise it returns false .
2016-10-28 12:46:30 +00:00
*
2017-06-28 06:15:06 +00:00
* @ todo Remove that `return_id` in the next major release
*
2016-10-28 12:46:30 +00:00
* @ ApiDoc (
* parameters = {
2017-06-23 06:30:23 +00:00
* { " name " = " return_id " , " dataType " = " string " , " required " = false , " format " = " 1 or 0 " , " description " = " Set 1 if you want to retrieve ID in case entry(ies) exists, 0 by default " },
2016-10-28 12:46:30 +00:00
* { " name " = " url " , " dataType " = " string " , " required " = true , " format " = " An url " , " description " = " Url to check if it exists " },
* { " name " = " urls " , " dataType " = " string " , " required " = false , " format " = " An array of urls (?urls[]=http...&urls[]=http...) " , " description " = " Urls (as an array) to check if it exists " }
* }
* )
*
* @ return JsonResponse
*/
public function getEntriesExistsAction ( Request $request )
{
$this -> validateAuthentication ();
2017-06-28 07:18:22 +00:00
$returnId = ( null === $request -> query -> get ( 'return_id' )) ? false : ( bool ) $request -> query -> get ( 'return_id' );
2016-10-28 12:46:30 +00:00
$urls = $request -> query -> get ( 'urls' , []);
// handle multiple urls first
if ( ! empty ( $urls )) {
$results = [];
foreach ( $urls as $url ) {
$res = $this -> getDoctrine ()
-> getRepository ( 'WallabagCoreBundle:Entry' )
-> findByUrlAndUserId ( $url , $this -> getUser () -> getId ());
2017-06-28 06:15:06 +00:00
$results [ $url ] = $this -> returnExistInformation ( $res , $returnId );
2016-10-28 12:46:30 +00:00
}
2017-05-05 10:05:50 +00:00
return $this -> sendResponse ( $results );
2016-10-28 12:46:30 +00:00
}
// let's see if it is a simple url?
$url = $request -> query -> get ( 'url' , '' );
if ( empty ( $url )) {
2017-07-01 07:52:38 +00:00
throw $this -> createAccessDeniedException ( 'URL is empty?, logged user id: ' . $this -> getUser () -> getId ());
2016-10-28 12:46:30 +00:00
}
$res = $this -> getDoctrine ()
-> getRepository ( 'WallabagCoreBundle:Entry' )
-> findByUrlAndUserId ( $url , $this -> getUser () -> getId ());
2017-06-28 06:15:06 +00:00
$exists = $this -> returnExistInformation ( $res , $returnId );
2016-10-28 12:46:30 +00:00
2017-05-05 10:05:50 +00:00
return $this -> sendResponse ([ 'exists' => $exists ]);
2016-10-28 12:46:30 +00:00
}
/**
* Retrieve all entries . It could be filtered by many options .
*
* @ ApiDoc (
* parameters = {
* { " name " = " archive " , " dataType " = " integer " , " required " = false , " format " = " 1 or 0, all entries by default " , " description " = " filter by archived status. " },
* { " name " = " starred " , " dataType " = " integer " , " required " = false , " format " = " 1 or 0, all entries by default " , " description " = " filter by starred status. " },
* { " name " = " sort " , " dataType " = " string " , " required " = false , " format " = " 'created' or 'updated', default 'created' " , " description " = " sort entries by date. " },
* { " name " = " order " , " dataType " = " string " , " required " = false , " format " = " 'asc' or 'desc', default 'desc' " , " description " = " order of sort. " },
* { " name " = " page " , " dataType " = " integer " , " required " = false , " format " = " default '1' " , " description " = " what page you want. " },
* { " 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. " },
2017-06-10 13:31:57 +00:00
* { " name " = " public " , " dataType " = " integer " , " required " = false , " format " = " 1 or 0, all entries by default " , " description " = " filter by entries with a public link " },
2016-10-28 12:46:30 +00:00
* }
* )
*
* @ return JsonResponse
*/
public function getEntriesAction ( Request $request )
{
$this -> validateAuthentication ();
$isArchived = ( null === $request -> query -> get ( 'archive' )) ? null : ( bool ) $request -> query -> get ( 'archive' );
$isStarred = ( null === $request -> query -> get ( 'starred' )) ? null : ( bool ) $request -> query -> get ( 'starred' );
2017-06-10 13:31:57 +00:00
$isPublic = ( null === $request -> query -> get ( 'public' )) ? null : ( bool ) $request -> query -> get ( 'public' );
2016-10-28 12:46:30 +00:00
$sort = $request -> query -> get ( 'sort' , 'created' );
$order = $request -> query -> get ( 'order' , 'desc' );
$page = ( int ) $request -> query -> get ( 'page' , 1 );
$perPage = ( int ) $request -> query -> get ( 'perPage' , 30 );
$tags = $request -> query -> get ( 'tags' , '' );
$since = $request -> query -> get ( 'since' , 0 );
2017-05-08 14:27:16 +00:00
/** @var \Pagerfanta\Pagerfanta $pager */
2017-06-10 13:31:57 +00:00
$pager = $this -> get ( 'wallabag_core.entry_repository' ) -> findEntries (
$this -> getUser () -> getId (),
$isArchived ,
$isStarred ,
$isPublic ,
$sort ,
$order ,
$since ,
$tags
);
2016-10-28 12:46:30 +00:00
$pager -> setMaxPerPage ( $perPage );
2017-05-08 14:27:16 +00:00
$pager -> setCurrentPage ( $page );
2016-10-28 12:46:30 +00:00
$pagerfantaFactory = new PagerfantaFactory ( 'page' , 'perPage' );
$paginatedCollection = $pagerfantaFactory -> createRepresentation (
$pager ,
new Route (
'api_get_entries' ,
[
'archive' => $isArchived ,
'starred' => $isStarred ,
2017-06-10 13:31:57 +00:00
'public' => $isPublic ,
2016-10-28 12:46:30 +00:00
'sort' => $sort ,
'order' => $order ,
'page' => $page ,
'perPage' => $perPage ,
'tags' => $tags ,
'since' => $since ,
],
UrlGeneratorInterface :: ABSOLUTE_URL
)
);
2017-05-05 10:05:50 +00:00
return $this -> sendResponse ( $paginatedCollection );
2016-10-28 12:46:30 +00:00
}
/**
* Retrieve a single entry .
*
* @ ApiDoc (
* requirements = {
* { " name " = " entry " , " dataType " = " integer " , " requirement " = " \ w+ " , " description " = " The entry ID " }
* }
* )
*
* @ return JsonResponse
*/
public function getEntryAction ( Entry $entry )
{
$this -> validateAuthentication ();
$this -> validateUserAccess ( $entry -> getUser () -> getId ());
2017-05-05 10:05:50 +00:00
return $this -> sendResponse ( $entry );
2016-10-28 12:46:30 +00:00
}
2016-11-03 16:29:16 +00:00
/**
* Retrieve a single entry as a predefined format .
*
* @ ApiDoc (
* requirements = {
* { " name " = " entry " , " dataType " = " integer " , " requirement " = " \ w+ " , " description " = " The entry ID " }
* }
* )
*
* @ return Response
*/
public function getEntryExportAction ( Entry $entry , Request $request )
{
$this -> validateAuthentication ();
$this -> validateUserAccess ( $entry -> getUser () -> getId ());
return $this -> get ( 'wallabag_core.helper.entries_export' )
-> setEntries ( $entry )
-> updateTitle ( 'entry' )
2017-07-08 15:55:58 +00:00
-> updateAuthor ( 'entry' )
2016-11-03 16:29:16 +00:00
-> exportAs ( $request -> attributes -> get ( '_format' ));
}
2017-04-24 08:22:57 +00:00
/**
2017-04-24 09:31:00 +00:00
* Handles an entries list and delete URL .
2017-04-24 08:22:57 +00:00
*
* @ ApiDoc (
* parameters = {
2017-04-24 09:31:00 +00:00
* { " name " = " urls " , " dataType " = " string " , " required " = true , " format " = " A JSON array of urls [ { 'url': 'http://...'}, { 'url': 'http://...'}] " , " description " = " Urls (as an array) to delete. " }
2017-04-24 08:22:57 +00:00
* }
* )
*
* @ return JsonResponse
*/
2017-04-24 09:31:00 +00:00
public function deleteEntriesListAction ( Request $request )
2017-04-24 08:22:57 +00:00
{
$this -> validateAuthentication ();
2017-04-24 09:31:00 +00:00
$urls = json_decode ( $request -> query -> get ( 'urls' , []));
2017-05-05 10:05:50 +00:00
if ( empty ( $urls )) {
return $this -> sendResponse ([]);
}
2017-04-24 08:22:57 +00:00
$results = [];
// handle multiple urls
2017-05-05 10:05:50 +00:00
foreach ( $urls as $key => $url ) {
$entry = $this -> get ( 'wallabag_core.entry_repository' ) -> findByUrlAndUserId (
$url ,
$this -> getUser () -> getId ()
);
2017-04-24 09:31:00 +00:00
2017-05-05 10:05:50 +00:00
$results [ $key ][ 'url' ] = $url ;
2017-04-24 09:31:00 +00:00
2017-05-05 10:05:50 +00:00
if ( false !== $entry ) {
$em = $this -> getDoctrine () -> getManager ();
$em -> remove ( $entry );
$em -> flush ();
2017-04-24 08:22:57 +00:00
2017-05-05 10:05:50 +00:00
// entry deleted, dispatch event about it!
$this -> get ( 'event_dispatcher' ) -> dispatch ( EntryDeletedEvent :: NAME , new EntryDeletedEvent ( $entry ));
2017-04-24 09:31:00 +00:00
}
2017-04-24 08:22:57 +00:00
2017-05-05 10:05:50 +00:00
$results [ $key ][ 'entry' ] = $entry instanceof Entry ? true : false ;
}
2017-04-24 08:22:57 +00:00
2017-05-05 10:05:50 +00:00
return $this -> sendResponse ( $results );
2017-04-24 09:31:00 +00:00
}
2017-04-24 08:22:57 +00:00
2017-04-24 09:31:00 +00:00
/**
* Handles an entries list and create URL .
*
* @ ApiDoc (
* parameters = {
* { " name " = " urls " , " dataType " = " string " , " required " = true , " format " = " A JSON array of urls [ { 'url': 'http://...'}, { 'url': 'http://...'}] " , " description " = " Urls (as an array) to create. " }
* }
* )
*
2017-05-05 10:05:50 +00:00
* @ throws HttpException When limit is reached
2017-07-01 07:52:38 +00:00
*
* @ return JsonResponse
2017-04-24 09:31:00 +00:00
*/
public function postEntriesListAction ( Request $request )
{
$this -> validateAuthentication ();
2017-04-24 08:22:57 +00:00
2017-04-24 09:31:00 +00:00
$urls = json_decode ( $request -> query -> get ( 'urls' , []));
2017-04-24 08:22:57 +00:00
2017-05-01 07:21:59 +00:00
$limit = $this -> container -> getParameter ( 'wallabag_core.api_limit_mass_actions' );
if ( count ( $urls ) > $limit ) {
2017-05-05 10:05:50 +00:00
throw new HttpException ( 400 , 'API limit reached' );
2017-05-01 07:21:59 +00:00
}
2017-05-30 15:48:24 +00:00
$results = [];
if ( empty ( $urls )) {
return $this -> sendResponse ( $results );
}
2017-04-24 09:31:00 +00:00
// handle multiple urls
2017-05-30 15:48:24 +00:00
foreach ( $urls as $key => $url ) {
$entry = $this -> get ( 'wallabag_core.entry_repository' ) -> findByUrlAndUserId (
$url ,
$this -> getUser () -> getId ()
);
2017-04-24 08:22:57 +00:00
2017-05-30 15:48:24 +00:00
$results [ $key ][ 'url' ] = $url ;
2017-04-24 08:22:57 +00:00
2017-05-30 15:48:24 +00:00
if ( false === $entry ) {
$entry = new Entry ( $this -> getUser ());
2017-04-24 09:31:00 +00:00
2017-05-30 15:48:24 +00:00
$this -> get ( 'wallabag_core.content_proxy' ) -> updateEntry ( $entry , $url );
}
2017-04-24 09:31:00 +00:00
2017-05-30 15:48:24 +00:00
$em = $this -> getDoctrine () -> getManager ();
$em -> persist ( $entry );
$em -> flush ();
2017-04-24 09:31:00 +00:00
2017-05-30 15:48:24 +00:00
$results [ $key ][ 'entry' ] = $entry instanceof Entry ? $entry -> getId () : false ;
// entry saved, dispatch event about it!
$this -> get ( 'event_dispatcher' ) -> dispatch ( EntrySavedEvent :: NAME , new EntrySavedEvent ( $entry ));
2017-04-24 08:22:57 +00:00
}
2017-05-05 10:05:50 +00:00
return $this -> sendResponse ( $results );
2017-04-24 08:22:57 +00:00
}
2016-10-28 12:46:30 +00:00
/**
* Create an entry .
*
2017-05-24 14:02:49 +00:00
* If you want to provide the HTML content ( which means wallabag won ' t fetch it from the url ), you must provide `content` , `title` & `url` fields ** non - empty **.
* Otherwise , content will be fetched as normal from the url and values will be overwritten .
*
2016-10-28 12:46:30 +00:00
* @ ApiDoc (
* parameters = {
* { " name " = " url " , " dataType " = " string " , " required " = true , " format " = " http://www.test.com/article.html " , " description " = " Url for the entry. " },
* { " name " = " title " , " dataType " = " string " , " required " = false , " description " = " Optional, we'll get the title from the page. " },
* { " name " = " tags " , " dataType " = " string " , " required " = false , " format " = " tag1,tag2,tag3 " , " description " = " a comma-separated list of tags. " },
* { " name " = " archive " , " dataType " = " integer " , " required " = false , " format " = " 1 or 0 " , " description " = " entry already archived " },
2017-06-30 14:54:26 +00:00
* { " name " = " starred " , " dataType " = " integer " , " required " = false , " format " = " 1 or 0 " , " description " = " entry already starred " },
2017-05-11 06:14:29 +00:00
* { " name " = " content " , " dataType " = " string " , " required " = false , " description " = " Content of the entry " },
* { " name " = " language " , " dataType " = " string " , " required " = false , " description " = " Language of the entry " },
* { " name " = " preview_picture " , " dataType " = " string " , " required " = false , " description " = " Preview picture of the entry " },
2017-05-24 14:44:03 +00:00
* { " name " = " published_at " , " dataType " = " datetime|integer " , " format " = " YYYY-MM-DDTHH:II:SS+TZ or a timestamp " , " required " = false , " description " = " Published date of the entry " },
2017-05-11 18:10:22 +00:00
* { " name " = " authors " , " dataType " = " string " , " format " = " Name Firstname,author2,author3 " , " required " = false , " description " = " Authors of the entry " },
2017-06-10 13:31:57 +00:00
* { " name " = " public " , " dataType " = " integer " , " required " = false , " format " = " 1 or 0 " , " description " = " will generate a public link for the entry " },
2016-10-28 12:46:30 +00:00
* }
* )
*
* @ return JsonResponse
*/
public function postEntriesAction ( Request $request )
{
$this -> validateAuthentication ();
$url = $request -> request -> get ( 'url' );
2017-06-07 13:07:55 +00:00
$entry = $this -> get ( 'wallabag_core.entry_repository' ) -> findByUrlAndUserId (
$url ,
$this -> getUser () -> getId ()
);
2016-10-28 12:46:30 +00:00
if ( false === $entry ) {
2017-05-08 10:35:02 +00:00
$entry = new Entry ( $this -> getUser ());
2017-05-11 06:14:29 +00:00
$entry -> setUrl ( $url );
2016-10-28 12:46:30 +00:00
}
2017-06-30 14:54:26 +00:00
$data = $this -> retrieveValueFromRequest ( $request );
try {
$this -> get ( 'wallabag_core.content_proxy' ) -> updateEntry (
$entry ,
$entry -> getUrl (),
[
'title' => ! empty ( $data [ 'title' ]) ? $data [ 'title' ] : $entry -> getTitle (),
'html' => ! empty ( $data [ 'content' ]) ? $data [ 'content' ] : $entry -> getContent (),
'url' => $entry -> getUrl (),
'language' => ! empty ( $data [ 'language' ]) ? $data [ 'language' ] : $entry -> getLanguage (),
'date' => ! empty ( $data [ 'publishedAt' ]) ? $data [ 'publishedAt' ] : $entry -> getPublishedAt (),
// faking the open graph preview picture
'open_graph' => [
'og_image' => ! empty ( $data [ 'picture' ]) ? $data [ 'picture' ] : $entry -> getPreviewPicture (),
],
'authors' => is_string ( $data [ 'authors' ]) ? explode ( ',' , $data [ 'authors' ]) : $entry -> getPublishedBy (),
]
);
} catch ( \Exception $e ) {
$this -> get ( 'logger' ) -> error ( 'Error while saving an entry' , [
'exception' => $e ,
'entry' => $entry ,
]);
}
2017-07-03 11:56:39 +00:00
if ( null !== $data [ 'isArchived' ]) {
2017-06-30 14:54:26 +00:00
$entry -> setArchived (( bool ) $data [ 'isArchived' ]);
}
2017-07-03 11:56:39 +00:00
if ( null !== $data [ 'isStarred' ]) {
2017-06-30 14:54:26 +00:00
$entry -> setStarred (( bool ) $data [ 'isStarred' ]);
}
if ( ! empty ( $data [ 'tags' ])) {
$this -> get ( 'wallabag_core.tags_assigner' ) -> assignTagsToEntry ( $entry , $data [ 'tags' ]);
}
2017-07-03 11:56:39 +00:00
if ( null !== $data [ 'isPublic' ]) {
2017-06-30 14:54:26 +00:00
if ( true === ( bool ) $data [ 'isPublic' ] && null === $entry -> getUid ()) {
$entry -> generateUid ();
} elseif ( false === ( bool ) $data [ 'isPublic' ]) {
$entry -> cleanUid ();
}
}
$em = $this -> getDoctrine () -> getManager ();
$em -> persist ( $entry );
$em -> flush ();
// entry saved, dispatch event about it!
$this -> get ( 'event_dispatcher' ) -> dispatch ( EntrySavedEvent :: NAME , new EntrySavedEvent ( $entry ));
2016-11-03 15:41:29 +00:00
2017-05-05 10:05:50 +00:00
return $this -> sendResponse ( $entry );
2016-10-28 12:46:30 +00:00
}
/**
* Change several properties of an entry .
*
* @ ApiDoc (
* requirements = {
* { " name " = " entry " , " dataType " = " integer " , " requirement " = " \ w+ " , " description " = " The entry ID " }
* },
* parameters = {
* { " name " = " title " , " dataType " = " string " , " required " = false },
* { " name " = " tags " , " dataType " = " string " , " required " = false , " format " = " tag1,tag2,tag3 " , " description " = " a comma-separated list of tags. " },
* { " name " = " archive " , " dataType " = " integer " , " required " = false , " format " = " 1 or 0 " , " description " = " archived the entry. " },
* { " name " = " starred " , " dataType " = " integer " , " required " = false , " format " = " 1 or 0 " , " description " = " starred the entry. " },
2017-06-02 18:52:49 +00:00
* { " name " = " content " , " dataType " = " string " , " required " = false , " description " = " Content of the entry " },
* { " name " = " language " , " dataType " = " string " , " required " = false , " description " = " Language of 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 " },
2017-06-10 13:31:57 +00:00
* { " name " = " public " , " dataType " = " integer " , " required " = false , " format " = " 1 or 0 " , " description " = " will generate a public link for the entry " },
2016-10-28 12:46:30 +00:00
* }
* )
*
* @ return JsonResponse
*/
public function patchEntriesAction ( Entry $entry , Request $request )
{
$this -> validateAuthentication ();
$this -> validateUserAccess ( $entry -> getUser () -> getId ());
2017-06-30 14:54:26 +00:00
$contentProxy = $this -> get ( 'wallabag_core.content_proxy' );
$data = $this -> retrieveValueFromRequest ( $request );
// this is a special case where user want to manually update the entry content
// the ContentProxy will only cleanup the html
// and also we force to not re-fetch the content in case of error
if ( ! empty ( $data [ 'content' ])) {
try {
$contentProxy -> updateEntry (
$entry ,
$entry -> getUrl (),
[
'html' => $data [ 'content' ],
],
true
);
} catch ( \Exception $e ) {
$this -> get ( 'logger' ) -> error ( 'Error while saving an entry' , [
'exception' => $e ,
'entry' => $entry ,
]);
}
}
if ( ! empty ( $data [ 'title' ])) {
$entry -> setTitle ( $data [ 'title' ]);
}
if ( ! empty ( $data [ 'language' ])) {
$contentProxy -> updateLanguage ( $entry , $data [ 'language' ]);
}
if ( ! empty ( $data [ 'authors' ]) && is_string ( $data [ 'authors' ])) {
$entry -> setPublishedBy ( explode ( ',' , $data [ 'authors' ]));
}
if ( ! empty ( $data [ 'picture' ])) {
$contentProxy -> updatePreviewPicture ( $entry , $data [ 'picture' ]);
}
if ( ! empty ( $data [ 'publishedAt' ])) {
$contentProxy -> updatePublishedAt ( $entry , $data [ 'publishedAt' ]);
}
2017-07-03 11:56:39 +00:00
if ( null !== $data [ 'isArchived' ]) {
2017-06-30 14:54:26 +00:00
$entry -> setArchived (( bool ) $data [ 'isArchived' ]);
}
2017-07-03 11:56:39 +00:00
if ( null !== $data [ 'isStarred' ]) {
2017-06-30 14:54:26 +00:00
$entry -> setStarred (( bool ) $data [ 'isStarred' ]);
}
if ( ! empty ( $data [ 'tags' ])) {
$entry -> removeAllTags ();
$this -> get ( 'wallabag_core.tags_assigner' ) -> assignTagsToEntry ( $entry , $data [ 'tags' ]);
}
2017-07-03 11:56:39 +00:00
if ( null !== $data [ 'isPublic' ]) {
2017-06-30 14:54:26 +00:00
if ( true === ( bool ) $data [ 'isPublic' ] && null === $entry -> getUid ()) {
$entry -> generateUid ();
} elseif ( false === ( bool ) $data [ 'isPublic' ]) {
$entry -> cleanUid ();
}
}
$em = $this -> getDoctrine () -> getManager ();
$em -> persist ( $entry );
$em -> flush ();
// entry saved, dispatch event about it!
$this -> get ( 'event_dispatcher' ) -> dispatch ( EntrySavedEvent :: NAME , new EntrySavedEvent ( $entry ));
2016-10-28 12:46:30 +00:00
2017-05-05 10:05:50 +00:00
return $this -> sendResponse ( $entry );
2016-10-28 12:46:30 +00:00
}
2016-11-20 12:08:41 +00:00
/**
* Reload an entry .
2016-11-22 09:45:17 +00:00
* An empty response with HTTP Status 304 will be send if we weren 't able to update the content (because it hasn' t changed or we got an error ) .
2016-11-20 12:08:41 +00:00
*
* @ ApiDoc (
* requirements = {
* { " name " = " entry " , " dataType " = " integer " , " requirement " = " \ w+ " , " description " = " The entry ID " }
* }
* )
*
* @ return JsonResponse
*/
public function patchEntriesReloadAction ( Entry $entry )
{
$this -> validateAuthentication ();
$this -> validateUserAccess ( $entry -> getUser () -> getId ());
try {
2016-12-07 03:17:44 +00:00
$this -> get ( 'wallabag_core.content_proxy' ) -> updateEntry ( $entry , $entry -> getUrl ());
2016-11-20 12:08:41 +00:00
} catch ( \Exception $e ) {
$this -> get ( 'logger' ) -> error ( 'Error while saving an entry' , [
'exception' => $e ,
'entry' => $entry ,
]);
2016-11-22 09:45:17 +00:00
return new JsonResponse ([], 304 );
2016-11-20 12:08:41 +00:00
}
// if refreshing entry failed, don't save it
if ( $this -> getParameter ( 'wallabag_core.fetching_error_message' ) === $entry -> getContent ()) {
2016-11-22 09:45:17 +00:00
return new JsonResponse ([], 304 );
2016-11-20 12:08:41 +00:00
}
$em = $this -> getDoctrine () -> getManager ();
$em -> persist ( $entry );
$em -> flush ();
// entry saved, dispatch event about it!
$this -> get ( 'event_dispatcher' ) -> dispatch ( EntrySavedEvent :: NAME , new EntrySavedEvent ( $entry ));
2017-05-05 10:05:50 +00:00
return $this -> sendResponse ( $entry );
2016-11-20 12:08:41 +00:00
}
2016-10-28 12:46:30 +00:00
/**
* Delete ** permanently ** an entry .
*
* @ ApiDoc (
* requirements = {
* { " name " = " entry " , " dataType " = " integer " , " requirement " = " \ w+ " , " description " = " The entry ID " }
* }
* )
*
* @ return JsonResponse
*/
public function deleteEntriesAction ( Entry $entry )
{
$this -> validateAuthentication ();
$this -> validateUserAccess ( $entry -> getUser () -> getId ());
$em = $this -> getDoctrine () -> getManager ();
$em -> remove ( $entry );
$em -> flush ();
2016-11-03 15:41:29 +00:00
// entry deleted, dispatch event about it!
$this -> get ( 'event_dispatcher' ) -> dispatch ( EntryDeletedEvent :: NAME , new EntryDeletedEvent ( $entry ));
2017-05-05 10:05:50 +00:00
return $this -> sendResponse ( $entry );
2016-10-28 12:46:30 +00:00
}
/**
* Retrieve all tags for an entry .
*
* @ ApiDoc (
* requirements = {
* { " name " = " entry " , " dataType " = " integer " , " requirement " = " \ w+ " , " description " = " The entry ID " }
* }
* )
*
* @ return JsonResponse
*/
public function getEntriesTagsAction ( Entry $entry )
{
$this -> validateAuthentication ();
$this -> validateUserAccess ( $entry -> getUser () -> getId ());
2017-05-05 10:05:50 +00:00
return $this -> sendResponse ( $entry -> getTags ());
2016-10-28 12:46:30 +00:00
}
/**
* Add one or more tags to an entry .
*
* @ ApiDoc (
* requirements = {
* { " name " = " entry " , " dataType " = " integer " , " requirement " = " \ w+ " , " description " = " The entry ID " }
* },
* parameters = {
* { " name " = " tags " , " dataType " = " string " , " required " = false , " format " = " tag1,tag2,tag3 " , " description " = " a comma-separated list of tags. " },
* }
* )
*
* @ return JsonResponse
*/
public function postEntriesTagsAction ( Request $request , Entry $entry )
{
$this -> validateAuthentication ();
$this -> validateUserAccess ( $entry -> getUser () -> getId ());
$tags = $request -> request -> get ( 'tags' , '' );
if ( ! empty ( $tags )) {
2017-05-27 20:08:14 +00:00
$this -> get ( 'wallabag_core.tags_assigner' ) -> assignTagsToEntry ( $entry , $tags );
2016-10-28 12:46:30 +00:00
}
$em = $this -> getDoctrine () -> getManager ();
$em -> persist ( $entry );
$em -> flush ();
2017-05-05 10:05:50 +00:00
return $this -> sendResponse ( $entry );
2016-10-28 12:46:30 +00:00
}
/**
* Permanently remove one tag for an entry .
*
* @ ApiDoc (
* requirements = {
* { " name " = " tag " , " dataType " = " integer " , " requirement " = " \ w+ " , " description " = " The tag ID " },
* { " name " = " entry " , " dataType " = " integer " , " requirement " = " \ w+ " , " description " = " The entry ID " }
* }
* )
*
* @ return JsonResponse
*/
public function deleteEntriesTagsAction ( Entry $entry , Tag $tag )
{
$this -> validateAuthentication ();
$this -> validateUserAccess ( $entry -> getUser () -> getId ());
$entry -> removeTag ( $tag );
$em = $this -> getDoctrine () -> getManager ();
$em -> persist ( $entry );
$em -> flush ();
2017-05-05 10:05:50 +00:00
return $this -> sendResponse ( $entry );
2016-10-28 12:46:30 +00:00
}
2017-04-24 09:12:41 +00:00
/**
2017-04-24 10:24:17 +00:00
* Handles an entries list delete tags from them .
2017-04-24 09:12:41 +00:00
*
* @ ApiDoc (
* parameters = {
2017-04-24 10:24:17 +00:00
* { " name " = " list " , " dataType " = " string " , " required " = true , " format " = " A JSON array of urls [ { 'url': 'http://...','tags': 'tag1, tag2'}, { 'url': 'http://...','tags': 'tag1, tag2'}] " , " description " = " Urls (as an array) to handle. " }
2017-04-24 09:12:41 +00:00
* }
* )
*
* @ return JsonResponse
*/
2017-04-24 10:24:17 +00:00
public function deleteEntriesTagsListAction ( Request $request )
2017-04-24 09:12:41 +00:00
{
$this -> validateAuthentication ();
$list = json_decode ( $request -> query -> get ( 'list' , []));
2017-05-05 10:05:50 +00:00
if ( empty ( $list )) {
return $this -> sendResponse ([]);
}
2017-04-24 09:12:41 +00:00
// handle multiple urls
2017-05-05 10:05:50 +00:00
$results = [];
2017-04-24 09:12:41 +00:00
2017-05-05 10:05:50 +00:00
foreach ( $list as $key => $element ) {
$entry = $this -> get ( 'wallabag_core.entry_repository' ) -> findByUrlAndUserId (
$element -> url ,
$this -> getUser () -> getId ()
);
2017-04-24 09:12:41 +00:00
2017-05-05 10:05:50 +00:00
$results [ $key ][ 'url' ] = $element -> url ;
$results [ $key ][ 'entry' ] = $entry instanceof Entry ? $entry -> getId () : false ;
2017-04-24 09:12:41 +00:00
2017-05-05 10:05:50 +00:00
$tags = $element -> tags ;
2017-04-24 10:24:17 +00:00
2017-05-05 10:05:50 +00:00
if ( false !== $entry && ! ( empty ( $tags ))) {
$tags = explode ( ',' , $tags );
foreach ( $tags as $label ) {
$label = trim ( $label );
2017-04-24 10:24:17 +00:00
2017-05-05 10:05:50 +00:00
$tag = $this -> getDoctrine ()
-> getRepository ( 'WallabagCoreBundle:Tag' )
-> findOneByLabel ( $label );
2017-04-24 09:12:41 +00:00
2017-05-05 10:05:50 +00:00
if ( false !== $tag ) {
$entry -> removeTag ( $tag );
}
2017-04-24 09:12:41 +00:00
}
2017-05-05 10:05:50 +00:00
$em = $this -> getDoctrine () -> getManager ();
$em -> persist ( $entry );
$em -> flush ();
2017-04-24 09:12:41 +00:00
}
}
2017-05-05 10:05:50 +00:00
return $this -> sendResponse ( $results );
2017-04-24 09:12:41 +00:00
}
2017-04-24 10:24:17 +00:00
/**
* Handles an entries list and add tags to them .
*
* @ ApiDoc (
* parameters = {
* { " name " = " list " , " dataType " = " string " , " required " = true , " format " = " A JSON array of urls [ { 'url': 'http://...','tags': 'tag1, tag2'}, { 'url': 'http://...','tags': 'tag1, tag2'}] " , " description " = " Urls (as an array) to handle. " }
* }
* )
*
* @ return JsonResponse
*/
public function postEntriesTagsListAction ( Request $request )
{
$this -> validateAuthentication ();
$list = json_decode ( $request -> query -> get ( 'list' , []));
2017-05-05 10:05:50 +00:00
if ( empty ( $list )) {
return $this -> sendResponse ([]);
}
2017-04-24 10:24:17 +00:00
$results = [];
// handle multiple urls
2017-05-05 10:05:50 +00:00
foreach ( $list as $key => $element ) {
$entry = $this -> get ( 'wallabag_core.entry_repository' ) -> findByUrlAndUserId (
$element -> url ,
$this -> getUser () -> getId ()
);
2017-04-24 10:24:17 +00:00
2017-05-05 10:05:50 +00:00
$results [ $key ][ 'url' ] = $element -> url ;
$results [ $key ][ 'entry' ] = $entry instanceof Entry ? $entry -> getId () : false ;
2017-04-24 10:24:17 +00:00
2017-05-05 10:05:50 +00:00
$tags = $element -> tags ;
2017-04-24 10:24:17 +00:00
2017-05-05 10:05:50 +00:00
if ( false !== $entry && ! ( empty ( $tags ))) {
2017-05-27 20:08:14 +00:00
$this -> get ( 'wallabag_core.tags_assigner' ) -> assignTagsToEntry ( $entry , $tags );
2017-04-24 10:24:17 +00:00
2017-05-05 10:05:50 +00:00
$em = $this -> getDoctrine () -> getManager ();
$em -> persist ( $entry );
$em -> flush ();
2017-04-24 10:24:17 +00:00
}
}
2017-05-05 10:05:50 +00:00
return $this -> sendResponse ( $results );
}
/**
* Shortcut to send data serialized in json .
*
* @ param mixed $data
*
* @ return JsonResponse
*/
private function sendResponse ( $data )
{
2017-06-28 06:15:06 +00:00
// https://github.com/schmittjoh/JMSSerializerBundle/issues/293
$context = new SerializationContext ();
$context -> setSerializeNull ( true );
$json = $this -> get ( 'serializer' ) -> serialize ( $data , 'json' , $context );
2017-04-24 10:24:17 +00:00
return ( new JsonResponse ()) -> setJson ( $json );
}
2017-06-07 13:07:55 +00:00
/**
2017-06-30 14:54:26 +00:00
* Retrieve value from the request .
* Used for POST & PATCH on a an entry .
2017-06-07 13:07:55 +00:00
*
* @ param Request $request
2017-06-30 14:54:26 +00:00
*
* @ return array
2017-06-07 13:07:55 +00:00
*/
2017-06-30 14:54:26 +00:00
private function retrieveValueFromRequest ( Request $request )
2017-06-07 13:07:55 +00:00
{
2017-06-30 14:54:26 +00:00
return [
'title' => $request -> request -> get ( 'title' ),
'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' ),
'publishedAt' => $request -> request -> get ( 'published_at' ),
'authors' => $request -> request -> get ( 'authors' , '' ),
];
2017-06-07 13:07:55 +00:00
}
2017-06-28 06:15:06 +00:00
/**
* Return information about the entry if it exist and depending on the id or not .
*
* @ param Entry | null $entry
* @ param bool $returnId
*
* @ return bool | int
*/
private function returnExistInformation ( $entry , $returnId )
{
if ( $returnId ) {
return $entry instanceof Entry ? $entry -> getId () : null ;
}
2017-06-28 07:18:22 +00:00
return $entry instanceof Entry ;
2017-06-28 06:15:06 +00:00
}
2016-10-28 12:46:30 +00:00
}