]> git.immae.eu Git - github/wallabag/wallabag.git/commitdiff
Merge pull request #1904 from wallabag/feature-public-mode
authorJeremy Benoist <j0k3r@users.noreply.github.com>
Thu, 25 Aug 2016 07:30:51 +0000 (09:30 +0200)
committerGitHub <noreply@github.com>
Thu, 25 Aug 2016 07:30:51 +0000 (09:30 +0200)
Share entry with a public URL

33 files changed:
app/DoctrineMigrations/Version20160410190541.php [new file with mode: 0644]
app/DoctrineMigrations/Version20160812120952.php
app/Resources/CraueConfigBundle/translations/CraueConfigBundle.da.yml
app/Resources/CraueConfigBundle/translations/CraueConfigBundle.de.yml
app/Resources/CraueConfigBundle/translations/CraueConfigBundle.en.yml
app/Resources/CraueConfigBundle/translations/CraueConfigBundle.es.yml
app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fa.yml
app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fr.yml
app/Resources/CraueConfigBundle/translations/CraueConfigBundle.it.yml
app/Resources/CraueConfigBundle/translations/CraueConfigBundle.oc.yml
app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pl.yml
app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ro.yml
app/config/security.yml
src/Wallabag/CoreBundle/Command/InstallCommand.php
src/Wallabag/CoreBundle/Controller/EntryController.php
src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSettingData.php
src/Wallabag/CoreBundle/Entity/Entry.php
src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entry.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entry.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/share.html.twig [new file with mode: 0644]
tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php
var/SymfonyRequirements.php

diff --git a/app/DoctrineMigrations/Version20160410190541.php b/app/DoctrineMigrations/Version20160410190541.php
new file mode 100644 (file)
index 0000000..4014857
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+
+namespace Application\Migrations;
+
+use Doctrine\DBAL\Migrations\AbstractMigration;
+use Doctrine\DBAL\Schema\Schema;
+use Symfony\Component\DependencyInjection\ContainerAwareInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+class Version20160410190541 extends AbstractMigration implements ContainerAwareInterface
+{
+    /**
+     * @var ContainerInterface
+     */
+    private $container;
+
+    public function setContainer(ContainerInterface $container = null)
+    {
+        $this->container = $container;
+    }
+
+    private function getTable($tableName)
+    {
+        return $this->container->getParameter('database_table_prefix') . $tableName;
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE `'.$this->getTable('entry').'` ADD `uuid` LONGTEXT DEFAULT NULL');
+        $this->addSql("INSERT INTO `".$this->getTable('craue_config_setting')."` (`name`, `value`, `section`) VALUES ('share_public', '1', 'entry')");
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'sqlite', 'This down migration can\'t be executed on SQLite databases, because SQLite don\'t support DROP COLUMN.');
+
+        $this->addSql('ALTER TABLE `'.$this->getTable('entry').'` DROP `uuid`');
+        $this->addSql("DELETE FROM `".$this->getTable('craue_config_setting')."` WHERE `name` = 'share_public'");
+    }
+}
index 58f070c7e152b21b0bd24ebc2f24bc5d799695d5..9adfdc8be35e87f66fcc49fac5c161e56ef1ae75 100644 (file)
@@ -4,15 +4,32 @@ namespace Application\Migrations;
 
 use Doctrine\DBAL\Migrations\AbstractMigration;
 use Doctrine\DBAL\Schema\Schema;
