Commit 5c89b009 authored by Ghislain Loas's avatar Ghislain Loas

Merge remote-tracking branch 'refs/remotes/origin/master' into…

Merge remote-tracking branch 'refs/remotes/origin/master' into dev#85637_a_cacherretirer_par_variable
parents a53faff2 90b78988
Pipeline #6159 failed with stage
in 28 minutes and 36 seconds
'69586' =>
['Label' => $this->_('Inclure des articles dans les lettres d/'information'),
'Desc' => $this->_('Bokeh permet d\'envoyer des articles dans les lettres d\'information.'),
'Image' => '',
'Video' => '',
'Category' => $this->_('Rédaction'),
'Right' => function($feature_description, $user) {return true;},
'Wiki' => 'http://wiki.bokeh-library-portal.org/index.php?title=Lettre_d\'information',
'Test' => '',
'Date' => '2018-01-10'],
\ No newline at end of file
- ticket #69586 : Newsletter : Ajout de la possibilité d'inclure des articles dans les newsletters
\ No newline at end of file
<?php
$adapter = Zend_Db_Table_Abstract::getDefaultAdapter();
try {
$adapter->query('ALTER TABLE newsletters ADD articles_ids varchar(255) NULL default NULL');
} catch(Exception $e) {}
try {
$adapter->query('ALTER TABLE newsletters ADD articles_categories_ids varchar(255) NULL default NULL');
} catch(Exception $e) {}
<?php
/**
* Copyright (c) 2012-2019, Agence Française Informatique (AFI). All rights reserved.
*
* BOKEH is free software; you can redistribute it and/or modify
* it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
* the Free Software Foundation.
*
* There are special exceptions to the terms and conditions of the AGPL as it
* is applied to this software (see README file).
*
* BOKEH is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
* along with BOKEH; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
class Class_Article_MailRenderer {
use Trait_Translator;
public function renderTextInto($article, &$data) {
if (!$article)
return;
$data[] = '- ' . $article->getLabel();
$data[] = strip_tags($article->getFullContent());
$data[] = $this->_('Lien: ') . Class_Url::absolute(['controller' => 'cms',
'action' => 'viewarticle',
'id' => $article->getId()], null, true);
$data[] = "\n";
}
public function renderHtml($article) {
if (!$article)
return '';
return '<div style="padding:5px">' .
'<h1>' . $article->getLabel() . '</h1>' .
'<div>' . $article->getFullContent() . '</div>' .
'<div style="clear:both"></div>'.
'</div>';
}
}
...@@ -89,7 +89,9 @@ class Class_Newsletter extends Storm_Model_Abstract { ...@@ -89,7 +89,9 @@ class Class_Newsletter extends Storm_Model_Abstract {
protected $_notices_finder; protected $_notices_finder;
protected $_recipent_size = 20; protected $_recipent_size = 20;
protected $_default_attribute_values = ['titre' => '', protected $_default_attribute_values = ['titre' => '',
'draft' => 0]; 'draft' => 0,
'articles_ids' => '',
'articles_categories_ids' => ''];
public function describeAssociationsOn($associations) { public function describeAssociationsOn($associations) {
...@@ -136,11 +138,12 @@ class Class_Newsletter extends Storm_Model_Abstract { ...@@ -136,11 +138,12 @@ class Class_Newsletter extends Storm_Model_Abstract {
$template = new Class_Entity(); $template = new Class_Entity();
$notices = $this->getNotices(); $notices = $this->getNotices();
$articles = $this->getArticles();
$template $template
->setTitre($this->getTitre()) ->setTitre($this->getTitre())
->setBodyText($this->_getBodyText($notices)) ->setBodyText($this->_getBodyText($notices, $articles))
->setBodyHTML($this->_getBodyHTML($notices)) ->setBodyHTML($this->_getBodyHTML($notices, $articles))
->setExpediteur($this->getExpediteur()); ->setExpediteur($this->getExpediteur());
return $template; return $template;
...@@ -214,10 +217,23 @@ class Class_Newsletter extends Storm_Model_Abstract { ...@@ -214,10 +217,23 @@ class Class_Newsletter extends Storm_Model_Abstract {
'only_img' => false, 'only_img' => false,
'aleatoire' => 0, 'aleatoire' => 0,
'tri' => 1); 'tri' => 1);
return Class_Notice::getNoticesFromPreferences($preferences); return Class_Notice::getNoticesFromPreferences($preferences);
} }
public function getArticles() {
$articles = [];
foreach (Class_ArticleCategorie::findAllBy(['id_cat' => $this->getArticlesCategoriesIds()]) as $categorie)
$articles = array_merge($articles,
$categorie->getArticles());
return array_merge($articles,
Class_Article::findAllBy(['id_article' => $this->getArticlesIds()]));
}
protected function _htmlToText($html) { protected function _htmlToText($html) {
return strip_tags(preg_replace('/<br[^>]*>/i', "\n", $html)); return strip_tags(preg_replace('/<br[^>]*>/i', "\n", $html));
} }
...@@ -245,13 +261,17 @@ class Class_Newsletter extends Storm_Model_Abstract { ...@@ -245,13 +261,17 @@ class Class_Newsletter extends Storm_Model_Abstract {
} }
protected function _getBodyText($records) { protected function _getBodyText($records, $articles) {
$lines = [$this->_htmlToText($this->getContenu())]; $lines = [$this->_htmlToText($this->getContenu())];
$renderer = new Class_Notice_MailRenderer(); $renderer = new Class_Notice_MailRenderer();
foreach($records as $record) foreach($records as $record)
$renderer->renderTextInto($record, $lines); $renderer->renderTextInto($record, $lines);
$renderer = new Class_Article_MailRenderer();
foreach($articles as $article)
$renderer->renderTextInto($article, $lines);
$lines[] = $this->_getUnsubscribeText(); $lines[] = $this->_getUnsubscribeText();
return implode("\n", $lines); return implode("\n", $lines);
...@@ -273,13 +293,17 @@ class Class_Newsletter extends Storm_Model_Abstract { ...@@ -273,13 +293,17 @@ class Class_Newsletter extends Storm_Model_Abstract {
* @param array $records * @param array $records
* @return string * @return string
*/ */
protected function _getBodyHTML($records) { protected function _getBodyHTML($records, $articles) {
$html = $this->getContenu(); $html = $this->getContenu();
$renderer = new Class_Notice_MailRenderer(); $renderer = new Class_Notice_MailRenderer();
foreach($records as $record) foreach($records as $record)
$html .= $renderer->renderHtml($record); $html .= $renderer->renderHtml($record);
$renderer = new Class_Article_MailRenderer();
foreach($articles as $article)
$html .= $renderer->renderHtml($article);
$html .= $this->_getUnsubscribeHTML(); $html .= $this->_getUnsubscribeHTML();
return $html; return $html;
......
...@@ -62,6 +62,7 @@ class ZendAfi_Form_Admin_Newsletter extends ZendAfi_Form { ...@@ -62,6 +62,7 @@ class ZendAfi_Form_Admin_Newsletter extends ZendAfi_Form {
'value' => 0, 'value' => 0,
'validators' => [new Zend_Validate_Int()]]) 'validators' => [new Zend_Validate_Int()]])
->addDisplayGroup(['titre', 'expediteur', 'draft'], ->addDisplayGroup(['titre', 'expediteur', 'draft'],
'letter', 'letter',
['legend' => $this->_('Lettre')]) ['legend' => $this->_('Lettre')])
...@@ -74,4 +75,39 @@ class ZendAfi_Form_Admin_Newsletter extends ZendAfi_Form { ...@@ -74,4 +75,39 @@ class ZendAfi_Form_Admin_Newsletter extends ZendAfi_Form {
'notices', 'notices',
['legend' => $this->_('Notices')]); ['legend' => $this->_('Notices')]);
} }
public function populate($datas) {
parent::populate($datas);
$this
->addElement('treeSelect',
'articles_selector',
['UrlDataSource' => Class_Url::assemble(['module' => 'admin',
'controller' => 'bib',
'action' => 'articles']),
'InputIdItemsName' => 'articles_ids',
'IdItems' => isset($datas['articles_ids']) ? $datas['articles_ids'] : '',
'ItemRenderer' => function($id)
{
if ($model = Class_Article::find($id))
return $model->getTitre();
},
'InputIdCategoriesName' => 'articles_categories_ids',
'IdCategories' => isset($datas['articles_categories_ids']) ? $datas['articles_categories_ids'] : '',
'CategoryRenderer' => function($id)
{
if ($model = Class_ArticleCategry::find($id))
return $model->getLibelle();
},
]);
$this->addDisplayGroup(['articles_selector'],
'articles',
['legend' => $this->_('Articles')]);
return $this;
}
} }
...@@ -316,6 +316,7 @@ class Admin_NewsletterControllerEditActionTest extends Admin_NewsletterControlle ...@@ -316,6 +316,7 @@ class Admin_NewsletterControllerEditActionTest extends Admin_NewsletterControlle
'titre' => 'Nouveautés', 'titre' => 'Nouveautés',
'contenu'=>'Notre sélection du mois', 'contenu'=>'Notre sélection du mois',
'expediteur' => 'laurent@free.fr', 'expediteur' => 'laurent@free.fr',
'articles_ids' => '6-42',
'user_groups' => [Class_UserGroup::find(14), 'user_groups' => [Class_UserGroup::find(14),
Class_UserGroup::find(15)]]); Class_UserGroup::find(15)]]);
...@@ -359,6 +360,19 @@ class Admin_NewsletterControllerEditActionTest extends Admin_NewsletterControlle ...@@ -359,6 +360,19 @@ class Admin_NewsletterControllerEditActionTest extends Admin_NewsletterControlle
public function testSubmitButton() { public function testSubmitButton() {
$this->assertXPath("//div//button[contains(@onclick,\"submit()\")]"); $this->assertXPath("//div//button[contains(@onclick,\"submit()\")]");
} }
/** @test */
public function articlesTabShouldBePresent() {
$this->assertXPathContentContains('//form//fieldset//legend', 'Articles');
}
/** @test */
public function articleSelectionFieldsShouldBePresent() {
$this->assertXPath('//form//input[@name="articles_ids"][@value="6-42"]');
$this->assertXPath('//form//input[@name="articles_categories_ids"][@value=""]');
}
} }
...@@ -374,7 +388,9 @@ class Admin_NewsletterControllerAddActionPostTest extends Admin_NewsletterContro ...@@ -374,7 +388,9 @@ class Admin_NewsletterControllerAddActionPostTest extends Admin_NewsletterContro
'contenu' => 'Plein les yeux', 'contenu' => 'Plein les yeux',
'id_catalogue' => '', 'id_catalogue' => '',
'id_panier' => '', 'id_panier' => '',
'nb_notices' => 2]; 'nb_notices' => 2,
'articles_ids' => '6-42',
'articles_categories_ids' => '3-4'];
$this->postDispatch('/admin/newsletter/add', $data); $this->postDispatch('/admin/newsletter/add', $data);
$this->_new = Class_Newsletter::findFirstBy(['titre' => 'Fêtes du lac']); $this->_new = Class_Newsletter::findFirstBy(['titre' => 'Fêtes du lac']);
...@@ -404,6 +420,17 @@ class Admin_NewsletterControllerAddActionPostTest extends Admin_NewsletterContro ...@@ -404,6 +420,17 @@ class Admin_NewsletterControllerAddActionPostTest extends Admin_NewsletterContro
$this->assertEquals('Groupe manuel pour la lettre "Fêtes du lac"', $this->assertEquals('Groupe manuel pour la lettre "Fêtes du lac"',
$this->_new->getDedicatedGroup()->getLibelle()); $this->_new->getDedicatedGroup()->getLibelle());
} }
/** @test */
public function articlesIdsShouldBe6_42() {
$this->assertEquals('6-42', $this->_new->getArticlesIds());
}
/** @test */
public function articlesCategoriesIdsShouldBe3And4() {
$this->assertEquals('3-4', $this->_new->getArticlesCategoriesIds());
}
} }
...@@ -837,6 +864,27 @@ class Admin_NewsletterControllerPreviewActionTest extends Admin_NewsletterContro ...@@ -837,6 +864,27 @@ class Admin_NewsletterControllerPreviewActionTest extends Admin_NewsletterContro
'libelle' => 'Mon catalogue', 'libelle' => 'Mon catalogue',
'type_doc' => 5]); 'type_doc' => 5]);
$septante_millions = $this->fixture('Class_Article',
['id' => 35,
'titre' => '70 millions …',
'contenu' => 'Ils sont 70 millions prêts à prendre sa place.']);
$le_roi_des_cons = $this->fixture('Class_Article',
['id' => 36,
'titre' => 'Le Roi des cons',
'contenu' => 'Il est beau, il est fier sur son throne.']);
$l_arnaque = $this->fixture('Class_Article',
['id' => 12,
'titre' => 'L\'arnaque',
'contenu' => 'La révolution a oublié de décapiter la misère et l\'exploitation.']);
$this->fixture('Class_ArticleCategorie',
['id' => 89,
'libelle' => 'La France',
'articles' => [$le_roi_des_cons,
$septante_millions]]);
$nouveautes = $this->fixture('Class_Newsletter', $nouveautes = $this->fixture('Class_Newsletter',
['id' => 3, ['id' => 3,
'titre' => 'Nouveautés', 'titre' => 'Nouveautés',
...@@ -844,6 +892,8 @@ class Admin_NewsletterControllerPreviewActionTest extends Admin_NewsletterContro ...@@ -844,6 +892,8 @@ class Admin_NewsletterControllerPreviewActionTest extends Admin_NewsletterContro
'id_catalogue' => 1, 'id_catalogue' => 1,
'nb_notices' => 0, 'nb_notices' => 0,
'id_panier' => null, 'id_panier' => null,
'articles_categories_ids' => '89-99',
'articles_ids' => '12',
'last_distribution_date' => '2012-03-02']); 'last_distribution_date' => '2012-03-02']);
...@@ -854,18 +904,22 @@ class Admin_NewsletterControllerPreviewActionTest extends Admin_NewsletterContro ...@@ -854,18 +904,22 @@ class Admin_NewsletterControllerPreviewActionTest extends Admin_NewsletterContro
$this->dispatch('/admin/newsletter/preview/id/3', true); $this->dispatch('/admin/newsletter/preview/id/3', true);
} }
public function testFrom() { public function testFrom() {
$this->assertQueryContentContains('p', 'laurent@afi-sa.net'); $this->assertQueryContentContains('p', 'laurent@afi-sa.net');
} }
public function testSubject() { public function testSubject() {
$this->assertQueryContentContains('p', 'Nouveautés'); $this->assertQueryContentContains('p', 'Nouveautés');
} }
public function testBodyText() { public function testBodyText() {
$this->assertQueryContentContains('p', 'Notre sélection du mois Hoho'); $this->assertQueryContentContains('p', 'Notre sélection du mois Hoho');
} }
public function testBodyHtml() { public function testBodyHtml() {
$this->assertXPath('//div//img[@src="zork.jpg"]', $this->_response->getBody()); $this->assertXPath('//div//img[@src="zork.jpg"]', $this->_response->getBody());
} }
...@@ -876,16 +930,29 @@ class Admin_NewsletterControllerPreviewActionTest extends Admin_NewsletterContro ...@@ -876,16 +930,29 @@ class Admin_NewsletterControllerPreviewActionTest extends Admin_NewsletterContro
$this->assertQueryContentContains('p', 'Martine à la plage', $this->_response->getBody()); $this->assertQueryContentContains('p', 'Martine à la plage', $this->_response->getBody());
} }
/** @test */ /** @test */
public function noticeMartineALaPlageUrlShouldBeRechercheViewNotice42() { public function noticeMartineALaPlageUrlShouldBeRechercheViewNotice42() {
$this->assertXPath('//a[@href="' . Class_Url::absolute('/recherche/viewnotice/id/42') . '"]'); $this->assertXPath('//a[@href="' . Class_Url::absolute('/recherche/viewnotice/id/42') . '"]');
} }
/** @test */ /** @test */
public function templateShouldNotCreateNewsletterDispatch() { public function templateShouldNotCreateNewsletterDispatch() {
$this->assertEmpty(Class_Newsletter_Dispatch::findAll()); $this->assertEmpty(Class_Newsletter_Dispatch::findAll());
} }
/** @test */
public function leRoiDesConsShouldBeDisplay() {
$this->assertXpath('//div', 'Le Roi des cons', $this->_response->getBody());
}
/** @test */
public function lArnaqueShouldBeDisplay() {
$this->assertXpath('//div', 'L\'arnaque', $this->_response->getBody());
}
} }
......
...@@ -1999,7 +1999,6 @@ class UpgradeDB_341_Test extends UpgradeDBTestCase { ...@@ -1999,7 +1999,6 @@ class UpgradeDB_341_Test extends UpgradeDBTestCase {
class UpgradeDB_342_Test extends UpgradeDBTestCase { class UpgradeDB_342_Test extends UpgradeDBTestCase {
public function prepare() {} public function prepare() {}
...@@ -2438,3 +2437,22 @@ class UpgradeDB_363_Test extends UpgradeDBTestCase { ...@@ -2438,3 +2437,22 @@ class UpgradeDB_363_Test extends UpgradeDBTestCase {
$this->assertEquals($expected, $thesaurus['rules']); $this->assertEquals($expected, $thesaurus['rules']);
} }
} }
class UpgradeDB_364_Test extends UpgradeDBTestCase {
public function prepare() {
$this->silentQuery('ALTER TABLE newsletters DROP column articles_ids');
$this->silentQuery('ALTER TABLE newsletters DROP column articles_categories_ids');
}
/** @test **/
public function articlesIdsShouldBePresent() {
$this->assertColumn('newsletters', 'articles_ids');
}
/** @test **/
public function articlesCategoriesShouldBePresent() {
$this->assertColumn('newsletters', 'articles_categories_ids');
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment