diff --git a/composer.json b/composer.json index 9ea257b717..38780390e2 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,7 @@ "symfony/symfony" : "2.4.x-dev@dev", "alchemy-fr/tcpdf-clone" : "~6.0", "themattharris/tmhoauth" : "~0.7", - "twig/twig" : "~1.12", + "twig/twig" : "~1.13.0", "twig/extensions" : "~1.0", "zend/gdata" : "~1.12.1" }, diff --git a/composer.lock b/composer.lock index acf5e8e88e..490cfc5f6d 100644 --- a/composer.lock +++ b/composer.lock @@ -3,7 +3,7 @@ "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" ], - "hash": "5e87a9e3f046e1b4ee9795d6b213d1a5", + "hash": "684aeefa47272d816be20c930dc3d664", "packages": [ { "name": "alchemy-fr/tcpdf-clone", @@ -443,16 +443,16 @@ }, { "name": "doctrine/cache", - "version": "v1.2.0", + "version": "v1.3.0", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "d0e4447707a064a5814b18cb0dcc2f24185f6179" + "reference": "e16d7adf45664a50fa86f515b6d5e7f670130449" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/d0e4447707a064a5814b18cb0dcc2f24185f6179", - "reference": "d0e4447707a064a5814b18cb0dcc2f24185f6179", + "url": "https://api.github.com/repos/doctrine/cache/zipball/e16d7adf45664a50fa86f515b6d5e7f670130449", + "reference": "e16d7adf45664a50fa86f515b6d5e7f670130449", "shasum": "" }, "require": { @@ -461,6 +461,10 @@ "conflict": { "doctrine/common": ">2.2,<2.4" }, + "require-dev": { + "phpunit/phpunit": ">=3.7", + "satooshi/php-coveralls": "~0.6" + }, "type": "library", "extra": { "branch-alias": { @@ -508,7 +512,7 @@ "cache", "caching" ], - "time": "2013-09-26 19:23:25" + "time": "2013-10-25 19:04:14" }, { "name": "doctrine/collections", @@ -1160,12 +1164,12 @@ "source": { "type": "git", "url": "https://github.com/avalanche123/Imagine.git", - "reference": "bae39d07a8f56ff21ca773a6b4e1ed2ab13b1c03" + "reference": "237ccf205dd5ece7a00a574b4f18bd118aa08a5d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/avalanche123/Imagine/zipball/bae39d07a8f56ff21ca773a6b4e1ed2ab13b1c03", - "reference": "bae39d07a8f56ff21ca773a6b4e1ed2ab13b1c03", + "url": "https://api.github.com/repos/avalanche123/Imagine/zipball/237ccf205dd5ece7a00a574b4f18bd118aa08a5d", + "reference": "237ccf205dd5ece7a00a574b4f18bd118aa08a5d", "shasum": "" }, "require": { @@ -1209,7 +1213,7 @@ "image manipulation", "image processing" ], - "time": "2013-10-10 08:13:00" + "time": "2013-10-26 10:53:02" }, { "name": "jms/metadata", @@ -2397,12 +2401,12 @@ "source": { "type": "git", "url": "https://github.com/fabpot/Silex.git", - "reference": "bc673b478ec276217305f6a81c8aeafb0f9ffe63" + "reference": "c60a10bf93f5a91b24672c7f80670d235f19acc3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fabpot/Silex/zipball/bc673b478ec276217305f6a81c8aeafb0f9ffe63", - "reference": "bc673b478ec276217305f6a81c8aeafb0f9ffe63", + "url": "https://api.github.com/repos/fabpot/Silex/zipball/c60a10bf93f5a91b24672c7f80670d235f19acc3", + "reference": "c60a10bf93f5a91b24672c7f80670d235f19acc3", "shasum": "" }, "require": { @@ -2473,7 +2477,7 @@ "keywords": [ "microframework" ], - "time": "2013-10-16 17:53:18" + "time": "2013-10-28 09:44:08" }, { "name": "silex/web-profiler", @@ -2677,12 +2681,12 @@ "source": { "type": "git", "url": "https://github.com/symfony/symfony.git", - "reference": "1206176fc40eb22b00cb2419de3f832c9afecb76" + "reference": "d866a5acc45426f3c48c82b7cedb985d9e24568c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/symfony/zipball/1206176fc40eb22b00cb2419de3f832c9afecb76", - "reference": "1206176fc40eb22b00cb2419de3f832c9afecb76", + "url": "https://api.github.com/repos/symfony/symfony/zipball/d866a5acc45426f3c48c82b7cedb985d9e24568c", + "reference": "d866a5acc45426f3c48c82b7cedb985d9e24568c", "shasum": "" }, "require": { @@ -2782,7 +2786,7 @@ "keywords": [ "framework" ], - "time": "2013-10-18 15:01:47" + "time": "2013-10-28 14:29:55" }, { "name": "themattharris/tmhoauth", @@ -2875,16 +2879,16 @@ }, { "name": "twig/twig", - "version": "v1.14.1", + "version": "v1.13.2", "source": { "type": "git", "url": "https://github.com/fabpot/Twig.git", - "reference": "8873d7593ad7c120004f177c0fd01459b383c9cb" + "reference": "6d6a1009427d1f398c9d40904147bf9f723d5755" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fabpot/Twig/zipball/8873d7593ad7c120004f177c0fd01459b383c9cb", - "reference": "8873d7593ad7c120004f177c0fd01459b383c9cb", + "url": "https://api.github.com/repos/fabpot/Twig/zipball/6d6a1009427d1f398c9d40904147bf9f723d5755", + "reference": "6d6a1009427d1f398c9d40904147bf9f723d5755", "shasum": "" }, "require": { @@ -2893,7 +2897,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.14-dev" + "dev-master": "1.13-dev" } }, "autoload": { @@ -2920,7 +2924,7 @@ "keywords": [ "templating" ], - "time": "2013-10-15 19:17:38" + "time": "2013-08-03 15:35:31" }, { "name": "zend/gdata", diff --git a/lib/Alchemy/Phrasea/Application.php b/lib/Alchemy/Phrasea/Application.php index e424656745..0667920376 100644 --- a/lib/Alchemy/Phrasea/Application.php +++ b/lib/Alchemy/Phrasea/Application.php @@ -94,6 +94,7 @@ use Alchemy\Phrasea\Core\Provider\ManipulatorServiceProvider; use Alchemy\Phrasea\Core\Provider\NotificationDelivererServiceProvider; use Alchemy\Phrasea\Core\Provider\ORMServiceProvider; use Alchemy\Phrasea\Core\Provider\PhraseanetServiceProvider; +use Alchemy\Phrasea\Core\Provider\PluginServiceProvider; use Alchemy\Phrasea\Core\Provider\PhraseaVersionServiceProvider; use Alchemy\Phrasea\Core\Provider\RegistrationServiceProvider; use Alchemy\Phrasea\Core\Provider\SearchEngineServiceProvider; @@ -202,7 +203,6 @@ class Application extends SilexApplication $this->register(new ImagineServiceProvider()); $this->register(new JMSSerializerServiceProvider()); $this->register(new FFMpegServiceProvider()); - $this->register(new FeedServiceProvider()); $this->register(new FilesystemServiceProvider()); $this->register(new FtpServiceProvider()); $this->register(new GeonamesServiceProvider()); @@ -298,6 +298,7 @@ class Application extends SilexApplication $this->register(new XPDFServiceProvider()); $this->register(new FileServeServiceProvider()); $this->register(new ManipulatorServiceProvider()); + $this->register(new PluginServiceProvider()); $this['phraseanet.exception_handler'] = $this->share(function ($app) { return PhraseaExceptionHandler::register($app['debug']); diff --git a/lib/Alchemy/Phrasea/Core/CLIProvider/PluginServiceProvider.php b/lib/Alchemy/Phrasea/Core/CLIProvider/PluginServiceProvider.php index 8819cbba2d..795c141609 100644 --- a/lib/Alchemy/Phrasea/Core/CLIProvider/PluginServiceProvider.php +++ b/lib/Alchemy/Phrasea/Core/CLIProvider/PluginServiceProvider.php @@ -83,13 +83,5 @@ class PluginServiceProvider implements ServiceProviderInterface 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; - }) - ); } } diff --git a/lib/Alchemy/Phrasea/Core/Provider/PluginServiceProvider.php b/lib/Alchemy/Phrasea/Core/Provider/PluginServiceProvider.php new file mode 100644 index 0000000000..6eae3d1617 --- /dev/null +++ b/lib/Alchemy/Phrasea/Core/Provider/PluginServiceProvider.php @@ -0,0 +1,34 @@ +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; + }) + ); + } +} diff --git a/lib/Doctrine/Repositories/FeedItemRepository.php b/lib/Doctrine/Repositories/FeedItemRepository.php index 7203bd3582..5ab3935fc2 100644 --- a/lib/Doctrine/Repositories/FeedItemRepository.php +++ b/lib/Doctrine/Repositories/FeedItemRepository.php @@ -4,6 +4,7 @@ namespace Repositories; use Alchemy\Phrasea\Application; use Doctrine\ORM\EntityRepository; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * FeedItemRepository @@ -66,7 +67,17 @@ class FeedItemRepository extends EntityRepository $result = $query->getResult(); 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()) { $items[] = $item; @@ -77,6 +88,7 @@ class FeedItemRepository extends EntityRepository } } + $app['EM']->flush(); $execution++; } while (count($items) < $nbItems && count($result) !== 0); diff --git a/lib/classes/caption/record.php b/lib/classes/caption/record.php index 12fb94eac7..2cd0253a34 100644 --- a/lib/classes/caption/record.php +++ b/lib/classes/caption/record.php @@ -104,12 +104,12 @@ class caption_record implements caption_interface, cache_cacheableInterface $buffer[$field->get_name()] = array(); foreach ($vi as $value) { $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 { $value = array_pop($vi); $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) { $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_struct_id', $field->get_meta_struct_id()); $description->appendChild($elem); @@ -153,6 +153,40 @@ class caption_record implements caption_interface, cache_cacheableInterface 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() { if (is_array($this->fields)) { diff --git a/lib/classes/patch/3820.php b/lib/classes/patch/3820.php new file mode 100644 index 0000000000..26d14f7a90 --- /dev/null +++ b/lib/classes/patch/3820.php @@ -0,0 +1,69 @@ +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; + } +} diff --git a/templates/web/common/dialog_export.html.twig b/templates/web/common/dialog_export.html.twig index bef5bfd6f2..b2b5371f38 100644 --- a/templates/web/common/dialog_export.html.twig +++ b/templates/web/common/dialog_export.html.twig @@ -246,7 +246,6 @@ - {% endif %} @@ -798,8 +797,13 @@ if (!check_TOU($('#sendmail'))) { return false; } - dialog.Close(); + + if ($('iframe[name=""]').length === 0) { + $('body').append(''); + } + $('#sendmail form').submit(); + dialog.Close(); }); $('.datepicker', dialog.getDomElement()).datepicker({ diff --git a/tests/Doctrine/Tests/Repositories/FeedItemRepositoryTest.php b/tests/Doctrine/Tests/Repositories/FeedItemRepositoryTest.php index b59e1fb466..177b9b9711 100644 --- a/tests/Doctrine/Tests/Repositories/FeedItemRepositoryTest.php +++ b/tests/Doctrine/Tests/Repositories/FeedItemRepositoryTest.php @@ -38,4 +38,36 @@ class FeedItemRepositoryTest extends \PhraseanetPHPUnitAbstract $this->insertOneFeedItem(self::$DI['user'], false, 2); $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)); + } }