Merge branch '3.8'

Conflicts:
	composer.lock
	lib/Alchemy/Phrasea/Application.php
	lib/classes/Feed/Entry/Item.php
	tests/classes/Feed/Entry/Feed_Entry_ItemTest.php
This commit is contained in:
Romain Neutron
2013-10-28 18:21:15 +01:00
10 changed files with 222 additions and 40 deletions

View File

@@ -37,7 +37,7 @@
"symfony/symfony" : "2.4.x-dev@dev", "symfony/symfony" : "2.4.x-dev@dev",
"alchemy-fr/tcpdf-clone" : "~6.0", "alchemy-fr/tcpdf-clone" : "~6.0",
"themattharris/tmhoauth" : "~0.7", "themattharris/tmhoauth" : "~0.7",
"twig/twig" : "~1.12", "twig/twig" : "~1.13.0",
"twig/extensions" : "~1.0", "twig/extensions" : "~1.0",
"zend/gdata" : "~1.12.1" "zend/gdata" : "~1.12.1"
}, },

52
composer.lock generated
View File

@@ -3,7 +3,7 @@
"This file locks the dependencies of your project to a known state", "This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
], ],
"hash": "5e87a9e3f046e1b4ee9795d6b213d1a5", "hash": "684aeefa47272d816be20c930dc3d664",
"packages": [ "packages": [
{ {
"name": "alchemy-fr/tcpdf-clone", "name": "alchemy-fr/tcpdf-clone",
@@ -443,16 +443,16 @@
}, },
{ {
"name": "doctrine/cache", "name": "doctrine/cache",
"version": "v1.2.0", "version": "v1.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/doctrine/cache.git", "url": "https://github.com/doctrine/cache.git",
"reference": "d0e4447707a064a5814b18cb0dcc2f24185f6179" "reference": "e16d7adf45664a50fa86f515b6d5e7f670130449"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/doctrine/cache/zipball/d0e4447707a064a5814b18cb0dcc2f24185f6179", "url": "https://api.github.com/repos/doctrine/cache/zipball/e16d7adf45664a50fa86f515b6d5e7f670130449",
"reference": "d0e4447707a064a5814b18cb0dcc2f24185f6179", "reference": "e16d7adf45664a50fa86f515b6d5e7f670130449",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -461,6 +461,10 @@
"conflict": { "conflict": {
"doctrine/common": ">2.2,<2.4" "doctrine/common": ">2.2,<2.4"
}, },
"require-dev": {
"phpunit/phpunit": ">=3.7",
"satooshi/php-coveralls": "~0.6"
},
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
@@ -508,7 +512,7 @@
"cache", "cache",
"caching" "caching"
], ],
"time": "2013-09-26 19:23:25" "time": "2013-10-25 19:04:14"
}, },
{ {
"name": "doctrine/collections", "name": "doctrine/collections",
@@ -1160,12 +1164,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/avalanche123/Imagine.git", "url": "https://github.com/avalanche123/Imagine.git",
"reference": "bae39d07a8f56ff21ca773a6b4e1ed2ab13b1c03" "reference": "237ccf205dd5ece7a00a574b4f18bd118aa08a5d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/avalanche123/Imagine/zipball/bae39d07a8f56ff21ca773a6b4e1ed2ab13b1c03", "url": "https://api.github.com/repos/avalanche123/Imagine/zipball/237ccf205dd5ece7a00a574b4f18bd118aa08a5d",
"reference": "bae39d07a8f56ff21ca773a6b4e1ed2ab13b1c03", "reference": "237ccf205dd5ece7a00a574b4f18bd118aa08a5d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1209,7 +1213,7 @@
"image manipulation", "image manipulation",
"image processing" "image processing"
], ],
"time": "2013-10-10 08:13:00" "time": "2013-10-26 10:53:02"
}, },
{ {
"name": "jms/metadata", "name": "jms/metadata",
@@ -2397,12 +2401,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/fabpot/Silex.git", "url": "https://github.com/fabpot/Silex.git",
"reference": "bc673b478ec276217305f6a81c8aeafb0f9ffe63" "reference": "c60a10bf93f5a91b24672c7f80670d235f19acc3"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/fabpot/Silex/zipball/bc673b478ec276217305f6a81c8aeafb0f9ffe63", "url": "https://api.github.com/repos/fabpot/Silex/zipball/c60a10bf93f5a91b24672c7f80670d235f19acc3",
"reference": "bc673b478ec276217305f6a81c8aeafb0f9ffe63", "reference": "c60a10bf93f5a91b24672c7f80670d235f19acc3",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2473,7 +2477,7 @@
"keywords": [ "keywords": [
"microframework" "microframework"
], ],
"time": "2013-10-16 17:53:18" "time": "2013-10-28 09:44:08"
}, },
{ {
"name": "silex/web-profiler", "name": "silex/web-profiler",
@@ -2677,12 +2681,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/symfony.git", "url": "https://github.com/symfony/symfony.git",
"reference": "1206176fc40eb22b00cb2419de3f832c9afecb76" "reference": "d866a5acc45426f3c48c82b7cedb985d9e24568c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/symfony/zipball/1206176fc40eb22b00cb2419de3f832c9afecb76", "url": "https://api.github.com/repos/symfony/symfony/zipball/d866a5acc45426f3c48c82b7cedb985d9e24568c",
"reference": "1206176fc40eb22b00cb2419de3f832c9afecb76", "reference": "d866a5acc45426f3c48c82b7cedb985d9e24568c",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2782,7 +2786,7 @@
"keywords": [ "keywords": [
"framework" "framework"
], ],
"time": "2013-10-18 15:01:47" "time": "2013-10-28 14:29:55"
}, },
{ {
"name": "themattharris/tmhoauth", "name": "themattharris/tmhoauth",
@@ -2875,16 +2879,16 @@
}, },
{ {
"name": "twig/twig", "name": "twig/twig",
"version": "v1.14.1", "version": "v1.13.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/fabpot/Twig.git", "url": "https://github.com/fabpot/Twig.git",
"reference": "8873d7593ad7c120004f177c0fd01459b383c9cb" "reference": "6d6a1009427d1f398c9d40904147bf9f723d5755"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/fabpot/Twig/zipball/8873d7593ad7c120004f177c0fd01459b383c9cb", "url": "https://api.github.com/repos/fabpot/Twig/zipball/6d6a1009427d1f398c9d40904147bf9f723d5755",
"reference": "8873d7593ad7c120004f177c0fd01459b383c9cb", "reference": "6d6a1009427d1f398c9d40904147bf9f723d5755",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2893,7 +2897,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.14-dev" "dev-master": "1.13-dev"
} }
}, },
"autoload": { "autoload": {
@@ -2920,7 +2924,7 @@
"keywords": [ "keywords": [
"templating" "templating"
], ],
"time": "2013-10-15 19:17:38" "time": "2013-08-03 15:35:31"
}, },
{ {
"name": "zend/gdata", "name": "zend/gdata",

View File

@@ -94,6 +94,7 @@ use Alchemy\Phrasea\Core\Provider\ManipulatorServiceProvider;
use Alchemy\Phrasea\Core\Provider\NotificationDelivererServiceProvider; use Alchemy\Phrasea\Core\Provider\NotificationDelivererServiceProvider;
use Alchemy\Phrasea\Core\Provider\ORMServiceProvider; use Alchemy\Phrasea\Core\Provider\ORMServiceProvider;
use Alchemy\Phrasea\Core\Provider\PhraseanetServiceProvider; use Alchemy\Phrasea\Core\Provider\PhraseanetServiceProvider;
use Alchemy\Phrasea\Core\Provider\PluginServiceProvider;
use Alchemy\Phrasea\Core\Provider\PhraseaVersionServiceProvider; use Alchemy\Phrasea\Core\Provider\PhraseaVersionServiceProvider;
use Alchemy\Phrasea\Core\Provider\RegistrationServiceProvider; use Alchemy\Phrasea\Core\Provider\RegistrationServiceProvider;
use Alchemy\Phrasea\Core\Provider\SearchEngineServiceProvider; use Alchemy\Phrasea\Core\Provider\SearchEngineServiceProvider;
@@ -202,7 +203,6 @@ class Application extends SilexApplication
$this->register(new ImagineServiceProvider()); $this->register(new ImagineServiceProvider());
$this->register(new JMSSerializerServiceProvider()); $this->register(new JMSSerializerServiceProvider());
$this->register(new FFMpegServiceProvider()); $this->register(new FFMpegServiceProvider());
$this->register(new FeedServiceProvider());
$this->register(new FilesystemServiceProvider()); $this->register(new FilesystemServiceProvider());
$this->register(new FtpServiceProvider()); $this->register(new FtpServiceProvider());
$this->register(new GeonamesServiceProvider()); $this->register(new GeonamesServiceProvider());
@@ -298,6 +298,7 @@ class Application extends SilexApplication
$this->register(new XPDFServiceProvider()); $this->register(new XPDFServiceProvider());
$this->register(new FileServeServiceProvider()); $this->register(new FileServeServiceProvider());
$this->register(new ManipulatorServiceProvider()); $this->register(new ManipulatorServiceProvider());
$this->register(new PluginServiceProvider());
$this['phraseanet.exception_handler'] = $this->share(function ($app) { $this['phraseanet.exception_handler'] = $this->share(function ($app) {
return PhraseaExceptionHandler::register($app['debug']); return PhraseaExceptionHandler::register($app['debug']);

View File

@@ -83,13 +83,5 @@ class PluginServiceProvider implements ServiceProviderInterface
public function boot(Application $app) public function boot(Application $app)
{ {
$app['twig'] = $app->share(
$app->extend('twig', function($twig, Application $app){
$function = new \Twig_SimpleFunction('plugin_asset', array('Alchemy\Phrasea\Plugin\Management\AssetsManager', 'twigPluginAsset'));
$twig->addFunction($function);
return $twig;
})
);
} }
} }

View File

@@ -0,0 +1,34 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Core\Provider;
use Silex\Application;
use Silex\ServiceProviderInterface;
class PluginServiceProvider implements ServiceProviderInterface
{
public function register(Application $app)
{
}
public function boot(Application $app)
{
$app['twig'] = $app->share(
$app->extend('twig', function($twig, Application $app){
$function = new \Twig_SimpleFunction('plugin_asset', array('Alchemy\Phrasea\Plugin\Management\AssetsManager', 'twigPluginAsset'));
$twig->addFunction($function);
return $twig;
})
);
}
}

View File

@@ -4,6 +4,7 @@ namespace Repositories;
use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Application;
use Doctrine\ORM\EntityRepository; use Doctrine\ORM\EntityRepository;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/** /**
* FeedItemRepository * FeedItemRepository
@@ -66,7 +67,17 @@ class FeedItemRepository extends EntityRepository
$result = $query->getResult(); $result = $query->getResult();
foreach($result as $item) { foreach($result as $item) {
if (null !== $preview = $item->getRecord($app)->get_subdef('preview')) { try {
$record = $item->getRecord($app);
} catch (NotFoundHttpException $e) {
$app['EM']->remove($item);
continue;
} catch (\Exception_Record_AdapterNotFound $e) {
$app['EM']->remove($item);
continue;
}
if (null !== $preview = $record->get_subdef('preview')) {
if (null !== $permalink = $preview->get_permalink()) { if (null !== $permalink = $preview->get_permalink()) {
$items[] = $item; $items[] = $item;
@@ -77,6 +88,7 @@ class FeedItemRepository extends EntityRepository
} }
} }
$app['EM']->flush();
$execution++; $execution++;
} while (count($items) < $nbItems && count($result) !== 0); } while (count($items) < $nbItems && count($result) !== 0);

View File

@@ -104,12 +104,12 @@ class caption_record implements caption_interface, cache_cacheableInterface
$buffer[$field->get_name()] = array(); $buffer[$field->get_name()] = array();
foreach ($vi as $value) { foreach ($vi as $value) {
$val = $value->getValue(); $val = $value->getValue();
$buffer[$field->get_name()][] = ctype_digit($val) ? (int) $val : $val; $buffer[$field->get_name()][] = ctype_digit($val) ? (int) $val : $this->sanitizeSerializedValue($val);
} }
} else { } else {
$value = array_pop($vi); $value = array_pop($vi);
$val = $value->getValue(); $val = $value->getValue();
$buffer[$field->get_name()] = ctype_digit($val) ? (int) $val : $val; $buffer[$field->get_name()] = ctype_digit($val) ? (int) $val : $this->sanitizeSerializedValue($val);
} }
} }
@@ -133,7 +133,7 @@ class caption_record implements caption_interface, cache_cacheableInterface
foreach ($values as $value) { foreach ($values as $value) {
$elem = $dom_doc->createElement($field->get_name()); $elem = $dom_doc->createElement($field->get_name());
$elem->appendChild($dom_doc->createTextNode($value->getValue())); $elem->appendChild($dom_doc->createTextNode($this->sanitizeSerializedValue($value->getValue())));
$elem->setAttribute('meta_id', $value->getId()); $elem->setAttribute('meta_id', $value->getId());
$elem->setAttribute('meta_struct_id', $field->get_meta_struct_id()); $elem->setAttribute('meta_struct_id', $field->get_meta_struct_id());
$description->appendChild($elem); $description->appendChild($elem);
@@ -153,6 +153,40 @@ class caption_record implements caption_interface, cache_cacheableInterface
return $dom_doc->saveXML(); return $dom_doc->saveXML();
} }
private function sanitizeSerializedValue($value)
{
return str_replace(array(
"\x00", //null
"\x01", //start heading
"\x02", //start text
"\x03", //end of text
"\x04", //end of transmission
"\x05", //enquiry
"\x06", //acknowledge
"\x07", //bell
"\x08", //backspace
"\x0C", //new page
"\x0E", //shift out
"\x0F", //shift in
"\x10", //data link escape
"\x11", //dc 1
"\x12", //dc 2
"\x13", //dc 3
"\x14", //dc 4
"\x15", //negative ack
"\x16", //synchronous idle
"\x17", //end of trans block
"\x18", //cancel
"\x19", //end of medium
"\x1A", //substitute
"\x1B", //escape
"\x1C", //file separator
"\x1D", //group sep
"\x1E", //record sep
"\x1F", //unit sep
), '', $value);
}
protected function retrieve_fields() protected function retrieve_fields()
{ {
if (is_array($this->fields)) { if (is_array($this->fields)) {

View File

@@ -0,0 +1,69 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2012 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Alchemy\Phrasea\Application;
use Symfony\Component\Process\ExecutableFinder;
class patch_3820 implements patchInterface
{
/** @var string */
private $release = '3.8.1';
/** @var array */
private $concern = array(base::DATA_BOX);
/**
* {@inheritdoc}
*/
public function get_release()
{
return $this->release;
}
/**
* {@inheritdoc}
*/
public function require_all_upgrades()
{
return false;
}
/**
* {@inheritdoc}
*/
public function concern()
{
return $this->concern;
}
/**
* {@inheritdoc}
*/
public function apply(base $databox, Application $app)
{
$sql = "SHOW INDEX FROM metadatas_structure WHERE KEY_NAME = 'sorter'";
$stmt = $databox->get_connection()->prepare($sql);
$stmt->execute();
$rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);
$stmt->closeCursor();
if (count($rows) === 0) {
return true;
}
$sql = "DROP INDEX sorter ON metadatas_structure";
$stmt = $databox->get_connection()->prepare($sql);
$stmt->execute();
$stmt->closeCursor();
return true;
}
}

View File

@@ -246,7 +246,6 @@
<button type="button" class="close_button btn btn-inverse">{% trans 'boutton::annuler'%}</button> <button type="button" class="close_button btn btn-inverse">{% trans 'boutton::annuler'%}</button>
</div> </div>
</form> </form>
<iframe style="display:none;" name="sendmail_target"></iframe>
</div> </div>
</div> </div>
{% endif %} {% endif %}
@@ -798,8 +797,13 @@
if (!check_TOU($('#sendmail'))) { if (!check_TOU($('#sendmail'))) {
return false; return false;
} }
dialog.Close();
if ($('iframe[name=""]').length === 0) {
$('body').append('<iframe style="display:none;" name="sendmail_target"></iframe>');
}
$('#sendmail form').submit(); $('#sendmail form').submit();
dialog.Close();
}); });
$('.datepicker', dialog.getDomElement()).datepicker({ $('.datepicker', dialog.getDomElement()).datepicker({

View File

@@ -38,4 +38,36 @@ class FeedItemRepositoryTest extends \PhraseanetPHPUnitAbstract
$this->insertOneFeedItem(self::$DI['user'], false, 2); $this->insertOneFeedItem(self::$DI['user'], false, 2);
$this->assertCount(0, self::$DI['app']['EM']->getRepository('Entities\FeedItem')->loadLatest(self::$DI['app'], 20)); $this->assertCount(0, self::$DI['app']['EM']->getRepository('Entities\FeedItem')->loadLatest(self::$DI['app'], 20));
} }
public function testLoadLatestWithDeletedDatabox()
{
$record = $this->getMockBuilder('record_adapter')
->disableOriginalConstructor()
->getMock();
$record->expects($this->any())
->method('get_sbas_id')
->will($this->returnValue(0));
$record->expects($this->any())
->method('get_record_id')
->will($this->returnValue(self::$DI['record_1']->get_record_id()));
$this->insertOneFeedItem(self::$DI['user'], true, 1, $record);
$this->assertCount(0, self::$DI['app']['EM']->getRepository('Entities\FeedItem')->loadLatest(self::$DI['app'], 20));
}
public function testLoadLatestWithDeletedRecord()
{
$record = $this->getMockBuilder('record_adapter')
->disableOriginalConstructor()
->getMock();
$record->expects($this->any())
->method('get_sbas_id')
->will($this->returnValue(self::$DI['record_1']->get_sbas_id()));
$record->expects($this->any())
->method('get_record_id')
->will($this->returnValue(0));
$this->insertOneFeedItem(self::$DI['user'], true, 1, $record);
$this->assertCount(0, self::$DI['app']['EM']->getRepository('Entities\FeedItem')->loadLatest(self::$DI['app'], 20));
}
} }