mirror of
https://github.com/wallabag/wallabag.git
synced 2024-12-25 00:50:29 +00:00
Merge pull request #1386 from wallabag/v2-refactor
WIP – Fixing things around 💨
This commit is contained in:
commit
109d67dbb1
16 changed files with 190 additions and 298 deletions
|
@ -51,6 +51,7 @@ twig:
|
||||||
form:
|
form:
|
||||||
resources:
|
resources:
|
||||||
- LexikFormFilterBundle:Form:form_div_layout.html.twig
|
- LexikFormFilterBundle:Form:form_div_layout.html.twig
|
||||||
|
|
||||||
# Assetic Configuration
|
# Assetic Configuration
|
||||||
assetic:
|
assetic:
|
||||||
debug: "%kernel.debug%"
|
debug: "%kernel.debug%"
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Jérémy Benoist",
|
"name": "Jérémy Benoist",
|
||||||
|
"homepage": "http://www.j0k3r.net",
|
||||||
"role": "Developer"
|
"role": "Developer"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
@ -170,6 +170,31 @@ class WallabagRestControllerTest extends WebTestCase
|
||||||
$client = $this->createClient();
|
$client = $this->createClient();
|
||||||
$headers = $this->generateHeaders('admin', 'mypassword');
|
$headers = $this->generateHeaders('admin', 'mypassword');
|
||||||
|
|
||||||
|
$client->request('GET', '/api/entries', array('star' => 1, 'sort' => 'updated'), array(), $headers);
|
||||||
|
|
||||||
|
$this->assertEquals(200, $client->getResponse()->getStatusCode());
|
||||||
|
|
||||||
|
$content = json_decode($client->getResponse()->getContent(), true);
|
||||||
|
|
||||||
|
$this->assertGreaterThanOrEqual(1, count($content));
|
||||||
|
$this->assertNotEmpty($content['_embedded']['items']);
|
||||||
|
$this->assertGreaterThanOrEqual(1, $content['total']);
|
||||||
|
$this->assertEquals(1, $content['page']);
|
||||||
|
$this->assertGreaterThanOrEqual(1, $content['pages']);
|
||||||
|
|
||||||
|
$this->assertTrue(
|
||||||
|
$client->getResponse()->headers->contains(
|
||||||
|
'Content-Type',
|
||||||
|
'application/json'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetArchiveEntries()
|
||||||
|
{
|
||||||
|
$client = $this->createClient();
|
||||||
|
$headers = $this->generateHeaders('admin', 'mypassword');
|
||||||
|
|
||||||
$client->request('GET', '/api/entries', array('archive' => 1), array(), $headers);
|
$client->request('GET', '/api/entries', array('archive' => 1), array(), $headers);
|
||||||
|
|
||||||
$this->assertEquals(200, $client->getResponse()->getStatusCode());
|
$this->assertEquals(200, $client->getResponse()->getStatusCode());
|
||||||
|
|
|
@ -113,34 +113,7 @@ class EntryController extends Controller
|
||||||
*/
|
*/
|
||||||
public function showUnreadAction(Request $request, $page)
|
public function showUnreadAction(Request $request, $page)
|
||||||
{
|
{
|
||||||
$form = $this->get('form.factory')->create(new EntryFilterType());
|
return $this->showEntries('unread', $request, $page);
|
||||||
|
|
||||||
$filterBuilder = $this->getDoctrine()
|
|
||||||
->getRepository('WallabagCoreBundle:Entry')
|
|
||||||
->findUnreadByUser($this->getUser()->getId());
|
|
||||||
|
|
||||||
if ($request->query->has($form->getName())) {
|
|
||||||
// manually bind values from the request
|
|
||||||
$form->submit($request->query->get($form->getName()));
|
|
||||||
|
|
||||||
// build the query from the given form object
|
|
||||||
$this->get('lexik_form_filter.query_builder_updater')->addFilterConditions($form, $filterBuilder);
|
|
||||||
}
|
|
||||||
|
|
||||||
$pagerAdapter = new DoctrineORMAdapter($filterBuilder->getQuery());
|
|
||||||
$entries = new Pagerfanta($pagerAdapter);
|
|
||||||
|
|
||||||
$entries->setMaxPerPage($this->getUser()->getConfig()->getItemsPerPage());
|
|
||||||
$entries->setCurrentPage($page);
|
|
||||||
|
|
||||||
return $this->render(
|
|
||||||
'WallabagCoreBundle:Entry:entries.html.twig',
|
|
||||||
array(
|
|
||||||
'form' => $form->createView(),
|
|
||||||
'entries' => $entries,
|
|
||||||
'currentPage' => $page,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -155,34 +128,7 @@ class EntryController extends Controller
|
||||||
*/
|
*/
|
||||||
public function showArchiveAction(Request $request, $page)
|
public function showArchiveAction(Request $request, $page)
|
||||||
{
|
{
|
||||||
$form = $this->get('form.factory')->create(new EntryFilterType());
|
return $this->showEntries('archive', $request, $page);
|
||||||
|
|
||||||
$filterBuilder = $this->getDoctrine()
|
|
||||||
->getRepository('WallabagCoreBundle:Entry')
|
|
||||||
->findArchiveByUser($this->getUser()->getId());
|
|
||||||
|
|
||||||
if ($request->query->has($form->getName())) {
|
|
||||||
// manually bind values from the request
|
|
||||||
$form->submit($request->query->get($form->getName()));
|
|
||||||
|
|
||||||
// build the query from the given form object
|
|
||||||
$this->get('lexik_form_filter.query_builder_updater')->addFilterConditions($form, $filterBuilder);
|
|
||||||
}
|
|
||||||
|
|
||||||
$pagerAdapter = new DoctrineORMAdapter($filterBuilder->getQuery());
|
|
||||||
$entries = new Pagerfanta($pagerAdapter);
|
|
||||||
|
|
||||||
$entries->setMaxPerPage($this->getUser()->getConfig()->getItemsPerPage());
|
|
||||||
$entries->setCurrentPage($page);
|
|
||||||
|
|
||||||
return $this->render(
|
|
||||||
'WallabagCoreBundle:Entry:entries.html.twig',
|
|
||||||
array(
|
|
||||||
'form' => $form->createView(),
|
|
||||||
'entries' => $entries,
|
|
||||||
'currentPage' => $page,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -197,11 +143,64 @@ class EntryController extends Controller
|
||||||
*/
|
*/
|
||||||
public function showStarredAction(Request $request, $page)
|
public function showStarredAction(Request $request, $page)
|
||||||
{
|
{
|
||||||
|
return $this->showEntries('starred', $request, $page);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global method to retrieve entries depending on the given type
|
||||||
|
* It returns the response to be send.
|
||||||
|
*
|
||||||
|
* @param string $type Entries type: unread, starred or archive
|
||||||
|
* @param Request $request
|
||||||
|
* @param int $page
|
||||||
|
*
|
||||||
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
|
*/
|
||||||
|
private function showEntries($type, Request $request, $page)
|
||||||
|
{
|
||||||
|
$repository = $this->getDoctrine()->getRepository('WallabagCoreBundle:Entry');
|
||||||
|
|
||||||
|
switch ($type) {
|
||||||
|
case 'starred':
|
||||||
|
$qb = $repository->getBuilderForStarredByUser($this->getUser()->getId());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'archive':
|
||||||
|
$qb = $repository->getBuilderForArchiveByUser($this->getUser()->getId());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'unread':
|
||||||
|
$qb = $repository->getBuilderForUnreadByUser($this->getUser()->getId());
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new \InvalidArgumentException(sprintf('Type "%s" is not implemented.', $type));
|
||||||
|
}
|
||||||
|
|
||||||
$form = $this->get('form.factory')->create(new EntryFilterType());
|
$form = $this->get('form.factory')->create(new EntryFilterType());
|
||||||
|
|
||||||
$filterBuilder = $this->getDoctrine()
|
if ($request->query->has($form->getName())) {
|
||||||
->getRepository('WallabagCoreBundle:Entry')
|
// manually bind values from the request
|
||||||
->findStarredByUser($this->getUser()->getId());
|
$form->submit($request->query->get($form->getName()));
|
||||||
|
|
||||||
|
// build the query from the given form object
|
||||||
|
$this->get('lexik_form_filter.query_builder_updater')->addFilterConditions($form, $qb);
|
||||||
|
}
|
||||||
|
|
||||||
|
$pagerAdapter = new DoctrineORMAdapter($qb->getQuery());
|
||||||
|
$entries = new Pagerfanta($pagerAdapter);
|
||||||
|
|
||||||
|
$entries->setMaxPerPage($this->getUser()->getConfig()->getItemsPerPage());
|
||||||
|
$entries->setCurrentPage($page);
|
||||||
|
|
||||||
|
return $this->render(
|
||||||
|
'WallabagCoreBundle:Entry:entries.html.twig',
|
||||||
|
array(
|
||||||
|
'form' => $form->createView(),
|
||||||
|
'entries' => $entries,
|
||||||
|
'currentPage' => $page,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
if ($request->query->has($form->getName())) {
|
if ($request->query->has($form->getName())) {
|
||||||
// manually bind values from the request
|
// manually bind values from the request
|
||||||
|
|
|
@ -22,22 +22,7 @@ class RssController extends Controller
|
||||||
*/
|
*/
|
||||||
public function showUnreadAction(User $user)
|
public function showUnreadAction(User $user)
|
||||||
{
|
{
|
||||||
$qb = $this->getDoctrine()
|
return $this->showEntries('unread', $user);
|
||||||
->getRepository('WallabagCoreBundle:Entry')
|
|
||||||
->findUnreadByUser(
|
|
||||||
$user->getId()
|
|
||||||
);
|
|
||||||
|
|
||||||
$pagerAdapter = new DoctrineORMAdapter($qb->getQuery());
|
|
||||||
$entries = new Pagerfanta($pagerAdapter);
|
|
||||||
|
|
||||||
$perPage = $user->getConfig()->getRssLimit() ?: $this->container->getParameter('rss_limit');
|
|
||||||
$entries->setMaxPerPage($perPage);
|
|
||||||
|
|
||||||
return $this->render('WallabagCoreBundle:Entry:entries.xml.twig', array(
|
|
||||||
'type' => 'unread',
|
|
||||||
'entries' => $entries,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,22 +35,7 @@ class RssController extends Controller
|
||||||
*/
|
*/
|
||||||
public function showArchiveAction(User $user)
|
public function showArchiveAction(User $user)
|
||||||
{
|
{
|
||||||
$qb = $this->getDoctrine()
|
return $this->showEntries('archive', $user);
|
||||||
->getRepository('WallabagCoreBundle:Entry')
|
|
||||||
->findArchiveByUser(
|
|
||||||
$user->getId()
|
|
||||||
);
|
|
||||||
|
|
||||||
$pagerAdapter = new DoctrineORMAdapter($qb->getQuery());
|
|
||||||
$entries = new Pagerfanta($pagerAdapter);
|
|
||||||
|
|
||||||
$perPage = $user->getConfig()->getRssLimit() ?: $this->container->getParameter('rss_limit');
|
|
||||||
$entries->setMaxPerPage($perPage);
|
|
||||||
|
|
||||||
return $this->render('WallabagCoreBundle:Entry:entries.xml.twig', array(
|
|
||||||
'type' => 'archive',
|
|
||||||
'entries' => $entries,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,11 +48,38 @@ class RssController extends Controller
|
||||||
*/
|
*/
|
||||||
public function showStarredAction(User $user)
|
public function showStarredAction(User $user)
|
||||||
{
|
{
|
||||||
$qb = $this->getDoctrine()
|
return $this->showEntries('starred', $user);
|
||||||
->getRepository('WallabagCoreBundle:Entry')
|
}
|
||||||
->findStarredByUser(
|
|
||||||
$user->getId()
|
/**
|
||||||
);
|
* Global method to retrieve entries depending on the given type
|
||||||
|
* It returns the response to be send.
|
||||||
|
*
|
||||||
|
* @param string $type Entries type: unread, starred or archive
|
||||||
|
* @param User $user
|
||||||
|
*
|
||||||
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
|
*/
|
||||||
|
private function showEntries($type, User $user)
|
||||||
|
{
|
||||||
|
$repository = $this->getDoctrine()->getRepository('WallabagCoreBundle:Entry');
|
||||||
|
|
||||||
|
switch ($type) {
|
||||||
|
case 'starred':
|
||||||
|
$qb = $repository->getBuilderForStarredByUser($user->getId());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'archive':
|
||||||
|
$qb = $repository->getBuilderForArchiveByUser($user->getId());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'unread':
|
||||||
|
$qb = $repository->getBuilderForUnreadByUser($user->getId());
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new \InvalidArgumentException(sprintf('Type "%s" is not implemented.', $type));
|
||||||
|
}
|
||||||
|
|
||||||
$pagerAdapter = new DoctrineORMAdapter($qb->getQuery());
|
$pagerAdapter = new DoctrineORMAdapter($qb->getQuery());
|
||||||
$entries = new Pagerfanta($pagerAdapter);
|
$entries = new Pagerfanta($pagerAdapter);
|
||||||
|
@ -91,7 +88,7 @@ class RssController extends Controller
|
||||||
$entries->setMaxPerPage($perPage);
|
$entries->setMaxPerPage($perPage);
|
||||||
|
|
||||||
return $this->render('WallabagCoreBundle:Entry:entries.xml.twig', array(
|
return $this->render('WallabagCoreBundle:Entry:entries.xml.twig', array(
|
||||||
'type' => 'starred',
|
'type' => $type,
|
||||||
'entries' => $entries,
|
'entries' => $entries,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,12 +28,4 @@ class StaticController extends Controller
|
||||||
array()
|
array()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/", name="homepage")
|
|
||||||
*/
|
|
||||||
public function apiAction()
|
|
||||||
{
|
|
||||||
return $this->redirect($this->generateUrl('nelmio_api_doc_index'));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use Doctrine\ORM\Mapping as ORM;
|
||||||
use Symfony\Component\Validator\Constraints as Assert;
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
use Hateoas\Configuration\Annotation as Hateoas;
|
use Hateoas\Configuration\Annotation as Hateoas;
|
||||||
use JMS\Serializer\Annotation\XmlRoot;
|
use JMS\Serializer\Annotation\XmlRoot;
|
||||||
use Wallabag\CoreBundle\Helper\Tools;
|
use Wallabag\CoreBundle\Tools\Utils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entry.
|
* Entry.
|
||||||
|
@ -265,7 +265,7 @@ class Entry
|
||||||
public function setContent($content)
|
public function setContent($content)
|
||||||
{
|
{
|
||||||
$this->content = $content;
|
$this->content = $content;
|
||||||
$this->readingTime = Tools::getReadingTime($content);
|
$this->readingTime = Utils::getReadingTime($content);
|
||||||
$this->domainName = parse_url($this->url, PHP_URL_HOST);
|
$this->domainName = parse_url($this->url, PHP_URL_HOST);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Wallabag\CoreBundle\Helper;
|
|
||||||
|
|
||||||
class Entry
|
|
||||||
{
|
|
||||||
}
|
|
|
@ -1,133 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Wallabag\CoreBundle\Helper;
|
|
||||||
|
|
||||||
final class Tools
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Download a file (typically, for downloading pictures on web server).
|
|
||||||
*
|
|
||||||
* @param $url
|
|
||||||
*
|
|
||||||
* @return bool|mixed|string
|
|
||||||
*/
|
|
||||||
public static function getFile($url)
|
|
||||||
{
|
|
||||||
$timeout = 15;
|
|
||||||
$useragent = 'Mozilla/5.0 (Windows NT 5.1; rv:18.0) Gecko/20100101 Firefox/18.0';
|
|
||||||
|
|
||||||
if (in_array('curl', get_loaded_extensions())) {
|
|
||||||
# Fetch feed from URL
|
|
||||||
$curl = curl_init();
|
|
||||||
curl_setopt($curl, CURLOPT_URL, $url);
|
|
||||||
curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);
|
|
||||||
if (!ini_get('open_basedir') && !ini_get('safe_mode')) {
|
|
||||||
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
|
|
||||||
}
|
|
||||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($curl, CURLOPT_HEADER, false);
|
|
||||||
|
|
||||||
# for ssl, do not verified certificate
|
|
||||||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
|
|
||||||
curl_setopt($curl, CURLOPT_AUTOREFERER, true);
|
|
||||||
|
|
||||||
# FeedBurner requires a proper USER-AGENT...
|
|
||||||
curl_setopt($curl, CURL_HTTP_VERSION_1_1, true);
|
|
||||||
curl_setopt($curl, CURLOPT_ENCODING, 'gzip, deflate');
|
|
||||||
curl_setopt($curl, CURLOPT_USERAGENT, $useragent);
|
|
||||||
|
|
||||||
$data = curl_exec($curl);
|
|
||||||
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
|
||||||
$httpcodeOK = isset($httpcode) and ($httpcode == 200 or $httpcode == 301);
|
|
||||||
curl_close($curl);
|
|
||||||
} else {
|
|
||||||
# create http context and add timeout and user-agent
|
|
||||||
$context = stream_context_create(
|
|
||||||
array(
|
|
||||||
'http' => array(
|
|
||||||
'timeout' => $timeout,
|
|
||||||
'header' => 'User-Agent: '.$useragent,
|
|
||||||
'follow_location' => true,
|
|
||||||
),
|
|
||||||
'ssl' => array(
|
|
||||||
'verify_peer' => false,
|
|
||||||
'allow_self_signed' => true,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
# only download page lesser than 4MB
|
|
||||||
$data = @file_get_contents($url, false, $context, -1, 4000000);
|
|
||||||
|
|
||||||
if (isset($http_response_header) and isset($http_response_header[0])) {
|
|
||||||
$httpcodeOK = isset($http_response_header) and isset($http_response_header[0]) and ((strpos($http_response_header[0], '200 OK') !== false) or (strpos($http_response_header[0], '301 Moved Permanently') !== false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# if response is not empty and response is OK
|
|
||||||
if (isset($data) and isset($httpcodeOK) and $httpcodeOK) {
|
|
||||||
# take charset of page and get it
|
|
||||||
preg_match('#<meta .*charset=.*>#Usi', $data, $meta);
|
|
||||||
|
|
||||||
# if meta tag is found
|
|
||||||
if (!empty($meta[0])) {
|
|
||||||
preg_match('#charset="?(.*)"#si', $meta[0], $encoding);
|
|
||||||
# if charset is found set it otherwise, set it to utf-8
|
|
||||||
$html_charset = (!empty($encoding[1])) ? strtolower($encoding[1]) : 'utf-8';
|
|
||||||
if (empty($encoding[1])) {
|
|
||||||
$encoding[1] = 'utf-8';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$html_charset = 'utf-8';
|
|
||||||
$encoding[1] = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
# replace charset of url to charset of page
|
|
||||||
$data = str_replace('charset='.$encoding[1], 'charset='.$html_charset, $data);
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encode a URL by using a salt.
|
|
||||||
*
|
|
||||||
* @param $string
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function encodeString($string)
|
|
||||||
{
|
|
||||||
return sha1($string.SALT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function generateToken()
|
|
||||||
{
|
|
||||||
if (ini_get('open_basedir') === '') {
|
|
||||||
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
|
||||||
// alternative to /dev/urandom for Windows
|
|
||||||
$token = substr(base64_encode(uniqid(mt_rand(), true)), 0, 20);
|
|
||||||
} else {
|
|
||||||
$token = substr(base64_encode(file_get_contents('/dev/urandom', false, null, 0, 20)), 0, 15);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$token = substr(base64_encode(uniqid(mt_rand(), true)), 0, 20);
|
|
||||||
}
|
|
||||||
|
|
||||||
return str_replace('+', '', $token);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For a given text, we calculate reading time for an article.
|
|
||||||
*
|
|
||||||
* @param $text
|
|
||||||
*
|
|
||||||
* @return float
|
|
||||||
*/
|
|
||||||
public static function getReadingTime($text)
|
|
||||||
{
|
|
||||||
return floor(str_word_count(strip_tags($text)) / 200);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,6 +8,22 @@ use Pagerfanta\Pagerfanta;
|
||||||
|
|
||||||
class EntryRepository extends EntityRepository
|
class EntryRepository extends EntityRepository
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Return a query builder to used by other getBuilderFor* method.
|
||||||
|
*
|
||||||
|
* @param int $userId
|
||||||
|
*
|
||||||
|
* @return QueryBuilder
|
||||||
|
*/
|
||||||
|
private function getBuilderByUser($userId)
|
||||||
|
{
|
||||||
|
return $this->createQueryBuilder('e')
|
||||||
|
->leftJoin('e.user', 'u')
|
||||||
|
->andWhere('u.id = :userId')->setParameter('userId', $userId)
|
||||||
|
->orderBy('e.id', 'desc')
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves unread entries for a user.
|
* Retrieves unread entries for a user.
|
||||||
*
|
*
|
||||||
|
@ -15,13 +31,12 @@ class EntryRepository extends EntityRepository
|
||||||
*
|
*
|
||||||
* @return QueryBuilder
|
* @return QueryBuilder
|
||||||
*/
|
*/
|
||||||
public function findUnreadByUser($userId)
|
public function getBuilderForUnreadByUser($userId)
|
||||||
{
|
{
|
||||||
return $this->createQueryBuilder('e')
|
return $this
|
||||||
->leftJoin('e.user', 'u')
|
->getBuilderByUser($userId)
|
||||||
->where('e.isArchived = false')
|
->andWhere('e.isArchived = false')
|
||||||
->andWhere('u.id =:userId')->setParameter('userId', $userId)
|
;
|
||||||
->orderBy('e.id', 'desc');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,13 +46,12 @@ class EntryRepository extends EntityRepository
|
||||||
*
|
*
|
||||||
* @return QueryBuilder
|
* @return QueryBuilder
|
||||||
*/
|
*/
|
||||||
public function findArchiveByUser($userId)
|
public function getBuilderForArchiveByUser($userId)
|
||||||
{
|
{
|
||||||
return $this->createQueryBuilder('e')
|
return $this
|
||||||
->leftJoin('e.user', 'u')
|
->getBuilderByUser($userId)
|
||||||
->where('e.isArchived = true')
|
->andWhere('e.isArchived = true')
|
||||||
->andWhere('u.id =:userId')->setParameter('userId', $userId)
|
;
|
||||||
->orderBy('e.id', 'desc');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -47,13 +61,12 @@ class EntryRepository extends EntityRepository
|
||||||
*
|
*
|
||||||
* @return QueryBuilder
|
* @return QueryBuilder
|
||||||
*/
|
*/
|
||||||
public function findStarredByUser($userId)
|
public function getBuilderForStarredByUser($userId)
|
||||||
{
|
{
|
||||||
return $this->createQueryBuilder('e')
|
return $this
|
||||||
->leftJoin('e.user', 'u')
|
->getBuilderByUser($userId)
|
||||||
->where('e.isStarred = true')
|
->andWhere('e.isStarred = true')
|
||||||
->andWhere('u.id =:userId')->setParameter('userId', $userId)
|
;
|
||||||
->orderBy('e.id', 'desc');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
entry:
|
|
||||||
resource: "@WallabagCoreBundle/Controller/EntryController.php"
|
|
||||||
type: annotation
|
|
||||||
|
|
||||||
config:
|
|
||||||
resource: "@WallabagCoreBundle/Controller/ConfigController.php"
|
|
||||||
type: annotation
|
|
|
@ -3,38 +3,34 @@
|
||||||
{% block title %}{% trans %}About{% endtrans %}{% endblock %}
|
{% block title %}{% trans %}About{% endtrans %}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h2>{% trans %}About wallabag{% endtrans %}</h2>
|
<h2>{% trans %}Who is behind wallabag{% endtrans %}</h2>
|
||||||
|
|
||||||
<dl>
|
<dl>
|
||||||
|
<dt>{% trans %}Developed by{% endtrans %}</dt>
|
||||||
|
<dd><a href="mailto:nicolas@loeuillet.org">Nicolas Lœuillet</a> — <a href="http://cdetc.fr">{% trans %}website{% endtrans %}</a></dd>
|
||||||
|
<dd>Thomas Citharel — <a href="https://tcit.fr">{% trans %}website{% endtrans %}</a></dd>
|
||||||
|
<dd>Jérémy Benoist — <a href="http://www.j0k3r.net">{% trans %}website{% endtrans %}</a></dd>
|
||||||
|
|
||||||
|
<dt>{% trans %}And many others contributors ♥{% endtrans %} <a href="https://github.com/wallabag/wallabag/graphs/contributors">{% trans %}on Github{% endtrans %}</a></dt>
|
||||||
|
|
||||||
<dt>{% trans %}Project website{% endtrans %}</dt>
|
<dt>{% trans %}Project website{% endtrans %}</dt>
|
||||||
<dd><a href="https://www.wallabag.org">https://www.wallabag.org</a></dd>
|
<dd><a href="https://www.wallabag.org">https://www.wallabag.org</a></dd>
|
||||||
|
|
||||||
<dt>{% trans %}Main developer{% endtrans %}</dt>
|
<dt>{% trans %}License{% endtrans %}: <a href="http://en.wikipedia.org/wiki/MIT_License">MIT</a></dt>
|
||||||
<dd><a href="mailto:nicolas@loeuillet.org">Nicolas Lœuillet</a> — <a href="http://cdetc.fr">{% trans %}website{% endtrans %}</a></dd>
|
|
||||||
|
|
||||||
<dt>{% trans %}Contributors ♥:{% endtrans %}</dt>
|
<dt>{% trans %}Version{% endtrans %}: {{ version }}</dt>
|
||||||
<dd><a href="https://github.com/wallabag/wallabag/graphs/contributors">{% trans %}on Github{% endtrans %}</a></dd>
|
|
||||||
|
|
||||||
<dt>{% trans %}Bug reports{% endtrans %}</dt>
|
|
||||||
<dd><a href="https://support.wallabag.org">{% trans %}On our support website{% endtrans %}</a> {% trans %}or{% endtrans %} <a href="https://github.com/wallabag/wallabag/issues">{% trans %}on Github{% endtrans %}</a></dd>
|
|
||||||
|
|
||||||
<dt>{% trans %}License{% endtrans %}</dt>
|
|
||||||
<dd><a href="http://en.wikipedia.org/wiki/MIT_License">MIT</a></dd>
|
|
||||||
|
|
||||||
<dt>{% trans %}Version{% endtrans %}</dt>
|
|
||||||
<dd>{{ version }}</dd>
|
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<p>{% trans %}wallabag is a read-it-later application: you can save a web page by keeping only content. Elements like ads or menus are deleted.{% endtrans %}</p>
|
|
||||||
|
|
||||||
<h2>{% trans %}Getting help{% endtrans %}</h2>
|
<h2>{% trans %}Getting help{% endtrans %}</h2>
|
||||||
|
|
||||||
<dl>
|
<dl>
|
||||||
<dt>{% trans %}Documentation{% endtrans %}</dt>
|
<dt>{% trans %}Documentation{% endtrans %}</dt>
|
||||||
<dd><a href="https://doc.wallabag.org/">Online documentation</a></dd>
|
<dd><a href="https://doc.wallabag.org/en">english</a></dd>
|
||||||
|
<dd><a href="https://doc.wallabag.org/fr">français</a></dd>
|
||||||
|
<dd><a href="https://doc.wallabag.org/de">deutsch</a></dd>
|
||||||
|
|
||||||
<dt>{% trans %}Support{% endtrans %}</dt>
|
<dt>{% trans %}Bug reports{% endtrans %}</dt>
|
||||||
<dd><a href="http://support.wallabag.org/">http://support.wallabag.org/</a></dd>
|
<dd><a href="https://support.wallabag.org">{% trans %}On our support website{% endtrans %}</a> {% trans %}or{% endtrans %} <a href="https://github.com/wallabag/wallabag/issues">{% trans %}on Github{% endtrans %}</a></dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<h2>{% trans %}Helping wallabag{% endtrans %}</h2>
|
<h2>{% trans %}Helping wallabag{% endtrans %}</h2>
|
||||||
|
@ -42,8 +38,10 @@
|
||||||
<p>{% trans %}wallabag is free and opensource. You can help us:{% endtrans %}</p>
|
<p>{% trans %}wallabag is free and opensource. You can help us:{% endtrans %}</p>
|
||||||
|
|
||||||
<dl>
|
<dl>
|
||||||
<dt><a href="{{ paypal_url }}">{% trans %}via Paypal{% endtrans %}</a></dt>
|
<dt>{% trans %}wallabag is free and opensource. You can help us:{% endtrans %}</dt>
|
||||||
|
<dd>by contributing to the project: <a href="https://github.com/wallabag/wallabag/issues/1254">an issue lists all our needs</a></dd>
|
||||||
|
<dd><a href="{{ paypal_url }}">{% trans %}via Paypal{% endtrans %}</a></dd>
|
||||||
|
|
||||||
<dt><a href="{{ flattr_url }}">{% trans %}via Flattr{% endtrans %}</a></dt>
|
<dd><a href="{{ flattr_url }}">{% trans %}via Flattr{% endtrans %}</a></dd>
|
||||||
</dl>
|
</dl>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
<dt>{% trans %}Developed by{% endtrans %}</dt>
|
<dt>{% trans %}Developed by{% endtrans %}</dt>
|
||||||
<dd><a href="mailto:nicolas@loeuillet.org">Nicolas Lœuillet</a> — <a href="http://cdetc.fr">{% trans %}website{% endtrans %}</a></dd>
|
<dd><a href="mailto:nicolas@loeuillet.org">Nicolas Lœuillet</a> — <a href="http://cdetc.fr">{% trans %}website{% endtrans %}</a></dd>
|
||||||
<dd>Thomas Citharel — <a href="https://tcit.fr">{% trans %}website{% endtrans %}</a></dd>
|
<dd>Thomas Citharel — <a href="https://tcit.fr">{% trans %}website{% endtrans %}</a></dd>
|
||||||
<dd>Jérémy Besnoit — <a href="http://wildtrip.net">{% trans %}website{% endtrans %}</a></dd>
|
<dd>Jérémy Benoist — <a href="http://www.j0k3r.net">{% trans %}website{% endtrans %}</a></dd>
|
||||||
<dt>{% trans %}And many others contributors ♥{% endtrans %} <a href="https://github.com/wallabag/wallabag/graphs/contributors">{% trans %}on Github{% endtrans %}</a></dt>
|
<dt>{% trans %}And many others contributors ♥{% endtrans %} <a href="https://github.com/wallabag/wallabag/graphs/contributors">{% trans %}on Github{% endtrans %}</a></dt>
|
||||||
<dt>{% trans %}Project website{% endtrans %}</dt>
|
<dt>{% trans %}Project website{% endtrans %}</dt>
|
||||||
<dd><a href="https://www.wallabag.org">https://www.wallabag.org</a></dd>
|
<dd><a href="https://www.wallabag.org">https://www.wallabag.org</a></dd>
|
||||||
|
|
|
@ -55,9 +55,9 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="input-field nav-panel-buttom">
|
<div class="input-field nav-panel-buttom">
|
||||||
<ul>
|
<ul>
|
||||||
<li class="bold"><a class="waves-effect" href="{{ path('new') }}" id="nav-btn-add"><i class="mdi-content-add"></i></a></li>
|
<li class="bold"><a title="{% trans %}Add a new entry{% endtrans %}" class="waves-effect" href="{{ path('new') }}" id="nav-btn-add"><i class="mdi-content-add"></i></a></li>
|
||||||
<li><a class="waves-effect" href="javascript: void(null);" id="nav-btn-search"><i class="mdi-action-search"></i></a>
|
<li><a title="{% trans %}Search{% endtrans %}" class="waves-effect" href="javascript: void(null);" id="nav-btn-search"><i class="mdi-action-search"></i></a>
|
||||||
<li id="button_filters"><a href="#" data-activates="filters" class="nav-panel-menu button-collapse-right"><i class="mdi-content-filter-list"></i></a></li>
|
<li id="button_filters"><a title="{% trans %}Filter entries{% endtrans %}" href="#" data-activates="filters" class="nav-panel-menu button-collapse-right"><i class="mdi-content-filter-list"></i></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<form method="get" action="index.php">
|
<form method="get" action="index.php">
|
||||||
|
|
|
@ -25,4 +25,17 @@ class Utils
|
||||||
// remove character which can broken the url
|
// remove character which can broken the url
|
||||||
return str_replace(array('+', '/'), '', $token);
|
return str_replace(array('+', '/'), '', $token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For a given text, we calculate reading time for an article
|
||||||
|
* based on 200 words per minute.
|
||||||
|
*
|
||||||
|
* @param $text
|
||||||
|
*
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public static function getReadingTime($text)
|
||||||
|
{
|
||||||
|
return floor(str_word_count(strip_tags($text)) / 200);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue