aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJeremy Benoist <j0k3r@users.noreply.github.com>2016-08-25 09:30:51 +0200
committerGitHub <noreply@github.com>2016-08-25 09:30:51 +0200
commit60e722040665c836fb9d3c4a35c37aad5c1cba64 (patch)
tree4e90d355a5c12c311dec4d569dfc256ebef110f2
parenta1ab7d1d32cb69af563fcec4395fce5217f154f7 (diff)
parenteddda878a0ec375fa738e3228a72dd01b23e0fab (diff)
downloadwallabag-60e722040665c836fb9d3c4a35c37aad5c1cba64.tar.gz
wallabag-60e722040665c836fb9d3c4a35c37aad5c1cba64.tar.zst
wallabag-60e722040665c836fb9d3c4a35c37aad5c1cba64.zip
Merge pull request #1904 from wallabag/feature-public-mode
Share entry with a public URL
-rw-r--r--app/DoctrineMigrations/Version20160410190541.php46
-rw-r--r--app/DoctrineMigrations/Version20160812120952.php25
-rw-r--r--app/Resources/CraueConfigBundle/translations/CraueConfigBundle.da.yml1
-rw-r--r--app/Resources/CraueConfigBundle/translations/CraueConfigBundle.de.yml1
-rw-r--r--app/Resources/CraueConfigBundle/translations/CraueConfigBundle.en.yml1
-rw-r--r--app/Resources/CraueConfigBundle/translations/CraueConfigBundle.es.yml1
-rw-r--r--app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fa.yml6
-rw-r--r--app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fr.yml1
-rw-r--r--app/Resources/CraueConfigBundle/translations/CraueConfigBundle.it.yml1
-rw-r--r--app/Resources/CraueConfigBundle/translations/CraueConfigBundle.oc.yml1
-rw-r--r--app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pl.yml6
-rw-r--r--app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ro.yml6
-rw-r--r--app/config/security.yml1
-rw-r--r--src/Wallabag/CoreBundle/Command/InstallCommand.php5
-rw-r--r--src/Wallabag/CoreBundle/Controller/EntryController.php75
-rw-r--r--src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSettingData.php5
-rw-r--r--src/Wallabag/CoreBundle/Entity/Entry.php42
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.da.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.de.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.en.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.es.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.it.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entry.html.twig1
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entry.html.twig13
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/share.html.twig39
-rw-r--r--tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php43
-rw-r--r--var/SymfonyRequirements.php13
33 files changed, 346 insertions, 9 deletions
diff --git a/app/DoctrineMigrations/Version20160410190541.php b/app/DoctrineMigrations/Version20160410190541.php
new file mode 100644
index 00000000..4014857b
--- /dev/null
+++ b/app/DoctrineMigrations/Version20160410190541.php
@@ -0,0 +1,46 @@
1<?php
2
3namespace Application\Migrations;
4
5use Doctrine\DBAL\Migrations\AbstractMigration;
6use Doctrine\DBAL\Schema\Schema;
7use Symfony\Component\DependencyInjection\ContainerAwareInterface;
8use Symfony\Component\DependencyInjection\ContainerInterface;
9
10class Version20160410190541 extends AbstractMigration implements ContainerAwareInterface
11{
12 /**
13 * @var ContainerInterface
14 */
15 private $container;
16
17 public function setContainer(ContainerInterface $container = null)
18 {
19 $this->container = $container;
20 }
21
22 private function getTable($tableName)
23 {
24 return $this->container->getParameter('database_table_prefix') . $tableName;
25 }
26
27 /**
28 * @param Schema $schema
29 */
30 public function up(Schema $schema)
31 {
32 $this->addSql('ALTER TABLE `'.$this->getTable('entry').'` ADD `uuid` LONGTEXT DEFAULT NULL');
33 $this->addSql("INSERT INTO `".$this->getTable('craue_config_setting')."` (`name`, `value`, `section`) VALUES ('share_public', '1', 'entry')");
34 }
35
36 /**
37 * @param Schema $schema
38 */
39 public function down(Schema $schema)
40 {
41 $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'sqlite', 'This down migration can\'t be executed on SQLite databases, because SQLite don\'t support DROP COLUMN.');
42
43 $this->addSql('ALTER TABLE `'.$this->getTable('entry').'` DROP `uuid`');
44 $this->addSql("DELETE FROM `".$this->getTable('craue_config_setting')."` WHERE `name` = 'share_public'");
45 }
46}
diff --git a/app/DoctrineMigrations/Version20160812120952.php b/app/DoctrineMigrations/Version20160812120952.php
index 58f070c7..9adfdc8b 100644
--- a/app/DoctrineMigrations/Version20160812120952.php
+++ b/app/DoctrineMigrations/Version20160812120952.php
@@ -4,15 +4,32 @@ namespace Application\Migrations;
4 4
5use Doctrine\DBAL\Migrations\AbstractMigration; 5use Doctrine\DBAL\Migrations\AbstractMigration;
6use Doctrine\DBAL\Schema\Schema; 6use Doctrine\DBAL\Schema\Schema;
7use Symfony\Component\DependencyInjection\ContainerAwareInterface;
8use Symfony\Component\DependencyInjection\ContainerInterface;
7 9
8class Version20160812120952 extends AbstractMigration 10class Version20160812120952 extends AbstractMigration implements ContainerAwareInterface
9{ 11{
10 /** 12 /**
13 * @var ContainerInterface
14 */
15 private $container;
16
17 public function setContainer(ContainerInterface $container = null)
18 {
19 $this->container = $container;
20 }
21
22 private function getTable($tableName)
23 {
24 return $this->container->getParameter('database_table_prefix') . $tableName;
25 }
26
27 /**
11 * @param Schema $schema 28 * @param Schema $schema
12 */ 29 */
13 public function up(Schema $schema) 30 public function up(Schema $schema)
14 { 31 {
15 $this->addSql('ALTER TABLE wallabag_oauth2_clients ADD name CLOB DEFAULT NULL COLLATE BINARY'); 32 $this->addSql('ALTER TABLE '.$this->getTable('oauth2_clients').' ADD name longtext COLLATE \'utf8_unicode_ci\' DEFAULT NULL');
16 } 33 }
17 34
18 /** 35 /**
@@ -21,7 +38,7 @@ class Version20160812120952 extends AbstractMigration
21 public function down(Schema $schema) 38 public function down(Schema $schema)
22 { 39 {
23 $this->abortIf($this->connection->getDatabasePlatform()->getName() == 'sqlite', 'Migration can only be executed safely on \'mysql\' or \'postgresql\'.'); 40 $this->abortIf($this->connection->getDatabasePlatform()->getName() == 'sqlite', 'Migration can only be executed safely on \'mysql\' or \'postgresql\'.');
24 $this->addSql('ALTER TABLE wallabag_oauth2_clients DROP COLUMN name; 41
25'); 42 $this->addSql('ALTER TABLE '.$this->getTable('oauth2_clients').' DROP COLUMN name');
26 } 43 }
27} 44}
diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.da.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.da.yml
index c46fdb14..3478d638 100644
--- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.da.yml
+++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.da.yml
@@ -27,3 +27,4 @@ piwik_site_id: ID for din side hos Piwik
27piwik_enabled: Aktiver Piwik 27piwik_enabled: Aktiver Piwik
28demo_mode_enabled: "Aktiver demo-indstilling? (anvendes kun til wallabags offentlige demo)" 28demo_mode_enabled: "Aktiver demo-indstilling? (anvendes kun til wallabags offentlige demo)"
29demo_mode_username: "Demobruger" 29demo_mode_username: "Demobruger"
30# share_public: Allow public url for entries
diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.de.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.de.yml
index fa2093b5..f655a27f 100644
--- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.de.yml
+++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.de.yml
@@ -27,3 +27,4 @@ piwik_site_id: ID deiner Webseite in Piwik
27piwik_enabled: Piwik aktivieren 27piwik_enabled: Piwik aktivieren
28demo_mode_enabled: "Test-Modus aktivieren? (nur für die öffentliche wallabag-Demo genutzt)" 28demo_mode_enabled: "Test-Modus aktivieren? (nur für die öffentliche wallabag-Demo genutzt)"
29demo_mode_username: "Test-Benutzer" 29demo_mode_username: "Test-Benutzer"
30# share_public: Allow public url for entries
diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.en.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.en.yml
index b627376e..48d0ec4b 100644
--- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.en.yml
+++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.en.yml
@@ -27,3 +27,4 @@ piwik_site_id: ID of your website in Piwik
27piwik_enabled: Enable Piwik 27piwik_enabled: Enable Piwik
28demo_mode_enabled: "Enable demo mode ? (only used for the wallabag public demo)" 28demo_mode_enabled: "Enable demo mode ? (only used for the wallabag public demo)"
29demo_mode_username: "Demo user" 29demo_mode_username: "Demo user"
30share_public: Allow public url for entries
diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.es.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.es.yml
index af1657e4..7aac9adf 100644
--- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.es.yml
+++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.es.yml
@@ -27,3 +27,4 @@ piwik_site_id: ID de tu website de Piwik
27piwik_enabled: Activar Piwik 27piwik_enabled: Activar Piwik
28demo_mode_enabled: "Activar modo demo (sólo usado para la demo de wallabag)" 28demo_mode_enabled: "Activar modo demo (sólo usado para la demo de wallabag)"
29demo_mode_username: "Nombre de usuario demo" 29demo_mode_username: "Nombre de usuario demo"
30# share_public: Allow public url for entries
diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fa.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fa.yml
index 7cb4e833..613cf86d 100644
--- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fa.yml
+++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fa.yml
@@ -22,3 +22,9 @@ export: "برون‌سپاری"
22import: "درون‌ریزی" 22import: "درون‌ریزی"
23misc: "غیره" 23misc: "غیره"
24modify_settings: "اعمال" 24modify_settings: "اعمال"
25# piwik_host: Host of your website in Piwik
26# piwik_site_id: ID of your website in Piwik
27# piwik_enabled: Enable Piwik
28# demo_mode_enabled: "Enable demo mode ? (only used for the wallabag public demo)"
29# demo_mode_username: "Demo user"
30# share_public: Allow public url for entries
diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fr.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fr.yml
index 084eb6df..f21f2439 100644
--- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fr.yml
+++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fr.yml
@@ -27,3 +27,4 @@ piwik_site_id: ID de votre site dans Piwik
27piwik_enabled: Activer Piwik 27piwik_enabled: Activer Piwik
28demo_mode_enabled: "Activer le mode démo ? (utiliser uniquement pour la démo publique de wallabag)" 28demo_mode_enabled: "Activer le mode démo ? (utiliser uniquement pour la démo publique de wallabag)"
29demo_mode_username: "Utilisateur de la démo" 29demo_mode_username: "Utilisateur de la démo"
30share_public: Autoriser une URL publique pour les articles
diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.it.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.it.yml
index e4417139..1202edd5 100644
--- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.it.yml
+++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.it.yml
@@ -27,3 +27,4 @@ piwik_site_id: ID del tuo sito in Piwik
27piwik_enabled: Abilita Piwik 27piwik_enabled: Abilita Piwik
28demo_mode_enabled: "Abilita modalità demo ? (usato solo per la demo pubblica di wallabag)" 28demo_mode_enabled: "Abilita modalità demo ? (usato solo per la demo pubblica di wallabag)"
29demo_mode_username: "Utente Demo" 29demo_mode_username: "Utente Demo"
30# share_public: Allow public url for entries
diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.oc.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.oc.yml
index 67880b8b..dd91ee49 100644
--- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.oc.yml
+++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.oc.yml
@@ -27,3 +27,4 @@ piwik_site_id: ID de vòstre site dins Piwik
27piwik_enabled: Activar Piwik 27piwik_enabled: Activar Piwik
28demo_mode_enabled: "Activar lo mode demostracion ? (utilizar solament per la demostracion publica de wallabag)" 28demo_mode_enabled: "Activar lo mode demostracion ? (utilizar solament per la demostracion publica de wallabag)"
29demo_mode_username: "Utilizaire de la demostracion" 29demo_mode_username: "Utilizaire de la demostracion"
30# share_public: Allow public url for entries
diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pl.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pl.yml
index 87ca5060..93b36c8f 100644
--- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pl.yml
+++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pl.yml
@@ -22,3 +22,9 @@ export: "eksport"
22import: "import" 22import: "import"
23misc: "różne" 23misc: "różne"
24modify_settings: "zatwierdz" 24modify_settings: "zatwierdz"
25# piwik_host: Host of your website in Piwik
26# piwik_site_id: ID of your website in Piwik
27# piwik_enabled: Enable Piwik
28# demo_mode_enabled: "Enable demo mode ? (only used for the wallabag public demo)"
29# demo_mode_username: "Demo user"
30# share_public: Allow public url for entries
diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ro.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ro.yml
index f5ff8c6a..326c9f90 100644
--- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ro.yml
+++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ro.yml
@@ -22,3 +22,9 @@ export: "exportă"
22import: "importă" 22import: "importă"
23misc: "diverse" 23misc: "diverse"
24modify_settings: "aplică" 24modify_settings: "aplică"
25# piwik_host: Host of your website in Piwik
26# piwik_site_id: ID of your website in Piwik
27# piwik_enabled: Enable Piwik
28# demo_mode_enabled: "Enable demo mode ? (only used for the wallabag public demo)"
29# demo_mode_username: "Demo user"
30# share_public: Allow public url for entries
diff --git a/app/config/security.yml b/app/config/security.yml
index e24e03df..1f30e58b 100644
--- a/app/config/security.yml
+++ b/app/config/security.yml
@@ -60,6 +60,7 @@ security:
60 - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY } 60 - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
61 - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY } 61 - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
62 - { path: /(unread|starred|archive).xml$, roles: IS_AUTHENTICATED_ANONYMOUSLY } 62 - { path: /(unread|starred|archive).xml$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
63 - { path: ^/share, roles: IS_AUTHENTICATED_ANONYMOUSLY }
63 - { path: ^/settings, roles: ROLE_SUPER_ADMIN } 64 - { path: ^/settings, roles: ROLE_SUPER_ADMIN }
64 - { path: ^/annotations, roles: ROLE_USER } 65 - { path: ^/annotations, roles: ROLE_USER }
65 - { path: ^/, roles: ROLE_USER } 66 - { path: ^/, roles: ROLE_USER }
diff --git a/src/Wallabag/CoreBundle/Command/InstallCommand.php b/src/Wallabag/CoreBundle/Command/InstallCommand.php
index e134ced5..143def4f 100644
--- a/src/Wallabag/CoreBundle/Command/InstallCommand.php
+++ b/src/Wallabag/CoreBundle/Command/InstallCommand.php
@@ -242,6 +242,11 @@ class InstallCommand extends ContainerAwareCommand
242 242
243 $settings = [ 243 $settings = [
244 [ 244 [
245 'name' => 'share_public',
246 'value' => '1',
247 'section' => 'entry',
248 ],
249 [
245 'name' => 'carrot', 250 'name' => 'carrot',
246 'value' => '1', 251 'value' => '1',
247 'section' => 'entry', 252 'section' => 'entry',
diff --git a/src/Wallabag/CoreBundle/Controller/EntryController.php b/src/Wallabag/CoreBundle/Controller/EntryController.php
index 93db0d6c..d71ba6cd 100644
--- a/src/Wallabag/CoreBundle/Controller/EntryController.php
+++ b/src/Wallabag/CoreBundle/Controller/EntryController.php
@@ -12,6 +12,7 @@ use Wallabag\CoreBundle\Entity\Entry;
12use Wallabag\CoreBundle\Form\Type\EntryFilterType; 12use Wallabag\CoreBundle\Form\Type\EntryFilterType;
13use Wallabag\CoreBundle\Form\Type\EditEntryType; 13use Wallabag\CoreBundle\Form\Type\EditEntryType;
14use Wallabag\CoreBundle\Form\Type\NewEntryType; 14use Wallabag\CoreBundle\Form\Type\NewEntryType;
15use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
15 16
16class EntryController extends Controller 17class EntryController extends Controller
17{ 18{
@@ -434,7 +435,7 @@ class EntryController extends Controller
434 */ 435 */
435 private function checkUserAction(Entry $entry) 436 private function checkUserAction(Entry $entry)
436 { 437 {
437 if ($this->getUser()->getId() != $entry->getUser()->getId()) { 438 if (null === $this->getUser() || $this->getUser()->getId() != $entry->getUser()->getId()) {
438 throw $this->createAccessDeniedException('You can not access this entry.'); 439 throw $this->createAccessDeniedException('You can not access this entry.');
439 } 440 }
440 } 441 }
@@ -450,4 +451,76 @@ class EntryController extends Controller
450 { 451 {
451 return $this->get('wallabag_core.entry_repository')->findByUrlAndUserId($entry->getUrl(), $this->getUser()->getId()); 452 return $this->get('wallabag_core.entry_repository')->findByUrlAndUserId($entry->getUrl(), $this->getUser()->getId());
452 } 453 }
454
455 /**
456 * Get public URL for entry (and generate it if necessary).
457 *
458 * @param Entry $entry
459 *
460 * @Route("/share/{id}", requirements={"id" = "\d+"}, name="share")
461 *
462 * @return \Symfony\Component\HttpFoundation\Response
463 */
464 public function shareAction(Entry $entry)
465 {
466 $this->checkUserAction($entry);
467
468 if (null === $entry->getUuid()) {
469 $entry->generateUuid();
470
471 $em = $this->getDoctrine()->getManager();
472 $em->persist($entry);
473 $em->flush();
474 }
475
476 return $this->redirect($this->generateUrl('share_entry', [
477 'uuid' => $entry->getUuid(),
478 ]));
479 }
480
481 /**
482 * Disable public sharing for an entry.
483 *
484 * @param Entry $entry
485 *
486 * @Route("/share/delete/{id}", requirements={"id" = "\d+"}, name="delete_share")
487 *
488 * @return \Symfony\Component\HttpFoundation\Response
489 */
490 public function deleteShareAction(Entry $entry)
491 {
492 $this->checkUserAction($entry);
493
494 $entry->cleanUuid();
495
496 $em = $this->getDoctrine()->getManager();
497 $em->persist($entry);
498 $em->flush();
499
500 return $this->redirect($this->generateUrl('view', [
501 'id' => $entry->getId(),
502 ]));
503 }
504
505 /**
506 * Ability to view a content publicly.
507 *
508 * @param Entry $entry
509 *
510 * @Route("/share/{uuid}", requirements={"uuid" = ".+"}, name="share_entry")
511 * @Cache(maxage="25200", smaxage="25200", public=true)
512 *
513 * @return \Symfony\Component\HttpFoundation\Response
514 */
515 public function shareEntryAction(Entry $entry)
516 {
517 if (!$this->get('craue_config')->get('share_public')) {
518 throw $this->createAccessDeniedException('Sharing an entry is disabled for this user.');
519 }
520
521 return $this->render(
522 '@WallabagCore/themes/share.html.twig',
523 ['entry' => $entry]
524 );
525 }
453} 526}
diff --git a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSettingData.php b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSettingData.php
index 09058796..b4309304 100644
--- a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSettingData.php
+++ b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSettingData.php
@@ -16,6 +16,11 @@ class LoadSettingData extends AbstractFixture implements OrderedFixtureInterface
16 { 16 {
17 $settings = [ 17 $settings = [
18 [ 18 [
19 'name' => 'share_public',
20 'value' => '1',
21 'section' => 'entry',
22 ],
23 [
19 'name' => 'carrot', 24 'name' => 'carrot',
20 'value' => '1', 25 'value' => '1',
21 'section' => 'entry', 26 'section' => 'entry',
diff --git a/src/Wallabag/CoreBundle/Entity/Entry.php b/src/Wallabag/CoreBundle/Entity/Entry.php
index ceae78b0..4d7e001b 100644
--- a/src/Wallabag/CoreBundle/Entity/Entry.php
+++ b/src/Wallabag/CoreBundle/Entity/Entry.php
@@ -40,6 +40,15 @@ class Entry
40 /** 40 /**
41 * @var string 41 * @var string
42 * 42 *
43 * @ORM\Column(name="uuid", type="text", nullable=true)
44 *
45 * @Groups({"entries_for_user", "export_all"})
46 */
47 private $uuid;
48
49 /**
50 * @var string
51 *
43 * @ORM\Column(name="title", type="text", nullable=true) 52 * @ORM\Column(name="title", type="text", nullable=true)
44 * 53 *
45 * @Groups({"entries_for_user", "export_all"}) 54 * @Groups({"entries_for_user", "export_all"})
@@ -595,4 +604,37 @@ class Entry
595 { 604 {
596 return $this->language; 605 return $this->language;
597 } 606 }
607
608 /**
609 * @return string
610 */
611 public function getUuid()
612 {
613 return $this->uuid;
614 }
615
616 /**
617 * @param string $uuid
618 *
619 * @return Entry
620 */
621 public function setUuid($uuid)
622 {
623 $this->uuid = $uuid;
624
625 return $this;
626 }
627
628 public function generateUuid()
629 {
630 if (null === $this->uuid) {
631 // @see http://blog.kevingomez.fr/til/2015/07/26/why-is-uniqid-slow/ for true parameter
632 $this->uuid = uniqid('', true);
633 }
634 }
635
636 public function cleanUuid()
637 {
638 $this->uuid = null;
639 }
598} 640}
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
index 87988539..f9b7bfac 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
@@ -187,6 +187,8 @@ entry:
187 add_a_tag: 'Tliføj et tag' 187 add_a_tag: 'Tliføj et tag'
188 share_content: 'Deling' 188 share_content: 'Deling'
189 # share_email_label: 'Email' 189 # share_email_label: 'Email'
190 # public_link: 'public link'
191 # delete_public_link: 'delete public link'
190 download: 'Download' 192 download: 'Download'
191 # print: 'Print' 193 # print: 'Print'
192 problem: 194 problem:
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
index 461967d6..79d03286 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
@@ -187,6 +187,8 @@ entry:
187 add_a_tag: 'Tag hinzufügen' 187 add_a_tag: 'Tag hinzufügen'
188 share_content: 'Teilen' 188 share_content: 'Teilen'
189 share_email_label: 'E-Mail' 189 share_email_label: 'E-Mail'
190 # public_link: 'public link'
191 # delete_public_link: 'delete public link'
190 download: 'Herunterladen' 192 download: 'Herunterladen'
191 print: 'Drucken' 193 print: 'Drucken'
192 problem: 194 problem:
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
index 600b7472..d921b39f 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
@@ -187,6 +187,8 @@ entry:
187 add_a_tag: 'Add a tag' 187 add_a_tag: 'Add a tag'
188 share_content: 'Share' 188 share_content: 'Share'
189 share_email_label: 'Email' 189 share_email_label: 'Email'
190 public_link: 'public link'
191 delete_public_link: 'delete public link'
190 download: 'Download' 192 download: 'Download'
191 print: 'Print' 193 print: 'Print'
192 problem: 194 problem:
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
index 6da8a593..c2ec4dbd 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
@@ -187,6 +187,8 @@ entry:
187 add_a_tag: 'Añadir una etiqueta' 187 add_a_tag: 'Añadir una etiqueta'
188 share_content: 'Compartir' 188 share_content: 'Compartir'
189 share_email_label: 'Dirección e-mail' 189 share_email_label: 'Dirección e-mail'
190 # public_link: 'public link'
191 # delete_public_link: 'delete public link'
190 download: 'Descargar' 192 download: 'Descargar'
191 print: 'Imprimir' 193 print: 'Imprimir'
192 problem: 194 problem:
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
index 4684b08b..561ed907 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
@@ -187,6 +187,8 @@ entry:
187 add_a_tag: 'افزودن برچسب' 187 add_a_tag: 'افزودن برچسب'
188 share_content: 'هم‌رسانی' 188 share_content: 'هم‌رسانی'
189 share_email_label: 'نشانی ایمیل' 189 share_email_label: 'نشانی ایمیل'
190 # public_link: 'public link'
191 # delete_public_link: 'delete public link'
190 download: 'بارگیری' 192 download: 'بارگیری'
191 print: 'چاپ' 193 print: 'چاپ'
192 problem: 194 problem:
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
index 2b6e4194..c0671883 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
@@ -187,6 +187,8 @@ entry:
187 add_a_tag: 'Ajouter un tag' 187 add_a_tag: 'Ajouter un tag'
188 share_content: 'Partager' 188 share_content: 'Partager'
189 share_email_label: 'Email' 189 share_email_label: 'Email'
190 public_link: 'Lien public'
191 delete_public_link: 'Supprimer lien public'
190 download: 'Télécharger' 192 download: 'Télécharger'
191 print: 'Imprimer' 193 print: 'Imprimer'
192 problem: 194 problem:
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
index 3760c2d6..2e3dd08b 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
@@ -185,6 +185,8 @@ entry:
185 add_a_tag: 'Aggiungi un tag' 185 add_a_tag: 'Aggiungi un tag'
186 share_content: 'Condividi' 186 share_content: 'Condividi'
187 share_email_label: 'E-mail' 187 share_email_label: 'E-mail'
188 # public_link: 'public link'
189 # delete_public_link: 'delete public link'
188 download: 'Download' 190 download: 'Download'
189 print: 'Stampa' 191 print: 'Stampa'
190 problem: 192 problem:
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
index 95435606..7b978a60 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
@@ -187,6 +187,8 @@ entry:
187 add_a_tag: 'Ajustar una etiqueta' 187 add_a_tag: 'Ajustar una etiqueta'
188 share_content: 'Partatjar' 188 share_content: 'Partatjar'
189 share_email_label: 'Corrièl' 189 share_email_label: 'Corrièl'
190 # public_link: 'public link'
191 # delete_public_link: 'delete public link'
190 download: 'Telecargar' 192 download: 'Telecargar'
191 print: 'Imprimir' 193 print: 'Imprimir'
192 problem: 194 problem:
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
index b0b7e49b..da170e4d 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
@@ -187,6 +187,8 @@ entry:
187 add_a_tag: 'Dodaj tag' 187 add_a_tag: 'Dodaj tag'
188 share_content: 'Udostępnij' 188 share_content: 'Udostępnij'
189 share_email_label: 'Adres email' 189 share_email_label: 'Adres email'
190 # public_link: 'public link'
191 # delete_public_link: 'delete public link'
190 download: 'Pobierz' 192 download: 'Pobierz'
191 print: 'Drukuj' 193 print: 'Drukuj'
192 problem: 194 problem:
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
index d735df4c..fa2d6468 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
@@ -187,6 +187,8 @@ entry:
187 add_a_tag: 'Adaugă un tag' 187 add_a_tag: 'Adaugă un tag'
188 share_content: 'Dă mai departe' 188 share_content: 'Dă mai departe'
189 share_email_label: 'E-mail' 189 share_email_label: 'E-mail'
190 # public_link: 'public link'
191 # delete_public_link: 'delete public link'
190 download: 'Descarcă' 192 download: 'Descarcă'
191 # print: 'Print' 193 # print: 'Print'
192 problem: 194 problem:
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
index 77bfa0f0..05c31336 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
@@ -187,6 +187,8 @@ entry:
187 add_a_tag: 'Bir etiket ekle' 187 add_a_tag: 'Bir etiket ekle'
188 share_content: 'Paylaş' 188 share_content: 'Paylaş'
189 share_email_label: 'E-posta' 189 share_email_label: 'E-posta'
190 # public_link: 'public link'
191 # delete_public_link: 'delete public link'
190 download: 'İndir' 192 download: 'İndir'
191 # print: 'Print' 193 # print: 'Print'
192 problem: 194 problem:
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entry.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entry.html.twig
index ce47a677..6c46f91f 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entry.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entry.html.twig
@@ -17,6 +17,7 @@
17 <li><a title="{{ 'entry.view.left_menu.set_as_starred'|trans }}" class="tool icon icon-star {% if entry.isStarred == 0 %}fav-off{% else %}fav{% endif %}" href="{{ path('star_entry', { 'id': entry.id }) }}"><span>{{ 'entry.view.left_menu.set_as_starred'|trans }}</span></a></li> 17 <li><a title="{{ 'entry.view.left_menu.set_as_starred'|trans }}" class="tool icon icon-star {% if entry.isStarred == 0 %}fav-off{% else %}fav{% endif %}" href="{{ path('star_entry', { 'id': entry.id }) }}"><span>{{ 'entry.view.left_menu.set_as_starred'|trans }}</span></a></li>
18 <li><a id="nav-btn-add-tag" title="{{ 'entry.view.left_menu.add_a_tag'|trans }}"><span>{{ 'entry.view.left_menu.add_a_tag'|trans }}</span></a></li> 18 <li><a id="nav-btn-add-tag" title="{{ 'entry.view.left_menu.add_a_tag'|trans }}"><span>{{ 'entry.view.left_menu.add_a_tag'|trans }}</span></a></li>
19 <li><a title="{{ 'entry.view.left_menu.delete'|trans }}" class="tool delete icon icon-trash" href="{{ path('delete_entry', { 'id': entry.id }) }}"><span>{{ 'entry.view.left_menu.delete'|trans }}</span></a></li> 19 <li><a title="{{ 'entry.view.left_menu.delete'|trans }}" class="tool delete icon icon-trash" href="{{ path('delete_entry', { 'id': entry.id }) }}"><span>{{ 'entry.view.left_menu.delete'|trans }}</span></a></li>
20 {% if craue_setting('share_public') %}<li><a href="{{ path('share', {'id': entry.id }) }}" target="_blank" class="tool public" title="{{ 'entry.view.left_menu.public_link'|trans }}"><span>{{ 'entry.view.left_menu.public_link'|trans }}</span></a></li> <li><a href="{{ path('delete_share', {'id': entry.id }) }}" class="tool public" title="{{ 'entry.view.left_menu.delete_public_link'|trans }}"><span>{{ 'entry.view.left_menu.delete_public_link'|trans }}</span></a></li>{% endif %}
20 {% if craue_setting('share_twitter') %}<li><a href="https://twitter.com/home?status={{entry.title|url_encode}}%20{{ entry.url|url_encode }}%20via%20@wallabagapp" target="_blank" class="tool twitter icon icon-twitter" title="Tweet"><span>Tweet</span></a></li>{% endif %} 21 {% if craue_setting('share_twitter') %}<li><a href="https://twitter.com/home?status={{entry.title|url_encode}}%20{{ entry.url|url_encode }}%20via%20@wallabagapp" target="_blank" class="tool twitter icon icon-twitter" title="Tweet"><span>Tweet</span></a></li>{% endif %}
21 {% if craue_setting('share_mail') %}<li><a href="mailto:?subject={{ entry.title|url_encode }}&amp;body={{ entry.url|url_encode }}%20via%20@wallabagapp" class="tool email icon icon-mail" title="Email"><span>Email</span></a></li>{% endif %} 22 {% if craue_setting('share_mail') %}<li><a href="mailto:?subject={{ entry.title|url_encode }}&amp;body={{ entry.url|url_encode }}%20via%20@wallabagapp" class="tool email icon icon-mail" title="Email"><span>Email</span></a></li>{% endif %}
22 {% if craue_setting('share_shaarli') %}<li><a href="{{ craue_setting('shaarli_url') }}/index.php?post={{ entry.url|url_encode }}&amp;title={{ entry.title|url_encode }}" target="_blank" class="tool shaarli" title="shaarli"><span>shaarli</span></a></li>{% endif %} 23 {% if craue_setting('share_shaarli') %}<li><a href="{{ craue_setting('shaarli_url') }}/index.php?post={{ entry.url|url_encode }}&amp;title={{ entry.title|url_encode }}" target="_blank" class="tool shaarli" title="shaarli"><span>shaarli</span></a></li>{% endif %}
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 5dd2afb3..05bb378d 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
@@ -99,6 +99,18 @@
99 </a> 99 </a>
100 <div class="collapsible-body"> 100 <div class="collapsible-body">
101 <ul> 101 <ul>
102 {% if craue_setting('share_public') %}
103 <li>
104 <a href="{{ path('share', {'id': entry.id }) }}" target="_blank" class="tool public" title="{{ 'entry.view.left_menu.public_link'|trans }}">
105 <span>{{ 'entry.view.left_menu.public_link'|trans }}</span>
106 </a>
107 </li>
108 <li>
109 <a href="{{ path('delete_share', {'id': entry.id }) }}" class="tool public" title="{{ 'entry.view.left_menu.delete_public_link'|trans }}">
110 <span>{{ 'entry.view.left_menu.delete_public_link'|trans }}</span>
111 </a>
112 </li>
113 {% endif %}
102 {% if craue_setting('share_twitter') %} 114 {% if craue_setting('share_twitter') %}
103 <li> 115 <li>
104 <a href="https://twitter.com/home?status={{entry.title|url_encode}}%20{{ entry.url|url_encode }}%20via%20@wallabagapp" target="_blank" class="tool twitter icon icon-twitter" title="twitter"> 116 <a href="https://twitter.com/home?status={{entry.title|url_encode}}%20{{ entry.url|url_encode }}%20via%20@wallabagapp" target="_blank" class="tool twitter icon icon-twitter" title="twitter">
@@ -149,7 +161,6 @@
149 </li> 161 </li>
150 {% endif %} 162 {% endif %}
151 163
152
153 <li class="bold"> 164 <li class="bold">
154 <a class="waves-effect collapsible-header"> 165 <a class="waves-effect collapsible-header">
155 <i class="material-icons small">file_download</i> 166 <i class="material-icons small">file_download</i>
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/share.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/share.html.twig
new file mode 100644
index 00000000..37ca14f1
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/share.html.twig
@@ -0,0 +1,39 @@
1<html>
2 <head>
3 <title>{{ entry.title | raw }}</title>
4 <style>
5 body {
6 margin: 10px;
7 font-family: 'Roboto',Verdana,Geneva,sans-serif;
8 font-size: 16px;
9 color: #000;
10 }
11 header {
12 text-align: center;
13 }
14
15 header h1 {
16 font-size: 1.3em;
17 }
18
19 a,
20 a:hover,
21 a:visited {
22 color: #000;
23 }
24
25 article {
26 margin: 0 auto;
27 width: 600px;
28 }
29 </style>
30 </head>
31 <body>
32 <header>
33 <h1>{{ entry.title | raw }}</h1>
34 </header>
35 <article>
36 {{ entry.content | raw }}
37 </article>
38 </body>
39</html>
diff --git a/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php b/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php
index 5c739c78..f9ac28c3 100644
--- a/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php
+++ b/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php
@@ -698,4 +698,47 @@ class EntryControllerTest extends WallabagCoreTestCase
698 $crawler = $client->submit($form, $data); 698 $crawler = $client->submit($form, $data);
699 $this->assertCount(2, $crawler->filter('div[class=entry]')); 699 $this->assertCount(2, $crawler->filter('div[class=entry]'));
700 } 700 }
701
702 public function testCache()
703 {
704 $this->logInAs('admin');
705 $client = $this->getClient();
706
707 $content = $client->getContainer()
708 ->get('doctrine.orm.entity_manager')
709 ->getRepository('WallabagCoreBundle:Entry')
710 ->findOneByUser($this->getLoggedInUserId());
711
712 // no uuid
713 $client->request('GET', '/share/'.$content->getUuid());
714 $this->assertEquals(404, $client->getResponse()->getStatusCode());
715
716 // generating the uuid
717 $client->request('GET', '/share/'.$content->getId());
718 $this->assertEquals(302, $client->getResponse()->getStatusCode());
719
720 // follow link with uuid
721 $crawler = $client->followRedirect();
722 $this->assertEquals(200, $client->getResponse()->getStatusCode());
723 $this->assertContains('max-age=25200', $client->getResponse()->headers->get('cache-control'));
724 $this->assertContains('public', $client->getResponse()->headers->get('cache-control'));
725 $this->assertContains('s-maxage=25200', $client->getResponse()->headers->get('cache-control'));
726 $this->assertNotContains('no-cache', $client->getResponse()->headers->get('cache-control'));
727
728 // sharing is now disabled
729 $client->getContainer()->get('craue_config')->set('share_public', 0);
730 $client->request('GET', '/share/'.$content->getUuid());
731 $this->assertEquals(404, $client->getResponse()->getStatusCode());
732
733 $client->request('GET', '/view/'.$content->getId());
734 $this->assertContains('no-cache', $client->getResponse()->headers->get('cache-control'));
735
736 // removing the share
737 $client->request('GET', '/share/delete/'.$content->getId());
738 $this->assertEquals(302, $client->getResponse()->getStatusCode());
739
740 // share is now disable
741 $client->request('GET', '/share/'.$content->getUuid());
742 $this->assertEquals(404, $client->getResponse()->getStatusCode());
743 }
701} 744}
diff --git a/var/SymfonyRequirements.php b/var/SymfonyRequirements.php
index 841338f4..0a5de546 100644
--- a/var/SymfonyRequirements.php
+++ b/var/SymfonyRequirements.php
@@ -681,10 +681,17 @@ class SymfonyRequirements extends RequirementCollection
681 681
682 if (class_exists('Symfony\Component\Intl\Intl')) { 682 if (class_exists('Symfony\Component\Intl\Intl')) {
683 $this->addRecommendation( 683 $this->addRecommendation(
684 \Symfony\Component\Intl\Intl::getIcuDataVersion() === \Symfony\Component\Intl\Intl::getIcuVersion(), 684 \Symfony\Component\Intl\Intl::getIcuDataVersion() <= \Symfony\Component\Intl\Intl::getIcuVersion(),
685 sprintf('intl ICU version installed on your system (%s) should match the ICU data bundled with Symfony (%s)', \Symfony\Component\Intl\Intl::getIcuVersion(), \Symfony\Component\Intl\Intl::getIcuDataVersion()), 685 sprintf('intl ICU version installed on your system is outdated (%s) and does not match the ICU data bundled with Symfony (%s)', \Symfony\Component\Intl\Intl::getIcuVersion(), \Symfony\Component\Intl\Intl::getIcuDataVersion()),
686 'In most cases you should be fine, but please verify there is no inconsistencies between data provided by Symfony and the intl extension. See https://github.com/symfony/symfony/issues/15007 for an example of inconsistencies you might run into.' 686 'To get the latest internationalization data upgrade the ICU system package and the intl PHP extension.'
687 ); 687 );
688 if (\Symfony\Component\Intl\Intl::getIcuDataVersion() <= \Symfony\Component\Intl\Intl::getIcuVersion()) {
689 $this->addRecommendation(
690 \Symfony\Component\Intl\Intl::getIcuDataVersion() === \Symfony\Component\Intl\Intl::getIcuVersion(),
691 sprintf('intl ICU version installed on your system (%s) does not match the ICU data bundled with Symfony (%s)', \Symfony\Component\Intl\Intl::getIcuVersion(), \Symfony\Component\Intl\Intl::getIcuDataVersion()),
692 'To avoid internationalization data incosistencies upgrade the symfony/intl component.'
693 );
694 }
688 } 695 }
689 696
690 $this->addPhpIniRecommendation( 697 $this->addPhpIniRecommendation(