+use Symfony\Component\DependencyInjection\ContainerAwareInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
-class Version20160812120952 extends AbstractMigration
+class Version20160812120952 extends AbstractMigration implements ContainerAwareInterface
 {
+    /**
+     * @var ContainerInterface
+     */
+    private $container;
+
+    public function setContainer(ContainerInterface $container = null)
+    {
+        $this->container = $container;
+    }
+
+    private function getTable($tableName)
+    {
+        return $this->container->getParameter('database_table_prefix') . $tableName;
+    }
+
     /**
      * @param Schema $schema
      */
     public function up(Schema $schema)
     {
-        $this->addSql('ALTER TABLE wallabag_oauth2_clients ADD name CLOB DEFAULT NULL COLLATE BINARY');
+        $this->addSql('ALTER TABLE '.$this->getTable('oauth2_clients').' ADD name longtext COLLATE \'utf8_unicode_ci\' DEFAULT NULL');
     }
 
     /**
@@ -21,7 +38,7 @@ class Version20160812120952 extends AbstractMigration
     public function down(Schema $schema)
     {
         $this->abortIf($this->connection->getDatabasePlatform()->getName() == 'sqlite', 'Migration can only be executed safely on \'mysql\' or \'postgresql\'.');
-        $this->addSql('ALTER TABLE wallabag_oauth2_clients DROP COLUMN name;
-');
+
+        $this->addSql('ALTER TABLE '.$this->getTable('oauth2_clients').' DROP COLUMN name');
     }
 }
index c46fdb142519f82f47424cfb0f03d07fa57042f6..3478d6381edd5af416a4eb14cbff4b736b35eb62 100644 (file)
@@ -27,3 +27,4 @@ piwik_site_id: ID for din side hos Piwik
 piwik_enabled: Aktiver Piwik
 demo_mode_enabled: "Aktiver demo-indstilling? (anvendes kun til wallabags offentlige demo)"
 demo_mode_username: "Demobruger"
+# share_public: Allow public url for entries
index fa2093b52c5dc6ce23d85157a79e6adfc4b0e7cd..f655a27fcd4c06957fdd2a2d3765614f9955010a 100644 (file)
@@ -27,3 +27,4 @@ piwik_site_id: ID deiner Webseite in Piwik
 piwik_enabled: Piwik aktivieren
 demo_mode_enabled: "Test-Modus aktivieren? (nur für die öffentliche wallabag-Demo genutzt)"
 demo_mode_username: "Test-Benutzer"
+# share_public: Allow public url for entries
index b627376ec72700f1032e880b03e8e76b340fff3e..48d0ec4b4a082dbea8d794653116ada901c72c35 100644 (file)
@@ -27,3 +27,4 @@ piwik_site_id: ID of your website in Piwik
 piwik_enabled: Enable Piwik
 demo_mode_enabled: "Enable demo mode ? (only used for the wallabag public demo)"
 demo_mode_username: "Demo user"
+share_public: Allow public url for entries
index af1657e4a466680f87d0a0137866e5c0c9177bae..7aac9adff9160a92666cbce879625b8997cd98f6 100644 (file)
@@ -27,3 +27,4 @@ piwik_site_id: ID de tu website de Piwik
 piwik_enabled: Activar Piwik
 demo_mode_enabled: "Activar modo demo (sólo usado para la demo de wallabag)"
 demo_mode_username: "Nombre de usuario demo"
+# share_public: Allow public url for entries
index 7cb4e833a06dd1139f0c105b17dcc527f47049bc..613cf86d4d0f307daaac1917bf63942bea115094 100644 (file)
@@ -22,3 +22,9 @@ export: "برون‌سپاری"
 import: "درون‌ریزی"
 misc: "غیره"
 modify_settings: "اعمال"
+# piwik_host: Host of your website in Piwik
+# piwik_site_id: ID of your website in Piwik
+# piwik_enabled: Enable Piwik
+# demo_mode_enabled: "Enable demo mode ? (only used for the wallabag public demo)"
+# demo_mode_username: "Demo user"
+# share_public: Allow public url for entries
index 084eb6df11c30eb01205b4a8c564dd549739178b..f21f2439ac0222d388177e8a27c7df3592d726ee 100644 (file)
@@ -27,3 +27,4 @@ piwik_site_id: ID de votre site dans Piwik
 piwik_enabled: Activer Piwik
 demo_mode_enabled: "Activer le mode démo ? (utiliser uniquement pour la démo publique de wallabag)"
 demo_mode_username: "Utilisateur de la démo"
+share_public: Autoriser une URL publique pour les articles
index e4417139358a069e8d0aee90c4fad2475719c2c5..1202edd582c95e76b435c371d3758e7a575f4408 100644 (file)
@@ -27,3 +27,4 @@ piwik_site_id: ID del tuo sito in Piwik
 piwik_enabled: Abilita Piwik
 demo_mode_enabled: "Abilita modalità demo ? (usato solo per la demo pubblica di wallabag)"
 demo_mode_username: "Utente Demo"
+# share_public: Allow public url for entries
index 67880b8bbb0ec7e5455852d93e5c3e84cfd7d47c..dd91ee497934c547ab943942199b659f9f1a3796 100644 (file)
@@ -27,3 +27,4 @@ piwik_site_id: ID de vòstre site dins Piwik
 piwik_enabled: Activar Piwik
 demo_mode_enabled: "Activar lo mode demostracion ? (utilizar solament per la demostracion publica de wallabag)"
 demo_mode_username: "Utilizaire de la demostracion"
+# share_public: Allow public url for entries
index 87ca5060e5c4654704af98bed460622b6b957678..93b36c8f644f5f1ad1e52993f93310f2e3b051f2 100644 (file)
@@ -22,3 +22,9 @@ export: "eksport"
 import: "import"
 misc: "różne"
 modify_settings: "zatwierdz"
+# piwik_host: Host of your website in Piwik
+# piwik_site_id: ID of your website in Piwik
+# piwik_enabled: Enable Piwik
+# demo_mode_enabled: "Enable demo mode ? (only used for the wallabag public demo)"
+# demo_mode_username: "Demo user"
+# share_public: Allow public url for entries
index f5ff8c6a458194c0716851f258ce13bb27a6b04d..326c9f90ff753d73bf2e288f7b33f5454c9fa14f 100644 (file)
@@ -22,3 +22,9 @@ export: "exportă"
 import: "importă"
 misc: "diverse"
 modify_settings: "aplică"
+# piwik_host: Host of your website in Piwik
+# piwik_site_id: ID of your website in Piwik
+# piwik_enabled: Enable Piwik
+# demo_mode_enabled: "Enable demo mode ? (only used for the wallabag public demo)"
+# demo_mode_username: "Demo user"
+# share_public: Allow public url for entries
index e24e03df2e921d98eff8325b86a1ae2733a8ea6d..1f30e58b845abceb50011a28ed32b0f7ab57daca 100644 (file)
@@ -60,6 +60,7 @@ security:
         - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
         - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
         - { path: /(unread|starred|archive).xml$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
+        - { path: ^/share, roles: IS_AUTHENTICATED_ANONYMOUSLY }
         - { path: ^/settings, roles: ROLE_SUPER_ADMIN }
         - { path: ^/annotations, roles: ROLE_USER }
         - { path: ^/, roles: ROLE_USER }
index e134ced52b2cc5116bb97c7f6dc01bc5895d002a..143def4f158ea572ad871db1fbbbc2316df3e1e1 100644 (file)
@@ -241,6 +241,11 @@ class InstallCommand extends ContainerAwareCommand
         $em->createQuery('DELETE FROM CraueConfigBundle:Setting')->execute();
 
         $settings = [
+            [
+                'name' => 'share_public',
+                'value' => '1',
+                'section' => 'entry',
+            ],
             [
                 'name' => 'carrot',
                 'value' => '1',
index 93db0d6caa117d1d0ba9442c8b4a3ea66ace11c8..d71ba6cd5858df70dbe9afdf7e7a318274b7bc19 100644 (file)
@@ -12,6 +12,7 @@ use Wallabag\CoreBundle\Entity\Entry;
 use Wallabag\CoreBundle\Form\Type\EntryFilterType;
 use Wallabag\CoreBundle\Form\Type\EditEntryType;
 use Wallabag\CoreBundle\Form\Type\NewEntryType;
+use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
 
 class EntryController extends Controller
 {
@@ -434,7 +435,7 @@ class EntryController extends Controller
      */
     private function checkUserAction(Entry $entry)
     {
-        if ($this->getUser()->getId() != $entry->getUser()->getId()) {
+        if (null === $this->getUser() || $this->getUser()->getId() != $entry->getUser()->getId()) {
             throw $this->createAccessDeniedException('You can not access this entry.');
         }
     }
@@ -450,4 +451,76 @@ class EntryController extends Controller
     {
         return $this->get('wallabag_core.entry_repository')->findByUrlAndUserId($entry->getUrl(), $this->getUser()->getId());
     }
+
+    /**
+     * Get public URL for entry (and generate it if necessary).
+     *
+     * @param Entry $entry
+     *
+     * @Route("/share/{id}", requirements={"id" = "\d+"}, name="share")
+     *
+     * @return \Symfony\Component\HttpFoundation\Response
+     */
+    public function shareAction(Entry $entry)
+    {
+        $this->checkUserAction($entry);
+
+        if (null === $entry->getUuid()) {
+            $entry->generateUuid();
+
+            $em = $this->getDoctrine()->getManager();
+            $em->persist($entry);
+            $em->flush();
+        }
+
+        return $this->redirect($this->generateUrl('share_entry', [
+            'uuid' => $entry->getUuid(),
+        ]));
+    }
+
+    /**
+     * Disable public sharing for an entry.
+     *
+     * @param Entry $entry
+     *
+     * @Route("/share/delete/{id}", requirements={"id" = "\d+"}, name="delete_share")
+     *
+     * @return \Symfony\Component\HttpFoundation\Response
+     */
+    public function deleteShareAction(Entry $entry)
+    {
+        $this->checkUserAction($entry);
+
+        $entry->cleanUuid();
+
+        $em = $this->getDoctrine()->getManager();
+        $em->persist($entry);
+        $em->flush();
+
+        return $this->redirect($this->generateUrl('view', [
+            'id' => $entry->getId(),
+        ]));
+    }
+
+    /**
+     * Ability to view a content publicly.
+     *
+     * @param Entry $entry
+     *
+     * @Route("/share/{uuid}", requirements={"uuid" = ".+"}, name="share_entry")
+     * @Cache(maxage="25200", smaxage="25200", public=true)
+     *
+     * @return \Symfony\Component\HttpFoundation\Response
+     */
+    public function shareEntryAction(Entry $entry)
+    {
+        if (!$this->get('craue_config')->get('share_public')) {
+            throw $this->createAccessDeniedException('Sharing an entry is disabled for this user.');
+        }
+
+        return $this->render(
+            '@WallabagCore/themes/share.html.twig',
+            ['entry' => $entry]
+        );
+    }
 }
index 0905879616e06afa13b302c62df918dfcc8c47c6..b4309304ecfea459328a239a337d994b36894f7e 100644 (file)
@@ -15,6 +15,11 @@ class LoadSettingData extends AbstractFixture implements OrderedFixtureInterface
     public function load(ObjectManager $manager)
     {
         $settings = [
+            [
+                'name' => 'share_public',
+                'value' => '1',
+                'section' => 'entry',
+            ],
             [
                 'name' => 'carrot',
                 'value' => '1',
index ceae78b05556e4005f0c51e35e1eb93a5bf6c57a..4d7e001bed619a58bc85d1f1d886fd8f21130208 100644 (file)
@@ -37,6 +37,15 @@ class Entry
      */
     private $id;
 
+    /**
+     * @var string
+     *
+     * @ORM\Column(name="uuid", type="text", nullable=true)
+     *
+     * @Groups({"entries_for_user", "export_all"})
+     */
+    private $uuid;
+
     /**
      * @var string
      *
@@ -595,4 +604,37 @@ class Entry
     {
         return $this->language;
     }
+
+    /**
+     * @return string
+     */
+    public function getUuid()
+    {
+        return $this->uuid;
+    }
+
+    /**
+     * @param string $uuid
+     *
+     * @return Entry
+     */
+    public function setUuid($uuid)
+    {
+        $this->uuid = $uuid;
+
+        return $this;
+    }
+
+    public function generateUuid()
+    {
+        if (null === $this->uuid) {
+            // @see http://blog.kevingomez.fr/til/2015/07/26/why-is-uniqid-slow/ for true parameter
+            $this->uuid = uniqid('', true);
+        }
+    }
+
+    public function cleanUuid()
+    {
+        $this->uuid = null;
+    }
 }
index 8798853968948a1a1481565975c8b69a8e65759f..f9b7bfacdac8c9a93aeb541527f77eaf1dbb5e94 100644 (file)
@@ -187,6 +187,8 @@ entry:
             add_a_tag: 'Tliføj et tag'
             share_content: 'Deling'
             # share_email_label: 'Email'
+            # public_link: 'public link'
+            # delete_public_link: 'delete public link'
             download: 'Download'
             # print: 'Print'
             problem:
index 461967d612783d3c14587c6d16be2387488d7776..79d03286bdc7e989784168b8dc534fcd0b686cc8 100644 (file)
@@ -187,6 +187,8 @@ entry:
             add_a_tag: 'Tag hinzufügen'
             share_content: 'Teilen'
             share_email_label: 'E-Mail'
+            # public_link: 'public link'
+            # delete_public_link: 'delete public link'
             download: 'Herunterladen'
             print: 'Drucken'
             problem:
index 600b74724e3c05b549d8cca0ef59a5c3fbe1e7bd..d921b39f9579a9cac1123a45dc3f7d96fe8d71ef 100644 (file)
@@ -187,6 +187,8 @@ entry:
             add_a_tag: 'Add a tag'
             share_content: 'Share'
             share_email_label: 'Email'
+            public_link: 'public link'
+            delete_public_link: 'delete public link'
             download: 'Download'
             print: 'Print'
             problem:
index 6da8a593162483e62ee4883000d50484f89d15ec..c2ec4dbd77fae8227a168c2420cde87737d4ae70 100644 (file)
@@ -187,6 +187,8 @@ entry:
             add_a_tag: 'Añadir una etiqueta'
             share_content: 'Compartir'
             share_email_label: 'Dirección e-mail'
+            # public_link: 'public link'
+            # delete_public_link: 'delete public link'
             download: 'Descargar'
             print: 'Imprimir'
             problem:
index 4684b08b7489ae018bf229bdd1136d2c13c48b7c..561ed907487675070e5677cbffc0e84780f85100 100644 (file)
@@ -187,6 +187,8 @@ entry:
             add_a_tag: 'افزودن برچسب'
             share_content: 'هم‌رسانی'
             share_email_label: 'نشانی ایمیل'
+            # public_link: 'public link'
+            # delete_public_link: 'delete public link'
             download: 'بارگیری'
             print: 'چاپ'
             problem:
index 2b6e419465e8b46b130f2db8e9c25ec94a842296..c0671883ab9432c86d85d8a396f7ab226eb1261f 100644 (file)
@@ -187,6 +187,8 @@ entry:
             add_a_tag: 'Ajouter un tag'
             share_content: 'Partager'
             share_email_label: 'Email'
+            public_link: 'Lien public'
+            delete_public_link: 'Supprimer lien public'
             download: 'Télécharger'
             print: 'Imprimer'
             problem:
index 3760c2d64f4d3de3e290a48d87cee085dcbf40b7..2e3dd08b0c82680b706badc54e1d7039367691d1 100644 (file)
@@ -185,6 +185,8 @@ entry:
             add_a_tag: 'Aggiungi un tag'
             share_content: 'Condividi'
             share_email_label: 'E-mail'
+            # public_link: 'public link'
+            # delete_public_link: 'delete public link'
             download: 'Download'
             print: 'Stampa'
             problem:
index 954356067cb2e9af0e154ae943269f6083358729..7b978a609eadf0abaccb477ea746e3ace0dc8922 100644 (file)
@@ -187,6 +187,8 @@ entry:
             add_a_tag: 'Ajustar una etiqueta'
             share_content: 'Partatjar'
             share_email_label: 'Corrièl'
+            # public_link: 'public link'
+            # delete_public_link: 'delete public link'
             download: 'Telecargar'
             print: 'Imprimir'
             problem:
index b0b7e49b71a62a401860285763060b0f95570511..da170e4d64cd50459bdadfebd43842d947a24407 100644 (file)
@@ -187,6 +187,8 @@ entry:
             add_a_tag: 'Dodaj tag'
             share_content: 'Udostępnij'
             share_email_label: 'Adres email'
+            # public_link: 'public link'
+            # delete_public_link: 'delete public link'
             download: 'Pobierz'
             print: 'Drukuj'
             problem:
index d735df4c0e504bc7f74673ed109d9ed362759873..fa2d6468cd8b253c1e6031c5b83c99bbf008d3eb 100644 (file)
@@ -187,6 +187,8 @@ entry:
             add_a_tag: 'Adaugă un tag'
             share_content: 'Dă mai departe'
             share_email_label: 'E-mail'
+            # public_link: 'public link'
+            # delete_public_link: 'delete public link'
             download: 'Descarcă'
             # print: 'Print'
             problem:
index 77bfa0f080bafd9eb417f63c12e56081e6bf99ba..05c31336fb8d8f204b7ec47e349c53a288cbfac1 100644 (file)
@@ -187,6 +187,8 @@ entry:
             add_a_tag: 'Bir etiket ekle'
             share_content: 'Paylaş'
             share_email_label: 'E-posta'
+            # public_link: 'public link'
+            # delete_public_link: 'delete public link'
             download: 'İndir'
             # print: 'Print'
             problem:
index ce47a6771977718ce7a590e27f67df3483468a18..6c46f91fcc6a8aa1ff343f2b80f7179109fdfed9 100644 (file)
@@ -17,6 +17,7 @@
                 <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>
                 <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>
                 <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>
+                {% 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 %}
                 {% 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 %}
                 {% 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 %}
                 {% 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 %}
index 5dd2afb3e32d58d52b953067086da402ea844557..05bb378d33aeb0c60f3549051915b239359f4bf9 100644 (file)
             </a>
             <div class="collapsible-body">
                 <ul>
+                    {% 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 %}
                     {% 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="twitter">
         </li>
         {% endif %}
 
-
         <li class="bold">
             <a class="waves-effect collapsible-header">
                 <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 (file)
index 0000000..37ca14f
--- /dev/null
@@ -0,0 +1,39 @@
+<html>
+    <head>
+        <title>{{ entry.title | raw }}</title>
+        <style>
+            body {
+                margin: 10px;
+                font-family: 'Roboto',Verdana,Geneva,sans-serif;
+                font-size: 16px;
+                color: #000;
+            }
+            header {
+                text-align: center;
+            }
+
+            header h1 {
+                font-size: 1.3em;
+            }
+
+            a,
+            a:hover,
+            a:visited {
+                color: #000;
+            }
+
+            article {
+                margin: 0 auto;
+                width: 600px;
+            }
+        </style>
+    </head>
+    <body>
+        <header>
+            <h1>{{ entry.title | raw }}</h1>
+        </header>
+        <article>
+            {{ entry.content | raw }}
+        </article>
+    </body>
+</html>
index 5c739c78a3349f167f49c2d273971e31cd453526..f9ac28c3ac3fc125bc324d8e189db3283ac1e7b5 100644 (file)
@@ -698,4 +698,47 @@ class EntryControllerTest extends WallabagCoreTestCase
         $crawler = $client->submit($form, $data);
         $this->assertCount(2, $crawler->filter('div[class=entry]'));
     }
+
+    public function testCache()
+    {
+        $this->logInAs('admin');
+        $client = $this->getClient();
+
+        $content = $client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findOneByUser($this->getLoggedInUserId());
+
+        // no uuid
+        $client->request('GET', '/share/'.$content->getUuid());
+        $this->assertEquals(404, $client->getResponse()->getStatusCode());
+
+        // generating the uuid
+        $client->request('GET', '/share/'.$content->getId());
+        $this->assertEquals(302, $client->getResponse()->getStatusCode());
+
+        // follow link with uuid
+        $crawler = $client->followRedirect();
+        $this->assertEquals(200, $client->getResponse()->getStatusCode());
+        $this->assertContains('max-age=25200', $client->getResponse()->headers->get('cache-control'));
+        $this->assertContains('public', $client->getResponse()->headers->get('cache-control'));
+        $this->assertContains('s-maxage=25200', $client->getResponse()->headers->get('cache-control'));
+        $this->assertNotContains('no-cache', $client->getResponse()->headers->get('cache-control'));
+
+        // sharing is now disabled
+        $client->getContainer()->get('craue_config')->set('share_public', 0);
+        $client->request('GET', '/share/'.$content->getUuid());
+        $this->assertEquals(404, $client->getResponse()->getStatusCode());
+
+        $client->request('GET', '/view/'.$content->getId());
+        $this->assertContains('no-cache', $client->getResponse()->headers->get('cache-control'));
+
+        // removing the share
+        $client->request('GET', '/share/delete/'.$content->getId());
+        $this->assertEquals(302, $client->getResponse()->getStatusCode());
+
+        // share is now disable
+        $client->request('GET', '/share/'.$content->getUuid());
+        $this->assertEquals(404, $client->getResponse()->getStatusCode());
+    }
 }
index 841338f443bebd1c6ef1fb9490fc05fa00d81800..0a5de5461b46d31fd1006244bb33c235676efc29 100644 (file)
@@ -681,10 +681,17 @@ class SymfonyRequirements extends RequirementCollection
 
             if (class_exists('Symfony\Component\Intl\Intl')) {
                 $this->addRecommendation(
-                    \Symfony\Component\Intl\Intl::getIcuDataVersion() === \Symfony\Component\Intl\Intl::getIcuVersion(),
-                    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()),
-                    '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.'
+                    \Symfony\Component\Intl\Intl::getIcuDataVersion() <= \Symfony\Component\Intl\Intl::getIcuVersion(),
+                    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()),
+                    'To get the latest internationalization data upgrade the ICU system package and the intl PHP extension.'
                 );
+                if (\Symfony\Component\Intl\Intl::getIcuDataVersion() <= \Symfony\Component\Intl\Intl::getIcuVersion()) {
+                    $this->addRecommendation(
+                        \Symfony\Component\Intl\Intl::getIcuDataVersion() === \Symfony\Component\Intl\Intl::getIcuVersion(),
+                        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()),
+                        'To avoid internationalization data incosistencies upgrade the symfony/intl component.'
+                    );
+                }
             }
 
             $this->addPhpIniRecommendation(