Merge pull request #712 from romainneutron/master

Merge 3.8 in master
This commit is contained in:
Romain Neutron
2013-10-25 04:49:40 -07:00
24 changed files with 288 additions and 55 deletions

View File

@@ -22,7 +22,8 @@
"zxcvbn": "https://github.com/lowe/zxcvbn.git", "zxcvbn": "https://github.com/lowe/zxcvbn.git",
"geonames-server-jquery-plugin": "~0.2", "geonames-server-jquery-plugin": "~0.2",
"swfobject": "latest", "swfobject": "latest",
"tinymce": "~4.0" "tinymce": "~4.0",
"jquery-galleria": "1.2.9"
}, },
"devDependencies": { "devDependencies": {
"mocha": "latest", "mocha": "latest",

View File

@@ -31,14 +31,24 @@ class Permalink extends AbstractDelivery
$that = $this; $that = $this;
$deliverPermaview = function($sbas_id, $record_id, $token, $subdef, PhraseaApplication $app) { $retrieveRecord = function ($app, $databox, $token, $record_id, $subdef) {
if (in_array($subdef, array(\databox_subdef::CLASS_PREVIEW, \databox_subdef::CLASS_THUMBNAIL)) && $app['EM']->getRepository('Entities\FeedItem')->isRecordInPublicFeed($app, $databox->get_sbas_id(), $record_id)) {
$record = $databox->get_record($record_id);
} else {
$record = \media_Permalink_Adapter::challenge_token($app, $databox, $token, $record_id, $subdef);
if (!($record instanceof \record_adapter)) {
throw new NotFoundHttpException('Wrong token.');
}
}
return $record;
};
$deliverPermaview = function($sbas_id, $record_id, $token, $subdef, PhraseaApplication $app) use ($retrieveRecord) {
$databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id);
$record = \media_Permalink_Adapter::challenge_token($app, $databox, $token, $record_id, $subdef); $record = $retrieveRecord($app, $databox, $token, $record_id, $subdef);
if (!$record instanceof \record_adapter) {
throw new NotFoundHttpException('bad luck');
}
$params = array( $params = array(
'subdef_name' => $subdef 'subdef_name' => $subdef
@@ -51,13 +61,10 @@ class Permalink extends AbstractDelivery
return $app['twig']->render('overview.html.twig', $params); return $app['twig']->render('overview.html.twig', $params);
}; };
$deliverPermalink = function(PhraseaApplication $app, $sbas_id, $record_id, $token, $subdef) use ($that) { $deliverPermalink = function(PhraseaApplication $app, $sbas_id, $record_id, $token, $subdef) use ($that, $retrieveRecord) {
$databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id);
$record = \media_Permalink_Adapter::challenge_token($app, $databox, $token, $record_id, $subdef);
if (!($record instanceof \record_adapter)) { $record = $retrieveRecord($app, $databox, $token, $record_id, $subdef);
throw new NotFoundHttpException('bad luck');
}
$watermark = $stamp = false; $watermark = $stamp = false;
@@ -106,15 +113,11 @@ class Permalink extends AbstractDelivery
return $response; return $response;
}; };
$controllers->get('/v1/{sbas_id}/{record_id}/caption/', function(PhraseaApplication $app, Request $request, $sbas_id, $record_id) { $controllers->get('/v1/{sbas_id}/{record_id}/caption/', function(PhraseaApplication $app, Request $request, $sbas_id, $record_id) use ($retrieveRecord) {
$token = $request->query->get('token'); $token = $request->query->get('token');
$databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id);
$record = $retrieveRecord($app, $databox, $token, $record_id, \databox_subdef::CLASS_THUMBNAIL);
$record = \media_Permalink_Adapter::challenge_token($app, $databox, $token, $record_id, 'thumbnail');
if (null === $record) {
throw new NotFoundHttpException("Caption not found");
}
$caption = $record->get_caption(); $caption = $record->get_caption();
return new Response($caption->serialize(\caption_record::SERIALIZE_JSON), 200, array("Content-Type" => 'application/json')); return new Response($caption->serialize(\caption_record::SERIALIZE_JSON), 200, array("Content-Type" => 'application/json'));

View File

@@ -93,7 +93,7 @@ class Feed implements ControllerProviderInterface
$app['EM']->persist($feed); $app['EM']->persist($feed);
$app['EM']->flush(); $app['EM']->flush();
$app['events-manager']->trigger('__FEED_ENTRY_CREATE__', array('entry_id' => $entry->getId()), $entry); $app['events-manager']->trigger('__FEED_ENTRY_CREATE__', array('entry_id' => $entry->getId(), 'notify_email' => (Boolean) $request->request->get('notify')), $entry);
$datas = array('error' => false, 'message' => false); $datas = array('error' => false, 'message' => false);

View File

@@ -49,7 +49,22 @@ class Login implements ControllerProviderInterface
{ {
public static function getDefaultTemplateVariables(Application $app) public static function getDefaultTemplateVariables(Application $app)
{ {
$items = array();
foreach($app['EM']->getRepository('Entities\FeedItem')->loadLatest($app, 20) as $item) {
$record = $item->getRecord($app);
$preview = $record->get_subdef('preview');
$permalink = $preview->get_permalink();
$items[] = array(
'record' => $record,
'preview' => $preview,
'permalink' => $permalink
);
}
return array( return array(
'last_publication_items' => $items,
'instance_title' => $app['phraseanet.registry']->get('GV_homeTitle'), 'instance_title' => $app['phraseanet.registry']->get('GV_homeTitle'),
'has_terms_of_use' => $app->hasTermsOfUse(), 'has_terms_of_use' => $app->hasTermsOfUse(),
'meta_description' => $app['phraseanet.registry']->get('GV_metaDescription'), 'meta_description' => $app['phraseanet.registry']->get('GV_metaDescription'),

View File

@@ -2,6 +2,7 @@
namespace Repositories; namespace Repositories;
use Alchemy\Phrasea\Application;
use Doctrine\ORM\EntityRepository; use Doctrine\ORM\EntityRepository;
/** /**
@@ -12,4 +13,73 @@ use Doctrine\ORM\EntityRepository;
*/ */
class FeedItemRepository extends EntityRepository class FeedItemRepository extends EntityRepository
{ {
/**
* Checks if a record is published in a public feed.
*
* @param Application $app
* @param integer $sbas_id
* @param integer $record_id
*
* @return Boolean
*/
public function isRecordInPublicFeed(Application $app, $sbas_id, $record_id)
{
$dql = 'SELECT i
FROM Entities\FeedItem i
JOIN i.entry e
JOIN e.feed f
WHERE i.sbasId = :sbas_id
AND i.recordId = :record_id
AND f.public = true';
$query = $this->_em->createQuery($dql);
$query->setParameters(array('sbas_id' => $sbas_id, 'record_id' => $record_id));
return count($query->getResult()) > 0;
}
/**
* Gets latest items from public feeds.
*
* @param Application $app
* @param integer $nbItems
*
* @return FeedItem[] An array of FeedItem
*/
public function loadLatest(Application $app, $nbItems = 20)
{
$execution = 0;
$items = array();
do {
$dql = 'SELECT i
FROM Entities\FeedItem i
JOIN i.entry e
JOIN e.feed f
WHERE f.public = true ORDER BY i.createdOn DESC';
$query = $this->_em->createQuery($dql);
$query
->setFirstResult((integer) $nbItems * $execution)
->setMaxResults((integer) $nbItems);
$result = $query->getResult();
foreach($result as $item) {
if (null !== $preview = $item->getRecord($app)->get_subdef('preview')) {
if (null !== $permalink = $preview->get_permalink()) {
$items[] = $item;
if (count($items) >= $nbItems) {
break;
}
}
}
}
$execution++;
} while (count($items) < $nbItems && count($result) !== 0);
return $items;
}
} }

View File

@@ -119,6 +119,11 @@ class ACL implements cache_cacheableInterface
return $this; return $this;
} }
public function set_app(Application $app)
{
$this->app = $app;
}
/** /**
* Check if a hd grant has been received for a record * Check if a hd grant has been received for a record
* *
@@ -253,6 +258,10 @@ class ACL implements cache_cacheableInterface
$granted = true; $granted = true;
} }
if (false === $granted && $this->app['EM']->getRepository('Entities\FeedItem')->isRecordInPublicFeed($this->app, $record->get_sbas_id(), $record->get_record_id())) {
$granted = true;
}
return $granted; return $granted;
} }

View File

@@ -327,6 +327,8 @@ class User_Adapter implements User_Interface, cache_cacheableInterface
self::$_instance[$id] = new self($id, $app); self::$_instance[$id] = new self($id, $app);
$app['phraseanet.appbox']->set_data_to_cache(self::$_instance[$id], '_user_' . $id); $app['phraseanet.appbox']->set_data_to_cache(self::$_instance[$id], '_user_' . $id);
} }
} else {
self::$_instance[$id]->set_app($app);
} }
return array_key_exists($id, self::$_instance) ? self::$_instance[$id] : false; return array_key_exists($id, self::$_instance) ? self::$_instance[$id] : false;
@@ -349,6 +351,9 @@ class User_Adapter implements User_Interface, cache_cacheableInterface
protected function set_app(Application $app) protected function set_app(Application $app)
{ {
$this->app = $app; $this->app = $app;
if (null !== $this->ACL) {
$this->ACL->set_app($app);
}
} }
/** /**
@@ -1074,6 +1079,8 @@ class User_Adapter implements User_Interface, cache_cacheableInterface
} }
} }
$this->load_notifications_preferences($this->app);
return $this; return $this;
} }
@@ -1090,22 +1097,18 @@ class User_Adapter implements User_Interface, cache_cacheableInterface
} }
} }
} }
$this->notification_preferences_loaded = true;
} }
protected $notifications_preferences_loaded = false;
public function get_notifications_preference(Application $app, $notification_id) public function get_notifications_preference(Application $app, $notification_id)
{ {
if (!$this->notifications_preferences_loaded) $this->load_preferences($app);
$this->load_notifications_preferences($app);
return $this->_prefs['notification_' . $notification_id]; return isset($this->_prefs['notification_' . $notification_id]) ? $this->_prefs['notification_' . $notification_id] : null;
} }
public function set_notification_preference(Application $app, $notification_id, $value) public function set_notification_preference(Application $app, $notification_id, $value)
{ {
if (!$this->notifications_preferences_loaded) $this->load_preferences($app);
$this->load_notifications_preferences($app);
return $this->_prefs['notification_' . $notification_id] = $value ? '1' : '0'; return $this->_prefs['notification_' . $notification_id] = $value ? '1' : '0';
} }

View File

@@ -285,6 +285,7 @@ class databox_field implements cache_cacheableInterface
$databox->set_data_to_cache(self::$_instance[$instance_id], $cache_key); $databox->set_data_to_cache(self::$_instance[$instance_id], $cache_key);
} }
} }
self::$_instance[$instance_id]->app = $app;
return self::$_instance[$instance_id]; return self::$_instance[$instance_id];
} }

View File

@@ -45,7 +45,8 @@ class eventsmanager_notify_feed extends eventsmanager_notifyAbstract
public function fire($event, $params, &$entry) public function fire($event, $params, &$entry)
{ {
$params = array( $params = array(
'entry_id' => $entry->getId() 'entry_id' => $entry->getId(),
'notify_email' => $params['notify_email'],
); );
$dom_xml = new DOMDocument('1.0', 'UTF-8'); $dom_xml = new DOMDocument('1.0', 'UTF-8');
@@ -91,7 +92,7 @@ class eventsmanager_notify_feed extends eventsmanager_notifyAbstract
/* @var $user_to_notif \User_Adapter */ /* @var $user_to_notif \User_Adapter */
$mailed = false; $mailed = false;
if ($this->shouldSendNotificationFor($user_to_notif->get_id())) { if ($params['notify_email'] && $this->shouldSendNotificationFor($user_to_notif->get_id())) {
$readyToSend = false; $readyToSend = false;
try { try {
$token = $this->app['tokens']->getUrlToken( $token = $this->app['tokens']->getUrlToken(

View File

@@ -26,7 +26,7 @@ abstract class eventsmanager_notifyAbstract extends eventsmanager_eventAbstract
protected function get_prefs($class, $usr_id) protected function get_prefs($class, $usr_id)
{ {
$user = User_Adapter::getInstance($usr_id, $this->app); $user = User_Adapter::getInstance($usr_id, $this->app);
$pref = $user->getPrefs('notification_' . $class); $pref = $user->get_notifications_preference($this->app, $class);
return null !== $pref ? $pref : 1; return null !== $pref ? $pref : 1;
} }

View File

@@ -47,9 +47,7 @@ class LoadOneFeed extends AbstractFixture implements FixtureInterface
$feed->setTitle("test"); $feed->setTitle("test");
} }
if (isset($this->public) && $this->public !== null) { $feed->setIsPublic((Boolean) $this->public);
$feed->setIsPublic($this->public);
}
$feed->setSubtitle("description"); $feed->setSubtitle("description");

View File

@@ -348,7 +348,9 @@ return call_user_func_array(function(Application $app) {
'available' => array( 'available' => array(
'DISPLAYx1' => _('Single image'), 'DISPLAYx1' => _('Single image'),
'SCROLL' => _('Slide show'), 'SCROLL' => _('Slide show'),
'COOLIRIS' => 'Cooliris' 'COOLIRIS' => 'Cooliris',
'CAROUSEL' => _('Carousel'),
'GALLERIA' => _('Gallery')
), ),
'required' => true 'required' => true
) )

View File

@@ -0,0 +1,16 @@
<div id="carousel" class="carousel slide" style="height: 400px;">
{% set firstItem = true %}
<div class="carousel-inner">
{% for item in last_publication_items %}
<div class="{% if loop.first %}active {% endif %}item text-center">
<img src="{{ item['permalink'].get_url() }}" />
</div>
{% endfor %}
</div>
</div>
<script type="text/javascript">
require(["bootstrap"], function() {
$("#carousel").carousel();
});
</script>

View File

@@ -0,0 +1,25 @@
<div id="galleria" class="hidden">
{% for item in last_publication_items %}
<img src="{{ item['permalink'].get_url() }}" />
{% endfor %}
</div>
<script type="text/javascript">
requirejs.config({
paths: {
'galleria' : '../assets/jquery-galleria/src/galleria'
},
shim: {
'galleria': {
deps: ['jquery'],
exports: 'Galleria'
}
}
});
require(["jquery", "galleria"], function($, Galleria) {
Galleria.loadTheme('/assets/jquery-galleria/src/themes/classic/galleria.classic.js');
Galleria.run("#galleria");
$("#galleria").removeClass("hidden");
});
</script>

View File

@@ -123,9 +123,35 @@
{% include 'login/include/cooliris-content.html.twig' %} {% include 'login/include/cooliris-content.html.twig' %}
{% elseif display_layout == "SCROLL" %} {% elseif display_layout == "SCROLL" %}
{% include 'login/include/scroll-content.html.twig' %} {% include 'login/include/scroll-content.html.twig' %}
{% elseif display_layout == "CAROUSEL" %}
{% include 'login/include/carousel.html.twig' %}
{% elseif display_layout == "GALLERIA" %}
{% include 'login/include/galleria.html.twig' %}
{% endif %} {% endif %}
{% endblock %} {% endblock %}
{% block header_stylesheet %}
{{ parent() }}
{% if display_layout == "CAROUSEL" %}
<style type="text/css">
#carousel {
height: 400px;
}
#carousel .item img {
margin: 0 auto;
max-height: 400px;
}
</style>
{% elseif display_layout == "GALLERIA" %}
<style type="text/css">
#galleria {
height: 400px;
</style>
{% endif %}
{% endblock %}
{% block scripts %} {% block scripts %}
{{ parent() }} {{ parent() }}
<script type="text/javascript" src="{{ path('minifier', {'f': 'scripts/apps/login/home/login.js'}) }}"></script> <script type="text/javascript" src="{{ path('minifier', {'f': 'scripts/apps/login/home/login.js'}) }}"></script>

View File

@@ -39,6 +39,8 @@
{% set title = publishing.basket().getName() %} {% set title = publishing.basket().getName() %}
{% set desc = publishing.basket().getDescription() %} {% set desc = publishing.basket().getDescription() %}
{% endif %} {% endif %}
<input class="required_text checkbox" checked="checked" type="checkbox" name="notify" id="feed_add_notify" value="1" />
<label for="feed_add_notify">{% trans 'Notify users about this publication' %}</label><br/>
<label for="feed_add_title">{% trans 'publication : titre' %}</label> <label for="feed_add_title">{% trans 'publication : titre' %}</label>
<input class="required_text" type="text" name="title" id="feed_add_title" value="{{title}}" /> <input class="required_text" type="text" name="title" id="feed_add_title" value="{{title}}" />
<label for="feed_add_subtitle">{% trans 'publication : sous titre' %}</label> <label for="feed_add_subtitle">{% trans 'publication : sous titre' %}</label>
@@ -60,7 +62,7 @@
{% if feed.isPublic() %} {% if feed.isPublic() %}
<img src="/skins/icons/ligth-on.png" title="{% trans 'This feed is public' %}"/> <img src="/skins/icons/ligth-on.png" title="{% trans 'This feed is public' %}"/>
{% endif %} {% endif %}
<input type="hidden" value="{{ feed.getId() }}"/> <input type="hidden" name="feed_proposal[]" value="{{ feed.getId() }}"/>
</div> </div>
{% endif %} {% endif %}
{% endfor %} {% endfor %}

View File

@@ -2,7 +2,7 @@
namespace Alchemy\Tests\Phrasea\Application; namespace Alchemy\Tests\Phrasea\Application;
class ApplicationLightboxTest extends \PhraseanetWebTestCaseAuthenticatedAbstract class LightboxTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
{ {
protected $client; protected $client;
@@ -311,21 +311,24 @@ class ApplicationLightboxTest extends \PhraseanetWebTestCaseAuthenticatedAbstrac
$this->assertObjectHasAttribute('error', $datas); $this->assertObjectHasAttribute('error', $datas);
} }
public function testAjaxSetRelease() public function testAjaxSetReleaseWithRegularBasket()
{ {
$basket = $this->insertOneBasket(); $basket = $this->insertOneBasket();
$this->mockNotificationDeliverer('Alchemy\Phrasea\Notification\Mail\MailInfoValidationDone');
$crawler = self::$DI['client']->request('POST', '/lightbox/ajax/SET_RELEASE/' . $basket->getId() . '/'); $crawler = self::$DI['client']->request('POST', '/lightbox/ajax/SET_RELEASE/' . $basket->getId() . '/');
$this->assertEquals(200, self::$DI['client']->getResponse()->getStatusCode()); $this->assertEquals(200, self::$DI['client']->getResponse()->getStatusCode());
$this->assertEquals('application/json', self::$DI['client']->getResponse()->headers->get('Content-type')); $this->assertEquals('application/json', self::$DI['client']->getResponse()->headers->get('Content-type'));
$datas = json_decode(self::$DI['client']->getResponse()->getContent()); $datas = json_decode(self::$DI['client']->getResponse()->getContent());
$this->assertTrue(is_object($datas), 'asserting good json datas'); $this->assertTrue(is_object($datas), 'asserting good json datas');
$this->assertTrue($datas->error); $this->assertTrue($datas->error);
}
public function testAjaxSetReleaseWithRegularBasketWithValidation()
{
$validationBasket = $this->insertOneValidationBasket(); $validationBasket = $this->insertOneValidationBasket();
$this->mockNotificationDeliverer('Alchemy\Phrasea\Notification\Mail\MailInfoValidationDone');
foreach ($validationBasket->getElements() as $element) { foreach ($validationBasket->getElements() as $element) {
$element->getUserValidationDatas(self::$DI['app']['authentication']->getUser(), self::$DI['app'])->setAgreement(true); $element->getUserValidationDatas(self::$DI['app']['authentication']->getUser(), self::$DI['app'])->setAgreement(true);
break; break;

View File

@@ -5,7 +5,7 @@ namespace Alchemy\Tests\Phrasea\Application;
use Alchemy\Phrasea\Border\File; use Alchemy\Phrasea\Border\File;
use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\File\UploadedFile;
class ApplicationOverviewTest extends \PhraseanetWebTestCaseAuthenticatedAbstract class OverviewTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
{ {
public function testDatafilesRouteAuthenticated() public function testDatafilesRouteAuthenticated()
{ {
@@ -61,6 +61,25 @@ class ApplicationOverviewTest extends \PhraseanetWebTestCaseAuthenticatedAbstrac
$this->assertForbiddenResponse(self::$DI['client']->getResponse()); $this->assertForbiddenResponse(self::$DI['client']->getResponse());
} }
public function testDatafilesRouteOnUnaccessibleRecordIsOkInPublicFeed()
{
$tmp = tempnam(sys_get_temp_dir(), 'testEtag');
copy(__DIR__ . '/../../../../files/cestlafete.jpg', $tmp);
$media = self::$DI['app']['mediavorus']->guess($tmp);
$file = new File(self::$DI['app'], $media, self::$DI['collection_no_access']);
$record = \record_adapter::createFromFile($file, self::$DI['app']);
$record->generate_subdefs($record->get_databox(), self::$DI['app']);
$item = $this->insertOneFeedItem(self::$DI['user'], true, 1, $record);
self::$DI['client']->request('GET', '/datafiles/' . $record->get_sbas_id() . '/' . $record->get_record_id() . '/preview/');
$this->assertEquals(200, self::$DI['client']->getResponse()->getStatusCode());
unlink($tmp);
}
public function testDatafilesRouteNotAuthenticatedUnknownSubdef() public function testDatafilesRouteNotAuthenticatedUnknownSubdef()
{ {
self::$DI['app']['authentication']->closeAccount(); self::$DI['app']['authentication']->closeAccount();
@@ -189,6 +208,16 @@ class ApplicationOverviewTest extends \PhraseanetWebTestCaseAuthenticatedAbstrac
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
} }
public function testPermalinkRouteNotAuthenticatedIsOkInPublicFeed()
{
$record = $this->insertOneFeedItem(self::$DI['user'], true)->getRecord(self::$DI['app']);
self::$DI['app']['authentication']->closeAccount();
self::$DI['client']->request('GET', '/permalink/v1/' . $record->get_sbas_id() . '/' . $record->get_record_id() . '/preview/');
$this->assertEquals(200, self::$DI['client']->getResponse()->getStatusCode());
}
protected function get_a_permaviewBCcompatibility(array $headers = array()) protected function get_a_permaviewBCcompatibility(array $headers = array())
{ {
$token = self::$DI['record_1']->get_preview()->get_permalink()->get_token(); $token = self::$DI['record_1']->get_preview()->get_permalink()->get_token();

View File

@@ -28,7 +28,7 @@ class FeedTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$feeds = self::$DI['app']['EM']->getRepository('Entities\Feed')->getAllForUser(self::$DI['user']); $feeds = self::$DI['app']['EM']->getRepository('Entities\Feed')->getAllForUser(self::$DI['user']);
foreach ($feeds as $one_feed) { foreach ($feeds as $one_feed) {
if ($one_feed->isPublisher(self::$DI['user'])) { if ($one_feed->isPublisher(self::$DI['user'])) {
$this->assertEquals(1, $crawler->filterXPath("//input[@value='" . $one_feed->getId() . "']")->count()); $this->assertEquals(1, $crawler->filterXPath("//input[@value='" . $one_feed->getId() . "' and @name='feed_proposal[]']")->count());
} }
} }
} }
@@ -46,6 +46,7 @@ class FeedTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$feed = $this->insertOneFeed(self::$DI['user']); $feed = $this->insertOneFeed(self::$DI['user']);
$params = array( $params = array(
"feed_id" => $feed->getId() "feed_id" => $feed->getId()
, "notify" => 1
, "title" => "salut" , "title" => "salut"
, "subtitle" => "coucou" , "subtitle" => "coucou"
, "author_name" => "robert" , "author_name" => "robert"

View File

@@ -14,7 +14,7 @@ main:
driver: pdo_sqlite driver: pdo_sqlite
path: '/tmp/db.sqlite' path: '/tmp/db.sqlite'
charset: UTF8 charset: UTF8
api-timers: true api-timers: false
cache: cache:
type: MemcacheCache type: MemcacheCache
options: options:

View File

@@ -14,7 +14,7 @@ main:
driver: pdo_sqlite driver: pdo_sqlite
path: '/tmp/db.sqlite' path: '/tmp/db.sqlite'
charset: UTF8 charset: UTF8
api-timers: true api-timers: false
cache: cache:
type: MemcacheCache type: MemcacheCache
options: options:

View File

@@ -6,6 +6,9 @@ use Alchemy\Phrasea\Border\File;
use Doctrine\Common\DataFixtures\Loader; use Doctrine\Common\DataFixtures\Loader;
use Entities\AggregateToken; use Entities\AggregateToken;
use Entities\Feed; use Entities\Feed;
use Entities\FeedEntry;
use Entities\FeedItem;
use Entities\FeedPublisher;
use Entities\FeedToken; use Entities\FeedToken;
use Entities\User; use Entities\User;
use Silex\WebTestCase; use Silex\WebTestCase;
@@ -360,10 +363,10 @@ abstract class PhraseanetPHPUnitAbstract extends WebTestCase
* *
* @return \Entities\FeedEntry * @return \Entities\FeedEntry
*/ */
protected function insertOneFeedEntry(\User_Adapter $user) protected function insertOneFeedEntry(\User_Adapter $user, $public = false)
{ {
try { try {
$feed = $this->insertOneFeed($user); $feed = $this->insertOneFeed($user, '', $public);
$em = self::$DI['app']['EM']; $em = self::$DI['app']['EM'];
@@ -433,22 +436,31 @@ abstract class PhraseanetPHPUnitAbstract extends WebTestCase
* *
* @return \Entities\FeedItem * @return \Entities\FeedItem
*/ */
protected function insertOneFeedItem(\User_Adapter $user) protected function insertOneFeedItem(\User_Adapter $user, $public = false, $qty = 1, \record_adapter $record = null)
{ {
try { try {
$entry = $this->insertOneFeedEntry($user);
$item = new \Entities\FeedItem();
$item->setEntry($entry);
$item->setRecordId(self::$DI['record_1']->get_record_id());
$item->setSbasId(self::$DI['record_1']->get_sbas_id());
$entry->addItem($item);
$em = self::$DI['app']['EM']; $em = self::$DI['app']['EM'];
$entry = $this->insertOneFeedEntry($user, $public);
for ($i = 0; $i < $qty; $i++) {
$item = new \Entities\FeedItem();
$item->setEntry($entry);
if (null === $record) {
$actual = self::$DI['record_'.($i+1)];
} else {
$actual = $record;
}
$item->setRecordId($actual->get_record_id());
$item->setSbasId($actual->get_sbas_id());
$item->setEntry($entry);
$entry->addItem($item);
$em->persist($item);
}
$em->persist($entry); $em->persist($entry);
$em->persist($item);
$em->flush(); $em->flush();
} catch (\Exception $e) { } catch (\Exception $e) {

View File

@@ -3203,6 +3203,14 @@ dans l'onglet thesaurus : arbres, menus contextuels
margin: 3px 0 10px 0; margin: 3px 0 10px 0;
} }
#modal_feed form label {
display:inline;
}
#modal_feed form input.checkbox {
width: 20px;
}
#modal_feed form textarea { #modal_feed form textarea {
height: 60px; height: 60px;
resize: none; resize: none;

View File

@@ -3283,6 +3283,14 @@ dans l'onglet thesaurus : arbres, menus contextuels
margin: 3px 0 10px 0; margin: 3px 0 10px 0;
} }
#modal_feed form label {
display:inline;
}
#modal_feed form input.checkbox {
width: 20px;
}
#modal_feed form textarea { #modal_feed form textarea {
height: 60px; height: 60px;
resize: none; resize: none;