diff --git a/Dockerfile b/Dockerfile
index ab22c72631..418e8e812d 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -36,7 +36,11 @@ RUN apt-get update \
xpdf \
&& update-locale "LANG=fr_FR.UTF-8 UTF-8" \
&& dpkg-reconfigure --frontend noninteractive locales \
- && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/*
+
+RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
+ && docker-php-source extract \
&& docker-php-ext-install -j$(nproc) gd \
&& docker-php-ext-install zip exif iconv mbstring pcntl sockets xsl intl pdo_mysql gettext bcmath mcrypt \
&& pecl install redis amqp-1.9.3 zmq-beta imagick-beta \
@@ -45,10 +49,7 @@ RUN apt-get update \
&& docker-php-source delete \
&& rm -rf /var/lib/apt/lists/*
-RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
- && php -r "if (hash_file('sha384', 'composer-setup.php') === 'a5c698ffe4b8e849a443b120cd5ba38043260d5c4023dbf93e1558871f1f07f58274fc6f4c93bcfd858c6bd0775cd8d1') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
- && php composer-setup.php --install-dir=/usr/local/bin --filename=composer \
- && php -r "unlink('composer-setup.php');"
+COPY --from=composer:1.9.1 /usr/bin/composer /usr/bin/composer
# Node Installation (node + yarn)
# Reference :
@@ -129,6 +130,12 @@ RUN mkdir -p /var/alchemy/Phraseanet/logs \
FROM phraseanet-system as phraseanet-fpm
+RUN docker-php-source extract \
+ && pecl install xdebug-2.9.0 \
+ && docker-php-ext-enable xdebug \
+ #&& pecl clear-cache \
+ && docker-php-source delete
+
COPY --from=builder --chown=app /var/alchemy /var/alchemy/Phraseanet
ADD ./docker/phraseanet/ /
WORKDIR /var/alchemy/Phraseanet
diff --git a/bin/console b/bin/console
index 552cb672d0..c973195ff6 100755
--- a/bin/console
+++ b/bin/console
@@ -23,7 +23,9 @@ use Alchemy\Phrasea\Command\SearchEngine\IndexPopulateCommand;
use Alchemy\Phrasea\Command\Thesaurus\FindConceptsCommand;
use Alchemy\Phrasea\Core\Version;
use Alchemy\Phrasea\Command\CreateCollection;
+use Alchemy\Phrasea\Command\Collection\ListCollectionCommand;
use Alchemy\Phrasea\Command\Databox\CreateDataboxCommand;
+use Alchemy\Phrasea\Command\Databox\ListDataboxCommand;
use Alchemy\Phrasea\Command\MailTest;
use Alchemy\Phrasea\Command\Compile\Configuration;
use Alchemy\Phrasea\Command\RecordAdd;
@@ -46,6 +48,9 @@ use Alchemy\Phrasea\Command\Task\TaskRun;
use Alchemy\Phrasea\Command\Task\TaskStart;
use Alchemy\Phrasea\Command\Task\TaskState;
use Alchemy\Phrasea\Command\Task\TaskStop;
+use Alchemy\Phrasea\Command\User\UserCreateCommand;
+use Alchemy\Phrasea\Command\User\UserSetPasswordCommand;
+use Alchemy\Phrasea\Command\User\UserListCommand;
use Alchemy\Phrasea\Command\UpgradeDBDatas;
require_once __DIR__ . '/../lib/autoload.php';
@@ -108,8 +113,18 @@ $cli->command(new \module_console_fieldsRename('fields:rename'));
$cli->command(new \module_console_fieldsMerge('fields:merge'));
$cli->command(new CreateCollection('collection:create'));
+$cli->command(new ListCollectionCommand('collection:list'));
+
+$cli->command(new ListDataboxCommand('databox:list'));
$cli->command(new CreateDataboxCommand('databox:create'));
+$cli->command(new UserCreateCommand('user:create'));
+
+$cli->command(new UserSetPasswordCommand('user:set-password'));
+
+$cli->command(new UserListCommand('user:list'));
+
+
$cli->command(new RecordAdd('records:add'));
$cli->command(new RescanTechnicalDatas('records:rescan-technical-datas'));
$cli->command(new BuildMissingSubdefs('records:build-missing-subdefs'));
diff --git a/composer.json b/composer.json
index 47635b0e47..46ff98203e 100644
--- a/composer.json
+++ b/composer.json
@@ -18,6 +18,18 @@
}
}
},
+ {
+ "type": "package",
+ "package": {
+ "name": "exiftool/exiftool",
+ "version": "11",
+ "source": {
+ "url": "https://github.com/exiftool/exiftool.git",
+ "type": "git",
+ "reference": "11.84"
+ }
+ }
+ },
{
"type": "vcs",
"url": "https://github.com/alchemy-fr/tcpdf-clone"
@@ -84,7 +96,7 @@
"league/flysystem": "^1.0",
"league/flysystem-aws-s3-v2": "^1.0",
"league/fractal": "dev-webgalleries#af1acc0275438571bc8c1d08a05a4b5af92c9f97 as 0.13.0",
- "media-alchemyst/media-alchemyst": "^0.5",
+ "media-alchemyst/media-alchemyst": "^0.5.5",
"monolog/monolog": "~1.3",
"mrclay/minify": "~2.1.6",
"neutron/process-manager": "2.0.x-dev@dev",
@@ -95,7 +107,7 @@
"pagerfanta/pagerfanta": "^1.0",
"php-ffmpeg/php-ffmpeg": "~0.5.0",
"php-xpdf/php-xpdf": "~0.2.1",
- "phpexiftool/exiftool": "10.10",
+ "exiftool/exiftool": "^11",
"ramsey/uuid": "^3.0",
"roave/security-advisories": "dev-master",
"silex/silex": "^1.3.0",
diff --git a/composer.lock b/composer.lock
index 482cce9daf..41a8b05beb 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1,11 +1,10 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
- "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "hash": "e5bed7b0b8cb8b45ffffc4965a7689db",
- "content-hash": "f3b1fc0a30bf14b05e57ce673550d9c0",
+ "content-hash": "5a4a0be62b13071a6b06893b7ce08372",
"packages": [
{
"name": "alchemy-fr/tcpdf-clone",
@@ -71,7 +70,7 @@
"source": "https://github.com/alchemy-fr/tcpdf-clone/tree/6.0.039",
"issues": "https://github.com/alchemy-fr/tcpdf-clone/issues"
},
- "time": "2013-10-13 16:11:17"
+ "time": "2013-10-13T16:11:17+00:00"
},
{
"name": "alchemy/binary-driver",
@@ -128,15 +127,21 @@
"binary",
"driver"
],
- "time": "2016-03-02 13:49:15"
+ "time": "2016-03-02T13:49:15+00:00"
},
{
"name": "alchemy/embed-bundle",
- "version": "2.0.8",
+ "version": "2.0.9",
"source": {
"type": "git",
"url": "https://github.com/alchemy-fr/embed-bundle.git",
- "reference": "cbaa5e34b7b6ccbe128f8c804649c8a3ecd1e621"
+ "reference": "8cdb9612a9e3edd998b68f0803eacca8e0f50775"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/alchemy-fr/embed-bundle/zipball/8cdb9612a9e3edd998b68f0803eacca8e0f50775",
+ "reference": "8cdb9612a9e3edd998b68f0803eacca8e0f50775",
+ "shasum": ""
},
"require-dev": {
"phpunit/phpunit": "^4.7",
@@ -172,7 +177,11 @@
}
],
"description": "Embed resources bundle",
- "time": "2019-10-09 14:34:23"
+ "support": {
+ "source": "https://github.com/alchemy-fr/embed-bundle/tree/2.0.9",
+ "issues": "https://github.com/alchemy-fr/embed-bundle/issues"
+ },
+ "time": "2020-02-04T14:53:00+00:00"
},
{
"name": "alchemy/geonames-api-consumer",
@@ -210,7 +219,7 @@
"keywords": [
"geonames"
],
- "time": "2014-02-05 15:29:39"
+ "time": "2014-02-05T15:29:39+00:00"
},
{
"name": "alchemy/ghostscript",
@@ -262,20 +271,20 @@
"ghostscript",
"pdf"
],
- "time": "2013-06-25 09:12:58"
+ "time": "2013-06-25T09:12:58+00:00"
},
{
"name": "alchemy/mediavorus",
- "version": "0.4.9",
+ "version": "0.4.10",
"source": {
"type": "git",
"url": "https://github.com/alchemy-fr/MediaVorus.git",
- "reference": "1a96dc4142ff8474c11285cab9eab11df9683255"
+ "reference": "3e235eb1efb528aea2973c946f4bf47630b98985"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/alchemy-fr/MediaVorus/zipball/1a96dc4142ff8474c11285cab9eab11df9683255",
- "reference": "1a96dc4142ff8474c11285cab9eab11df9683255",
+ "url": "https://api.github.com/repos/alchemy-fr/MediaVorus/zipball/3e235eb1efb528aea2973c946f4bf47630b98985",
+ "reference": "3e235eb1efb528aea2973c946f4bf47630b98985",
"shasum": ""
},
"require": {
@@ -291,6 +300,7 @@
},
"require-dev": {
"jms/serializer": "~0.12.0",
+ "phpunit/phpunit": "^4.0|^5.0",
"silex/silex": "~1.0",
"symfony/yaml": "~2.0"
},
@@ -324,7 +334,7 @@
"keywords": [
"metadata"
],
- "time": "2019-01-22 11:23:34"
+ "time": "2020-02-18T13:37:45+00:00"
},
{
"name": "alchemy/oauth2php",
@@ -347,7 +357,7 @@
]
},
"notification-url": "https://packagist.org/downloads/",
- "time": "2019-01-17 14:34:10"
+ "time": "2019-01-17T14:34:10+00:00"
},
{
"name": "alchemy/phlickr",
@@ -370,34 +380,31 @@
}
},
"notification-url": "https://packagist.org/downloads/",
- "time": "2014-12-15 14:27:57"
+ "time": "2014-12-15T14:27:57+00:00"
},
{
"name": "alchemy/phpexiftool",
- "version": "0.7.2",
+ "version": "0.7.3",
"source": {
"type": "git",
"url": "https://github.com/alchemy-fr/PHPExiftool.git",
- "reference": "ba1cb51eceb6562d7996023478977a8739de188b"
+ "reference": "0b22e7d7cc40f2a6b9c85c0cfbd968a39a31dab2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/alchemy-fr/PHPExiftool/zipball/ba1cb51eceb6562d7996023478977a8739de188b",
- "reference": "ba1cb51eceb6562d7996023478977a8739de188b",
+ "url": "https://api.github.com/repos/alchemy-fr/PHPExiftool/zipball/0b22e7d7cc40f2a6b9c85c0cfbd968a39a31dab2",
+ "reference": "0b22e7d7cc40f2a6b9c85c0cfbd968a39a31dab2",
"shasum": ""
},
"require": {
"doctrine/cache": "^1.0",
"doctrine/collections": "^1.0",
+ "exiftool/exiftool": "^11",
"monolog/monolog": "^1.3",
"php": ">=5.5.9",
- "phpexiftool/exiftool": "10.10",
"symfony/console": "^2.1|^3.0",
"symfony/process": "^2.1|^3.0"
},
- "replace": {
- "phpexiftool/phpexiftool": "<0.5.0"
- },
"require-dev": {
"jms/serializer": "~0.10|^1.0",
"phpunit/phpunit": "^4.0|^5.0",
@@ -443,7 +450,7 @@
"exiftool",
"metadata"
],
- "time": "2019-02-13 13:06:43"
+ "time": "2020-01-17T14:28:33+00:00"
},
{
"name": "alchemy/queue-bundle",
@@ -491,7 +498,7 @@
}
],
"description": "Symfony bundle for alchemy/queue-component",
- "time": "2016-10-04 14:19:39"
+ "time": "2016-10-04T14:19:39+00:00"
},
{
"name": "alchemy/queue-component",
@@ -536,7 +543,7 @@
"MIT"
],
"description": "Message queue component",
- "time": "2016-10-05 10:41:36"
+ "time": "2016-10-05T10:41:36+00:00"
},
{
"name": "alchemy/rest-bundle",
@@ -588,7 +595,7 @@
}
],
"description": "Simple REST utility bundle",
- "time": "2016-05-16 09:37:34"
+ "time": "2016-05-16T09:37:34+00:00"
},
{
"name": "alchemy/symfony-cors",
@@ -635,7 +642,7 @@
}
],
"description": "A library that adds CORS services to Silex/Symfony Applications",
- "time": "2015-12-17 15:34:43"
+ "time": "2015-12-17T15:34:43+00:00"
},
{
"name": "alchemy/task-manager",
@@ -698,7 +705,7 @@
"parallel",
"process"
],
- "time": "2016-11-30 13:34:30"
+ "time": "2016-11-30T13:34:30+00:00"
},
{
"name": "alchemy/worker-bundle",
@@ -747,7 +754,7 @@
}
],
"description": "Symfony bundle for alchemy/worker-component",
- "time": "2016-12-06 10:39:58"
+ "time": "2016-12-06T10:39:58+00:00"
},
{
"name": "alchemy/worker-component",
@@ -793,7 +800,7 @@
"MIT"
],
"description": "Message queue worker component",
- "time": "2016-11-14 16:41:16"
+ "time": "2016-11-14T16:41:16+00:00"
},
{
"name": "alchemy/zippy",
@@ -855,7 +862,7 @@
"tar",
"zip"
],
- "time": "2016-02-15 22:46:40"
+ "time": "2016-02-15T22:46:40+00:00"
},
{
"name": "aws/aws-sdk-php",
@@ -918,7 +925,7 @@
"s3",
"sdk"
],
- "time": "2016-07-25 18:03:20"
+ "time": "2016-07-25T18:03:20+00:00"
},
{
"name": "beberlei/assert",
@@ -973,7 +980,7 @@
"assertion",
"validation"
],
- "time": "2017-01-24 15:14:39"
+ "time": "2017-01-24T15:14:39+00:00"
},
{
"name": "behat/transliterator",
@@ -1013,7 +1020,7 @@
"slug",
"transliterator"
],
- "time": "2015-09-28 16:26:35"
+ "time": "2015-09-28T16:26:35+00:00"
},
{
"name": "box/spout",
@@ -1081,7 +1088,7 @@
"write",
"xlsx"
],
- "time": "2017-09-25 19:44:35"
+ "time": "2017-09-25T19:44:35+00:00"
},
{
"name": "cocur/slugify",
@@ -1145,7 +1152,7 @@
"slug",
"slugify"
],
- "time": "2016-08-09 20:10:17"
+ "time": "2016-08-09T20:10:17+00:00"
},
{
"name": "czproject/git-php",
@@ -1187,7 +1194,7 @@
"keywords": [
"git"
],
- "time": "2019-02-09 13:11:36"
+ "time": "2019-02-09T13:11:36+00:00"
},
{
"name": "dailymotion/sdk",
@@ -1220,7 +1227,7 @@
"dailymotion",
"sdk"
],
- "time": "2015-11-20 11:18:32"
+ "time": "2015-11-20T11:18:32+00:00"
},
{
"name": "data-uri/data-uri",
@@ -1265,7 +1272,7 @@
"data-uri",
"uri"
],
- "time": "2014-08-22 15:01:57"
+ "time": "2014-08-22T15:01:57+00:00"
},
{
"name": "dflydev/doctrine-orm-service-provider",
@@ -1327,7 +1334,7 @@
"pimple",
"silex"
],
- "time": "2015-09-07 12:16:54"
+ "time": "2015-09-07T12:16:54+00:00"
},
{
"name": "doctrine/annotations",
@@ -1395,7 +1402,7 @@
"docblock",
"parser"
],
- "time": "2015-08-31 12:32:49"
+ "time": "2015-08-31T12:32:49+00:00"
},
{
"name": "doctrine/cache",
@@ -1407,7 +1414,7 @@
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/cache/zipball/eb152c5100571c7a45470ff2a35095ab3f3b900b",
+ "url": "https://api.github.com/repos/doctrine/cache/zipball/b6f544a20f4807e81f7044d31e679ccbb1866dc3",
"reference": "b6f544a20f4807e81f7044d31e679ccbb1866dc3",
"shasum": ""
},
@@ -1465,7 +1472,7 @@
"cache",
"caching"
],
- "time": "2016-10-29 11:16:17"
+ "time": "2016-10-29T11:16:17+00:00"
},
{
"name": "doctrine/collections",
@@ -1531,7 +1538,7 @@
"collections",
"iterator"
],
- "time": "2015-04-14 22:21:58"
+ "time": "2015-04-14T22:21:58+00:00"
},
{
"name": "doctrine/common",
@@ -1604,7 +1611,7 @@
"persistence",
"spl"
],
- "time": "2016-11-30 16:50:46"
+ "time": "2016-11-30T16:50:46+00:00"
},
{
"name": "doctrine/dbal",
@@ -1675,7 +1682,7 @@
"persistence",
"queryobject"
],
- "time": "2017-01-23 23:17:10"
+ "time": "2017-01-23T23:17:10+00:00"
},
{
"name": "doctrine/inflector",
@@ -1742,7 +1749,7 @@
"singularize",
"string"
],
- "time": "2015-11-06 14:35:42"
+ "time": "2015-11-06T14:35:42+00:00"
},
{
"name": "doctrine/instantiator",
@@ -1796,7 +1803,7 @@
"constructor",
"instantiate"
],
- "time": "2015-06-14 21:17:01"
+ "time": "2015-06-14T21:17:01+00:00"
},
{
"name": "doctrine/lexer",
@@ -1850,7 +1857,7 @@
"lexer",
"parser"
],
- "time": "2014-09-09 13:34:57"
+ "time": "2014-09-09T13:34:57+00:00"
},
{
"name": "doctrine/migrations",
@@ -1924,7 +1931,7 @@
"database",
"migrations"
],
- "time": "2016-12-25 22:54:00"
+ "time": "2016-12-25T22:54:00+00:00"
},
{
"name": "doctrine/orm",
@@ -2000,7 +2007,7 @@
"database",
"orm"
],
- "time": "2016-12-18 15:42:34"
+ "time": "2016-12-18T15:42:34+00:00"
},
{
"name": "elasticsearch/elasticsearch",
@@ -2054,7 +2061,7 @@
"elasticsearch",
"search"
],
- "time": "2016-11-30 17:15:05"
+ "time": "2016-11-30T17:15:05+00:00"
},
{
"name": "evenement/evenement",
@@ -2094,7 +2101,17 @@
"keywords": [
"event-dispatcher"
],
- "time": "2012-05-30 15:01:08"
+ "time": "2012-05-30T15:01:08+00:00"
+ },
+ {
+ "name": "exiftool/exiftool",
+ "version": "11",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/exiftool/exiftool.git",
+ "reference": "11.84"
+ },
+ "type": "library"
},
{
"name": "facebook/graph-sdk",
@@ -2152,7 +2169,7 @@
"facebook",
"sdk"
],
- "time": "2017-08-16 17:28:07"
+ "time": "2017-08-16T17:28:07+00:00"
},
{
"name": "firebase/php-jwt",
@@ -2195,7 +2212,7 @@
],
"description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
"homepage": "https://github.com/firebase/php-jwt",
- "time": "2015-07-22 18:31:08"
+ "time": "2015-07-22T18:31:08+00:00"
},
{
"name": "gedmo/doctrine-extensions",
@@ -2273,7 +2290,7 @@
"tree",
"uploadable"
],
- "time": "2015-02-24 21:41:37"
+ "time": "2015-02-24T21:41:37+00:00"
},
{
"name": "goodby/csv",
@@ -2330,7 +2347,7 @@
"export",
"import"
],
- "time": "2015-06-29 10:28:19"
+ "time": "2015-06-29T10:28:19+00:00"
},
{
"name": "google/apiclient",
@@ -2389,7 +2406,7 @@
"keywords": [
"google"
],
- "time": "2017-11-03 01:19:53"
+ "time": "2017-11-03T01:19:53+00:00"
},
{
"name": "google/apiclient-services",
@@ -2426,7 +2443,7 @@
"keywords": [
"google"
],
- "time": "2017-11-25 00:23:12"
+ "time": "2017-11-25T00:23:12+00:00"
},
{
"name": "google/auth",
@@ -2471,7 +2488,7 @@
"google",
"oauth2"
],
- "time": "2017-10-10 17:01:45"
+ "time": "2017-10-10T17:01:45+00:00"
},
{
"name": "google/recaptcha",
@@ -2516,7 +2533,7 @@
"recaptcha",
"spam"
],
- "time": "2017-03-09 18:44:34"
+ "time": "2017-03-09T18:44:34+00:00"
},
{
"name": "guzzle/guzzle",
@@ -2612,7 +2629,7 @@
"web service"
],
"abandoned": "guzzlehttp/guzzle",
- "time": "2015-03-18 18:23:50"
+ "time": "2015-03-18T18:23:50+00:00"
},
{
"name": "guzzlehttp/guzzle",
@@ -2677,7 +2694,7 @@
"rest",
"web service"
],
- "time": "2017-06-22 18:50:49"
+ "time": "2017-06-22T18:50:49+00:00"
},
{
"name": "guzzlehttp/promises",
@@ -2728,7 +2745,7 @@
"keywords": [
"promise"
],
- "time": "2016-12-20 10:07:11"
+ "time": "2016-12-20T10:07:11+00:00"
},
{
"name": "guzzlehttp/psr7",
@@ -2793,7 +2810,7 @@
"uri",
"url"
],
- "time": "2017-03-20 17:10:46"
+ "time": "2017-03-20T17:10:46+00:00"
},
{
"name": "guzzlehttp/ringphp",
@@ -2844,7 +2861,8 @@
}
],
"description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function.",
- "time": "2015-05-20 03:37:09"
+ "abandoned": true,
+ "time": "2015-05-20T03:37:09+00:00"
},
{
"name": "guzzlehttp/streams",
@@ -2894,7 +2912,8 @@
"Guzzle",
"stream"
],
- "time": "2014-10-12 19:18:40"
+ "abandoned": true,
+ "time": "2014-10-12T19:18:40+00:00"
},
{
"name": "hoa/compiler",
@@ -2974,7 +2993,7 @@
"trace",
"uniform"
],
- "time": "2015-10-29 21:35:12"
+ "time": "2015-10-29T21:35:12+00:00"
},
{
"name": "hoa/console",
@@ -3046,7 +3065,7 @@
"tput",
"window"
],
- "time": "2015-07-27 07:52:10"
+ "time": "2015-07-27T07:52:10+00:00"
},
{
"name": "hoa/core",
@@ -3114,7 +3133,7 @@
"protocol"
],
"abandoned": "hoa/consistency",
- "time": "2015-11-09 06:51:06"
+ "time": "2015-11-09T06:51:06+00:00"
},
{
"name": "hoa/dispatcher",
@@ -3174,7 +3193,7 @@
"kit",
"library"
],
- "time": "2015-11-09 06:52:08"
+ "time": "2015-11-09T06:52:08+00:00"
},
{
"name": "hoa/file",
@@ -3234,7 +3253,7 @@
"link",
"temporary"
],
- "time": "2015-11-09 06:55:20"
+ "time": "2015-11-09T06:55:20+00:00"
},
{
"name": "hoa/iterator",
@@ -3287,7 +3306,7 @@
"iterator",
"library"
],
- "time": "2015-10-29 21:37:16"
+ "time": "2015-10-29T21:37:16+00:00"
},
{
"name": "hoa/math",
@@ -3349,7 +3368,7 @@
"sampler",
"set"
],
- "time": "2015-10-26 15:22:52"
+ "time": "2015-10-26T15:22:52+00:00"
},
{
"name": "hoa/regex",
@@ -3403,7 +3422,7 @@
"library",
"regex"
],
- "time": "2015-08-13 06:48:47"
+ "time": "2015-08-13T06:48:47+00:00"
},
{
"name": "hoa/router",
@@ -3455,7 +3474,7 @@
"library",
"router"
],
- "time": "2015-10-21 14:12:51"
+ "time": "2015-10-21T14:12:51+00:00"
},
{
"name": "hoa/stream",
@@ -3513,7 +3532,7 @@
"stream",
"wrapper"
],
- "time": "2015-10-26 12:21:43"
+ "time": "2015-10-26T12:21:43+00:00"
},
{
"name": "hoa/ustring",
@@ -3572,7 +3591,7 @@
"string",
"unicode"
],
- "time": "2015-11-09 06:44:33"
+ "time": "2015-11-09T06:44:33+00:00"
},
{
"name": "hoa/visitor",
@@ -3627,7 +3646,7 @@
"visit",
"visitor"
],
- "time": "2015-08-17 06:30:58"
+ "time": "2015-08-17T06:30:58+00:00"
},
{
"name": "igorw/get-in",
@@ -3672,7 +3691,7 @@
"assoc-array",
"hash-map"
],
- "time": "2014-12-15 23:03:51"
+ "time": "2014-12-15T23:03:51+00:00"
},
{
"name": "imagine/imagine",
@@ -3731,7 +3750,7 @@
"support": {
"source": "https://github.com/alchemy-fr/Imagine/tree/alchemy-0.6.2"
},
- "time": "2015-01-13 18:12:26"
+ "time": "2015-01-13T18:12:26+00:00"
},
{
"name": "ircmaxell/password-compat",
@@ -3773,7 +3792,7 @@
"hashing",
"password"
],
- "time": "2014-11-20 16:49:30"
+ "time": "2014-11-20T16:49:30+00:00"
},
{
"name": "ircmaxell/security-lib",
@@ -3819,7 +3838,7 @@
],
"description": "A Base Security Library",
"homepage": "https://github.com/ircmaxell/SecurityLib",
- "time": "2015-03-20 14:31:23"
+ "time": "2015-03-20T14:31:23+00:00"
},
{
"name": "jms/metadata",
@@ -3870,7 +3889,7 @@
"xml",
"yaml"
],
- "time": "2016-12-05 10:18:33"
+ "time": "2016-12-05T10:18:33+00:00"
},
{
"name": "jms/parser-lib",
@@ -3905,7 +3924,7 @@
"Apache2"
],
"description": "A library for easily creating recursive-descent parsers.",
- "time": "2012-11-18 18:08:43"
+ "time": "2012-11-18T18:08:43+00:00"
},
{
"name": "jms/serializer",
@@ -3975,7 +3994,7 @@
"serialization",
"xml"
],
- "time": "2014-03-18 08:39:00"
+ "time": "2014-03-18T08:39:00+00:00"
},
{
"name": "jms/translation-bundle",
@@ -4051,7 +4070,7 @@
"support": {
"source": "https://github.com/alchemy-fr/JMSTranslationBundle/tree/rebase-2015-10-20"
},
- "time": "2015-11-04 15:09:44"
+ "time": "2015-11-04T15:09:44+00:00"
},
{
"name": "justinrainbow/json-schema",
@@ -4117,7 +4136,7 @@
"json",
"schema"
],
- "time": "2016-05-10 20:38:51"
+ "time": "2016-05-10T20:38:51+00:00"
},
{
"name": "league/flysystem",
@@ -4200,7 +4219,7 @@
"sftp",
"storage"
],
- "time": "2017-01-30 17:41:17"
+ "time": "2017-01-30T17:41:17+00:00"
},
{
"name": "league/flysystem-aws-s3-v2",
@@ -4247,7 +4266,7 @@
}
],
"description": "Flysystem adapter for AWS S3 SDK v2",
- "time": "2015-10-15 15:55:48"
+ "time": "2015-10-15T15:55:48+00:00"
},
{
"name": "league/fractal",
@@ -4308,20 +4327,20 @@
"league",
"rest"
],
- "time": "2016-12-02 14:55:48"
+ "time": "2016-12-02T14:55:48+00:00"
},
{
"name": "media-alchemyst/media-alchemyst",
- "version": "0.5.2",
+ "version": "0.5.5",
"source": {
"type": "git",
"url": "https://github.com/alchemy-fr/Media-Alchemyst.git",
- "reference": "5d2fe6dd95215804202ecf0466fd9cfaeedd0140"
+ "reference": "3bd3204b69882f495adfb617383a077face92ed0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/alchemy-fr/Media-Alchemyst/zipball/5d2fe6dd95215804202ecf0466fd9cfaeedd0140",
- "reference": "5d2fe6dd95215804202ecf0466fd9cfaeedd0140",
+ "url": "https://api.github.com/repos/alchemy-fr/Media-Alchemyst/zipball/3bd3204b69882f495adfb617383a077face92ed0",
+ "reference": "3bd3204b69882f495adfb617383a077face92ed0",
"shasum": ""
},
"require": {
@@ -4333,7 +4352,7 @@
"php": ">=5.3.3",
"php-ffmpeg/php-ffmpeg": ">=0.4.2,<0.6",
"php-mp4box/php-mp4box": "~0.3.0",
- "php-unoconv/php-unoconv": "~0.3.0",
+ "php-unoconv/php-unoconv": "~0.3.1",
"pimple/pimple": "~1.0",
"swftools/swftools": "~0.3.0",
"symfony/console": "^2.1|^3.0",
@@ -4382,7 +4401,7 @@
"video",
"video processing"
],
- "time": "2019-01-25 12:09:11"
+ "time": "2019-12-11T07:20:45+00:00"
},
{
"name": "monolog/monolog",
@@ -4460,7 +4479,7 @@
"logging",
"psr-3"
],
- "time": "2016-11-26 00:15:39"
+ "time": "2016-11-26T00:15:39+00:00"
},
{
"name": "mrclay/minify",
@@ -4500,7 +4519,7 @@
],
"description": "Minify is a PHP5 app that helps you follow several rules for client-side performance. It combines multiple CSS or Javascript files, removes unnecessary whitespace and comments, and serves them with gzip encoding and optimal client-side cache headers",
"homepage": "http://code.google.com/p/minify/",
- "time": "2013-07-23 19:58:28"
+ "time": "2013-07-23T19:58:28+00:00"
},
{
"name": "neutron/process-manager",
@@ -4539,7 +4558,7 @@
"homepage": "http://www.lickmychip.com/"
}
],
- "time": "2014-02-13 20:27:33"
+ "time": "2014-02-13T20:27:33+00:00"
},
{
"name": "neutron/recaptcha",
@@ -4583,7 +4602,7 @@
}
],
"description": "ReCaptcha Client",
- "time": "2013-02-14 13:42:00"
+ "time": "2013-02-14T13:42:00+00:00"
},
{
"name": "neutron/signal-handler",
@@ -4626,7 +4645,7 @@
"keywords": [
"signal"
],
- "time": "2014-01-15 17:24:13"
+ "time": "2014-01-15T17:24:13+00:00"
},
{
"name": "neutron/silex-filesystem-provider",
@@ -4670,7 +4689,7 @@
"silex",
"temporary-filesystem"
],
- "time": "2012-11-08 21:07:08"
+ "time": "2012-11-08T21:07:08+00:00"
},
{
"name": "neutron/silex-imagine-provider",
@@ -4717,7 +4736,7 @@
"imagine",
"silex"
],
- "time": "2013-05-03 18:48:51"
+ "time": "2013-05-03T18:48:51+00:00"
},
{
"name": "neutron/temporary-filesystem",
@@ -4757,7 +4776,7 @@
}
],
"description": "Symfony filesystem extension to handle temporary files",
- "time": "2016-03-05 10:22:50"
+ "time": "2016-03-05T10:22:50+00:00"
},
{
"name": "nikic/php-parser",
@@ -4802,7 +4821,7 @@
"parser",
"php"
],
- "time": "2015-09-19 14:15:08"
+ "time": "2015-09-19T14:15:08+00:00"
},
{
"name": "ocramius/proxy-manager",
@@ -4865,7 +4884,7 @@
"proxy pattern",
"service proxies"
],
- "time": "2015-08-09 04:28:19"
+ "time": "2015-08-09T04:28:19+00:00"
},
{
"name": "pagerfanta/pagerfanta",
@@ -4932,7 +4951,7 @@
"paginator",
"paging"
],
- "time": "2016-11-28 09:17:04"
+ "time": "2016-11-28T09:17:04+00:00"
},
{
"name": "paragonie/random-lib",
@@ -4994,7 +5013,7 @@
"random-numbers",
"random-strings"
],
- "time": "2017-10-06 23:34:21"
+ "time": "2017-10-06T23:34:21+00:00"
},
{
"name": "paragonie/random_compat",
@@ -5042,7 +5061,7 @@
"pseudorandom",
"random"
],
- "time": "2016-11-07 23:38:38"
+ "time": "2016-11-07T23:38:38+00:00"
},
{
"name": "paragonie/sodium_compat",
@@ -5124,7 +5143,7 @@
"secret-key cryptography",
"side-channel resistant"
],
- "time": "2019-03-20 17:19:05"
+ "time": "2019-03-20T17:19:05+00:00"
},
{
"name": "php-ffmpeg/php-ffmpeg",
@@ -5193,7 +5212,7 @@
"video",
"video processing"
],
- "time": "2014-08-26 08:46:56"
+ "time": "2014-08-26T08:46:56+00:00"
},
{
"name": "php-mp4box/php-mp4box",
@@ -5244,20 +5263,20 @@
"gpac",
"mp4box"
],
- "time": "2013-06-25 10:13:06"
+ "time": "2013-06-25T10:13:06+00:00"
},
{
"name": "php-unoconv/php-unoconv",
- "version": "0.3.0",
+ "version": "0.3.1",
"source": {
"type": "git",
"url": "https://github.com/alchemy-fr/PHP-Unoconv.git",
- "reference": "6d1e14a7467b5d637741396549529dc4d5f9f355"
+ "reference": "8fa666972f6c13fe9703dfe894cd311a61f89f33"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/alchemy-fr/PHP-Unoconv/zipball/6d1e14a7467b5d637741396549529dc4d5f9f355",
- "reference": "6d1e14a7467b5d637741396549529dc4d5f9f355",
+ "url": "https://api.github.com/repos/alchemy-fr/PHP-Unoconv/zipball/8fa666972f6c13fe9703dfe894cd311a61f89f33",
+ "reference": "8fa666972f6c13fe9703dfe894cd311a61f89f33",
"shasum": ""
},
"require": {
@@ -5294,7 +5313,7 @@
"keywords": [
"unoconv"
],
- "time": "2013-06-25 10:09:59"
+ "time": "2019-09-16T09:54:30+00:00"
},
{
"name": "php-xpdf/php-xpdf",
@@ -5346,7 +5365,7 @@
"pdf",
"xpdf"
],
- "time": "2016-07-04 07:30:16"
+ "time": "2016-07-04T07:30:16+00:00"
},
{
"name": "phpcollection/phpcollection",
@@ -5394,40 +5413,7 @@
"sequence",
"set"
],
- "time": "2015-05-17 12:39:23"
- },
- {
- "name": "phpexiftool/exiftool",
- "version": "10.10",
- "source": {
- "type": "git",
- "url": "https://github.com/alchemy-fr/exiftool.git",
- "reference": "0833cab894c890353192a83011428525a318bedf"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/alchemy-fr/exiftool/zipball/0833cab894c890353192a83011428525a318bedf",
- "reference": "0833cab894c890353192a83011428525a318bedf",
- "shasum": ""
- },
- "type": "library",
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "Perl Licensing"
- ],
- "authors": [
- {
- "name": "Phil Harvey",
- "email": "phil@owl.phy.queensu.ca",
- "homepage": "http://www.sno.phy.queensu.ca/~phil/exiftool/"
- }
- ],
- "description": "Exiftool is a library for reading, writing and editing meta information. This package is not PHP, but required for the main PHP driver : PHP Exiftool",
- "keywords": [
- "exiftool",
- "metadatas"
- ],
- "time": "2016-01-25 11:10:14"
+ "time": "2015-05-17T12:39:23+00:00"
},
{
"name": "phpoption/phpoption",
@@ -5477,7 +5463,7 @@
"php",
"type"
],
- "time": "2015-07-25 16:39:46"
+ "time": "2015-07-25T16:39:46+00:00"
},
{
"name": "phpseclib/phpseclib",
@@ -5569,7 +5555,7 @@
"x.509",
"x509"
],
- "time": "2017-10-23 05:04:54"
+ "time": "2017-10-23T05:04:54+00:00"
},
{
"name": "pimple/pimple",
@@ -5615,7 +5601,7 @@
"container",
"dependency injection"
],
- "time": "2013-11-22 08:30:29"
+ "time": "2013-11-22T08:30:29+00:00"
},
{
"name": "psr/cache",
@@ -5661,7 +5647,7 @@
"psr",
"psr-6"
],
- "time": "2016-08-06 20:24:11"
+ "time": "2016-08-06T20:24:11+00:00"
},
{
"name": "psr/http-message",
@@ -5711,7 +5697,7 @@
"request",
"response"
],
- "time": "2016-08-06 14:39:51"
+ "time": "2016-08-06T14:39:51+00:00"
},
{
"name": "psr/log",
@@ -5758,7 +5744,7 @@
"psr",
"psr-3"
],
- "time": "2016-10-10 12:19:37"
+ "time": "2016-10-10T12:19:37+00:00"
},
{
"name": "ramsey/uuid",
@@ -5840,7 +5826,7 @@
"identifier",
"uuid"
],
- "time": "2016-11-22 19:21:44"
+ "time": "2016-11-22T19:21:44+00:00"
},
{
"name": "react/promise",
@@ -5883,7 +5869,7 @@
"promise",
"promises"
],
- "time": "2016-12-22 14:09:01"
+ "time": "2016-12-22T14:09:01+00:00"
},
{
"name": "roave/security-advisories",
@@ -5893,6 +5879,12 @@
"url": "https://github.com/Roave/SecurityAdvisories.git",
"reference": "0698207bf8a9bed212fdde2d8c7cdc77085660c4"
},
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/0698207bf8a9bed212fdde2d8c7cdc77085660c4",
+ "reference": "0698207bf8a9bed212fdde2d8c7cdc77085660c4",
+ "shasum": ""
+ },
"conflict": {
"adodb/adodb-php": "<5.20.6",
"amphp/artax": ">=2,<2.0.4|>0.7.1,<1.0.4",
@@ -6008,7 +6000,7 @@
}
],
"description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it",
- "time": "2017-01-24 18:32:04"
+ "time": "2017-01-24T18:32:04+00:00"
},
{
"name": "seld/jsonlint",
@@ -6054,7 +6046,7 @@
"parser",
"validator"
],
- "time": "2016-11-14 17:59:58"
+ "time": "2016-11-14T17:59:58+00:00"
},
{
"name": "silex/silex",
@@ -6132,7 +6124,7 @@
"microframework"
],
"abandoned": "symfony/flex",
- "time": "2016-01-06 14:59:35"
+ "time": "2016-01-06T14:59:35+00:00"
},
{
"name": "silex/web-profiler",
@@ -6177,8 +6169,8 @@
],
"description": "A WebProfiler for Silex",
"homepage": "http://silex.sensiolabs.org/",
- "abandoned": true,
- "time": "2016-01-10 11:39:13"
+ "abandoned": "symfony/web-profiler-bundle",
+ "time": "2016-01-10T11:39:13+00:00"
},
{
"name": "simple-bus/doctrine-orm-bridge",
@@ -6232,7 +6224,7 @@
"doctrine",
"event bus"
],
- "time": "2015-04-29 12:27:27"
+ "time": "2015-04-29T12:27:27+00:00"
},
{
"name": "simple-bus/jms-serializer-bridge",
@@ -6281,7 +6273,7 @@
"message",
"serialization"
],
- "time": "2015-07-29 07:48:42"
+ "time": "2015-07-29T07:48:42+00:00"
},
{
"name": "simple-bus/message-bus",
@@ -6331,7 +6323,7 @@
"message",
"message bus"
],
- "time": "2016-02-12 08:35:53"
+ "time": "2016-02-12T08:35:53+00:00"
},
{
"name": "simple-bus/serialization",
@@ -6379,7 +6371,7 @@
"messages",
"serialization"
],
- "time": "2015-05-08 13:34:17"
+ "time": "2015-05-08T13:34:17+00:00"
},
{
"name": "sorien/silex-dbal-profiler",
@@ -6427,7 +6419,8 @@
"profiler",
"silex"
],
- "time": "2016-10-26 11:08:02"
+ "abandoned": true,
+ "time": "2016-10-26T11:08:02+00:00"
},
{
"name": "sorien/silex-pimple-dumper",
@@ -6469,7 +6462,8 @@
"plugin",
"silex"
],
- "time": "2015-11-11 07:16:28"
+ "abandoned": true,
+ "time": "2015-11-11T07:16:28+00:00"
},
{
"name": "swftools/swftools",
@@ -6523,7 +6517,7 @@
"flash",
"swf"
],
- "time": "2013-07-03 13:11:36"
+ "time": "2013-07-03T13:11:36+00:00"
},
{
"name": "swiftmailer/swiftmailer",
@@ -6577,7 +6571,7 @@
"mail",
"mailer"
],
- "time": "2016-12-29 10:02:40"
+ "time": "2016-12-29T10:02:40+00:00"
},
{
"name": "symfony/polyfill-apcu",
@@ -6630,7 +6624,7 @@
"portable",
"shim"
],
- "time": "2016-11-14 01:06:16"
+ "time": "2016-11-14T01:06:16+00:00"
},
{
"name": "symfony/polyfill-intl-icu",
@@ -6688,7 +6682,7 @@
"portable",
"shim"
],
- "time": "2016-11-14 01:06:16"
+ "time": "2016-11-14T01:06:16+00:00"
},
{
"name": "symfony/polyfill-mbstring",
@@ -6747,7 +6741,7 @@
"portable",
"shim"
],
- "time": "2016-11-14 01:06:16"
+ "time": "2016-11-14T01:06:16+00:00"
},
{
"name": "symfony/polyfill-php54",
@@ -6805,7 +6799,7 @@
"portable",
"shim"
],
- "time": "2016-11-14 01:06:16"
+ "time": "2016-11-14T01:06:16+00:00"
},
{
"name": "symfony/polyfill-php55",
@@ -6861,7 +6855,7 @@
"portable",
"shim"
],
- "time": "2016-11-14 01:06:16"
+ "time": "2016-11-14T01:06:16+00:00"
},
{
"name": "symfony/polyfill-php56",
@@ -6917,7 +6911,7 @@
"portable",
"shim"
],
- "time": "2016-11-14 01:06:16"
+ "time": "2016-11-14T01:06:16+00:00"
},
{
"name": "symfony/polyfill-php70",
@@ -6976,7 +6970,7 @@
"portable",
"shim"
],
- "time": "2016-11-14 01:06:16"
+ "time": "2016-11-14T01:06:16+00:00"
},
{
"name": "symfony/polyfill-util",
@@ -7028,7 +7022,7 @@
"polyfill",
"shim"
],
- "time": "2016-11-14 01:06:16"
+ "time": "2016-11-14T01:06:16+00:00"
},
{
"name": "symfony/security-acl",
@@ -7089,7 +7083,7 @@
],
"description": "Symfony Security Component - ACL (Access Control List)",
"homepage": "https://symfony.com",
- "time": "2015-12-28 09:39:46"
+ "time": "2015-12-28T09:39:46+00:00"
},
{
"name": "symfony/symfony",
@@ -7224,7 +7218,7 @@
"keywords": [
"framework"
],
- "time": "2017-01-12 20:27:46"
+ "time": "2017-01-12T20:27:46+00:00"
},
{
"name": "themattharris/tmhoauth",
@@ -7266,7 +7260,7 @@
"oauth",
"twitter"
],
- "time": "2014-08-06 22:29:35"
+ "time": "2014-08-06T22:29:35+00:00"
},
{
"name": "twig/extensions",
@@ -7318,7 +7312,7 @@
"i18n",
"text"
],
- "time": "2016-10-25 17:34:14"
+ "time": "2016-10-25T17:34:14+00:00"
},
{
"name": "twig/twig",
@@ -7379,7 +7373,7 @@
"keywords": [
"templating"
],
- "time": "2017-01-11 19:36:15"
+ "time": "2017-01-11T19:36:15+00:00"
},
{
"name": "vierbergenlars/php-semver",
@@ -7427,7 +7421,7 @@
"semver",
"versioning"
],
- "time": "2013-09-20 10:41:27"
+ "time": "2013-09-20T10:41:27+00:00"
},
{
"name": "webmozart/assert",
@@ -7477,7 +7471,7 @@
"check",
"validate"
],
- "time": "2016-11-23 20:04:58"
+ "time": "2016-11-23T20:04:58+00:00"
},
{
"name": "webmozart/json",
@@ -7526,7 +7520,7 @@
}
],
"description": "A robust JSON decoder/encoder with support for schema validation.",
- "time": "2016-01-14 12:11:46"
+ "time": "2016-01-14T12:11:46+00:00"
},
{
"name": "webmozart/path-util",
@@ -7572,7 +7566,7 @@
}
],
"description": "A robust cross-platform utility for normalizing, comparing and modifying file paths.",
- "time": "2015-12-17 08:42:14"
+ "time": "2015-12-17T08:42:14+00:00"
},
{
"name": "willdurand/negotiation",
@@ -7624,7 +7618,7 @@
"header",
"negotiation"
],
- "time": "2016-10-14 09:17:47"
+ "time": "2016-10-14T09:17:47+00:00"
},
{
"name": "zend/gdata",
@@ -7665,7 +7659,7 @@
"gdata",
"zend"
],
- "time": "2013-01-30 15:31:21"
+ "time": "2013-01-30T15:31:21+00:00"
},
{
"name": "zendframework/zend-code",
@@ -7717,7 +7711,8 @@
"code",
"zf2"
],
- "time": "2016-04-20 17:26:42"
+ "abandoned": "laminas/laminas-code",
+ "time": "2016-04-20T17:26:42+00:00"
},
{
"name": "zendframework/zend-eventmanager",
@@ -7771,7 +7766,8 @@
"events",
"zf2"
],
- "time": "2016-02-18 20:53:00"
+ "abandoned": "laminas/laminas-eventmanager",
+ "time": "2016-02-18T20:53:00+00:00"
}
],
"packages-dev": [
@@ -7819,7 +7815,7 @@
],
"description": "Virtual file system to mock the real file system in unit tests.",
"homepage": "http://vfs.bovigo.org/",
- "time": "2016-07-18 14:02:57"
+ "time": "2016-07-18T14:02:57+00:00"
},
{
"name": "phpdocumentor/reflection-common",
@@ -7873,7 +7869,7 @@
"reflection",
"static analysis"
],
- "time": "2015-12-27 11:43:31"
+ "time": "2015-12-27T11:43:31+00:00"
},
{
"name": "phpdocumentor/reflection-docblock",
@@ -7918,7 +7914,7 @@
}
],
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
- "time": "2016-09-30 07:12:33"
+ "time": "2016-09-30T07:12:33+00:00"
},
{
"name": "phpdocumentor/type-resolver",
@@ -7965,7 +7961,40 @@
"email": "me@mikevanriel.com"
}
],
- "time": "2016-11-25 06:54:22"
+ "time": "2016-11-25T06:54:22+00:00"
+ },
+ {
+ "name": "phpexiftool/exiftool",
+ "version": "10.10",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/alchemy-fr/exiftool.git",
+ "reference": "0833cab894c890353192a83011428525a318bedf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/alchemy-fr/exiftool/zipball/0833cab894c890353192a83011428525a318bedf",
+ "reference": "0833cab894c890353192a83011428525a318bedf",
+ "shasum": ""
+ },
+ "type": "library",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Perl Licensing"
+ ],
+ "authors": [
+ {
+ "name": "Phil Harvey",
+ "email": "phil@owl.phy.queensu.ca",
+ "homepage": "http://www.sno.phy.queensu.ca/~phil/exiftool/"
+ }
+ ],
+ "description": "Exiftool is a library for reading, writing and editing meta information. This package is not PHP, but required for the main PHP driver : PHP Exiftool",
+ "keywords": [
+ "exiftool",
+ "metadatas"
+ ],
+ "time": "2016-01-25T11:10:14+00:00"
},
{
"name": "phpspec/prophecy",
@@ -8028,7 +8057,7 @@
"spy",
"stub"
],
- "time": "2016-11-21 14:58:47"
+ "time": "2016-11-21T14:58:47+00:00"
},
{
"name": "phpunit/php-code-coverage",
@@ -8090,7 +8119,7 @@
"testing",
"xunit"
],
- "time": "2015-10-06 15:47:00"
+ "time": "2015-10-06T15:47:00+00:00"
},
{
"name": "phpunit/php-file-iterator",
@@ -8137,7 +8166,7 @@
"filesystem",
"iterator"
],
- "time": "2016-10-03 07:40:28"
+ "time": "2016-10-03T07:40:28+00:00"
},
{
"name": "phpunit/php-text-template",
@@ -8178,7 +8207,7 @@
"keywords": [
"template"
],
- "time": "2015-06-21 13:50:34"
+ "time": "2015-06-21T13:50:34+00:00"
},
{
"name": "phpunit/php-timer",
@@ -8222,7 +8251,7 @@
"keywords": [
"timer"
],
- "time": "2016-05-12 18:03:57"
+ "time": "2016-05-12T18:03:57+00:00"
},
{
"name": "phpunit/php-token-stream",
@@ -8271,7 +8300,7 @@
"keywords": [
"tokenizer"
],
- "time": "2016-11-15 14:06:22"
+ "time": "2016-11-15T14:06:22+00:00"
},
{
"name": "phpunit/phpunit",
@@ -8343,7 +8372,7 @@
"testing",
"xunit"
],
- "time": "2017-01-26 16:15:36"
+ "time": "2017-01-26T16:15:36+00:00"
},
{
"name": "phpunit/phpunit-mock-objects",
@@ -8400,7 +8429,7 @@
"xunit"
],
"abandoned": true,
- "time": "2015-10-02 06:51:40"
+ "time": "2015-10-02T06:51:40+00:00"
},
{
"name": "sebastian/comparator",
@@ -8464,7 +8493,7 @@
"compare",
"equality"
],
- "time": "2017-01-29 09:50:25"
+ "time": "2017-01-29T09:50:25+00:00"
},
{
"name": "sebastian/diff",
@@ -8516,7 +8545,7 @@
"keywords": [
"diff"
],
- "time": "2015-12-08 07:14:41"
+ "time": "2015-12-08T07:14:41+00:00"
},
{
"name": "sebastian/environment",
@@ -8566,7 +8595,7 @@
"environment",
"hhvm"
],
- "time": "2016-08-18 05:49:44"
+ "time": "2016-08-18T05:49:44+00:00"
},
{
"name": "sebastian/exporter",
@@ -8633,7 +8662,7 @@
"export",
"exporter"
],
- "time": "2016-06-17 09:04:28"
+ "time": "2016-06-17T09:04:28+00:00"
},
{
"name": "sebastian/global-state",
@@ -8684,7 +8713,7 @@
"keywords": [
"global state"
],
- "time": "2015-10-12 03:26:01"
+ "time": "2015-10-12T03:26:01+00:00"
},
{
"name": "sebastian/recursion-context",
@@ -8737,7 +8766,7 @@
],
"description": "Provides functionality to recursively process PHP variables",
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
- "time": "2015-11-11 19:50:13"
+ "time": "2015-11-11T19:50:13+00:00"
},
{
"name": "sebastian/version",
@@ -8772,7 +8801,7 @@
],
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
"homepage": "https://github.com/sebastianbergmann/version",
- "time": "2015-06-21 13:59:46"
+ "time": "2015-06-21T13:59:46+00:00"
}
],
"aliases": [
diff --git a/config/configuration.sample.yml b/config/configuration.sample.yml
index fbaa368ed9..9bbea0d4bc 100644
--- a/config/configuration.sample.yml
+++ b/config/configuration.sample.yml
@@ -22,13 +22,54 @@ main:
path: '/tmp/db.sqlite'
charset: UTF8
cache:
- type: MemcacheCache
+ type: redis
options:
host: localhost
- port: 11211
+ port: 6379
search-engine:
- type: phrasea
- options: []
+ type: elasticsearch
+ options:
+ host: elasticsearch
+ port: 9200
+ index: ''
+ shards: 3
+ replicas: 0
+ minScore: 2
+ highlight: true
+ populate_order: RECORD_ID
+ populate_direction: DESC
+ activeTab: ''
+ facets:
+ _base:
+ limit: 10
+ _collection:
+ limit: 10
+ _doctype:
+ limit: 10
+ _camera_model:
+ limit: 0
+ _iso:
+ limit: 0
+ _aperture:
+ limit: 0
+ _shutterspeed:
+ limit: 0
+ _flashfired:
+ limit: 0
+ _framerate:
+ limit: 0
+ _audiosamplerate:
+ limit: 0
+ _videocodec:
+ limit: 0
+ _audiocodec:
+ limit: 0
+ _orientation:
+ limit: 0
+ _colorspace:
+ limit: 0
+ _mimetype:
+ limit: 0
task-manager:
status: started
enabled: true
@@ -62,12 +103,7 @@ main:
mp4box_timeout: 60
swftools_timeout: 60
unoconv_timeout: 60
- task-manager:
- status: started
- listener:
- protocol: tcp
- host: 127.0.0.1
- port: 6700
+ exiftool_timeout: 60
storage:
subdefs: null
cache: null
@@ -75,20 +111,7 @@ main:
download: null
lazaret: null
caption: null
- bridge:
- youtube:
- enabled: false
- client_id: null
- client_secret: null
- developer_key: null
- flickr:
- enabled: false
- client_id: null
- client_secret: null
- dailymotion:
- enabled: false
- client_id: null
- client_secret: null
+ tmp_files: null
border-manager:
enabled: true
extension-mapping:
@@ -98,12 +121,17 @@ border-manager:
-
type: Checker\Sha256
enabled: true
+ collections: []
+ compare-ignore-collections: []
-
type: Checker\UUID
enabled: true
+ collections: []
+ compare-ignore-collections: []
-
type: Checker\Colorspace
enabled: false
+ collections: []
options:
colorspaces: [cmyk, grayscale, rgb]
media_types: [Image]
@@ -123,6 +151,8 @@ border-manager:
enabled: false
options:
sensitive: true
+ collections: []
+ compare-ignore-collections: []
-
type: Checker\MediaType
enabled: false
@@ -244,6 +274,14 @@ embed_bundle:
document:
player: flexpaper
enable_pdfjs: true
+video-editor:
+ ChapterVttFieldName: VideoTextTrackChapters
+ seekBackwardStep: 500 # in ms
+ seekForwardStep: 500 # in ms
+ playbackRates:
+ - 1
+ - '1.5'
+ - 3
geocoding-providers:
-
map-provider: mapboxWebGL
diff --git a/docker/phraseanet/auto-install.sh b/docker/phraseanet/auto-install.sh
index b69490fd03..00e8601edb 100755
--- a/docker/phraseanet/auto-install.sh
+++ b/docker/phraseanet/auto-install.sh
@@ -27,9 +27,10 @@ fi
/var/alchemy/Phraseanet/bin/setup system:config set main.search-engine.options.host elasticsearch
/var/alchemy/Phraseanet/bin/setup system:config set main.search-engine.options.minScore 2
-/var/alchemy/Phraseanet/bin/setup system:config set main.search-engine.options.base_aggregate_limit 10
-/var/alchemy/Phraseanet/bin/setup system:config set main.search-engine.options.collection_aggregate_limit 10
-/var/alchemy/Phraseanet/bin/setup system:config set main.search-engine.options.doctype_aggregate_limit 10
+/var/alchemy/Phraseanet/bin/setup system:config set main.search-engine.options.minScore 2
+/var/alchemy/Phraseanet/bin/setup system:config set main.search-engine.options.facets._base.limit 10
+/var/alchemy/Phraseanet/bin/setup system:config set main.search-engine.options.facets._collection.limit 10
+/var/alchemy/Phraseanet/bin/setup system:config set main.search-engine.options.facets._doctype.limit 10
## Redis
/var/alchemy/Phraseanet/bin/setup system:config set main.cache.options.host redis
diff --git a/docker/phraseanet/boot.sh b/docker/phraseanet/boot.sh
index 444b63a64c..578da3a8da 100755
--- a/docker/phraseanet/boot.sh
+++ b/docker/phraseanet/boot.sh
@@ -14,4 +14,4 @@ else
runuser app -c '/auto-install.sh'
fi
-php-fpm
+php-fpm -F
diff --git a/docker/phraseanet/phraseanet-entrypoint.sh b/docker/phraseanet/phraseanet-entrypoint.sh
index 225b56a672..3040718c11 100755
--- a/docker/phraseanet/phraseanet-entrypoint.sh
+++ b/docker/phraseanet/phraseanet-entrypoint.sh
@@ -4,5 +4,16 @@ set -e
envsubst < /php.ini.sample > /usr/local/etc/php/php.ini
envsubst < /php-fpm.conf.sample > /usr/local/etc/php-fpm.conf
+echo "XDEBUG=$XDEBUG"
+if [ $XDEBUG = "ON" ]; then
+ echo "XDEBUG IS ENABLED. YOU MAY KEEP THIS FEATURE DISABLED IN PRODUCTION."
+ echo "xdebug.remote_enable=1" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
+ echo "xdebug.remote_autostart=1" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
+ echo "xdebug.remote_host=$XDEBUG_SERVER" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
+ echo "xdebug.remote_port=$XDEBUG_REMOTE_PORT" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
+ echo "xdebug.remote_handler=dbgp" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
+ echo "xdebug.remote_connect_back=0" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
+ #echo "xdebug.idekey=11896" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
+fi
bash -e docker-php-entrypoint $@
diff --git a/lib/Alchemy/Phrasea/Application/ApiApplicationLoader.php b/lib/Alchemy/Phrasea/Application/ApiApplicationLoader.php
index 490554c95e..ca47f16baa 100644
--- a/lib/Alchemy/Phrasea/Application/ApiApplicationLoader.php
+++ b/lib/Alchemy/Phrasea/Application/ApiApplicationLoader.php
@@ -15,6 +15,7 @@ use Alchemy\Phrasea\Controller\Api\Result;
use Alchemy\Phrasea\ControllerProvider\Api\OAuth2;
use Alchemy\Phrasea\ControllerProvider\Api\V1;
use Alchemy\Phrasea\ControllerProvider\Api\V2;
+use Alchemy\Phrasea\ControllerProvider\Api\V3;
use Alchemy\Phrasea\ControllerProvider\Datafiles;
use Alchemy\Phrasea\ControllerProvider\MediaAccessor;
use Alchemy\Phrasea\ControllerProvider\Minifier;
@@ -36,6 +37,7 @@ class ApiApplicationLoader extends BaseApplicationLoader
$app->register(new OAuth2());
$app->register(new V1());
$app->register(new V2());
+ $app->register(new V3());
$app->register(new ApiReportControllerProvider());
$app->register(new JsonSchemaServiceProvider());
}
@@ -119,6 +121,16 @@ class ApiApplicationLoader extends BaseApplicationLoader
'access_token' => '/api/oauthv2/token'
],
],
+ '3' => [
+ 'number' => V3::VERSION,
+ 'uri' => '/api/v3/',
+ 'authenticationProtocol' => 'OAuth2',
+ 'authenticationVersion' => 'draft#v9',
+ 'authenticationEndPoints' => [
+ 'authorization_token' => '/api/oauthv2/authorize',
+ 'access_token' => '/api/oauthv2/token'
+ ]
+ ],
]
])->createResponse();
});
@@ -135,6 +147,7 @@ class ApiApplicationLoader extends BaseApplicationLoader
$app->mount('/datafiles/', new Datafiles());
$app->mount('/api/v1', new V1());
$app->mount('/api/v2', new V2());
+ $app->mount('/api/v3', new V3());
$app->mount('/api/report', new ApiReportControllerProvider());
$app->mount('/permalink/', new Permalink());
$app->mount($app['controller.media_accessor.route_prefix'], new MediaAccessor());
diff --git a/lib/Alchemy/Phrasea/Command/Collection/ListCollectionCommand.php b/lib/Alchemy/Phrasea/Command/Collection/ListCollectionCommand.php
new file mode 100644
index 0000000000..7cf2d91ced
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Command/Collection/ListCollectionCommand.php
@@ -0,0 +1,86 @@
+setDescription('List all collection in Phraseanet')
+ ->addOption('databox_id', 'd', InputOption::VALUE_REQUIRED, 'The id of the databox to list collection')
+ ->addOption('jsonformat', null, InputOption::VALUE_NONE, 'Output in json format')
+ ->setHelp('');
+ return $this;
+ }
+ protected function doExecute(InputInterface $input, OutputInterface $output)
+ {
+ try {
+ $jsonformat = $input->getOption('jsonformat');
+ $databox = $this->container->findDataboxById($input->getOption('databox_id'));
+ $collections = $this->listDataboxCollections($databox);
+
+ if ($jsonformat) {
+ foreach ($collections as $collection) {
+ $collectionList[] = array_combine(['id local for API', 'id distant', 'name','label','status','total records'], $collection);
+ }
+ echo json_encode($collectionList);
+ } else {
+ $table = $this->getHelperSet()->get('table');
+ $table
+ ->setHeaders(['id local for API', 'id distant', 'name','label','status','total records'])
+ ->setRows($collections)
+ ->render($output);
+ }
+
+ } catch (\Exception $e) {
+ $output->writeln("{$e->getMessage()}");
+ }
+ return 0;
+ }
+
+ private function listDataboxCollections(\databox $databox)
+ {
+ return array_map(function (\collection $collection) {
+ return $this->listCollection($collection);
+ }, array_merge($databox->get_collections(),$this->getUnabledCollection($databox->get_activable_colls())));
+ }
+
+ private function getUnabledCollection($collections)
+ {
+ return array_map(function ($colId){
+ return \collection::getByBaseId($this->container, $colId);
+ },$collections);
+
+ }
+
+ private function listCollection(\collection $collection)
+ {
+ return [
+ $collection->get_base_id(),
+ $collection->get_coll_id(),
+ $collection->get_name(),
+ 'en: ' . $collection->get_label('en') .
+ ', de: ' . $collection->get_label('de') .
+ ', fr: ' . $collection->get_label('fr') .
+ ', nl: ' . $collection->get_label('nl'),
+ ($collection->is_active()) ? 'enabled' : 'disabled',
+ $collection->get_record_amount()
+ ];
+ }
+}
\ No newline at end of file
diff --git a/lib/Alchemy/Phrasea/Command/Databox/ListDataboxCommand.php b/lib/Alchemy/Phrasea/Command/Databox/ListDataboxCommand.php
new file mode 100644
index 0000000000..92a30435fe
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Command/Databox/ListDataboxCommand.php
@@ -0,0 +1,72 @@
+setDescription('List all databox in Phraseanet')
+ ->addOption('jsonformat', null, InputOption::VALUE_NONE, 'Output in json format')
+ ->setHelp('');
+
+ return $this;
+ }
+
+ protected function doExecute(InputInterface $input, OutputInterface $output)
+ {
+ try {
+ $jsonformat = $input->getOption('jsonformat');
+ $databoxes = array_map(function (\databox $databox) {
+ return $this->listDatabox($databox);
+ }, $this->container->getApplicationBox()->get_databoxes());
+
+ if ($jsonformat) {
+ foreach ($databoxes as $databox) {
+ $databoxList[] = array_combine(['id', 'name', 'alias'], $databox);
+ }
+ echo json_encode($databoxList);
+ } else {
+ $table = $this->getHelperSet()->get('table');
+ $table
+ ->setHeaders(['id', 'name', 'alias'])
+ ->setRows($databoxes)
+ ->render($output);
+ }
+
+ } catch (\Exception $e) {
+ $output->writeln('Listing databox failed : '.$e->getMessage().'');
+ }
+
+ return 0;
+ }
+
+ private function listDatabox(\databox $databox)
+ {
+ return [
+ $databox->get_sbas_id(),
+ $databox->get_dbname(),
+ $databox->get_viewname()
+ ];
+ }
+
+}
diff --git a/lib/Alchemy/Phrasea/Command/Developer/JsFixtures.php b/lib/Alchemy/Phrasea/Command/Developer/JsFixtures.php
index 890fed9e6d..112914d088 100644
--- a/lib/Alchemy/Phrasea/Command/Developer/JsFixtures.php
+++ b/lib/Alchemy/Phrasea/Command/Developer/JsFixtures.php
@@ -15,6 +15,7 @@ use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Command\Command;
use Alchemy\Phrasea\Exception\RuntimeException;
use Alchemy\Phrasea\Model\Entities\User;
+use Alchemy\Phrasea\Plugin\Plugin;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\HttpKernel\Client;
@@ -30,6 +31,15 @@ class JsFixtures extends Command
protected function doExecute(InputInterface $input, OutputInterface $output)
{
+ /** @var Plugin $plugin */
+ $msg = [];
+ foreach($this->container['plugins.manager']->listPlugins() as $plugin) {
+ $msg[] = sprintf(" bin/setup plugins:remove \"%s\"", $plugin->getName());
+ }
+ if(count($msg) !== 0) {
+ throw new RuntimeException("You must remove plugins first:\n" . join("\n", $msg));
+ }
+
if (!file_exists($this->container['db.fixture.info']['path'])) {
throw new RuntimeException('You must generate sqlite db first, run "bin/developer phraseanet:regenerate-sqlite" command.');
}
@@ -104,6 +114,7 @@ class JsFixtures extends Command
private function writeResponse(OutputInterface $output, $method, $path, $to, $authenticateUser = false)
{
$environment = Application::ENV_TEST;
+ /** @var Application $app */
$app = require __DIR__ . '/../../Application/Root.php';
$app['orm.em'] = $app->extend('orm.em', function($em, $app) {
return $app['orm.ems'][$app['db.fixture.hash.key']];
diff --git a/lib/Alchemy/Phrasea/Command/User/UserCreateCommand.php b/lib/Alchemy/Phrasea/Command/User/UserCreateCommand.php
new file mode 100644
index 0000000000..66a33f1916
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Command/User/UserCreateCommand.php
@@ -0,0 +1,211 @@
+setDescription('Create user in Phraseanet')
+ ->addOption('user_login', null, InputOption::VALUE_REQUIRED, 'The desired login for created user.')
+ ->addOption('user_mail', null, InputOption::VALUE_OPTIONAL, 'The desired mail for created user.')
+ ->addOption('user_password', null, InputOption::VALUE_OPTIONAL, 'The desired password')
+ ->addOption('send_mail_confirm', null, InputOption::VALUE_NONE, 'Send an email to user, for validate email.')
+ ->addOption('send_mail_password', null, InputOption::VALUE_NONE, 'Send an email to user, for password definition, work only if user_password is not define')
+ ->addOption('model_number', null, InputOption::VALUE_OPTIONAL, 'Id of model')
+ ->addOption('user_gender', null, InputOption::VALUE_OPTIONAL, 'The gender for created user.')
+ ->addOption('user_firstname', null, InputOption::VALUE_OPTIONAL, 'The first name for created user.')
+ ->addOption('user_lastname', null, InputOption::VALUE_OPTIONAL, 'The last name for created user.')
+ ->addOption('user_compagny', null, InputOption::VALUE_OPTIONAL, 'The compagny for created user.')
+ ->addOption('user_job', null, InputOption::VALUE_OPTIONAL, 'The job for created user.')
+ ->addOption('user_activitie', null, InputOption::VALUE_OPTIONAL, 'The activitie for created user.')
+ ->addOption('user_phone', null, InputOption::VALUE_OPTIONAL, 'The phone number for created user.')
+ ->setHelp('');
+
+ return $this;
+ }
+
+ protected function doExecute(InputInterface $input, OutputInterface $output)
+ {
+
+ $userLogin = $input->getOption('user_login');
+ $userMail = $input->getOption('user_mail');
+ $userPassword = $input->getOption('user_password');
+ $sendMailConfirm = $input->getOption('send_mail_confirm');
+ $sendMailPassword = $input->getOption('send_mail_password');
+ $modelNumber = $input->getOption('model_number');
+ $userGender = $input->getOption('user_gender');
+ $userFirstName = $input->getOption('user_firstname');
+ $userLastName = $input->getOption('user_lastname');
+ $userCompagny = $input->getOption('user_compagny');
+ $userJob = $input->getOption('user_job');
+ $userActivity = $input->getOption('user_activitie');
+ $userPhone = $input->getOption('user_phone');
+
+ $userRepository = $this->container['repo.users'];
+
+ if ($userMail) {
+ if (!\Swift_Validate::email($userMail)) {
+ $output->writeln('Invalid mail address');
+ return 0;
+ }
+
+ if (null !== $userRepository->findByEmail($userMail)) {
+ $output->writeln('An user exist with this email.');
+ return 0;
+ }
+
+ }
+
+ $password = (!is_null($userPassword)) ? $userPassword : $this->container['random.medium']->generateString(128);
+ $userManipulator = $this->container['manipulator.user'];
+ $user = $userManipulator->createUser($userLogin, $password, $userMail);
+
+ if ($userGender) {
+ if (null === $gender = $this->verifyGender($userGender)) {
+ $output->writeln('Gender '.$userGender.' not exists.>');
+ }
+ $user->setGender($gender);
+ }
+
+ if($userFirstName) $user->setFirstName($userFirstName);
+ if($userLastName) $user->setLastName($userLastName);
+ if($userCompagny) $user->setCompany($userCompagny);
+ if($userJob) $user->setJob($userJob);
+ if($userActivity) $user->setActivity($userActivity);
+ if($userPhone) $user->setPhone($userPhone);
+
+ if ($sendMailPassword and $userMail and is_null($userPassword)) {
+ $this->sendPasswordSetupMail($user);
+ }
+
+ if ($sendMailConfirm and $userMail) {
+ $user->setMailLocked(true);
+ $this->sendAccountUnlockEmail($user);
+ }
+
+ if ($modelNumber) {
+ $template = $userRepository->find($modelNumber);
+ if (!$template) {
+ $output->writeln('Model '.$modelNumber.' not found.>');
+ } else {
+ $base_ids = [];
+ foreach ($this->container->getApplicationBox()->get_databoxes() as $databox) {
+ foreach ($databox->get_collections() as $collection) {
+ $base_ids[] = $collection->get_base_id();
+ }
+ }
+ $this->container->getAclForUser($user)->apply_model($template, $base_ids);
+ }
+ }
+
+ $this->container['orm.em']->flush();
+
+ $output->writeln("Create new user successful !");
+
+ return 0;
+ }
+
+ /**
+ * Get gender for user
+ * @param $type
+ * @return int|null
+ */
+ private function verifyGender($type)
+ {
+ switch (strtolower($type)) {
+ case "mlle.":
+ case "mlle":
+ case "miss":
+ case "mademoiselle":
+ case "0":
+ $gender = User::GENDER_MISS;
+ break;
+ case "mme":
+ case "madame":
+ case "ms":
+ case "ms.":
+ case "1":
+ $gender = User::GENDER_MRS;
+ break;
+ case "m":
+ case "m.":
+ case "mr":
+ case "mr.":
+ case "monsieur":
+ case "mister":
+ case "2":
+ $gender = User::GENDER_MR;
+ break;
+ default:
+ $gender = null;
+ }
+ return $gender;
+ }
+
+ /**
+ * Send mail for renew password
+ * @param User $user
+ */
+ public function sendPasswordSetupMail(User $user)
+ {
+ $this->setDelivererLocator(new LazyLocator($this->container, 'notification.deliverer'));
+ $receiver = Receiver::fromUser($user);
+
+ $token = $this->container['manipulator.token']->createResetPasswordToken($user);
+
+ $mail = MailRequestPasswordSetup::create($this->container, $receiver);
+ $servername = $this->container['conf']->get('servername');
+ $mail->setButtonUrl('http://'.$servername.'/login/renew-password/?token='.$token->getValue());
+ $mail->setLogin($user->getLogin());
+
+ $this->deliver($mail);
+ }
+
+ /**
+ * @param User $user
+ */
+ public function sendAccountUnlockEmail(User $user)
+ {
+ $this->setDelivererLocator(new LazyLocator($this->container, 'notification.deliverer'));
+ $receiver = Receiver::fromUser($user);
+
+ $token = $this->container['manipulator.token']->createAccountUnlockToken($user);
+
+ $mail = MailRequestEmailConfirmation::create($this->container, $receiver);
+ $servername = $this->container['conf']->get('servername');
+ $mail->setButtonUrl('http://'.$servername.'/login/register-confirm/?code='.$token->getValue());
+ $mail->setExpiration($token->getExpiration());
+
+ $this->deliver($mail);
+ }
+
+}
diff --git a/lib/Alchemy/Phrasea/Command/User/UserListCommand.php b/lib/Alchemy/Phrasea/Command/User/UserListCommand.php
new file mode 100644
index 0000000000..bf3f87e478
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Command/User/UserListCommand.php
@@ -0,0 +1,287 @@
+setDescription('List of all user (experimental)')
+ ->addOption('user_id', null, InputOption::VALUE_OPTIONAL, ' The id of user export only info this user ')
+ ->addOption('user_email', null, InputOption::VALUE_OPTIONAL, 'The mail of user export only info this user .')
+ ->addOption('database_id', null, InputOption::VALUE_OPTIONAL, 'Id of database.')
+ ->addOption('collection_id', null, InputOption::VALUE_OPTIONAL, 'Id of the collection.')
+ ->addOption('mail_lock_status', null, InputOption::VALUE_NONE, 'Status by mail locked')
+ ->addOption('guest', null, InputOption::VALUE_NONE, 'Only guest user')
+ ->addOption('created', null, InputOption::VALUE_OPTIONAL, 'Created at with operator,aaaa-mm-jj hh:mm:ss.')
+ ->addOption('updated', null, InputOption::VALUE_OPTIONAL, 'Update at with operator,aaaa-mm-jj hh:mm:ss.')
+ ->addOption('application', null, InputOption::VALUE_NONE, 'List application of user work only if --user_id is set')
+ ->addOption('right', null, InputOption::VALUE_NONE, 'Show right information')
+ ->addOption('adress', null, InputOption::VALUE_NONE, 'Show adress information')
+ ->addOption('models', null, InputOption::VALUE_NONE, "Show only defined models, if --user_id is set with --models it's the template owner")
+ ->addOption('jsonformat', null, InputOption::VALUE_NONE, 'Output in json format')
+ ->setHelp('');
+
+ return $this;
+ }
+
+ protected function doExecute(InputInterface $input, OutputInterface $output)
+ {
+
+ $userId = $input->getOption('user_id');
+ $userEmail = $input->getOption('user_email');
+ $databaseId = $input->getOption('database_id');
+ $collectionId = $input->getOption('collection_id');
+ $lockStatus = $input->getOption('mail_lock_status');
+ $guest = $input->getOption('guest');
+ $application = $input->getOption('application');
+ $withAdress = $input->getOption('adress');
+ $created = $input->getOption('created');
+ $updated = $input->getOption('updated');
+ $withRight = $input->getOption('right');
+ $models = $input->getOption('models');
+ $jsonformat = $input->getOption('jsonformat');
+
+ $query = $this->container['phraseanet.user-query'];
+
+ if($databaseId) $query->on_base_ids([$databaseId]);
+ if($collectionId) $query->on_sbas_ids([$collectionId]);
+ if($created) $this->addFilterDate($created,'created',$query);
+ if($updated) $this->addFilterDate($updated,'updated',$query);
+ if($userId && !$models) $query->addSqlFilter('Users.id = ?' ,[$userId]);
+ if($userEmail && !$models) $query->addSqlFilter('Users.email = ?' ,[$userEmail]);
+ if($lockStatus && !$models) $query->addSqlFilter('Users.mail_locked = 1');
+ if($guest && !$models) $query->include_invite(true)->addSqlFilter('Users.guest = 1');
+
+ if ($application and !$userId) {
+ $output->writeln('You must provide --user_id when using --application option');
+ return 0;
+ }
+
+ /** @var UserRepository $userRepository */
+ $userRepository = $this->container['repo.users'];
+
+ if ($models && $userId) {
+ $users = $userRepository->findBy(['templateOwner' => $userId]);
+ } elseif ($models) {
+ $users = $userRepository->findTemplate();
+ } else {
+ $users = $query->execute()->get_results();
+ }
+
+ $userList = [];
+ $showApplication = false;
+ foreach ($users as $key => $user) {
+ if ($userId and $application) {
+ $showApplication = true;
+ }
+ $userList[] = $this->listUser($user, $withAdress, $withRight);
+
+ $userListRaw[] = array_combine($this->headerTable($withAdress, $withRight), $this->listUser($user, $withAdress, $withRight));
+ }
+
+ if ($jsonformat) {
+ echo json_encode($userListRaw);
+ } else {
+ $table = $this->getHelperSet()->get('table');
+ $table
+ ->setHeaders($this->headerTable($withAdress, $withRight))
+ ->setRows($userList)
+ ->render($output);
+ ;
+
+
+ if ($showApplication) {
+ $applicationTable = $this->getHelperSet()->get('table');
+ $applicationTable->setHeaders(array(
+ array(new TableCell('Applications', array('colspan' => 5))),
+ ['name','callback','client_secret','client_id','token'],
+ ))->setRows($this->getApplicationOfUser($users[0]))->render($output);
+ }
+
+ }
+
+
+ return 0;
+ }
+
+ /**
+ * @param $withAdress
+ * @param $withRight
+ * @return array
+ */
+ private function headerTable($withAdress,$withRight)
+ {
+ $defaultHeader = ['id', 'login', 'email','last_model','first_name','last_name','gender','created','updated','status','locale'];
+ $adressHeader = [ 'address', 'zip_code', 'city', 'country', 'phone', 'fax', 'job','position', 'company', 'geoname_id'];
+ $rightHeader = [ 'admin', 'guest', 'mail_notification', 'ldap_created', 'mail_locked'];
+
+ return $this->createInformation($withAdress,$withRight,$defaultHeader,['adress' => $adressHeader,'right' =>$rightHeader]);
+ }
+
+ /**
+ * @param User $user
+ * @param $withAdress
+ * @param $withRight
+ * @return array
+ */
+ private function listUser(User $user,$withAdress,$withRight)
+ {
+ switch ($user->getGender()) {
+ case User::GENDER_MRS:
+ $gender = 'Mrs';
+ break;
+ case User::GENDER_MISS:
+ $gender = 'Miss';
+ break;
+ case User::GENDER_MR:
+ default:
+ $gender = 'Mr';
+ }
+
+ $defaultInfo = [
+ $user->getId(),
+ $user->getLogin() ?: '-',
+ $user->getEmail() ?: '-',
+ $user->getLastAppliedTemplate() ? $user->getLastAppliedTemplate()->getLogin() : '-',
+ $user->getFirstName() ?: '-',
+ $user->getLastName() ?: '-',
+ $gender,
+ NullableDateTime::format($user->getCreated(),'Y-m-d H:i:s'),
+ NullableDateTime::format($user->getUpdated(),'Y-m-d H:i:s'),
+ 'status',
+ $user->getLocale() ?: '-',
+ ];
+
+ return $this->createInformation($withAdress,$withRight,$defaultInfo,['adress' => $this->userAdress($user),'right' => $this->userRight($user)]);
+ }
+
+ /**
+ * @param User $user
+ * @return array
+ */
+ private function userAdress(User $user)
+ {
+ return [
+ $user->getAddress() ?: '-',
+ $user->getZipCode() ?: '-',
+ $user->getCity() ?: '-',
+ $user->getCountry() ?: '-',
+ $user->getPhone() ?: '-',
+ $user->getFax() ?: '-',
+ $user->getJob() ?: '-',
+ $user->getActivity() ?: '-',
+ $user->getCompany() ?: '-',
+ $user->getGeonameId() ?: '-',
+ ];
+ }
+
+ /**
+ * @param User $user
+ * @return array
+ */
+ private function userRight(User $user)
+ {
+ return [
+ $user->isAdmin() ?: false,
+ $user->isGuest() ?: false,
+ $user->hasMailNotificationsActivated() ?: false,
+ $user->hasLdapCreated() ?: false,
+ $user->isMailLocked() ?: false,
+ ];
+ }
+
+ /**
+ * @param User $user
+ * @return array
+ */
+ private function getApplicationOfUser(User $user)
+ {
+ $apiRepository = $this->container['repo.api-applications'];
+ $applications = $apiRepository->findByUser($user);
+
+ if (empty($applications)) {
+ return [];
+ }
+
+ $accountRepository = $this->container['repo.api-accounts'];
+ $apiOauthRepository = $this->container['repo.api-oauth-tokens'];
+ $usersApplication = [];
+ foreach ($applications as $application) {
+ $account = $accountRepository->findByUserAndApplication($user, $application);
+ $token = $account ? $apiOauthRepository->findDeveloperToken($account) : null;
+ $usersApplication[] = [
+ $application->getName(),
+ $application->getRedirectUri(),
+ $application->getClientSecret(),
+ $application->getClientId(),
+ ($token) ? $token->getOauthToken() : '-'
+ ];
+ }
+
+ return $usersApplication;
+ }
+
+ /**
+ * @param $withAdress
+ * @param $withRight
+ * @param $default
+ * @param $infoToMerge
+ * @return array
+ */
+ private function createInformation($withAdress,$withRight,$default,$infoToMerge)
+ {
+ if ($withAdress && $withRight) {
+ $information = array_merge($default, $infoToMerge['adress'],$infoToMerge['right']);
+ } elseif ($withAdress && !$withRight) {
+ $information = array_merge($default, $infoToMerge['adress']);
+ } elseif(!$withAdress && $withRight) {
+ $information = array_merge($default, $infoToMerge['right']);
+ } else {
+ $information = $default;
+ }
+
+ return $information;
+ }
+
+ /**
+ * @param $date
+ * @param $type
+ * @param $query
+ */
+ private function addFilterDate($date,$type,$query){
+
+ list($operator,$dateAt) = explode(',', $date);
+
+ if (!in_array($operator,['=','>=','<=','>','<'])) {
+ throw new \InvalidArgumentException(" '=' or '<=' or '>=' or '>' or '<'");
+ }
+
+ $query->addSqlFilter($type.$operator.' ?' ,[$dateAt]);
+ }
+
+}
diff --git a/lib/Alchemy/Phrasea/Command/User/UserSetPasswordCommand.php b/lib/Alchemy/Phrasea/Command/User/UserSetPasswordCommand.php
new file mode 100644
index 0000000000..963910db02
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Command/User/UserSetPasswordCommand.php
@@ -0,0 +1,79 @@
+setDescription('Set user password in Phraseanet')
+ ->addOption('user_id', null, InputOption::VALUE_REQUIRED, 'The id of user.')
+ ->addOption('generate', null, InputOption::VALUE_NONE, 'Generate the password')
+ ->addOption('password', null, InputOption::VALUE_OPTIONAL, 'The password')
+ ->setHelp('');
+
+ return $this;
+ }
+
+ protected function doExecute(InputInterface $input, OutputInterface $output)
+ {
+
+ $dialog = $this->getHelperSet()->get('dialog');
+ $userRepository = $this->container['repo.users'];
+ $userManipulator = $this->container['manipulator.user'];
+ $user = $userRepository->find($input->getOption('user_id'));
+ $password = $input->getOption('password');
+ $generate = $input->getOption('generate');
+
+ if ($user === null) {
+ $output->writeln('Not found User.');
+ return 0;
+ }
+
+ if ($generate) {
+ $password = $this->container['random.medium']->generateString(64);
+ } else {
+ if (!$password) {
+ $output->writeln('--password option not specified');
+ return 0;
+ }
+ }
+
+ do {
+ $continue = mb_strtolower($dialog->ask($output, 'Do you want really set password to this user? (y/N)', 'N'));
+ } while (!in_array($continue, ['y', 'n']));
+
+ if ($continue !== 'y') {
+ $output->writeln('Aborting !');
+
+ return;
+ }
+
+ $userManipulator->setPassword($user,$password);
+ $output->writeln('New password: ' . $password . '');
+
+ return 0;
+ }
+
+}
diff --git a/lib/Alchemy/Phrasea/Controller/Admin/SearchEngineController.php b/lib/Alchemy/Phrasea/Controller/Admin/SearchEngineController.php
index 8cf04e7839..04762b3aef 100644
--- a/lib/Alchemy/Phrasea/Controller/Admin/SearchEngineController.php
+++ b/lib/Alchemy/Phrasea/Controller/Admin/SearchEngineController.php
@@ -13,9 +13,11 @@ namespace Alchemy\Phrasea\Controller\Admin;
use Alchemy\Phrasea\Controller\Controller;
use Alchemy\Phrasea\SearchEngine\Elastic\ElasticsearchSettingsFormType;
use Alchemy\Phrasea\SearchEngine\Elastic\ElasticsearchOptions;
+use Alchemy\Phrasea\SearchEngine\Elastic\Structure\GlobalStructure;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
+use databox_descriptionStructure;
class SearchEngineController extends Controller
{
@@ -31,7 +33,19 @@ class SearchEngineController extends Controller
$form->handleRequest($request);
if ($form->isValid()) {
- $this->saveElasticSearchOptions($form->getData());
+ /** @var ElasticsearchOptions $data */
+ $data = $form->getData();
+ // $q = $request->request->get('elasticsearch_settings');
+ $facetNames = []; // rebuild the data "_customValues/facets" list following the form order
+ foreach($request->request->get('elasticsearch_settings') as $name=>$value) {
+ $matches = null;
+ if(preg_match('/^facets:(.+):limit$/', $name, $matches) === 1) {
+ $facetNames[] = $matches[1];
+ }
+ }
+ $data->reorderAggregableFields($facetNames);
+
+ $this->saveElasticSearchOptions($data);
return $this->app->redirectPath('admin_searchengine_form');
}
@@ -76,6 +90,16 @@ class SearchEngineController extends Controller
*/
private function saveElasticSearchOptions(ElasticsearchOptions $configuration)
{
+ // save to databoxes fields for backward compatibility (useless ?)
+ foreach($configuration->getAggregableFields() as $fname=>$aggregableField) {
+ foreach ($this->app->getDataboxes() as $databox) {
+ if(!is_null($f = $databox->get_meta_structure()->get_element_by_name($fname, databox_descriptionStructure::STRICT_COMPARE))) {
+ $f->set_aggregable($aggregableField['limit'])->save();
+ }
+ }
+ }
+
+ // save to conf
$this->getConf()->set(['main', 'search-engine', 'options'], $configuration->toArray());
}
@@ -85,7 +109,10 @@ class SearchEngineController extends Controller
*/
private function getConfigurationForm(ElasticsearchOptions $options)
{
- return $this->app->form(new ElasticsearchSettingsFormType(), $options, [
+ /** @var GlobalStructure $g */
+ $g = $this->app['search_engine.structure'];
+
+ return $this->app->form(new ElasticsearchSettingsFormType($g, $options), $options, [
'action' => $this->app->url('admin_searchengine_form'),
]);
}
diff --git a/lib/Alchemy/Phrasea/Controller/Api/Result.php b/lib/Alchemy/Phrasea/Controller/Api/Result.php
index 15624e1f6e..c7c45b4d0f 100644
--- a/lib/Alchemy/Phrasea/Controller/Api/Result.php
+++ b/lib/Alchemy/Phrasea/Controller/Api/Result.php
@@ -12,6 +12,7 @@
namespace Alchemy\Phrasea\Controller\Api;
use Alchemy\Phrasea\ControllerProvider\Api\V1;
+use Alchemy\Phrasea\ControllerProvider\Api\V3;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -268,11 +269,13 @@ class Result
public function getVersion()
{
if (null === $this->version) {
- if($this->request->attributes->get('api_version')){
+ if ($this->request->attributes->get('api_version')) {
$this->version = $this->request->attributes->get('api_version');
- }elseif(mb_strpos($this->request->getPathInfo(), '/api/v1') !== FALSE){
+ } elseif (mb_strpos($this->request->getPathInfo(), '/api/v1') !== FALSE) {
$this->version = V1::VERSION;
- }else{
+ } elseif (mb_strpos($this->request->getPathInfo(), '/api/v3') !== FALSE) {
+ $this->version = V3::VERSION;
+ } else {
$this->version = self::$defaultVersion;
}
}
diff --git a/lib/Alchemy/Phrasea/Controller/Api/V3Controller.php b/lib/Alchemy/Phrasea/Controller/Api/V3Controller.php
new file mode 100644
index 0000000000..4dcab291fe
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Controller/Api/V3Controller.php
@@ -0,0 +1,807 @@
+findDataboxById($databox_id)->get_record($record_id);
+
+ return Result::create($request, ['story' => $this->listStory($request, $story)])->createResponse();
+ } catch (NotFoundHttpException $e) {
+ return Result::createError($request, 404, $this->app->trans('Story Not Found'))->createResponse();
+ } catch (\Exception $e) {
+ return $this->app['controller.api.v1']->getBadRequestAction($request, $this->app->trans('An error occurred'));
+ }
+ }
+
+ /**
+ * Search for results
+ *
+ * @param Request $request
+ *
+ * @return Response
+ */
+ public function searchAction(Request $request)
+ {
+ $subdefTransformer = new SubdefTransformer($this->app['acl'], $this->getAuthenticatedUser(), new PermalinkTransformer());
+ $technicalDataTransformer = new TechnicalDataTransformer();
+ $recordTransformer = new RecordTransformer($subdefTransformer, $technicalDataTransformer);
+ $storyTransformer = new StoryTransformer($subdefTransformer, $recordTransformer);
+ $compositeTransformer = new V1SearchCompositeResultTransformer($recordTransformer, $storyTransformer);
+ $searchTransformer = new V1SearchResultTransformer($compositeTransformer);
+
+ $transformerResolver = new SearchResultTransformerResolver([
+ '' => $searchTransformer,
+ 'results' => $compositeTransformer,
+ 'results.stories' => $storyTransformer,
+ 'results.stories.thumbnail' => $subdefTransformer,
+ 'results.stories.metadatas' => new CallbackTransformer(),
+ 'results.stories.caption' => new CallbackTransformer(),
+ 'results.stories.records' => $recordTransformer,
+ 'results.stories.records.thumbnail' => $subdefTransformer,
+ 'results.stories.records.technical_informations' => $technicalDataTransformer,
+ 'results.stories.records.subdefs' => $subdefTransformer,
+ 'results.stories.records.metadata' => new CallbackTransformer(),
+ 'results.stories.records.status' => new CallbackTransformer(),
+ 'results.stories.records.caption' => new CallbackTransformer(),
+ 'results.records' => $recordTransformer,
+ 'results.records.thumbnail' => $subdefTransformer,
+ 'results.records.technical_informations' => $technicalDataTransformer,
+ 'results.records.subdefs' => $subdefTransformer,
+ 'results.records.metadata' => new CallbackTransformer(),
+ 'results.records.status' => new CallbackTransformer(),
+ 'results.records.caption' => new CallbackTransformer(),
+ ]);
+
+ $includeResolver = new IncludeResolver($transformerResolver);
+
+ $fractal = new \League\Fractal\Manager();
+ $fractal->setSerializer(new TraceableArraySerializer($this->app['dispatcher']));
+ $fractal->parseIncludes($this->resolveSearchIncludes($request));
+
+ $result = $this->doSearch($request);
+
+ $story_max_records = null;
+ // if search on story
+ if ($request->get('search_type') == 1) {
+ $story_max_records = (int)$request->get('story_max_records') ?: 10;
+ }
+
+ $searchView = $this->buildSearchView(
+ $result,
+ $includeResolver->resolve($fractal),
+ $this->resolveSubdefUrlTTL($request),
+ $story_max_records
+ );
+
+ $ret = $fractal->createData(new Item($searchView, $searchTransformer))->toArray();
+
+ return Result::create($request, $ret)->createResponse();
+ }
+
+ /**
+ * Retrieve detailed information about one story
+ *
+ * @param Request $request
+ * @param \record_adapter $story
+ * @return array
+ * @throws \Exception
+ */
+ private function listStory(Request $request, \record_adapter $story)
+ {
+ if (!$story->isStory()) {
+ return Result::createError($request, 404, 'Story not found')->createResponse();
+ }
+
+ $per_page = (int)$request->get('per_page')?:10;
+ $page = (int)$request->get('page')?:1;
+ $offset = ($per_page * ($page - 1)) + 1;
+
+ $caption = $story->get_caption();
+
+ $format = function (\caption_record $caption, $dcField) {
+
+ $field = $caption->get_dc_field($dcField);
+
+ if (!$field) {
+ return null;
+ }
+
+ return $field->get_serialized_values();
+ };
+
+ return [
+ '@entity@' => V1Controller::OBJECT_TYPE_STORY,
+ 'databox_id' => $story->getDataboxId(),
+ 'story_id' => $story->getRecordId(),
+ 'updated_on' => $story->getUpdated()->format(DATE_ATOM),
+ 'created_on' => $story->getCreated()->format(DATE_ATOM),
+ 'collection_id' => $story->getCollectionId(),
+ 'base_id' => $story->getBaseId(),
+ 'thumbnail' => $this->listEmbeddableMedia($request, $story, $story->get_thumbnail()),
+ 'uuid' => $story->getUuid(),
+ 'metadatas' => [
+ '@entity@' => V1Controller::OBJECT_TYPE_STORY_METADATA_BAG,
+ 'dc:contributor' => $format($caption, \databox_Field_DCESAbstract::Contributor),
+ 'dc:coverage' => $format($caption, \databox_Field_DCESAbstract::Coverage),
+ 'dc:creator' => $format($caption, \databox_Field_DCESAbstract::Creator),
+ 'dc:date' => $format($caption, \databox_Field_DCESAbstract::Date),
+ 'dc:description' => $format($caption, \databox_Field_DCESAbstract::Description),
+ 'dc:format' => $format($caption, \databox_Field_DCESAbstract::Format),
+ 'dc:identifier' => $format($caption, \databox_Field_DCESAbstract::Identifier),
+ 'dc:language' => $format($caption, \databox_Field_DCESAbstract::Language),
+ 'dc:publisher' => $format($caption, \databox_Field_DCESAbstract::Publisher),
+ 'dc:relation' => $format($caption, \databox_Field_DCESAbstract::Relation),
+ 'dc:rights' => $format($caption, \databox_Field_DCESAbstract::Rights),
+ 'dc:source' => $format($caption, \databox_Field_DCESAbstract::Source),
+ 'dc:subject' => $format($caption, \databox_Field_DCESAbstract::Subject),
+ 'dc:title' => $format($caption, \databox_Field_DCESAbstract::Title),
+ 'dc:type' => $format($caption, \databox_Field_DCESAbstract::Type),
+ ],
+ 'records' => $this->listRecords($request, array_values($story->getChildren($offset, $per_page)->get_elements())),
+ ];
+ }
+
+ private function listEmbeddableMedia(Request $request, \record_adapter $record, \media_subdef $media)
+ {
+ if (!$media->is_physically_present()) {
+ return null;
+ }
+
+ if ($this->getAuthenticator()->isAuthenticated()) {
+ $acl = $this->getAclForUser();
+ if ($media->get_name() !== 'document'
+ && false === $acl->has_access_to_subdef($record, $media->get_name())
+ ) {
+ return null;
+ }
+ if ($media->get_name() === 'document'
+ && !$acl->has_right_on_base($record->getBaseId(), \ACL::CANDWNLDHD)
+ && !$acl->has_hd_grant($record)
+ ) {
+ return null;
+ }
+ }
+
+ if ($media->get_permalink() instanceof \media_Permalink_Adapter) {
+ $permalink = $this->listPermalink($media->get_permalink());
+ } else {
+ $permalink = null;
+ }
+
+ $urlTTL = (int) $request->get(
+ 'subdef_url_ttl',
+ $this->getConf()->get(['registry', 'general', 'default-subdef-url-ttl'])
+ );
+ if ($urlTTL < 0) {
+ $urlTTL = -1;
+ }
+ $issuer = $this->getAuthenticatedUser();
+
+ return [
+ 'name' => $media->get_name(),
+ 'permalink' => $permalink,
+ 'height' => $media->get_height(),
+ 'width' => $media->get_width(),
+ 'filesize' => $media->get_size(),
+ 'devices' => $media->getDevices(),
+ 'player_type' => $media->get_type(),
+ 'mime_type' => $media->get_mime(),
+ 'substituted' => $media->is_substituted(),
+ 'created_on' => $media->get_creation_date()->format(DATE_ATOM),
+ 'updated_on' => $media->get_modification_date()->format(DATE_ATOM),
+ 'url' => $this->app['media_accessor.subdef_url_generator']->generate($issuer, $media, $urlTTL),
+ 'url_ttl' => $urlTTL,
+ ];
+ }
+
+ private function listPermalink(\media_Permalink_Adapter $permalink)
+ {
+ $downloadUrl = $permalink->get_url();
+ $downloadUrl->getQuery()->set('download', '1');
+
+ return [
+ 'created_on' => $permalink->get_created_on()->format(DATE_ATOM),
+ 'id' => $permalink->get_id(),
+ 'is_activated' => $permalink->get_is_activated(),
+ /** @Ignore */
+ 'label' => $permalink->get_label(),
+ 'updated_on' => $permalink->get_last_modified()->format(DATE_ATOM),
+ 'page_url' => $permalink->get_page(),
+ 'download_url' => (string)$downloadUrl,
+ 'url' => (string)$permalink->get_url(),
+ ];
+ }
+
+ /**
+ * @param Request $request
+ * @param RecordReferenceInterface[]|RecordReferenceCollection $records
+ * @return array
+ */
+ private function listRecords(Request $request, $records)
+ {
+ if (!$records instanceof RecordReferenceCollection) {
+ $records = new RecordReferenceCollection($records);
+ }
+
+ $technicalData = $this->app['service.technical_data']->fetchRecordsTechnicalData($records);
+
+ $data = [];
+
+ foreach ($records->toRecords($this->getApplicationBox()) as $index => $record) {
+ $record->setTechnicalDataSet($technicalData[$index]);
+
+ $data[$index] = $this->listRecord($request, $record);
+ }
+
+ return $data;
+ }
+
+ /**
+ * Retrieve detailed information about one record
+ *
+ * @param Request $request
+ * @param \record_adapter $record
+ * @return array
+ */
+ private function listRecord(Request $request, \record_adapter $record)
+ {
+ $technicalInformation = [];
+ foreach ($record->get_technical_infos()->getValues() as $name => $value) {
+ $technicalInformation[] = ['name' => $name, 'value' => $value];
+ }
+
+ $data = [
+ 'databox_id' => $record->getDataboxId(),
+ 'record_id' => $record->getRecordId(),
+ 'mime_type' => $record->getMimeType(),
+ 'title' => $record->get_title(),
+ 'original_name' => $record->get_original_name(),
+ 'updated_on' => $record->getUpdated()->format(DATE_ATOM),
+ 'created_on' => $record->getCreated()->format(DATE_ATOM),
+ 'collection_id' => $record->getCollectionId(),
+ 'base_id' => $record->getBaseId(),
+ 'sha256' => $record->getSha256(),
+ 'thumbnail' => $this->listEmbeddableMedia($request, $record, $record->get_thumbnail()),
+ 'technical_informations' => $technicalInformation,
+ 'phrasea_type' => $record->getType(),
+ 'uuid' => $record->getUuid(),
+ ];
+
+ if ($request->attributes->get('_extended', false)) {
+ $data = array_merge($data, [
+ 'subdefs' => $this->listRecordEmbeddableMedias($request, $record),
+ 'metadata' => $this->listRecordMetadata($record),
+ 'status' => $this->listRecordStatus($record),
+ 'caption' => $this->listRecordCaption($record),
+ ]);
+ }
+
+ return $data;
+ }
+
+ /**
+ * @param Request $request
+ * @param \record_adapter $record
+ * @return array
+ */
+ private function listRecordEmbeddableMedias(Request $request, \record_adapter $record)
+ {
+ $subdefs = [];
+
+ foreach ($record->get_embedable_medias([], []) as $name => $media) {
+ if (null !== $subdef = $this->listEmbeddableMedia($request, $record, $media)) {
+ $subdefs[] = $subdef;
+ }
+ }
+
+ return $subdefs;
+ }
+
+ /**
+ * List all fields of given record
+ *
+ * @param \record_adapter $record
+ * @return array
+ */
+ private function listRecordMetadata(\record_adapter $record)
+ {
+ $includeBusiness = $this->getAclForUser()->can_see_business_fields($record->getDatabox());
+
+ return $this->listRecordCaptionFields($record->get_caption()->get_fields(null, $includeBusiness));
+ }
+
+ /**
+ * @param \caption_field[] $fields
+ * @return array
+ */
+ private function listRecordCaptionFields($fields)
+ {
+ $ret = [];
+
+ foreach ($fields as $field) {
+ $databox_field = $field->get_databox_field();
+
+ $fieldData = [
+ 'meta_structure_id' => $field->get_meta_struct_id(),
+ 'name' => $field->get_name(),
+ 'labels' => [
+ 'fr' => $databox_field->get_label('fr'),
+ 'en' => $databox_field->get_label('en'),
+ 'de' => $databox_field->get_label('de'),
+ 'nl' => $databox_field->get_label('nl'),
+ ],
+ ];
+
+ foreach ($field->get_values() as $value) {
+ $data = [
+ 'meta_id' => $value->getId(),
+ 'value' => $value->getValue(),
+ ];
+
+ $ret[] = $fieldData + $data;
+ }
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Retrieve detailed information about one status
+ *
+ * @param \record_adapter $record
+ * @return array
+ */
+ private function listRecordStatus(\record_adapter $record)
+ {
+ $ret = [];
+ foreach ($record->getStatusStructure() as $bit => $status) {
+ $ret[] = [
+ 'bit' => $bit,
+ 'state' => \databox_status::bitIsSet($record->getStatusBitField(), $bit),
+ ];
+ }
+
+ return $ret;
+ }
+
+ /**
+ * @param \record_adapter $record
+ * @return array
+ */
+ private function listRecordCaption(\record_adapter $record)
+ {
+ $includeBusiness = $this->getAclForUser()->can_see_business_fields($record->getDatabox());
+
+ $caption = [];
+
+ foreach ($record->get_caption()->get_fields(null, $includeBusiness) as $field) {
+ $caption[] = [
+ 'meta_structure_id' => $field->get_meta_struct_id(),
+ 'name' => $field->get_name(),
+ 'value' => $field->get_serialized_values(';'),
+ ];
+ }
+
+ return $caption;
+ }
+
+ /**
+ * Returns requested includes
+ *
+ * @param Request $request
+ * @return string[]
+ */
+ private function resolveSearchIncludes(Request $request)
+ {
+ $includes = [
+ 'results.stories.records'
+ ];
+
+ if ($request->attributes->get('_extended', false)) {
+ if ($request->get('search_type') != SearchEngineOptions::RECORD_STORY) {
+ $includes = array_merge($includes, [
+ 'results.stories.records.subdefs',
+ 'results.stories.records.metadata',
+ 'results.stories.records.caption',
+ 'results.stories.records.status'
+ ]);
+ }
+ else {
+ $includes = [ 'results.stories.caption' ];
+ }
+
+ $includes = array_merge($includes, [
+ 'results.records.subdefs',
+ 'results.records.metadata',
+ 'results.records.caption',
+ 'results.records.status'
+ ]);
+ }
+
+ return $includes;
+ }
+
+ /**
+ * @param SearchEngineResult $result
+ * @param string[] $includes
+ * @param int $urlTTL
+ * @param int|null $story_max_records
+ * @return SearchResultView
+ */
+ private function buildSearchView(SearchEngineResult $result, array $includes, $urlTTL, $story_max_records = null)
+ {
+ $references = new RecordReferenceCollection($result->getResults());
+
+ $records = new RecordCollection();
+ $stories = new RecordCollection();
+
+ foreach ($references->toRecords($this->getApplicationBox()) as $record) {
+ if ($record->isStory()) {
+ $stories[$record->getId()] = $record;
+ } else {
+ $records[$record->getId()] = $record;
+ }
+ }
+
+ $resultView = new SearchResultView($result);
+
+ if ($stories->count() > 0) {
+ $user = $this->getAuthenticatedUser();
+ $children = [];
+
+ foreach ($stories->getDataboxIds() as $databoxId) {
+ $storyIds = $stories->getDataboxRecordIds($databoxId);
+
+ $selections = $this->findDataboxById($databoxId)
+ ->getRecordRepository()
+ ->findChildren($storyIds, $user,1, $story_max_records);
+ $children[$databoxId] = array_combine($storyIds, $selections);
+ }
+
+ /** @var StoryView[] $storyViews */
+ $storyViews = [];
+ /** @var RecordView[] $childrenViews */
+ $childrenViews = [];
+
+ foreach ($stories as $index => $story) {
+ $storyView = new StoryView($story);
+
+ $selection = $children[$story->getDataboxId()][$story->getRecordId()];
+
+ $childrenView = $this->buildRecordViews($selection);
+
+ foreach ($childrenView as $view) {
+ $childrenViews[spl_object_hash($view)] = $view;
+ }
+
+ $storyView->setChildren($childrenView);
+
+ $storyViews[$index] = $storyView;
+ }
+
+ if (in_array('results.stories.thumbnail', $includes, true)) {
+ $subdefViews = $this->buildSubdefsViews($stories, ['thumbnail'], $urlTTL);
+
+ foreach ($storyViews as $index => $storyView) {
+ $storyView->setSubdefs($subdefViews[$index]);
+ }
+ }
+
+ if (in_array('results.stories.metadatas', $includes, true) ||
+ in_array('results.stories.caption', $includes, true)) {
+ $captions = $this->app['service.caption']->findByReferenceCollection($stories);
+ $canSeeBusiness = $this->retrieveSeeBusinessPerDatabox($stories);
+
+ $this->buildCaptionViews($storyViews, $captions, $canSeeBusiness);
+ }
+
+ $allChildren = new RecordCollection();
+ foreach ($childrenViews as $index => $childrenView) {
+ $allChildren[$index] = $childrenView->getRecord();
+ }
+
+ $names = in_array('results.stories.records.subdefs', $includes, true) ? null : ['thumbnail'];
+ $subdefViews = $this->buildSubdefsViews($allChildren, $names, $urlTTL);
+ $technicalDatasets = $this->app['service.technical_data']->fetchRecordsTechnicalData($allChildren);
+
+ foreach ($childrenViews as $index => $recordView) {
+ $recordView->setSubdefs($subdefViews[$index]);
+ $recordView->setTechnicalDataView(new TechnicalDataView($technicalDatasets[$index]));
+ }
+
+ if (array_intersect($includes, ['results.stories.records.metadata', 'results.stories.records.caption'])) {
+ $captions = $this->app['service.caption']->findByReferenceCollection($allChildren);
+ $canSeeBusiness = $this->retrieveSeeBusinessPerDatabox($allChildren);
+
+ $this->buildCaptionViews($childrenViews, $captions, $canSeeBusiness);
+ }
+
+ $resultView->setStories($storyViews);
+ }
+
+ if ($records->count() > 0) {
+ $names = in_array('results.records.subdefs', $includes, true) ? null : ['thumbnail'];
+ $recordViews = $this->buildRecordViews($records);
+ $subdefViews = $this->buildSubdefsViews($records, $names, $urlTTL);
+
+ $technicalDatasets = $this->app['service.technical_data']->fetchRecordsTechnicalData($records);
+
+ foreach ($recordViews as $index => $recordView) {
+ $recordView->setSubdefs($subdefViews[$index]);
+ $recordView->setTechnicalDataView(new TechnicalDataView($technicalDatasets[$index]));
+ }
+
+ if (array_intersect($includes, ['results.records.metadata', 'results.records.caption'])) {
+ $captions = $this->app['service.caption']->findByReferenceCollection($records);
+ $canSeeBusiness = $this->retrieveSeeBusinessPerDatabox($records);
+
+ $this->buildCaptionViews($recordViews, $captions, $canSeeBusiness);
+ }
+
+ $resultView->setRecords($recordViews);
+ }
+
+ return $resultView;
+ }
+
+ /**
+ * @param Request $request
+ * @return SearchEngineResult
+ */
+ private function doSearch(Request $request)
+ {
+ $options = SearchEngineOptions::fromRequest($this->app, $request);
+ $options->setFirstResult((int)($request->get('offset_start') ?: 0));
+ $options->setMaxResults((int)$request->get('per_page') ?: 10);
+
+ $this->getSearchEngine()->resetCache();
+
+ $search_result = $this->getSearchEngine()->query((string)$request->get('query'), $options);
+
+ $this->getUserManipulator()->logQuery($this->getAuthenticatedUser(), $search_result->getQueryText());
+
+ // log array of collectionIds (from $options) for each databox
+ $collectionsReferencesByDatabox = $options->getCollectionsReferencesByDatabox();
+ foreach ($collectionsReferencesByDatabox as $sbid => $references) {
+ $databox = $this->findDataboxById($sbid);
+ $collectionsIds = array_map(function(CollectionReference $ref){return $ref->getCollectionId();}, $references);
+ $this->getSearchEngineLogger()->log($databox, $search_result->getQueryText(), $search_result->getTotal(), $collectionsIds);
+ }
+
+ $this->getSearchEngine()->clearCache();
+
+ return $search_result;
+ }
+
+ /**
+ * @return SearchEngineInterface
+ */
+ private function getSearchEngine()
+ {
+ return $this->app['phraseanet.SE'];
+ }
+
+ /**
+ * @return UserManipulator
+ */
+ private function getUserManipulator()
+ {
+ return $this->app['manipulator.user'];
+ }
+
+ /**
+ * @return SearchEngineLogger
+ */
+ private function getSearchEngineLogger()
+ {
+ return $this->app['phraseanet.SE.logger'];
+ }
+
+ /**
+ * @param Request $request
+ * @return int
+ */
+ private function resolveSubdefUrlTTL(Request $request)
+ {
+ $urlTTL = $request->query->get('subdef_url_ttl');
+
+ if (null !== $urlTTL) {
+ return (int)$urlTTL;
+ }
+
+ return $this->getConf()->get(['registry', 'general', 'default-subdef-url-ttl']);
+ }
+
+ /**
+ * @param RecordCollection|\record_adapter[] $references
+ * @return RecordView[]
+ */
+ private function buildRecordViews($references)
+ {
+ if (!$references instanceof RecordCollection) {
+ $references = new RecordCollection($references);
+ }
+
+ $recordViews = [];
+
+ foreach ($references as $index => $record) {
+ $recordViews[$index] = new RecordView($record);
+ }
+
+ return $recordViews;
+ }
+
+ /**
+ * @param RecordReferenceInterface[]|RecordReferenceCollection|DataboxGroupable $references
+ * @param array|null $names
+ * @param int $urlTTL
+ * @return SubdefView[][]
+ */
+ private function buildSubdefsViews($references, array $names = null, $urlTTL)
+ {
+ $subdefGroups = $this->app['service.media_subdef']
+ ->findSubdefsByRecordReferenceFromCollection($references, $names);
+
+ $fakeSubdefs = [];
+
+ foreach ($subdefGroups as $index => $subdefGroup) {
+ if (!isset($subdefGroup['thumbnail'])) {
+ $fakeSubdef = new \media_subdef($this->app, $references[$index], 'thumbnail', true, []);
+ $fakeSubdefs[spl_object_hash($fakeSubdef)] = $fakeSubdef;
+
+ $subdefGroups[$index]['thumbnail'] = $fakeSubdef;
+ }
+ }
+
+ $allSubdefs = $this->mergeGroupsIntoOneList($subdefGroups);
+ $allPermalinks = \media_Permalink_Adapter::getMany(
+ $this->app,
+ array_filter($allSubdefs, function (\media_subdef $subdef) use ($fakeSubdefs) {
+ return !isset($fakeSubdefs[spl_object_hash($subdef)]);
+ })
+ );
+ $urls = $this->app['media_accessor.subdef_url_generator']
+ ->generateMany($this->getAuthenticatedUser(), $allSubdefs, $urlTTL);
+
+ $subdefViews = [];
+
+ /** @var \media_subdef $subdef */
+ foreach ($allSubdefs as $index => $subdef) {
+ $subdefView = new SubdefView($subdef);
+
+ if (isset($allPermalinks[$index])) {
+ $subdefView->setPermalinkView(new PermalinkView($allPermalinks[$index]));
+ }
+
+ $subdefView->setUrl($urls[$index]);
+ $subdefView->setUrlTTL($urlTTL);
+
+ $subdefViews[spl_object_hash($subdef)] = $subdefView;
+ }
+
+ $reorderedGroups = [];
+
+ /** @var \media_subdef[] $subdefGroup */
+ foreach ($subdefGroups as $index => $subdefGroup) {
+ $reordered = [];
+
+ foreach ($subdefGroup as $subdef) {
+ $reordered[] = $subdefViews[spl_object_hash($subdef)];
+ }
+
+ $reorderedGroups[$index] = $reordered;
+ }
+
+ return $reorderedGroups;
+ }
+
+ /**
+ * @param array $groups
+ * @return array|mixed
+ */
+ private function mergeGroupsIntoOneList(array $groups)
+ {
+ // Strips keys from the internal array
+ array_walk($groups, function (array &$group) {
+ $group = array_values($group);
+ });
+
+ if ($groups) {
+ return call_user_func_array('array_merge', $groups);
+ }
+
+ return [];
+ }
+
+ /**
+ * @param RecordReferenceInterface[]|DataboxGroupable $references
+ * @return array
+ */
+ private function retrieveSeeBusinessPerDatabox($references)
+ {
+ if (!$references instanceof DataboxGroupable) {
+ $references = new RecordReferenceCollection($references);
+ }
+
+ $acl = $this->getAclForUser();
+
+ $canSeeBusiness = [];
+
+ foreach ($references->getDataboxIds() as $databoxId) {
+ $canSeeBusiness[$databoxId] = $acl->can_see_business_fields($this->findDataboxById($databoxId));
+ }
+
+ $rights = [];
+
+ foreach ($references as $index => $reference) {
+ $rights[$index] = $canSeeBusiness[$reference->getDataboxId()];
+ }
+
+ return $rights;
+ }
+
+ /**
+ * @param RecordView[] $recordViews
+ * @param \caption_record[] $captions
+ * @param bool[] $canSeeBusiness
+ */
+ private function buildCaptionViews($recordViews, $captions, $canSeeBusiness)
+ {
+ foreach ($recordViews as $index => $recordView) {
+ $caption = $captions[$index];
+
+ $captionView = new CaptionView($caption);
+
+ $captionView->setFields($caption->get_fields(null, isset($canSeeBusiness[$index]) && (bool)$canSeeBusiness[$index]));
+
+ $recordView->setCaption($captionView);
+ }
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/FeedController.php b/lib/Alchemy/Phrasea/Controller/Prod/FeedController.php
index 2bc333f45c..39a0a8f48d 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/FeedController.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/FeedController.php
@@ -19,8 +19,10 @@ use Alchemy\Phrasea\Core\PhraseaEvents;
use Alchemy\Phrasea\Feed\Aggregate;
use Alchemy\Phrasea\Feed\Link\AggregateLinkGenerator;
use Alchemy\Phrasea\Feed\Link\FeedLinkGenerator;
+use Alchemy\Phrasea\Model\Entities\Feed;
use Alchemy\Phrasea\Model\Entities\FeedEntry;
use Alchemy\Phrasea\Model\Entities\FeedItem;
+use Alchemy\Phrasea\Model\Entities\FeedPublisher;
use Alchemy\Phrasea\Model\Repositories\FeedEntryRepository;
use Alchemy\Phrasea\Model\Repositories\FeedItemRepository;
use Alchemy\Phrasea\Model\Repositories\FeedPublisherRepository;
@@ -46,6 +48,7 @@ class FeedController extends Controller
}
public function createFeedEntryAction(Request $request) {
+ /** @var Feed $feed */
$feed = $this->getFeedRepository()->find($request->request->get('feed_id'));
if (null === $feed) {
@@ -53,6 +56,8 @@ class FeedController extends Controller
}
$user = $this->getAuthenticatedUser();
+
+ /** @var FeedPublisher $publisher */
$publisher = $this->getFeedPublisherRepository()->findOneBy([
'feed' => $feed,
'user' => $user,
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/LanguageController.php b/lib/Alchemy/Phrasea/Controller/Prod/LanguageController.php
index 5137d3f219..254e3e9835 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/LanguageController.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/LanguageController.php
@@ -136,6 +136,7 @@ class LanguageController
'or' => $translator->trans('or'),
'Suppr' => $translator->trans('Suppr'),
'Add new range' => $translator->trans('Add new range'),
+ 'Save as VTT' => $translator->trans('Save as VTT'),
'Export ranges' => $translator->trans('Export ranges'),
'Start Range' => $translator->trans('Start Range'),
'End Range' => $translator->trans('End Range'),
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/PrinterController.php b/lib/Alchemy/Phrasea/Controller/Prod/PrinterController.php
index d2bc03b190..0d9c4a466f 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/PrinterController.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/PrinterController.php
@@ -12,7 +12,7 @@ namespace Alchemy\Phrasea\Controller\Prod;
use Alchemy\Phrasea\Application\Helper\DataboxLoggerAware;
use Alchemy\Phrasea\Controller\Controller;
use Alchemy\Phrasea\Helper\Record as RecordHelper;
-use Alchemy\Phrasea\Out\Module\PDF as PDFExport;
+use Alchemy\Phrasea\Out\Module\PDFRecords;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -24,19 +24,27 @@ class PrinterController extends Controller
{
$printer = new RecordHelper\Printer($this->app, $request);
- return $this->render('prod/actions/printer_default.html.twig', ['printer' => $printer, 'message' => '']);
+ $basketFeedbackId = null;
+ if($printer->is_basket() && ($basket = $printer->get_original_basket()) && ($validation = $basket->getValidation())) {
+ if($validation->getInitiator()->getId() === $this->app->getAuthenticatedUser()->getId()) {
+ $basketFeedbackId = $basket->getId();
+ }
+ }
+
+ return $this->render('prod/actions/printer_default.html.twig', ['printer' => $printer, 'message' => '', 'basketFeedbackId' => $basketFeedbackId]);
}
public function printAction(Request $request)
{
$printer = new RecordHelper\Printer($this->app, $request);
+ $b = $printer->get_original_basket();
$layout = $request->request->get('lay');
foreach ($printer->get_elements() as $record) {
$this->getDataboxLogger($record->getDatabox())->log($record, \Session_Logger::EVENT_PRINT, $layout, '');
}
- $PDF = new PDFExport($this->app, $printer->get_elements(), $layout);
+ $PDF = new PDFRecords($this->app, $printer, $layout);
$response = new Response($PDF->render(), 200, array('Content-Type' => 'application/pdf'));
$response->headers->set('Pragma', 'public', true);
@@ -44,4 +52,5 @@ class PrinterController extends Controller
return $response;
}
+
}
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/QueryController.php b/lib/Alchemy/Phrasea/Controller/Prod/QueryController.php
index d327e860c5..8afd22d2b3 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/QueryController.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/QueryController.php
@@ -433,24 +433,15 @@ class QueryController extends Controller
// populates facets (aggregates)
$facets = [];
- // $facetClauses = [];
foreach ($result->getFacets() as $facet) {
$facetName = $facet['name'];
if(array_key_exists($facetName, $fieldsInfosByName)) {
-
$f = $fieldsInfosByName[$facetName];
-
$facet['label'] = $f['trans_label'];
$facet['labels'] = $f['labels'];
$facet['type'] = strtoupper($f['type']) . "-AGGREGATE";
$facets[] = $facet;
-
- // $facetClauses[] = [
- // 'type' => strtoupper($f['type']) . "-AGGREGATE",
- // 'field' => $f['field'],
- // 'facet' => $facet
- // ];
}
}
diff --git a/lib/Alchemy/Phrasea/Controller/Root/AccountController.php b/lib/Alchemy/Phrasea/Controller/Root/AccountController.php
index c25fe8fd91..b56d428cec 100644
--- a/lib/Alchemy/Phrasea/Controller/Root/AccountController.php
+++ b/lib/Alchemy/Phrasea/Controller/Root/AccountController.php
@@ -458,9 +458,9 @@ class AccountController extends Controller
->setZipCode($request->request->get("form_zip"))
->setPhone($request->request->get("form_phone"))
->setFax($request->request->get("form_fax"))
- ->setJob($request->request->get("form_activity"))
+ ->setJob($request->request->get("form_function"))
->setCompany($request->request->get("form_company"))
- ->setPosition($request->request->get("form_function"))
+ ->setPosition($request->request->get("form_activity"))
->setNotifications((Boolean) $request->request->get("mail_notifications"));
$service->updateAccount($command);
diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Api/V3.php b/lib/Alchemy/Phrasea/ControllerProvider/Api/V3.php
new file mode 100644
index 0000000000..5925c74921
--- /dev/null
+++ b/lib/Alchemy/Phrasea/ControllerProvider/Api/V3.php
@@ -0,0 +1,48 @@
+share(function (PhraseaApplication $app) {
+ return (new V3Controller($app));
+ });
+ }
+
+ public function boot(Application $app)
+ {
+ }
+
+ public function connect(Application $app)
+ {
+ if (! $this->isApiEnabled($app)) {
+ return $app['controllers_factory'];
+ }
+
+ /** @var ControllerCollection $controllers */
+ $controllers = $app['controllers_factory'];
+
+ $controllers->before(new OAuthListener());
+
+ $controllers->get('/stories/{databox_id}/{record_id}/', 'controller.api.v3:getStoryAction')
+ ->before('controller.api.v1:ensureCanAccessToRecord')
+ ->assert('databox_id', '\d+')
+ ->assert('record_id', '\d+');
+
+ $controllers->match('/search/', 'controller.api.v3:searchAction');
+
+ return $controllers;
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Core/Configuration/DisplaySettingService.php b/lib/Alchemy/Phrasea/Core/Configuration/DisplaySettingService.php
index 104230411d..24fcff9b2c 100644
--- a/lib/Alchemy/Phrasea/Core/Configuration/DisplaySettingService.php
+++ b/lib/Alchemy/Phrasea/Core/Configuration/DisplaySettingService.php
@@ -20,6 +20,7 @@ class DisplaySettingService
const ORDER_BY_ADMIN = "ORDER_BY_ADMIN";
const ORDER_BY_BCT = "ORDER_BY_BCT";
const ORDER_BY_HITS = "ORDER_BY_HITS";
+ const ORDER_BY_HITS_ASC = "ORDER_BY_HITS_ASC";
/**
* The default user settings.
@@ -31,7 +32,7 @@ class DisplaySettingService
'images_per_page' => '20',
'images_size' => '120',
'editing_images_size' => '134',
- 'editing_top_box' => '180px',
+ 'editing_top_box' => '120px',
'editing_right_box' => '400px',
'editing_left_box' => '710px',
'basket_sort_field' => 'name',
diff --git a/lib/Alchemy/Phrasea/Core/Event/Listener/OAuthListener.php b/lib/Alchemy/Phrasea/Core/Event/Listener/OAuthListener.php
index 34c4685149..0dd4984306 100644
--- a/lib/Alchemy/Phrasea/Core/Event/Listener/OAuthListener.php
+++ b/lib/Alchemy/Phrasea/Core/Event/Listener/OAuthListener.php
@@ -15,6 +15,7 @@ use Alchemy\Phrasea\Authentication\Context;
use Alchemy\Phrasea\Controller\Api\Result;
use Alchemy\Phrasea\ControllerProvider\Api\V1;
use Alchemy\Phrasea\ControllerProvider\Api\V2;
+use Alchemy\Phrasea\ControllerProvider\Api\V3;
use Alchemy\Phrasea\Core\Configuration\PropertyAccess;
use Alchemy\Phrasea\Core\Event\ApiOAuth2EndEvent;
use Alchemy\Phrasea\Core\Event\ApiOAuth2StartEvent;
@@ -76,11 +77,13 @@ class OAuthListener
// Sets the Api Version
$CalledController = $request->attributes->get('_controller');
- if(mb_strpos($CalledController, 'controller.api.v1') !== FALSE){
+ if (mb_strpos($CalledController, 'controller.api.v1') !== FALSE) {
$request->attributes->set('api_version', V1::VERSION);
- }elseif(mb_strpos($CalledController, 'controller.api.v2') !== FALSE){
+ } elseif(mb_strpos($CalledController, 'controller.api.v2') !== FALSE) {
$request->attributes->set('api_version', V2::VERSION);
- }else{
+ } elseif(mb_strpos($CalledController, 'controller.api.v3') !== FALSE) {
+ $request->attributes->set('api_version', V3::VERSION);
+ } else {
$request->attributes->set('api_version', $oAuth2Account->getApiVersion());
}
diff --git a/lib/Alchemy/Phrasea/Core/Event/Subscriber/FeedEntrySubscriber.php b/lib/Alchemy/Phrasea/Core/Event/Subscriber/FeedEntrySubscriber.php
index 6a8b0cdaf4..e229cc3f44 100644
--- a/lib/Alchemy/Phrasea/Core/Event/Subscriber/FeedEntrySubscriber.php
+++ b/lib/Alchemy/Phrasea/Core/Event/Subscriber/FeedEntrySubscriber.php
@@ -13,7 +13,9 @@ namespace Alchemy\Phrasea\Core\Event\Subscriber;
use Alchemy\Phrasea\Core\Event\FeedEntryEvent;
use Alchemy\Phrasea\Core\PhraseaEvents;
+use Alchemy\Phrasea\Model\Entities\User;
use Alchemy\Phrasea\Model\Entities\WebhookEvent;
+use Alchemy\Phrasea\Model\Manipulator\TokenManipulator;
use Alchemy\Phrasea\Notification\Receiver;
use Alchemy\Phrasea\Notification\Mail\MailInfoNewPublication;
@@ -54,36 +56,43 @@ class FeedEntrySubscriber extends AbstractNotificationSubscriber
do {
$results = $Query->limit($start, $perLoop)->execute()->get_results();
- foreach ($results as $user_to_notif) {
- $mailed = false;
+ $users_emailed = []; // for all users
+ $users_to_email = []; // list only users who must be emailed (=create tokens)
- if ($params['notify_email'] && $this->shouldSendNotificationFor($user_to_notif, 'eventsmanager_notify_feed')) {
- $readyToSend = false;
- try {
- $token = $this->app['manipulator.token']->createFeedEntryToken($user_to_notif, $entry);
- $url = $this->app->url('lightbox', ['LOG' => $token->getValue()]);
-
- $receiver = Receiver::fromUser($user_to_notif);
- $readyToSend = true;
- } catch (\Exception $e) {
-
- }
-
- if ($readyToSend) {
- $mail = MailInfoNewPublication::create($this->app, $receiver);
- $mail->setButtonUrl($url);
- $mail->setAuthor($entry->getAuthorName());
- $mail->setTitle($entry->getTitle());
-
- $this->deliver($mail);
- $mailed = true;
- }
+ /** @var User $user */
+ foreach ($results as $user) {
+ $users_emailed[$user->getId()] = false;
+ if ($params['notify_email'] && $this->shouldSendNotificationFor($user, 'eventsmanager_notify_feed')) {
+ $users_to_email[$user->getId()] = $user;
}
-
- $this->app['events-manager']->notify($user_to_notif->getId(), 'eventsmanager_notify_feed', $datas, $mailed);
}
+
+ // get many tokens in one shot
+ $tokens = $this->getTokenManipulator()->createFeedEntryTokens($users_to_email, $entry);
+ foreach($tokens as $token) {
+ try {
+ $url = $this->app->url('lightbox', ['LOG' => $token->getValue()]);
+ $receiver = Receiver::fromUser($token->getUser());
+
+ $mail = MailInfoNewPublication::create($this->app, $receiver);
+ $mail->setButtonUrl($url);
+ $mail->setAuthor($entry->getAuthorName());
+ $mail->setTitle($entry->getTitle());
+
+ $this->deliver($mail);
+ $users_emailed[$token->getUser()->getId()] = true;
+ }
+ catch (\Exception $e) {
+ // no-op
+ }
+ }
+ foreach($users_emailed as $id => $emailed) {
+ $this->app['events-manager']->notify($id, 'eventsmanager_notify_feed', $datas, $emailed);
+ }
+
$start += $perLoop;
- } while (count($results) > 0);
+ }
+ while (count($results) > 0);
}
public static function getSubscribedEvents()
@@ -92,4 +101,12 @@ class FeedEntrySubscriber extends AbstractNotificationSubscriber
PhraseaEvents::FEED_ENTRY_CREATE => 'onCreate',
];
}
+
+ /**
+ * @return TokenManipulator
+ */
+ private function getTokenManipulator()
+ {
+ return $this->app['manipulator.token'];
+ }
}
diff --git a/lib/Alchemy/Phrasea/Core/MetaProvider/MediaUtilitiesMetaServiceProvider.php b/lib/Alchemy/Phrasea/Core/MetaProvider/MediaUtilitiesMetaServiceProvider.php
index 5092c6c77f..cc55894313 100644
--- a/lib/Alchemy/Phrasea/Core/MetaProvider/MediaUtilitiesMetaServiceProvider.php
+++ b/lib/Alchemy/Phrasea/Core/MetaProvider/MediaUtilitiesMetaServiceProvider.php
@@ -9,6 +9,8 @@ use MediaVorus\MediaVorusServiceProvider;
use MP4Box\MP4BoxServiceProvider;
use Neutron\Silex\Provider\ImagineServiceProvider;
use PHPExiftool\PHPExiftoolServiceProvider;
+use PHPExiftool\Reader;
+use PHPExiftool\Writer;
use Silex\Application;
use Silex\ServiceProviderInterface;
@@ -48,6 +50,21 @@ class MediaUtilitiesMetaServiceProvider implements ServiceProviderInterface
public function boot(Application $app)
{
- // no-op
+ if(isset($app['exiftool.reader']) && isset($app['conf'])) {
+ try {
+ $timeout = $app['conf']->get(['main', 'binaries', 'exiftool_timeout'], 60);
+
+ /** @var Reader $exiftoolReader */
+ $exiftoolReader = $app['exiftool.reader'];
+ $exiftoolReader->setTimeout($timeout);
+
+ /** @var Writer $exiftoolWriter */
+ $exiftoolWriter = $app['exiftool.writer'];
+ $exiftoolWriter->setTimeout($timeout);
+ }
+ catch(\Exception $e) {
+ // no-nop
+ }
+ }
}
}
diff --git a/lib/Alchemy/Phrasea/Core/Provider/SearchEngineServiceProvider.php b/lib/Alchemy/Phrasea/Core/Provider/SearchEngineServiceProvider.php
index 58f77475a1..e342bf8380 100644
--- a/lib/Alchemy/Phrasea/Core/Provider/SearchEngineServiceProvider.php
+++ b/lib/Alchemy/Phrasea/Core/Provider/SearchEngineServiceProvider.php
@@ -97,7 +97,7 @@ class SearchEngineServiceProvider implements ServiceProviderInterface
});
$app['elasticsearch.facets_response.factory'] = $app->protect(function (array $response) use ($app) {
- return new FacetsResponse(new Escaper(), $response, $app['search_engine.structure']);
+ return new FacetsResponse($app['elasticsearch.options'], new Escaper(), $response, $app['search_engine.structure']);
});
return $app;
@@ -228,7 +228,8 @@ class SearchEngineServiceProvider implements ServiceProviderInterface
});
$app['elasticsearch.options'] = $app->share(function ($app) {
- $options = ElasticsearchOptions::fromArray($app['conf']->get(['main', 'search-engine', 'options'], []));
+ $conf = $app['conf']->get(['main', 'search-engine', 'options'], []);
+ $options = ElasticsearchOptions::fromArray($conf);
if (empty($options->getIndexName())) {
$options->setIndexName(strtolower(sprintf('phraseanet_%s', str_replace(
diff --git a/lib/Alchemy/Phrasea/Core/Version.php b/lib/Alchemy/Phrasea/Core/Version.php
index c209691c0b..c029f2be01 100644
--- a/lib/Alchemy/Phrasea/Core/Version.php
+++ b/lib/Alchemy/Phrasea/Core/Version.php
@@ -16,7 +16,8 @@ class Version
/**
* @var string
*/
- private $number = '4.1.0-alpha.19a';
+
+ private $number = '4.1.0-alpha.23a';
/**
* @var string
diff --git a/lib/Alchemy/Phrasea/Databox/Record/LegacyRecordRepository.php b/lib/Alchemy/Phrasea/Databox/Record/LegacyRecordRepository.php
index 205a7c9b26..30feada346 100644
--- a/lib/Alchemy/Phrasea/Databox/Record/LegacyRecordRepository.php
+++ b/lib/Alchemy/Phrasea/Databox/Record/LegacyRecordRepository.php
@@ -182,7 +182,7 @@ class LegacyRecordRepository implements RecordRepository
return $this->mapRecordsFromResultSet($result);
}
- public function findChildren(array $storyIds, $user = null)
+ public function findChildren(array $storyIds, $user = null, $offset = 1, $max_items = null)
{
if (!$storyIds) {
return [];
@@ -191,26 +191,73 @@ class LegacyRecordRepository implements RecordRepository
$connection = $this->databox->get_connection();
$selects = $this->getRecordSelects();
- array_unshift($selects, 's.rid_parent as story_id');
- $builder = $connection->createQueryBuilder();
- $builder
- ->select($selects)
- ->from('regroup', 's')
- ->innerJoin('s', 'record', 'r', 'r.record_id = s.rid_child')
- ->where(
- 's.rid_parent IN (:storyIds)',
- 'r.parent_record_id = 0'
- )
- ->orderBy('s.ord', 'ASC')
- ->setParameter('storyIds', $storyIds, Connection::PARAM_INT_ARRAY)
- ;
+ if ($max_items) {
+ array_unshift($selects, 'sr.rid_parent as story_id');
- if (null !== $user) {
- $this->addUserFilter($builder, $user);
+ $subBuilder = $connection->createQueryBuilder();
+
+ $subBuilder
+ ->select('s.*,
+ IF(@old_rid_parent != s.rid_parent, @cpt := 1, @cpt := @cpt+1) AS CPT')
+ ->addSelect("IF(@old_rid_parent != s.rid_parent, IF(@old_rid_parent:=s.rid_parent,'NEW PARENT',0), '----------') AS Y")
+ ->from('regroup', 's')
+ ->where('s.rid_parent IN (:storyIds)')
+ ->setParameter('storyIds', $storyIds, Connection::PARAM_INT_ARRAY)
+ ->orderBy('s.rid_parent, s.ord')
+ ;
+
+ $builder = $subBuilder->getConnection()->createQueryBuilder();
+
+ $builder->select($selects)
+ ->from(sprintf('( %s )', $subBuilder->getSQL()), 'sr')
+ ->innerJoin('sr', 'record', 'r', 'r.record_id = sr.rid_child')
+ ->where('sr.CPT BETWEEN :offset AND :maxresult')
+ ->andWhere('r.parent_record_id = 0')
+ ->setParameter('offset', $offset)
+ ->setParameter('maxresult', ($offset + $max_items -1))
+ ->orderBy('story_id, sr.CPT')
+ ;
+
+ if (null !== $user) {
+ $this->addUserFilter($builder, $user);
+ }
+
+ $connection->executeQuery('SET @cpt = 1');
+
+ $connection->executeQuery('SET @old_rid_parent = -1');
+
+
+ $data = $connection->fetchAll(
+ $builder->getSQL(),
+ array_merge($subBuilder->getParameters(), $builder->getParameters()),
+ array_merge($subBuilder->getParameterTypes(), $builder->getParameterTypes())
+ );
+
+ } else {
+ array_unshift($selects, 's.rid_parent as story_id');
+
+ $builder = $connection->createQueryBuilder();
+
+ $builder
+ ->select($selects)
+ ->from('regroup', 's')
+ ->innerJoin('s', 'record', 'r', 'r.record_id = s.rid_child')
+ ->where(
+ 's.rid_parent IN (:storyIds)',
+ 'r.parent_record_id = 0'
+ )
+ ->orderBy('s.ord', 'ASC')
+ ->setParameter('storyIds', $storyIds, Connection::PARAM_INT_ARRAY)
+ ;
+
+ if (null !== $user) {
+ $this->addUserFilter($builder, $user);
+ }
+
+ $data = $connection->fetchAll($builder->getSQL(), $builder->getParameters(), $builder->getParameterTypes());
}
- $data = $connection->fetchAll($builder->getSQL(), $builder->getParameters(), $builder->getParameterTypes());
$records = $this->mapRecordsFromResultSet($data);
$selections = array_map(
diff --git a/lib/Alchemy/Phrasea/Databox/Record/RecordRepository.php b/lib/Alchemy/Phrasea/Databox/Record/RecordRepository.php
index 8817610cef..bab31055da 100644
--- a/lib/Alchemy/Phrasea/Databox/Record/RecordRepository.php
+++ b/lib/Alchemy/Phrasea/Databox/Record/RecordRepository.php
@@ -57,9 +57,11 @@ interface RecordRepository
*
* @param int[] $storyIds
* @param null|int|User $user
+ * @param int $offset
+ * @param null|int $max_items
* @return \set_selection[]
*/
- public function findChildren(array $storyIds, $user = null);
+ public function findChildren(array $storyIds, $user = null, $offset = 1, $max_items = null);
/**
diff --git a/lib/Alchemy/Phrasea/Helper/User/Edit.php b/lib/Alchemy/Phrasea/Helper/User/Edit.php
index f89ccbe383..5b73a879a4 100644
--- a/lib/Alchemy/Phrasea/Helper/User/Edit.php
+++ b/lib/Alchemy/Phrasea/Helper/User/Edit.php
@@ -659,8 +659,8 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper
->setEmail($parm['email'])
->setAddress($parm['address'])
->setZipCode($parm['zip'])
- ->setActivity($parm['function'])
- ->setJob($parm['activite'])
+ ->setActivity($parm['activite'])
+ ->setJob($parm['function'])
->setCompany($parm['company'])
->setPhone($parm['telephone'])
->setFax($parm['fax']);
diff --git a/lib/Alchemy/Phrasea/Model/Entities/Basket.php b/lib/Alchemy/Phrasea/Model/Entities/Basket.php
index c25b074634..eea18b21e0 100644
--- a/lib/Alchemy/Phrasea/Model/Entities/Basket.php
+++ b/lib/Alchemy/Phrasea/Model/Entities/Basket.php
@@ -456,17 +456,27 @@ class Basket
}
public function hasRecord(Application $app, \record_adapter $record)
+ {
+ return !is_null($this->getElementByRecord($app, $record));
+ }
+
+ /**
+ * @param Application $app
+ * @param \record_adapter $record
+ * @return BasketElement
+ */
+ public function getElementByRecord(Application $app, \record_adapter $record)
{
foreach ($this->getElements() as $basket_element) {
$bask_record = $basket_element->getRecord($app);
if ($bask_record->getRecordId() == $record->getRecordId()
&& $bask_record->getDataboxId() == $record->getDataboxId()) {
- return true;
+ return $basket_element;
}
}
- return false;
+ return null;
}
public function getSize(Application $app)
diff --git a/lib/Alchemy/Phrasea/Model/Entities/Token.php b/lib/Alchemy/Phrasea/Model/Entities/Token.php
index 576cf05d36..81c632f97d 100644
--- a/lib/Alchemy/Phrasea/Model/Entities/Token.php
+++ b/lib/Alchemy/Phrasea/Model/Entities/Token.php
@@ -15,7 +15,14 @@ use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
- * @ORM\Table(name="Tokens")
+ * @ORM\Table(name="Tokens",
+ * indexes={
+ * @ORM\index(name="type", columns={"type"}),
+ * @ORM\index(name="created", columns={"created"}),
+ * @ORM\index(name="updated", columns={"updated"}),
+ * @ORM\index(name="expiration", columns={"expiration"})
+ * }
+ * )
* @ORM\Entity(repositoryClass="Alchemy\Phrasea\Model\Repositories\TokenRepository")
*/
class Token
diff --git a/lib/Alchemy/Phrasea/Model/Entities/WebhookEventPayload.php b/lib/Alchemy/Phrasea/Model/Entities/WebhookEventPayload.php
index 1befac1843..141d415e22 100644
--- a/lib/Alchemy/Phrasea/Model/Entities/WebhookEventPayload.php
+++ b/lib/Alchemy/Phrasea/Model/Entities/WebhookEventPayload.php
@@ -30,7 +30,7 @@ class WebhookEventPayload
private $id;
/**
- * @ORM\OneToOne(targetEntity="WebhookEventDelivery")
+ * @ORM\OneToOne(targetEntity="WebhookEventDelivery", inversedBy="payload")
* @ORM\JoinColumn(name="delivery_id", referencedColumnName="id")
*/
private $delivery;
diff --git a/lib/Alchemy/Phrasea/Model/Manipulator/TokenManipulator.php b/lib/Alchemy/Phrasea/Model/Manipulator/TokenManipulator.php
index 2a43363693..56c4e9fc36 100644
--- a/lib/Alchemy/Phrasea/Model/Manipulator/TokenManipulator.php
+++ b/lib/Alchemy/Phrasea/Model/Manipulator/TokenManipulator.php
@@ -22,7 +22,6 @@ use RandomLib\Generator;
class TokenManipulator implements ManipulatorInterface
{
const LETTERS_AND_NUMBERS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
-
const TYPE_FEED_ENTRY = 'FEED_ENTRY';
const TYPE_PASSWORD = 'password';
const TYPE_ACCOUNT_UNLOCK = 'account-unlock';
@@ -126,6 +125,38 @@ class TokenManipulator implements ManipulatorInterface
return $this->create($user, self::TYPE_FEED_ENTRY, null, $entry->getId());
}
+ /**
+ * Create feedEntryTokens for many users in one shot
+ *
+ * @param User[] $users
+ * @param FeedEntry $entry
+ * @return Token[]
+ * @throws \Doctrine\DBAL\DBALException
+ */
+ public function createFeedEntryTokens($users, FeedEntry $entry)
+ {
+ // $this->removeExpiredTokens();
+
+ $tokens = [];
+ foreach ($users as $user) {
+ $value = $this->random->generateString(32, self::LETTERS_AND_NUMBERS) . $user->getId();
+
+ $token = new Token();
+ $token->setUser($user)
+ ->setType(self::TYPE_FEED_ENTRY)
+ ->setValue($value)
+ ->setExpiration(null)
+ ->setData($entry->getId());
+ $tokens[] = $token;
+
+ $this->om->persist($token);
+ }
+ $this->om->flush();
+ $this->om->clear();
+
+ return $tokens;
+ }
+
/**
* @param User $user
* @param $data
diff --git a/lib/Alchemy/Phrasea/Model/Manipulator/UserManipulator.php b/lib/Alchemy/Phrasea/Model/Manipulator/UserManipulator.php
index 51bb1de9b6..d36fbf527a 100644
--- a/lib/Alchemy/Phrasea/Model/Manipulator/UserManipulator.php
+++ b/lib/Alchemy/Phrasea/Model/Manipulator/UserManipulator.php
@@ -370,7 +370,7 @@ class UserManipulator implements ManipulatorInterface
throw new InvalidArgumentException(sprintf('Email %s is not legal.', $email));
}
- if (null !== $this->repository->findByEmail($email)) {
+ if (($email !== null) && (null !== $this->repository->findByEmail($email))) {
throw new RuntimeException(sprintf('User with email %s already exists.', $email));
}
diff --git a/lib/Alchemy/Phrasea/Model/Repositories/BasketRepository.php b/lib/Alchemy/Phrasea/Model/Repositories/BasketRepository.php
index b835a821e0..e01864e398 100644
--- a/lib/Alchemy/Phrasea/Model/Repositories/BasketRepository.php
+++ b/lib/Alchemy/Phrasea/Model/Repositories/BasketRepository.php
@@ -232,7 +232,7 @@ class BasketRepository extends EntityRepository
$dql = "SELECT b\n"
. "FROM Phraseanet:Basket b\n"
. " JOIN b.elements e\n"
- . "WHERE b.user = :usr_id AND b.pusher_id IS NOT NULL";
+ . "WHERE b.user = :usr_id AND b.pusher IS NOT NULL";
$params = [
'usr_id' => $user->getId()
];
diff --git a/lib/Alchemy/Phrasea/Model/Repositories/TokenRepository.php b/lib/Alchemy/Phrasea/Model/Repositories/TokenRepository.php
index ad45425f7c..8e40f9ebd8 100644
--- a/lib/Alchemy/Phrasea/Model/Repositories/TokenRepository.php
+++ b/lib/Alchemy/Phrasea/Model/Repositories/TokenRepository.php
@@ -72,4 +72,9 @@ class TokenRepository extends EntityRepository
return $query->getResult();
}
+
+ public function getEntityManager()
+ {
+ return parent::getEntityManager();
+ }
}
diff --git a/lib/Alchemy/Phrasea/Model/Repositories/UserRepository.php b/lib/Alchemy/Phrasea/Model/Repositories/UserRepository.php
index d122922091..e428f8554b 100644
--- a/lib/Alchemy/Phrasea/Model/Repositories/UserRepository.php
+++ b/lib/Alchemy/Phrasea/Model/Repositories/UserRepository.php
@@ -122,4 +122,15 @@ class UserRepository extends EntityRepository
{
return $this->findBy(['templateOwner' => $user->getId()]);
}
+
+ /**
+ * Finds all templates
+ */
+ public function findTemplate()
+ {
+ $qb = $this->createQueryBuilder('u');
+ $qb->where('u.templateOwner is NOT NULL');
+
+ return $qb->getQuery()->getResult();
+ }
}
diff --git a/lib/Alchemy/Phrasea/Out/Module/PDF.php b/lib/Alchemy/Phrasea/Out/Module/PDF.php
index 7514a099db..e436e6ec5e 100644
--- a/lib/Alchemy/Phrasea/Out/Module/PDF.php
+++ b/lib/Alchemy/Phrasea/Out/Module/PDF.php
@@ -20,6 +20,8 @@ class PDF
protected $records;
protected $pdf;
+ const LAYOUT_FEEDBACK = 'feedback';
+ const LAYOUT_FEEDBACKONLY = 'feedbackOnly';
const LAYOUT_PREVIEW = 'preview';
const LAYOUT_PREVIEWCAPTION = 'previewCaption';
const LAYOUT_PREVIEWCAPTIONTDM = 'previewCaptionTdm';
@@ -27,64 +29,10 @@ class PDF
const LAYOUT_THUMBNAILGRID = 'thumbnailGrid';
const LAYOUT_CAPTION = 'caption';
- public function __construct(Application $app, array $records, $layout)
+ public function __construct(Application $app)
{
$this->app = $app;
- $list = [];
-
- foreach ($records as $record) {
- switch ($layout) {
- default:
- throw new \Exception('Unknown layout');
- break;
- case self::LAYOUT_PREVIEW:
- case self::LAYOUT_PREVIEWCAPTION:
- case self::LAYOUT_PREVIEWCAPTIONTDM:
- try {
- $subdef = $record->get_subdef('preview');
- // fallback to thumbnail ( video, sound, doc ) ..
- if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) {
- $subdef = $record->get_thumbnail();
- }
-
- if (!$subdef->is_physically_present()) {
- continue 2;
- }
-
- if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) {
- continue 2;
- }
- } catch (\Exception $e) {
- continue 2;
- }
- break;
- case self::LAYOUT_THUMBNAILLIST:
- case self::LAYOUT_THUMBNAILGRID:
- try {
- $subdef = $record->get_thumbnail();
- if (!$subdef->is_physically_present()) {
- continue 2;
- }
-
- if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) {
- continue 2;
- }
- } catch (\Exception $e) {
- continue 2;
- }
- break;
- case self::LAYOUT_CAPTION:
- break;
- }
-
- $record->setNumber(count($list) + 1);
-
- $list[] = $record;
- }
-
- $this->records = $list;
-
$pdf = new PhraseaPDF("P", "mm", "A4", true, 'UTF-8', false);
$pdf->SetAuthor("Phraseanet");
@@ -92,29 +40,6 @@ class PDF
$pdf->SetDisplayMode("fullpage", "single");
$this->pdf = $pdf;
-
- switch ($layout) {
- case self::LAYOUT_PREVIEW:
- $this->print_preview(false, false);
- break;
- case self::LAYOUT_PREVIEWCAPTION:
- $this->print_preview(false, true);
- break;
- case self::LAYOUT_PREVIEWCAPTIONTDM:
- $this->print_preview(true, true);
- break;
- case self::LAYOUT_THUMBNAILLIST:
- $this->print_thumbnailList();
- break;
- case self::LAYOUT_THUMBNAILGRID:
- $this->print_thumbnailGrid();
- break;
- case self::LAYOUT_CAPTION:
- $this->print_caption();
- break;
- }
-
- return $this;
}
public function render()
@@ -123,447 +48,4 @@ class PDF
return $this->pdf->Output('', 'S');
}
-
- protected function print_thumbnailGrid($links = false)
- {
- $NDiapoW = 3;
- $NDiapoH = 4;
-
- $this->pdf->AddPage();
-
- $oldMargins = $this->pdf->getMargins();
- $tmargin = $oldMargins['top'];
- $lmargin = $oldMargins['left'];
- $bmargin = $oldMargins['bottom'];
- $rmargin = $oldMargins['right'];
-
- $this->pdf->SetLeftMargin($lmargin + 55);
-
- $clientW = $this->pdf->getPageWidth() - $lmargin - $rmargin;
- $clientH = $this->pdf->getPageHeight() - $tmargin - $bmargin;
-
- $DiapoW = floor($clientW / $NDiapoW);
- $DiapoH = floor($clientH / $NDiapoH);
- $TitleH = 5;
- $ImgSize = min($DiapoW, ($DiapoH - $TitleH)) - 5;
-
- $npages = ceil(count($this->records) / ($NDiapoW * $NDiapoH));
-
- $irow = $ipage = 0;
- $icol = -1;
- foreach ($this->records as $rec) {
- /* @var \record_adapter $rec */
- if (++$icol >= $NDiapoW) {
- $icol = 0;
- if (++$irow >= $NDiapoH) {
- $irow = 0;
- $ipage++;
- $this->pdf->AddPage();
- }
- }
- $fimg = null;
- $himg = 0;
-
- $subdef = $rec->get_subdef('preview');
-
- if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) {
- $subdef = $rec->get_thumbnail();
- }
-
- $fimg = $subdef->getRealPath();
-
- if (!$this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($rec->getBaseId(), \ACL::NOWATERMARK)
- && $subdef->get_type() == \media_subdef::TYPE_IMAGE) {
- $fimg = \recordutils_image::watermark($this->app, $subdef);
- }
-
- $wimg = $himg = $ImgSize;
- if ($subdef->get_height() > 0 && $subdef->get_width() > 0) {
- if ($subdef->get_width() > $subdef->get_height())
- $himg = $wimg * $subdef->get_height() / $subdef->get_width();
- else
- $wimg = $himg * $subdef->get_width() / $subdef->get_height();
- }
-
- if ($fimg) {
- $x = $lmargin + ($icol * $DiapoW);
- $y = $tmargin + ($irow * $DiapoH);
- $this->pdf->SetDrawColor(0);
- $this->pdf->Rect($x, $y, $DiapoW, $DiapoH, "D");
-
- $this->pdf->SetXY($x, $y + 1);
- $this->pdf->SetFont(PhraseaPDF::FONT, '', 10);
- $t = $irow . '-' . $x;
- $t = $rec->get_title();
-
- if ($links) {
- $lk = $this->pdf->AddLink();
- $this->pdf->SetLink($lk, 0, $npages + $rec->getNumber());
- $this->pdf->Image(
- $fimg
- , $x + (($DiapoW - $wimg) / 2)
- , $TitleH + $y + (($DiapoH - $TitleH - $himg) / 2)
- , $wimg, $himg
- , null, $lk
- );
- } else {
- $this->pdf->Image($fimg
- , $x + (($DiapoW - $wimg) / 2)
- , $TitleH + $y + (($DiapoH - $TitleH - $himg) / 2)
- , $wimg, $himg
- );
- }
-
- $this->pdf->MultiCell($DiapoW, $TitleH, $t, '0', 'C', false);
- }
- }
- $this->pdf->SetLeftMargin($oldMargins['left']);
- }
-
- protected function print_thumbnailList()
- {
- $this->pdf->AddPage();
- $oldMargins = $this->pdf->getMargins();
-
- $lmargin = $oldMargins['left'];
- $rmargin = $oldMargins['right'];
-
- $this->pdf->SetLeftMargin($lmargin + 55);
-
- $ndoc = 0;
- foreach ($this->records as $rec) {
- /* @var \record_adapter $rec */
- $subdef = $rec->get_subdef('thumbnail');
-
- $fimg = $subdef->getRealPath();
-
- $wimg = $himg = 50;
- // 1px = 3.77952 mm
- $finalWidth = round($subdef->get_width() / 3.779528, 2);
- $finalHeight = round($subdef->get_height() / 3.779528, 2);
- $aspectH = $finalWidth/$finalHeight;
- $aspectW = $finalHeight/$finalWidth;
-
- if ($finalWidth > 0 && $finalHeight > 0) {
- if ($finalWidth > $finalHeight && $finalWidth > $wimg) {
- $finalWidth = $wimg;
- $finalHeight = $wimg * $aspectW;
- } else if ($finalHeight > $finalWidth && $finalHeight > $himg) {
- $finalHeight = $himg;
- $finalWidth = $himg * $aspectH;
- } else if ($finalHeight == $finalWidth & $finalWidth > $wimg) {
- $finalHeight = $wimg;
- $finalWidth = $himg;
- }
- }
-
- if ($this->pdf->GetY() > $this->pdf->getPageHeight() - (6 + $finalHeight + 20))
- $this->pdf->AddPage();
-
- $title = "record : " . $rec->get_title();
-
- $y = $this->pdf->GetY();
-
- $t = \phrasea::bas_labels($rec->getBaseId(), $this->app);
- $this->pdf->SetFont(PhraseaPDF::FONT, '', 10);
- $this->pdf->SetFillColor(220, 220, 220);
- $this->pdf->SetLeftMargin($lmargin);
- $this->pdf->SetRightMargin($rmargin);
- $this->pdf->SetX($lmargin);
- $this->pdf->SetY($y);
-
- $this->pdf->out = false;
- $this->pdf->MultiCell(140, 4, $title, "LTR", "L", 1);
- $y2 = $this->pdf->GetY();
- $h = $y2 - $y;
- $this->pdf->out = true;
- $this->pdf->SetX($lmargin);
- $this->pdf->SetY($y);
- $this->pdf->Cell(0, $h, "", "LTR", 1, "R", 1);
- $this->pdf->SetX($lmargin);
- $this->pdf->SetY($y);
- $this->pdf->Cell(0, 4, $t, "", 1, "R");
- $this->pdf->SetX($lmargin);
- $this->pdf->SetY($y);
- $this->pdf->MultiCell(140, 4, $title, "", "L");
- $this->pdf->SetX($lmargin);
- $this->pdf->SetY($y = $y2);
-
- $this->pdf->SetLeftMargin($lmargin + 55);
- $this->pdf->SetY($y + 2);
-
- if ($fimg) {
- $y = $this->pdf->GetY();
- $this->pdf->Image($fimg, $lmargin, $y, $finalWidth, $finalHeight);
- $this->pdf->SetY($y + 3);
- }
-
- $nf = 0;
- $this->pdf->SetX($lmargin + 55);
- $p0 = $this->pdf->PageNo();
- $y0 = $this->pdf->GetY();
- foreach ($rec->get_caption()->get_fields() as $field) {
- /* @var $field caption_field */
-
- $this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
- $this->pdf->Write(5, $field->get_name() . " : ");
-
- $this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
- $this->pdf->Write(5, $field->get_serialized_values());
-
- $this->pdf->Write(6, "\n");
- $nf++;
- }
- if ($this->pdf->PageNo() == $p0 && ($this->pdf->GetY() - $y0) < $finalHeight)
- $this->pdf->SetY($y0 + $finalHeight);
- $ndoc++;
- }
- $this->pdf->SetLeftMargin($lmargin);
- }
-
- protected function print_caption()
- {
- $this->pdf->AddPage();
- $oldMargins = $this->pdf->getMargins();
-
- $lmargin = $oldMargins['left'];
- $rmargin = $oldMargins['right'];
-
- foreach ($this->records as $rec) {
- $title = "record : " . $rec->get_title();
-
- $y = $this->pdf->GetY();
- if($this->pdf->getPageHeight() - $y < 20){ // height of the footer is 15
- $this->pdf->AddPage();
- $y = $oldMargins['top'];
- }
-
- $t = \phrasea::bas_labels($rec->getBaseId(), $this->app);
- $this->pdf->SetFont(PhraseaPDF::FONT, '', 10);
- $this->pdf->SetFillColor(220, 220, 220);
- $this->pdf->SetLeftMargin($lmargin);
- $this->pdf->SetRightMargin($rmargin);
- $this->pdf->SetX($lmargin);
- $this->pdf->SetY($y);
-
- $this->pdf->out = false;
- $this->pdf->MultiCell(140, 4, $title, "LTR", "L", 1);
- $y2 = $this->pdf->GetY();
- $h = $y2 - $y;
- $this->pdf->out = true;
- $this->pdf->SetX($lmargin);
- $this->pdf->SetY($y);
- $this->pdf->Cell(0, $h, "", "LTR", 1, "R", 1);
- $this->pdf->SetX($lmargin);
- $this->pdf->SetY($y);
- $this->pdf->Cell(0, 4, $t, "", 1, "R");
- $this->pdf->SetX($lmargin);
- $this->pdf->SetY($y);
- $this->pdf->MultiCell(140, 4, $title, "", "L");
- $this->pdf->SetX($lmargin);
- $this->pdf->SetY($y = $y2);
- $this->pdf->SetY($y + 2);
-
- foreach ($rec->get_caption()->get_fields() as $field) {
- $this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
- $this->pdf->Write(5, $field->get_name() . " : ");
-
- $this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
- $t = str_replace(
- ["<", ">", "&"]
- , ["<", ">", "&"]
- , strip_tags($field->get_serialized_values())
- );
- $this->pdf->Write(5, $t);
-
- $this->pdf->Write(6, "\n");
- }
- $this->pdf->SetY($this->pdf->GetY() + 10);
- }
- }
-
- protected function print_preview($withtdm, $write_caption)
- {
- if ($withtdm === true) {
- $this->print_thumbnailGrid($this->pdf, $this->records, true);
- }
-
- foreach ($this->records as $krec => $rec) {
- /* @var \record_adapter $rec */
-
- $this->pdf->AddPage();
-
- if ($withtdm === "CALCPAGES") {
- $rec->setNumber($this->pdf->PageNo());
- }
- $lmargin = $this->pdf->GetX();
- $himg = 0;
- $y = 0;
- $miniConv = NULL;
-
- $LEFT__TEXT = "";
- $LEFT__IMG = NULL;
- $RIGHT_TEXT = "";
- $RIGHT_IMG = NULL;
-
- $LEFT__IMG = $this->app['root.path'] . "/config/minilogos/logopdf_" . $rec->getDataboxId() . ".jpg";
-
- if (!is_file($LEFT__IMG)) {
- $databox = $rec->getDatabox();
- $str = $databox->get_sxml_structure();
- $vn = (string) ($str->pdfPrintLogo);
- if (($vn * 1) == 1) {
- $LEFT__TEXT = $databox->get_label($this->app['locale']);
- }
- }
-
- $collection = \collection::getByBaseId($this->app, $rec->getBaseId());
-
- $vn = "";
- if (false !== $str = simplexml_load_string($collection->get_prefs())) {
- $vn = (string) ($str->pdfPrintappear);
- }
-
- if ($vn == "" || $vn == "1") {
- $RIGHT_TEXT = \phrasea::bas_labels($rec->getBaseId(), $this->app);
- } elseif ($vn == "2") {
- $RIGHT_IMG = $this->app['root.path'] . "/config/minilogos/" . $rec->getBaseId();
- }
-
- $xtmp = $this->pdf->GetX();
- $ytmp = $this->pdf->GetY();
-
- $this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
- $this->pdf->SetFillColor(220, 220, 220);
- $y = $this->pdf->GetY();
- $this->pdf->MultiCell(95, 7, $LEFT__TEXT, "LTB", "L", 1);
- $y2 = $this->pdf->GetY();
- $h = $y2 - $y;
- $this->pdf->SetY($y);
- $this->pdf->SetX(105);
- $this->pdf->Cell(95, $h, $RIGHT_TEXT, "TBR", 1, "R", 1);
-
- if ($LEFT__TEXT == "" && is_file($LEFT__IMG)) {
- if ($size = @getimagesize($LEFT__IMG)) {
- $wmm = (int) $size[0] * 25.4 / 72;
- $hmm = (int) $size[1] * 25.4 / 72;
- if ($hmm > 6) {
- $coeff = $hmm / 6;
- $wmm = (int) $wmm / $coeff;
- $hmm = (int) $hmm / $coeff;
- }
- $this->pdf->Image($LEFT__IMG, $xtmp + 0.5, $ytmp + 0.5, $wmm, $hmm);
- }
- }
-
- if ($RIGHT_IMG != NULL && is_file($RIGHT_IMG)) {
- if ($size = @getimagesize($RIGHT_IMG)) {
-
- if ($size[2] == '1') {
- if (!isset($miniConv[$RIGHT_IMG])) {
- $tmp_filename = tempnam('minilogos/', 'gif4fpdf');
- $img = imagecreatefromgif($RIGHT_IMG);
- imageinterlace($img, 0);
- imagepng($img, $tmp_filename);
- rename($tmp_filename, $tmp_filename . '.png');
- $miniConv[$RIGHT_IMG] = $tmp_filename . '.png';
- $RIGHT_IMG = $tmp_filename . '.png';
- } else
- $RIGHT_IMG = $miniConv[$RIGHT_IMG];
-
- $wmm = (int) $size[0] * 25.4 / 72;
- $hmm = (int) $size[1] * 25.4 / 72;
- if ($hmm > 6) {
- $coeff = $hmm / 6;
- $wmm = (int) $wmm / $coeff;
- $hmm = (int) $hmm / $coeff;
- }
- $tt = 0;
- if ($hmm < 6)
- $tt = (6 - $hmm) / 2;
- $this->pdf->Image($RIGHT_IMG, 200 - 0.5 - $wmm, $ytmp + 0.5 + $tt);
- } else {
- $wmm = (int) $size[0] * 25.4 / 72;
- $hmm = (int) $size[1] * 25.4 / 72;
- if ($hmm > 6) {
- $coeff = $hmm / 6;
- $wmm = (int) $wmm / $coeff;
- $hmm = (int) $hmm / $coeff;
- }
- $this->pdf->Image($RIGHT_IMG, 200 - 0.5 - $wmm, $ytmp + 0.5);
- }
- }
- }
-
- $y = $this->pdf->GetY() + 5;
-
- $subdef = $rec->get_subdef('preview');
-
- if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) {
- $subdef = $rec->get_thumbnail();
- }
-
- $f = $subdef->getRealPath();
-
- if (!$this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($rec->getBaseId(), \ACL::NOWATERMARK)
- && $subdef->get_type() == \media_subdef::TYPE_IMAGE)
- $f = \recordutils_image::watermark($this->app, $subdef);
-
- // original height / original width x new width = new height
- $wimg = $himg = 150; // preview dans un carre de 150 mm
- // 1px = 3.77952 mm
- $finalWidth = round($subdef->get_width() / 3.779528, 2);
- $finalHeight = round($subdef->get_height() / 3.779528, 2);
- $aspectH = $finalWidth/$finalHeight;
- $aspectW = $finalHeight/$finalWidth;
-
- if ($finalWidth > 0 && $finalHeight > 0) {
- if ($finalWidth > $finalHeight && $finalWidth > $wimg) {
- $finalWidth = $wimg;
- $finalHeight = $wimg * $aspectW;
- } else if ($finalHeight > $finalWidth && $finalHeight > $himg) {
- $finalHeight = $himg;
- $finalWidth = $himg * $aspectH;
- } else if ($finalHeight == $finalWidth & $finalWidth > $wimg) {
- $finalHeight = $wimg;
- $finalWidth = $himg;
- }
- }
-
- $this->pdf->Image($f, (210 - $finalWidth) / 2, $y, $finalWidth, $finalHeight);
-
- if ($miniConv != NULL) {
- foreach ($miniConv as $oneF)
- unlink($oneF);
- }
- $this->pdf->SetXY($lmargin, $y += ( $finalHeight + 5));
-
- $nf = 0;
- if ($write_caption) {
- foreach ($rec->get_caption()->get_fields() as $field) {
- /* @var $field caption_field */
- if ($nf > 0) {
- $this->pdf->Write(6, "\n");
- }
-
- $this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
- $this->pdf->Write(5, $field->get_name() . " : ");
-
- $this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
-
- $t = str_replace(
- ["<", ">", "&"]
- , ["<", ">", "&"]
- , strip_tags($field->get_serialized_values())
- );
-
- $this->pdf->Write(5, $t);
-
- $nf++;
- }
- }
- }
-
- return;
- }
}
diff --git a/lib/Alchemy/Phrasea/Out/Module/PDFRecords.php b/lib/Alchemy/Phrasea/Out/Module/PDFRecords.php
new file mode 100644
index 0000000000..8dd5dd4492
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Out/Module/PDFRecords.php
@@ -0,0 +1,789 @@
+printer = $printer;
+
+ $records = $printer->get_elements();
+
+ $list = [];
+
+ foreach ($records as $record) {
+ switch ($layout) {
+ default:
+ throw new \Exception('Unknown layout');
+ break;
+ case self::LAYOUT_FEEDBACK:
+ case self::LAYOUT_FEEDBACKONLY:
+ case self::LAYOUT_PREVIEW:
+ case self::LAYOUT_PREVIEWCAPTION:
+ case self::LAYOUT_PREVIEWCAPTIONTDM:
+ try {
+ $subdef = $record->get_subdef('preview');
+ // fallback to thumbnail ( video, sound, doc ) ..
+ if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) {
+ $subdef = $record->get_thumbnail();
+ }
+
+ if (!$subdef->is_physically_present()) {
+ continue 2;
+ }
+
+ if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) {
+ continue 2;
+ }
+ } catch (\Exception $e) {
+ continue 2;
+ }
+ break;
+ case self::LAYOUT_THUMBNAILLIST:
+ case self::LAYOUT_THUMBNAILGRID:
+ try {
+ $subdef = $record->get_thumbnail();
+ if (!$subdef->is_physically_present()) {
+ continue 2;
+ }
+
+ if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) {
+ continue 2;
+ }
+ } catch (\Exception $e) {
+ continue 2;
+ }
+ break;
+ case self::LAYOUT_CAPTION:
+ break;
+ }
+
+ $record->setNumber(count($list) + 1);
+
+ $list[] = $record;
+ }
+
+ $this->records = $list;
+
+ switch ($layout) {
+ case self::LAYOUT_FEEDBACK:
+ $this->print_preview(false, true, true);
+ break;
+ case self::LAYOUT_FEEDBACKONLY:
+ $this->print_preview(false, false, true);
+ break;
+ case self::LAYOUT_PREVIEW:
+ $this->print_preview(false, false, false);
+ break;
+ case self::LAYOUT_PREVIEWCAPTION:
+ $this->print_preview(false, true, false);
+ break;
+ case self::LAYOUT_PREVIEWCAPTIONTDM:
+ $this->print_preview(true, true, false);
+ break;
+ case self::LAYOUT_THUMBNAILLIST:
+ $this->print_thumbnailList();
+ break;
+ case self::LAYOUT_THUMBNAILGRID:
+ $this->print_thumbnailGrid();
+ break;
+ case self::LAYOUT_CAPTION:
+ $this->print_caption();
+ break;
+ }
+ }
+
+ protected function print_thumbnailGrid($links = false)
+ {
+ $NDiapoW = 3;
+ $NDiapoH = 4;
+
+ $this->pdf->AddPage();
+
+ $oldMargins = $this->pdf->getMargins();
+ $tmargin = $oldMargins['top'];
+ $lmargin = $oldMargins['left'];
+ $bmargin = $oldMargins['bottom'];
+ $rmargin = $oldMargins['right'];
+
+ $this->pdf->SetLeftMargin($lmargin + 55);
+
+ $clientW = $this->pdf->getPageWidth() - $lmargin - $rmargin;
+ $clientH = $this->pdf->getPageHeight() - $tmargin - $bmargin;
+
+ $DiapoW = floor($clientW / $NDiapoW);
+ $DiapoH = floor($clientH / $NDiapoH);
+ $TitleH = 5;
+ $ImgSize = min($DiapoW, ($DiapoH - $TitleH)) - 5;
+
+ $npages = ceil(count($this->records) / ($NDiapoW * $NDiapoH));
+
+ $irow = $ipage = 0;
+ $icol = -1;
+ foreach ($this->records as $rec) {
+ /* @var \record_adapter $rec */
+ if (++$icol >= $NDiapoW) {
+ $icol = 0;
+ if (++$irow >= $NDiapoH) {
+ $irow = 0;
+ $ipage++;
+ $this->pdf->AddPage();
+ }
+ }
+ $fimg = null;
+ $himg = 0;
+
+ $subdef = $rec->get_subdef('preview');
+
+ if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) {
+ $subdef = $rec->get_thumbnail();
+ }
+
+ $fimg = $subdef->getRealPath();
+
+ if (!$this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($rec->getBaseId(), \ACL::NOWATERMARK)
+ && $subdef->get_type() == \media_subdef::TYPE_IMAGE) {
+ $fimg = \recordutils_image::watermark($this->app, $subdef);
+ }
+
+ $wimg = $himg = $ImgSize;
+ if ($subdef->get_height() > 0 && $subdef->get_width() > 0) {
+ if ($subdef->get_width() > $subdef->get_height())
+ $himg = $wimg * $subdef->get_height() / $subdef->get_width();
+ else
+ $wimg = $himg * $subdef->get_width() / $subdef->get_height();
+ }
+
+ if ($fimg) {
+ $x = $lmargin + ($icol * $DiapoW);
+ $y = $tmargin + ($irow * $DiapoH);
+ $this->pdf->SetDrawColor(0);
+ $this->pdf->Rect($x, $y, $DiapoW, $DiapoH, "D");
+
+ $this->pdf->SetXY($x, $y + 1);
+ $this->pdf->SetFont(PhraseaPDF::FONT, '', 10);
+ $t = $irow . '-' . $x;
+ $t = $rec->get_title();
+
+ if ($links) {
+ $lk = $this->pdf->AddLink();
+ $this->pdf->SetLink($lk, 0, $npages + $rec->getNumber());
+ $this->pdf->Image(
+ $fimg
+ , $x + (($DiapoW - $wimg) / 2)
+ , $TitleH + $y + (($DiapoH - $TitleH - $himg) / 2)
+ , $wimg, $himg
+ , null, $lk
+ );
+ } else {
+ $this->pdf->Image($fimg
+ , $x + (($DiapoW - $wimg) / 2)
+ , $TitleH + $y + (($DiapoH - $TitleH - $himg) / 2)
+ , $wimg, $himg
+ );
+ }
+
+ $this->pdf->MultiCell($DiapoW, $TitleH, $t, '0', 'C', false);
+ }
+ }
+ $this->pdf->SetLeftMargin($oldMargins['left']);
+ }
+
+ protected function print_thumbnailList()
+ {
+ $this->pdf->AddPage();
+ $oldMargins = $this->pdf->getMargins();
+
+ $lmargin = $oldMargins['left'];
+ $rmargin = $oldMargins['right'];
+
+ $this->pdf->SetLeftMargin($lmargin + 55);
+
+ $ndoc = 0;
+ foreach ($this->records as $rec) {
+ /* @var \record_adapter $rec */
+ $subdef = $rec->get_subdef('thumbnail');
+
+ $fimg = $subdef->getRealPath();
+
+ $wimg = $himg = 50;
+ // 1px = 3.77952 mm
+ $finalWidth = round($subdef->get_width() / 3.779528, 2);
+ $finalHeight = round($subdef->get_height() / 3.779528, 2);
+ $aspectH = $finalWidth/$finalHeight;
+ $aspectW = $finalHeight/$finalWidth;
+
+ if ($finalWidth > 0 && $finalHeight > 0) {
+ if ($finalWidth > $finalHeight && $finalWidth > $wimg) {
+ $finalWidth = $wimg;
+ $finalHeight = $wimg * $aspectW;
+ } else if ($finalHeight > $finalWidth && $finalHeight > $himg) {
+ $finalHeight = $himg;
+ $finalWidth = $himg * $aspectH;
+ } else if ($finalHeight == $finalWidth & $finalWidth > $wimg) {
+ $finalHeight = $wimg;
+ $finalWidth = $himg;
+ }
+ }
+
+ if ($this->pdf->GetY() > $this->pdf->getPageHeight() - (6 + $finalHeight + 20))
+ $this->pdf->AddPage();
+
+ $title = "record : " . $rec->get_title();
+
+ $y = $this->pdf->GetY();
+
+ $t = \phrasea::bas_labels($rec->getBaseId(), $this->app);
+ $this->pdf->SetFont(PhraseaPDF::FONT, '', 10);
+ $this->pdf->SetFillColor(220, 220, 220);
+ $this->pdf->SetLeftMargin($lmargin);
+ $this->pdf->SetRightMargin($rmargin);
+ $this->pdf->SetX($lmargin);
+ $this->pdf->SetY($y);
+
+ $this->pdf->out = false;
+ $this->pdf->MultiCell(140, 4, $title, "LTR", "L", 1);
+ $y2 = $this->pdf->GetY();
+ $h = $y2 - $y;
+ $this->pdf->out = true;
+ $this->pdf->SetX($lmargin);
+ $this->pdf->SetY($y);
+ $this->pdf->Cell(0, $h, "", "LTR", 1, "R", 1);
+ $this->pdf->SetX($lmargin);
+ $this->pdf->SetY($y);
+ $this->pdf->Cell(0, 4, $t, "", 1, "R");
+ $this->pdf->SetX($lmargin);
+ $this->pdf->SetY($y);
+ $this->pdf->MultiCell(140, 4, $title, "", "L");
+ $this->pdf->SetX($lmargin);
+ $this->pdf->SetY($y = $y2);
+
+ $this->pdf->SetLeftMargin($lmargin + 55);
+ $this->pdf->SetY($y + 2);
+
+ if ($fimg) {
+ $y = $this->pdf->GetY();
+ $this->pdf->Image($fimg, $lmargin, $y, $finalWidth, $finalHeight);
+ $this->pdf->SetY($y + 3);
+ }
+
+ $nf = 0;
+ $this->pdf->SetX($lmargin + 55);
+ $p0 = $this->pdf->PageNo();
+ $y0 = $this->pdf->GetY();
+ foreach ($rec->get_caption()->get_fields() as $field) {
+ /* @var $field caption_field */
+
+ $this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
+ $this->pdf->Write(5, $field->get_name() . " : ");
+
+ $this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
+ $this->pdf->Write(5, $field->get_serialized_values());
+
+ $this->pdf->Write(6, "\n");
+ $nf++;
+ }
+ if ($this->pdf->PageNo() == $p0 && ($this->pdf->GetY() - $y0) < $finalHeight)
+ $this->pdf->SetY($y0 + $finalHeight);
+ $ndoc++;
+ }
+ $this->pdf->SetLeftMargin($lmargin);
+ }
+
+ protected function print_caption()
+ {
+ $this->pdf->AddPage();
+ $oldMargins = $this->pdf->getMargins();
+
+ $lmargin = $oldMargins['left'];
+ $rmargin = $oldMargins['right'];
+
+ foreach ($this->records as $rec) {
+ $title = "record : " . $rec->get_title();
+
+ $y = $this->pdf->GetY();
+ if($this->pdf->getPageHeight() - $y < 20){ // height of the footer is 15
+ $this->pdf->AddPage();
+ $y = $oldMargins['top'];
+ }
+
+ $t = \phrasea::bas_labels($rec->getBaseId(), $this->app);
+ $this->pdf->SetFont(PhraseaPDF::FONT, '', 10);
+ $this->pdf->SetFillColor(220, 220, 220);
+ $this->pdf->SetLeftMargin($lmargin);
+ $this->pdf->SetRightMargin($rmargin);
+ $this->pdf->SetX($lmargin);
+ $this->pdf->SetY($y);
+
+ $this->pdf->out = false;
+ $this->pdf->MultiCell(140, 4, $title, "LTR", "L", 1);
+ $y2 = $this->pdf->GetY();
+ $h = $y2 - $y;
+ $this->pdf->out = true;
+ $this->pdf->SetX($lmargin);
+ $this->pdf->SetY($y);
+ $this->pdf->Cell(0, $h, "", "LTR", 1, "R", 1);
+ $this->pdf->SetX($lmargin);
+ $this->pdf->SetY($y);
+ $this->pdf->Cell(0, 4, $t, "", 1, "R");
+ $this->pdf->SetX($lmargin);
+ $this->pdf->SetY($y);
+ $this->pdf->MultiCell(140, 4, $title, "", "L");
+ $this->pdf->SetX($lmargin);
+ $this->pdf->SetY($y = $y2);
+ $this->pdf->SetY($y + 2);
+
+ foreach ($rec->get_caption()->get_fields() as $field) {
+ if ($field->get_databox_field()->get_gui_visible()) {
+ $this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
+ $this->pdf->Write(5, $field->get_name() . " : ");
+
+ $this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
+ $t = str_replace(
+ ["<", ">", "&"]
+ , ["<", ">", "&"]
+ , strip_tags($field->get_serialized_values())
+ );
+ $this->pdf->Write(5, $t);
+
+ $this->pdf->Write(6, "\n");
+ }
+ }
+ $this->pdf->SetY($this->pdf->GetY() + 10);
+ }
+ }
+
+
+ protected function print_preview($withtdm, $write_caption, $withfeedback)
+ {
+ $basket = $validation = null;
+
+ if($this->printer->is_basket()) {
+ $basket = $this->printer->get_original_basket();
+
+ if($withfeedback) {
+ // first page : validation informations
+ $validation = $basket->getValidation();
+
+ $this->pdf->AddPage();
+
+ $this->pdf->SetY(20);
+ $this->pdf->SetFont(PhraseaPDF::FONT, 'B', 14);
+ $this->pdf->Cell(0, 0,
+ $this->app->trans("print_feedback:: Feedback on basket %name%", ['%name%'=>$basket->getName()]),
+ '', 1, 'C', false);
+
+ $this->pdf->SetY($this->pdf->GetY()+10);
+
+ $this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
+ $this->pdf->Write(5, $this->app->trans("print_feedback:: Document generated on : ") . " ");
+ $this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
+ $this->pdf->Write(5, $this->formatDate(new \DateTime('now')));
+ $this->pdf->Write(12, "\n");
+
+ $this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
+ $this->pdf->Write(5, $this->app->trans("print_feedback:: Feedback initiated by : ") . " ");
+ $this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
+ $this->pdf->Write(5, $this->getDisplayName($validation->getInitiator()));
+ $this->pdf->Write(6, "\n");
+
+ $this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
+ $this->pdf->Write(5, $this->app->trans("print_feedback:: Feedback initiated on : ") . " ");
+ $this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
+ $this->pdf->Write(5, $this->formatDate($validation->getCreated()));
+ $this->pdf->Write(6, "\n");
+
+ $this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
+ $this->pdf->Write(5, $this->app->trans("print_feedback:: Feedback expiring on : ") . " ");
+ $this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
+ $this->pdf->Write(5, $this->formatDate($validation->getExpires()));
+ $this->pdf->Write(12, "\n");
+
+ $this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
+ $validation->isFinished() ? $this->pdf->Write(5, $this->app->trans("print_feedback:: Feedback expired")) : $this->pdf->Write(5, $this->app->trans("print_feedback:: Feedback active"));
+ $this->pdf->Write(12, "\n");
+
+ $this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
+ $this->pdf->Write(5, $this->app->trans("print_feedback:: Participants : "));
+ $this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
+ foreach ($validation->getParticipants() as $participant) {
+ $this->pdf->Write(5, "\n - " . $this->getDisplayName($participant->getUser()));
+ }
+ }
+ }
+
+ if ($withtdm === true) {
+ $this->print_thumbnailGrid($this->pdf, $this->records, true);
+ }
+
+ foreach ($this->records as $krec => $rec) {
+ /* @var \record_adapter $rec */
+
+ $this->pdf->AddPage();
+
+ if ($withtdm === "CALCPAGES") {
+ $rec->setNumber($this->pdf->PageNo());
+ }
+ $lmargin = $this->pdf->GetX();
+ $himg = 0;
+ $y = 0;
+ $miniConv = NULL;
+
+ $LEFT__TEXT = "";
+ $LEFT__IMG = NULL;
+ $RIGHT_TEXT = "";
+ $RIGHT_IMG = NULL;
+
+ $LEFT__IMG = $this->app['root.path'] . "/config/minilogos/logopdf_" . $rec->getDataboxId() . ".jpg";
+
+ if (!is_file($LEFT__IMG)) {
+ $databox = $rec->getDatabox();
+ $str = $databox->get_sxml_structure();
+ $vn = (string) ($str->pdfPrintLogo);
+ if (($vn * 1) == 1) {
+ $LEFT__TEXT = $databox->get_label($this->app['locale']);
+ }
+ }
+
+ $collection = \collection::getByBaseId($this->app, $rec->getBaseId());
+
+ $vn = "";
+ if (false !== $str = simplexml_load_string($collection->get_prefs())) {
+ $vn = (string) ($str->pdfPrintappear);
+ }
+
+ if ($vn == "" || $vn == "1") {
+ $RIGHT_TEXT = \phrasea::bas_labels($rec->getBaseId(), $this->app);
+ } elseif ($vn == "2") {
+ $RIGHT_IMG = $this->app['root.path'] . "/config/minilogos/" . $rec->getBaseId();
+ }
+
+ $xtmp = $this->pdf->GetX();
+ $ytmp = $this->pdf->GetY();
+
+ $this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
+ $this->pdf->SetFillColor(220, 220, 220);
+ $y = $this->pdf->GetY();
+ $this->pdf->MultiCell(95, 7, $LEFT__TEXT, "LTB", "L", 1);
+ $y2 = $this->pdf->GetY();
+ $h = $y2 - $y;
+ $this->pdf->SetY($y);
+ $this->pdf->SetX(105);
+ $this->pdf->Cell(95, $h, $RIGHT_TEXT, "TBR", 1, "R", 1);
+
+ if($basket) {
+ $ord = $basket->getElementByRecord($this->app, $rec)->getOrd();
+ $this->pdf->SetY($y);
+ $this->pdf->SetX(10);
+ $this->pdf->Cell(190, $h, $ord, "", 1, "C", 0);
+ }
+
+ if ($LEFT__TEXT == "" && is_file($LEFT__IMG)) {
+ if ($size = @getimagesize($LEFT__IMG)) {
+ $wmm = (int) $size[0] * 25.4 / 72;
+ $hmm = (int) $size[1] * 25.4 / 72;
+ if ($hmm > 6) {
+ $coeff = $hmm / 6;
+ $wmm = (int) $wmm / $coeff;
+ $hmm = (int) $hmm / $coeff;
+ }
+ $this->pdf->Image($LEFT__IMG, $xtmp + 0.5, $ytmp + 0.5, $wmm, $hmm);
+ }
+ }
+
+ if ($RIGHT_IMG != NULL && is_file($RIGHT_IMG)) {
+ if ($size = @getimagesize($RIGHT_IMG)) {
+
+ if ($size[2] == '1') {
+ if (!isset($miniConv[$RIGHT_IMG])) {
+ $tmp_filename = tempnam('minilogos/', 'gif4fpdf');
+ $img = imagecreatefromgif($RIGHT_IMG);
+ imageinterlace($img, 0);
+ imagepng($img, $tmp_filename);
+ rename($tmp_filename, $tmp_filename . '.png');
+ $miniConv[$RIGHT_IMG] = $tmp_filename . '.png';
+ $RIGHT_IMG = $tmp_filename . '.png';
+ } else
+ $RIGHT_IMG = $miniConv[$RIGHT_IMG];
+
+ $wmm = (int) $size[0] * 25.4 / 72;
+ $hmm = (int) $size[1] * 25.4 / 72;
+ if ($hmm > 6) {
+ $coeff = $hmm / 6;
+ $wmm = (int) $wmm / $coeff;
+ $hmm = (int) $hmm / $coeff;
+ }
+ $tt = 0;
+ if ($hmm < 6)
+ $tt = (6 - $hmm) / 2;
+ $this->pdf->Image($RIGHT_IMG, 200 - 0.5 - $wmm, $ytmp + 0.5 + $tt);
+ } else {
+ $wmm = (int) $size[0] * 25.4 / 72;
+ $hmm = (int) $size[1] * 25.4 / 72;
+ if ($hmm > 6) {
+ $coeff = $hmm / 6;
+ $wmm = (int) $wmm / $coeff;
+ $hmm = (int) $hmm / $coeff;
+ }
+ $this->pdf->Image($RIGHT_IMG, 200 - 0.5 - $wmm, $ytmp + 0.5);
+ }
+ }
+ }
+
+ $y = $this->pdf->GetY() + 5;
+
+ $subdef = $rec->get_subdef('preview');
+
+ if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) {
+ $subdef = $rec->get_thumbnail();
+ }
+
+ $f = $subdef->getRealPath();
+
+ if (!$this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($rec->getBaseId(), \ACL::NOWATERMARK)
+ && $subdef->get_type() == \media_subdef::TYPE_IMAGE)
+ $f = \recordutils_image::watermark($this->app, $subdef);
+
+ // original height / original width x new width = new height
+ $wimg = $himg = 150; // preview dans un carre de 150 mm
+ // 1px = 3.77952 mm
+ $finalWidth = round($subdef->get_width() / 3.779528, 2);
+ $finalHeight = round($subdef->get_height() / 3.779528, 2);
+ $aspectH = $finalWidth/$finalHeight;
+ $aspectW = $finalHeight/$finalWidth;
+
+ if ($finalWidth > 0 && $finalHeight > 0) {
+ if ($finalWidth > $finalHeight && $finalWidth > $wimg) {
+ $finalWidth = $wimg;
+ $finalHeight = $wimg * $aspectW;
+ } else if ($finalHeight > $finalWidth && $finalHeight > $himg) {
+ $finalHeight = $himg;
+ $finalWidth = $himg * $aspectH;
+ } else if ($finalHeight == $finalWidth & $finalWidth > $wimg) {
+ $finalHeight = $wimg;
+ $finalWidth = $himg;
+ }
+ }
+
+ $this->pdf->Image($f, (210 - $finalWidth) / 2, $y, $finalWidth, $finalHeight);
+
+ if ($miniConv != NULL) {
+ foreach ($miniConv as $oneF)
+ unlink($oneF);
+ }
+ $this->pdf->SetXY($lmargin, $y += ( $finalHeight + 5));
+
+ $this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
+ $this->pdf->Write(5, $this->app->trans("print_feedback:: record title: ") . " ");
+ $this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
+ $this->pdf->Write(5, $rec->get_title());
+ $this->pdf->Write(6, "\n");
+
+ $this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
+ $this->pdf->Write(5, $this->app->trans("print_feedback:: record id: ") . " ");
+ $this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
+ $this->pdf->Write(5, $rec->getRecordId());
+ $this->pdf->Write(6, "\n");
+
+ $this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
+ $this->pdf->Write(5, $this->app->trans("print_feedback:: base name: ") . " ");
+ $this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
+ $this->pdf->Write(5, $rec->getDatabox()->get_label($this->app['locale']));
+ $this->pdf->Write(6, "\n");
+
+ $this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
+ $this->pdf->Write(5, $this->app->trans("print_feedback:: originale filename: ") . " ");
+ $this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
+ $this->pdf->Write(5, $rec->get_original_name());
+ $this->pdf->Write(6, "\n");
+
+ $this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
+ $this->pdf->Write(5, $this->app->trans("print_feedback:: document Uuid: ") . " ");
+ $this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
+ $this->pdf->Write(5, $rec->getUUID());
+ $this->pdf->Write(6, "\n");
+
+ $nf = 0;
+ if($basket && $validation) {
+ /** @var ValidationParticipant $participant */
+
+ if ($nf > 0) {
+ $this->pdf->Write(6, "\n");
+ }
+ $this->pdf->Write(12, "\n");
+ $this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
+ $this->pdf->Write(5, $this->app->trans("print_feedback:: Votes :"));
+ $this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
+
+ $basketElement = $basket->getElementByRecord($this->app, $rec);
+
+ $iparticipant = 0;
+ foreach ($validation->getParticipants() as $participant) {
+ $this->pdf->Write(6, "\n");
+ if($iparticipant++ > 0) {
+ // $this->pdf->SetY($this->pdf->GetY()+1);
+ }
+ $validationData = $basketElement->getUserValidationDatas($participant->getUser());
+
+ $this->pdf->Write(5, '- ' . $this->getDisplayName($participant->getUser(), true). " : ");
+
+ $r = $validationData->getAgreement();
+ $this->pdf->SetX(100);
+ if ($r === null) {
+ $this->pdf->Write(0, $this->app->trans("print_feedback:: non voté"));
+ }
+ else {
+ if($r) {
+ $this->pdf->SetTextColor(0, 127, 0);
+ $this->pdf->Write(0, $this->app->trans("print_feedback:: Oui"));
+ }
+ else {
+ $this->pdf->SetTextColor(200, 0, 0);
+ $this->pdf->Write(0, $this->app->trans("print_feedback:: Non"));
+ }
+ $this->pdf->SetTextColor(0);
+ $this->pdf->Write(0, " (" . $this->formatDate($validationData->getUpdated()) . ")");
+ }
+
+ if (($note = (string)($validationData->getNote())) !== '') {
+ $this->pdf->SetFont(PhraseaPDF::FONT, 'I', 11);
+ $this->pdf->Write(5,"\n");
+ $this->pdf->SetX(100);
+ $this->pdf->MultiCell(95, 0, $note, '', "L", false);
+ $this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
+ }
+
+ $nf++;
+ }
+ }
+
+ if ($write_caption) {
+ $this->pdf->Write(12, "\n");
+ foreach ($rec->get_caption()->get_fields() as $field) {
+ /* @var $field caption_field */
+
+ if ($field->get_databox_field()->get_gui_visible()) {
+ if ($nf > 0) {
+ $this->pdf->Write(6, "\n");
+ }
+
+ $this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
+ $this->pdf->Write(5, $field->get_name() . " : ");
+
+ $this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
+
+ $t = str_replace(
+ ["<", ">", "&"]
+ , ["<", ">", "&"]
+ , strip_tags($field->get_serialized_values())
+ );
+
+ $this->pdf->Write(5, $t);
+
+ $nf++;
+ }
+ }
+ }
+ }
+
+ return;
+ }
+
+ private function formatDate(\DateTime $date)
+ {
+ $locale = $this->app['locale'];
+
+ switch ($locale) {
+ case 'fr':
+ $fmt = new DateFormatter(
+ 'fr_FR',
+ DateFormatter::LONG,
+ DateFormatter::NONE
+ );
+
+ $date_formated = $fmt->format($date);
+ break;
+
+ case 'en':
+ $fmt = new DateFormatter(
+ 'en_EN',
+ DateFormatter::LONG,
+ DateFormatter::NONE
+ );
+
+ $date_formated = $fmt->format($date);
+ break;
+
+ case 'de':
+ $fmt = new DateFormatter(
+ 'de_DE',
+ DateFormatter::LONG,
+ DateFormatter::NONE
+ );
+
+ $date_formated = $fmt->format($date);
+ break;
+
+ default:
+ $fmt = new DateFormatter(
+ 'en_EN',
+ DateFormatter::LONG,
+ DateFormatter::NONE ,
+ null,
+ null,
+ 'yyyy/mm/dd'
+ );
+
+ $date_formated = $fmt->format($date);
+ break;
+ }
+
+ return $date_formated;
+ }
+
+ private function getDisplayName($user, $short = false)
+ {
+ $displayName = '';
+
+ if (trim($user->getLastName()) !== '' || trim($user->getFirstName()) !== '') {
+ $displayName = $user->getFirstName() . ('' !== $user->getFirstName() && '' !== $user->getLastName() ? ' ' : '') . $user->getLastName() ;
+
+ if ($short) {
+ return $displayName;
+ }
+ }
+
+ $email = trim($user->getEmail());
+
+ if ($email === '') {
+ $email = $user->getLogin();
+ }
+
+ if ($displayName !== '') {
+ return $displayName . ", " . $email;
+ } else {
+ return $email;
+ }
+ }
+
+}
diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php
index 63d9ec108e..2424330031 100644
--- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php
+++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php
@@ -668,17 +668,20 @@ class ElasticSearchEngine implements SearchEngineInterface
}
// fields aggregates
$structure = $this->context_factory->getLimitedStructure($options);
- foreach ($structure->getFacetFields() as $name => $field) {
- // 2015-05-26 (mdarse) Removed databox filtering.
- // It was already done by the ACL filter in the query scope, so no
- // document that shouldn't be displayed can go this far.
- $agg = [
- 'terms' => [
- 'field' => $field->getIndexField(true),
- 'size' => $field->getFacetValuesLimit()
- ]
- ];
- $aggs[$name] = AggregationHelper::wrapPrivateFieldAggregation($field, $agg);
+ foreach($structure->getAllFields() as $name => $field) {
+ $size = $this->options->getAggregableFieldLimit($name);
+ if ($size !== databox_field::FACET_DISABLED) {
+ if ($size === databox_field::FACET_NO_LIMIT) {
+ $size = ESField::FACET_NO_LIMIT;
+ }
+ $agg = [
+ 'terms' => [
+ 'field' => $field->getIndexField(true),
+ 'size' => $size
+ ]
+ ];
+ $aggs[$name] = AggregationHelper::wrapPrivateFieldAggregation($field, $agg);
+ }
}
return $aggs;
diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticsearchOptions.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticsearchOptions.php
index 0532f85c30..07e54449eb 100644
--- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticsearchOptions.php
+++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticsearchOptions.php
@@ -9,6 +9,10 @@
*/
namespace Alchemy\Phrasea\SearchEngine\Elastic;
+use databox_field;
+use igorw;
+
+
class ElasticsearchOptions
{
const POPULATE_ORDER_RID = "RECORD_ID";
@@ -35,7 +39,7 @@ class ElasticsearchOptions
private $populateDirection;
/** @var int[] */
- private $_customValues;
+ private $_customValues = [];
private $activeTab;
/**
@@ -57,14 +61,10 @@ class ElasticsearchOptions
'populate_order' => self::POPULATE_ORDER_RID,
'populate_direction' => self::POPULATE_DIRECTION_DESC,
'activeTab' => null,
+ 'facets' => []
];
-
- foreach(self::getAggregableTechnicalFields() as $k => $f) {
- $defaultOptions[$k.'_limit'] = 0;
- }
$options = array_replace($defaultOptions, $options);
-
$self = new self();
$self->setHost($options['host']);
$self->setPort($options['port']);
@@ -76,11 +76,10 @@ class ElasticsearchOptions
$self->setPopulateOrder($options['populate_order']);
$self->setPopulateDirection($options['populate_direction']);
$self->setActiveTab($options['activeTab']);
- foreach(self::getAggregableTechnicalFields() as $k => $f) {
- $self->setAggregableFieldLimit($k, $options[$k.'_limit']);
+ foreach($options['facets'] as $fieldname=>$attributes) {
+ $self->setAggregableField($fieldname, $attributes);
}
-
return $self;
}
@@ -99,10 +98,11 @@ class ElasticsearchOptions
'highlight' => $this->highlight,
'populate_order' => $this->populateOrder,
'populate_direction' => $this->populateDirection,
- 'activeTab' => $this->activeTab
+ 'activeTab' => $this->activeTab,
+ 'facets' => []
];
- foreach(self::getAggregableTechnicalFields() as $k => $f) {
- $ret[$k.'_limit'] = $this->getAggregableFieldLimit($k);
+ foreach($this->getAggregableFields() as $fieldname=>$attributes) {
+ $ret['facets'][$fieldname] = $attributes;
}
return $ret;
@@ -222,12 +222,51 @@ class ElasticsearchOptions
public function setAggregableFieldLimit($key, $value)
{
- $this->_customValues[$key.'_limit'] = $value;
+ if(is_null($this->getAggregableField($key))) {
+ $this->_customValues['facets'][$key] = [];
+ }
+ $this->_customValues['facets'][$key]['limit'] = $value;
+ }
+
+ public function setAggregableField($key, $attributes)
+ {
+ $this->getAggregableFields(); // ensure facets exists
+ $this->_customValues['facets'][$key] = $attributes;
}
public function getAggregableFieldLimit($key)
{
- return $this->_customValues[$key.'_limit'];
+ $facet = $this->getAggregableField($key);
+ return (is_array($facet) && array_key_exists('limit', $facet)) ? $facet['limit'] : databox_field::FACET_DISABLED;
+ }
+
+ public function getAggregableField($key)
+ {
+ $facets = $this->getAggregableFields();
+ return array_key_exists($key, $facets) ? $facets[$key] : null;
+ }
+
+ /**
+ * @return array
+ */
+ public function getAggregableFields()
+ {
+ if(!array_key_exists('facets', $this->_customValues) || !is_array($this->_customValues['facets'])) {
+ $this->_customValues['facets'] = [];
+ }
+ return $this->_customValues['facets'];
+ }
+
+ // set to change the facets order during admin/form save
+ public function reorderAggregableFields($facetNames)
+ {
+ $newFacets = [];
+ foreach ($facetNames as $name) {
+ if(($facet = $this->getAggregableField($name)) !== null) {
+ $newFacets[$name] = $facet;
+ }
+ }
+ $this->_customValues['facets'] = $newFacets;
}
public function getActiveTab()
@@ -241,56 +280,56 @@ class ElasticsearchOptions
public function __get($key)
{
- if(!array_key_exists($key, $this->_customValues)) {
- $this->_customValues[$key] = 0;
- }
- return $this->_customValues[$key];
+ $keys = explode(':', $key);
+
+ return igorw\get_in($this->_customValues, $keys);
}
public function __set($key, $value)
{
- $this->_customValues[$key] = $value;
+ $keys = explode(':', $key);
+ $this->_customValues = igorw\assoc_in($this->_customValues, $keys, $value);
}
public static function getAggregableTechnicalFields()
{
return [
- 'base_aggregate' => [
+ '_base' => [
'type' => 'string',
'label' => 'prod::facet:base_label',
'field' => "database",
'esfield' => 'databox_name',
'query' => 'database:%s',
],
- 'collection_aggregate' => [
+ '_collection' => [
'type' => 'string',
'label' => 'prod::facet:collection_label',
'field' => "collection",
'esfield' => 'collection_name',
'query' => 'collection:%s',
],
- 'doctype_aggregate' => [
+ '_doctype' => [
'type' => 'string',
'label' => 'prod::facet:doctype_label',
'field' => "type",
'esfield' => 'type',
'query' => 'type:%s',
],
- 'camera_model_aggregate' => [
+ '_camera_model' => [
'type' => 'string',
'label' => 'Camera Model',
'field' => "meta.CameraModel",
'esfield' => 'metadata_tags.CameraModel',
'query' => 'meta.CameraModel:%s',
],
- 'iso_aggregate' => [
+ '_iso' => [
'type' => 'number',
'label' => 'ISO',
'field' => "meta.ISO",
'esfield' => 'metadata_tags.ISO',
'query' => 'meta.ISO=%s',
],
- 'aperture_aggregate' => [
+ '_aperture' => [
'type' => 'number',
'label' => 'Aperture',
'field' => "meta.Aperture",
@@ -300,7 +339,7 @@ class ElasticsearchOptions
return round($value, 1);
},
],
- 'shutterspeed_aggregate' => [
+ '_shutterspeed' => [
'type' => 'number',
'label' => 'Shutter speed',
'field' => "meta.ShutterSpeed",
@@ -313,7 +352,7 @@ class ElasticsearchOptions
return $value . ' s.';
},
],
- 'flashfired_aggregate' => [
+ '_flashfired' => [
'type' => 'boolean',
'label' => 'FlashFired',
'field' => "meta.FlashFired",
@@ -327,49 +366,49 @@ class ElasticsearchOptions
return array_key_exists($value, $map) ? $map[$value] : $value;
},
],
- 'framerate_aggregate' => [
+ '_framerate' => [
'type' => 'number',
'label' => 'FrameRate',
'field' => "meta.FrameRate",
'esfield' => 'metadata_tags.FrameRate',
'query' => 'meta.FrameRate=%s',
],
- 'audiosamplerate_aggregate' => [
+ '_audiosamplerate' => [
'type' => 'number',
'label' => 'Audio Samplerate',
'field' => "meta.AudioSamplerate",
'esfield' => 'metadata_tags.AudioSamplerate',
'query' => 'meta.AudioSamplerate=%s',
],
- 'videocodec_aggregate' => [
+ '_videocodec' => [
'type' => 'string',
'label' => 'Video codec',
'field' => "meta.VideoCodec",
'esfield' => 'metadata_tags.VideoCodec',
'query' => 'meta.VideoCodec:%s',
],
- 'audiocodec_aggregate' => [
+ '_audiocodec' => [
'type' => 'string',
'label' => 'Audio codec',
'field' => "meta.AudioCodec",
'esfield' => 'metadata_tags.AudioCodec',
'query' => 'meta.AudioCodec:%s',
],
- 'orientation_aggregate' => [
+ '_orientation' => [
'type' => 'string',
'label' => 'Orientation',
'field' => "meta.Orientation",
'esfield' => 'metadata_tags.Orientation',
'query' => 'meta.Orientation=%s',
],
- 'colorspace_aggregate' => [
+ '_colorspace' => [
'type' => 'string',
'label' => 'Colorspace',
'field' => "meta.ColorSpace",
'esfield' => 'metadata_tags.ColorSpace',
'query' => 'meta.ColorSpace:%s',
],
- 'mimetype_aggregate' => [
+ '_mimetype' => [
'type' => 'string',
'label' => 'MimeType',
'field' => "meta.MimeType",
diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticsearchSettingsFormType.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticsearchSettingsFormType.php
index e1aaa3e378..1f2fa3d1e2 100644
--- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticsearchSettingsFormType.php
+++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticsearchSettingsFormType.php
@@ -9,6 +9,7 @@
*/
namespace Alchemy\Phrasea\SearchEngine\Elastic;
+use Alchemy\Phrasea\SearchEngine\Elastic\Structure\GlobalStructure;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
@@ -17,6 +18,18 @@ use Symfony\Component\Validator\Constraints\Range;
class ElasticsearchSettingsFormType extends AbstractType
{
+ /** @var GlobalStructure */
+ private $globalStructure;
+
+ /** @var ElasticsearchOptions */
+ private $esSettings;
+
+ public function __construct(GlobalStructure $g, ElasticsearchOptions $settings)
+ {
+ $this->globalStructure = $g;
+ $this->esSettings = $settings;
+ }
+
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
@@ -56,59 +69,89 @@ class ElasticsearchSettingsFormType extends AbstractType
->add('minScore', 'integer', [
'label' => 'Thesaurus Min score',
'constraints' => new Range(['min' => 0]),
- ]);
+ ])
+ ->add('highlight', 'checkbox', [
+ 'label' => 'Activate highlight',
+ 'required' => false
+ ])
+ // ->add('save', 'submit', [
+ // 'attr' => ['class' => 'btn btn-primary']
+ // ])
+ ->add('esSettingFromIndex', 'button', [
+ 'label' => 'Get setting form index',
+ 'attr' => [
+ 'onClick' => 'esSettingFromIndex()',
+ 'class' => 'btn'
+ ]
+ ])
+ ->add('dumpField', 'textarea', [
+ 'label' => false,
+ 'required' => false,
+ 'mapped' => false,
+ 'attr' => ['class' => 'dumpfield hide']
+ ])
+ ->add('activeTab', 'hidden');
- foreach(ElasticsearchOptions::getAggregableTechnicalFields() as $k => $f) {
- if(array_key_exists('choices', $f)) {
- // choices[] : choice_key => choice_value
- $choices = $f['choices'];
- }
- else {
- $choices = [
- "10 values" => 10,
- "20 values" => 20,
- "50 values" => 50,
- "100 values" => 100,
- "all values" => -1
- ];
- }
- // array_unshift($choices, "not aggregated"); // always as first choice
- $choices = array_merge(["not aggregated" => 0], $choices);
- $builder
- ->add($k.'_limit', ChoiceType::class, [
- // 'label' => $f['label'],// . ' ' . 'aggregate limit',
- 'choices_as_values' => true,
- 'choices' => $choices,
- 'attr' => [
- 'class' => 'aggregate'
- ]
- ]);
+ // keep aggregates in configuration order with this intermediate array
+ $aggs = [];
+
+ // helper fct to add aggregate to a tmp list
+ $addAgg = function($k, $label, $help, $disabled=false, $choices=null) use (&$aggs) {
+ if(!$choices) {
+ $choices = [
+ "10 values" => 10,
+ "50 values" => 50,
+ "100 values" => 100,
+ "all values" => -1
+ ];
}
+ $choices = array_merge(["not aggregated" => 0], $choices); // add this option always as first choice
+ $aggs[$k] = [ // default value will be replaced by hardcoded tech fields & all databoxes fields
+ 'label' => $label,
+ 'choices_as_values' => true,
+ 'choices' => $choices,
+ 'attr' => [
+ 'class' => 'aggregate'
+ ],
+ 'disabled' => $disabled,
+ 'help_message' => $help // todo : not displayed ?
+ ];
+ };
- $builder
- ->add('highlight', 'checkbox', [
- 'label' => 'Activate highlight',
- 'required' => false
- ])
-// ->add('save', 'submit', [
-// 'attr' => ['class' => 'btn btn-primary']
-// ])
- ->add('esSettingFromIndex', 'button', [
- 'label' => 'Get setting form index',
- 'attr' => [
- 'onClick' => 'esSettingFromIndex()',
- 'class' => 'btn'
- ]
- ])
- ->add('dumpField', 'textarea', [
- 'label' => false,
- 'required' => false,
- 'mapped' => false,
- 'attr' => ['class' => 'dumpfield hide']
- ])
- ->add('activeTab', 'hidden');
+ // all fields fron conf
+ foreach($this->esSettings->getAggregableFields() as $k=>$f) {
+ // default value will be replaced by hardcoded tech fields & all databoxes fields
+ $addAgg($k, "/?\\ " . $k, "This field does not exists in current databoxes.", true);
+ }
+
+ // add or replace hardcoded tech fields
+ foreach(ElasticsearchOptions::getAggregableTechnicalFields() as $k => $f) {
+ $choices = array_key_exists('choices', $f) ? $f['choices'] : null; // a tech-field can publish it's own choices
+ $help = null;
+ $label = '#' . $k;
+ if(!array_key_exists($k, $aggs)) {
+ $label = "/!\\ " . $label;
+ $help = "New field, please confirm setting.";
+ }
+ $addAgg($k, $label, $help, false, $choices);
+ }
+
+ // add or replace all databoxes fields (nb: new db field - unknown in conf - will be a the end)
+ foreach($this->globalStructure->getAllFields() as $field) {
+ $k = $label = $field->getName();
+ $help = null;
+ if(!array_key_exists($field->getName(), $aggs)) {
+ $label = "/!\\ " . $label;
+ $help = "New field, please confirm setting.";
+ }
+ $addAgg($k, $label, $help); // default choices
+ }
+
+ // populate aggs to form
+ foreach($aggs as $k=>$agg) {
+ $builder->add('facets:' . $k . ':limit', ChoiceType::class, $agg);
+ }
- ;
}
public function getName()
diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/FacetsResponse.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/FacetsResponse.php
index 2f2d966c51..efcc6d1c76 100644
--- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/FacetsResponse.php
+++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/FacetsResponse.php
@@ -15,7 +15,7 @@ class FacetsResponse
private $escaper;
private $facets = array();
- public function __construct(Escaper $escaper, array $response, GlobalStructure $structure)
+ public function __construct(ElasticsearchOptions $options, Escaper $escaper, array $response, GlobalStructure $structure)
{
$this->escaper = $escaper;
@@ -25,7 +25,13 @@ class FacetsResponse
$atf = ElasticsearchOptions::getAggregableTechnicalFields();
- foreach ($response['aggregations'] as $name => $aggregation) {
+ // sort facets respecting the order defined in options
+ foreach($options->getAggregableFields() as $name=>$foptions) {
+ if(!array_key_exists($name, $response['aggregations'])) {
+ continue;
+ }
+ $aggregation = $response['aggregations'][$name];
+
$tf = null;
$valueFormatter = function($v){ return $v; }; // default equality formatter
@@ -78,6 +84,7 @@ class FacetsResponse
];
}
}
+
}
diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Structure/GlobalStructure.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Structure/GlobalStructure.php
index ea4022dffb..0793c91c7b 100644
--- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Structure/GlobalStructure.php
+++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Structure/GlobalStructure.php
@@ -35,11 +35,6 @@ final class GlobalStructure implements Structure
*/
private $private = array();
- /**
- * @var Field[]
- */
- private $facets = array();
-
/**
* @var Flag[]
*/
@@ -145,9 +140,11 @@ final class GlobalStructure implements Structure
$this->private[$name] = $field;
}
+ /*
if ($field->isFacet() && $field->isSearchable()) {
$this->facets[$name] = $field;
}
+ */
if ($field->hasConceptInference()) {
$this->thesaurus_fields[$name] = $field;
@@ -183,14 +180,6 @@ final class GlobalStructure implements Structure
return $this->private;
}
- /**
- * @return Field[]
- */
- public function getFacetFields()
- {
- return $this->facets;
- }
-
/**
* @return Field[]
*/
diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Structure/LimitedStructure.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Structure/LimitedStructure.php
index 671bf87c93..053ca6b0e0 100644
--- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Structure/LimitedStructure.php
+++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Structure/LimitedStructure.php
@@ -47,14 +47,6 @@ final class LimitedStructure implements Structure
return $this->limit($this->structure->getPrivateFields());
}
- /**
- * @return Field[]
- */
- public function getFacetFields()
- {
- return $this->limit($this->structure->getFacetFields());
- }
-
public function getThesaurusEnabledFields()
{
return $this->limit($this->structure->getThesaurusEnabledFields());
diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Structure/Structure.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Structure/Structure.php
index 3c2be701e1..44d58e9d5f 100644
--- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Structure/Structure.php
+++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Structure/Structure.php
@@ -33,11 +33,6 @@ interface Structure
*/
public function getPrivateFields();
- /**
- * @return Field[]
- */
- public function getFacetFields();
-
/**
* @return Field[]
*/
diff --git a/lib/Alchemy/Phrasea/Setup/Requirements/BinariesRequirements.php b/lib/Alchemy/Phrasea/Setup/Requirements/BinariesRequirements.php
index 5e90593085..759809de61 100644
--- a/lib/Alchemy/Phrasea/Setup/Requirements/BinariesRequirements.php
+++ b/lib/Alchemy/Phrasea/Setup/Requirements/BinariesRequirements.php
@@ -60,7 +60,7 @@ class BinariesRequirements extends RequirementCollection implements RequirementI
);
}
- $exiftool = __DIR__ . '/../../../../../vendor/phpexiftool/exiftool/exiftool' . (defined('PHP_WINDOWS_VERSION_BUILD') ? '.exe' : '');
+ $exiftool = __DIR__ . '/../../../../../vendor/exiftool/exiftool/exiftool' . (defined('PHP_WINDOWS_VERSION_BUILD') ? '.exe' : '');
$this->addRequirement(
is_file($exiftool) && is_executable($exiftool),
diff --git a/lib/classes/eventsmanager/broker.php b/lib/classes/eventsmanager/broker.php
index 62244756ce..468a0bc621 100644
--- a/lib/classes/eventsmanager/broker.php
+++ b/lib/classes/eventsmanager/broker.php
@@ -39,7 +39,6 @@ class eventsmanager_broker
],
'notify' => [
'eventsmanager_notify_autoregister',
- 'eventsmanager_notify_bridgeuploadfail',
'eventsmanager_notify_downloadmailfail',
'eventsmanager_notify_feed',
'eventsmanager_notify_order',
diff --git a/lib/classes/eventsmanager/notify/order.php b/lib/classes/eventsmanager/notify/order.php
index d5aca30998..bba2c686f0 100644
--- a/lib/classes/eventsmanager/notify/order.php
+++ b/lib/classes/eventsmanager/notify/order.php
@@ -42,7 +42,7 @@ class eventsmanager_notify_order extends eventsmanager_notifyAbstract
$ret = [
'text' => $this->app->trans('%user% a passe une %opening_link% commande %end_link%', [
'%user%' => $sender,
- '%opening_link%' => '',
+ '%opening_link%' => '',
'%end_link%' => '',])
, 'class' => ''
];
diff --git a/lib/classes/patch/410alpha17a.php b/lib/classes/patch/410alpha17a.php
index ff682b1ef9..a719c2b62b 100644
--- a/lib/classes/patch/410alpha17a.php
+++ b/lib/classes/patch/410alpha17a.php
@@ -62,6 +62,16 @@ class patch_410alpha17a implements patchInterface
// $sql = "ALTER TABLE `metadatas_structure` ADD `gui_editable` INT(1) UNSIGNED NOT NULL DEFAULT '0' AFTER `readonly`";
// $databox->get_connection()->executeQuery($sql);
+ foreach ($databox->get_meta_structure() as $databox_field) {
+ if ($databox_field->get_tbranch() != '') {
+ $databox_field->set_generate_cterms(true);
+ } else {
+ $databox_field->set_generate_cterms(false);
+ }
+
+ $databox_field->save();
+ }
+
return true;
}
}
diff --git a/lib/classes/patch/410alpha21a.php b/lib/classes/patch/410alpha21a.php
new file mode 100644
index 0000000000..58091e62f2
--- /dev/null
+++ b/lib/classes/patch/410alpha21a.php
@@ -0,0 +1,111 @@
+release;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function concern()
+ {
+ return $this->concern;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function require_all_upgrades()
+ {
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDoctrineMigrations()
+ {
+ return [];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function apply(base $databox, Application $app)
+ {
+ // fix the Longitude value
+
+ $sql = 'SELECT id, record_id, name, value FROM technical_datas WHERE trim(name) = "LongitudeRef" ';
+ $stmt = $databox->get_connection()->prepare($sql);
+ $stmt->execute();
+ $rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ $stmt->closeCursor();
+
+ foreach ($rs as $row) {
+ if (trim($row['value']) === 'W' ) {
+ $sql = 'UPDATE technical_datas SET value = CONCAT("-", value) WHERE trim(name) = "Longitude" AND record_id =:record_id';
+ $stmt = $databox->get_connection()->prepare($sql);
+ $stmt->execute([':record_id' => $row['record_id']]);
+ }
+
+ $sqlDelete = 'DELETE FROM technical_datas WHERE id =:id';
+
+ $stmt1 = $databox->get_connection()->prepare($sqlDelete);
+ $stmt1->execute([':id' => $row['id']]);
+ $stmt1->closeCursor();
+ }
+
+ $stmt->closeCursor();
+
+ // fix the Latitude value
+
+ $sql = 'SELECT id, record_id, name, value FROM technical_datas WHERE trim(name) = "LatitudeRef" ';
+ $stmt = $databox->get_connection()->prepare($sql);
+ $stmt->execute();
+ $rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ $stmt->closeCursor();
+
+ foreach ($rs as $row) {
+ if (trim($row['value']) === 'S' ) {
+ $sql = 'UPDATE technical_datas SET value = CONCAT("-", value) WHERE trim(name) = "Latitude" AND record_id =:record_id';
+ $stmt = $databox->get_connection()->prepare($sql);
+ $stmt->execute([':record_id' => $row['record_id']]);
+ }
+
+ $sqlDelete = 'DELETE FROM technical_datas WHERE id =:id';
+
+ $stmt1 = $databox->get_connection()->prepare($sqlDelete);
+ $stmt1->execute([':id' => $row['id']]);
+ $stmt1->closeCursor();
+ }
+
+ $stmt->closeCursor();
+
+ return true;
+ }
+}
diff --git a/lib/classes/patch/410alpha22a.php b/lib/classes/patch/410alpha22a.php
new file mode 100644
index 0000000000..6a80bd058e
--- /dev/null
+++ b/lib/classes/patch/410alpha22a.php
@@ -0,0 +1,75 @@
+release;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function concern()
+ {
+ return $this->concern;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function require_all_upgrades()
+ {
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDoctrineMigrations()
+ {
+ return [];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function apply(base $appbox, Application $app)
+ {
+ foreach(['type', 'created', 'updated', 'expiration'] as $t) {
+ $sql = "ALTER TABLE `Tokens` ADD INDEX `".$t."` (`".$t."`);";
+ try {
+ $stmt = $appbox->get_connection()->prepare($sql);
+ $stmt->execute();
+ $stmt->closeCursor();
+ }
+ catch (\Exception $e) {
+ // the inex already exists ?
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/lib/classes/patch/410alpha23a.php b/lib/classes/patch/410alpha23a.php
new file mode 100644
index 0000000000..eae272bc8e
--- /dev/null
+++ b/lib/classes/patch/410alpha23a.php
@@ -0,0 +1,111 @@
+release;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function concern()
+ {
+ return $this->concern;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function require_all_upgrades()
+ {
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDoctrineMigrations()
+ {
+ return [];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function apply(base $appbox, Application $app)
+ {
+ // fix embed-bundle keys
+ if ($app['conf']->has(['embed_bundle', 'video', 'available-speeds'])) {
+ $availableSpeed = $app['conf']->get(['embed_bundle', 'video', 'available-speeds']);
+ $app['conf']->remove(['embed_bundle', 'video', 'available-speeds']);
+ $app['conf']->set(['embed_bundle', 'video', 'available_speeds'], $availableSpeed);
+ }
+
+ if ($app['conf']->has(['embed_bundle', 'audio', 'available-speeds'])) {
+ $availableSpeed = $app['conf']->get(['embed_bundle', 'audio', 'available-speeds']);
+ $app['conf']->remove(['embed_bundle', 'audio', 'available-speeds']);
+ $app['conf']->set(['embed_bundle', 'audio', 'available_speeds'], $availableSpeed);
+ }
+
+ if ($app['conf']->has(['embed_bundle', 'document', 'enable-pdfjs'])) {
+ $enablePdfjs = $app['conf']->get(['embed_bundle', 'document', 'enable-pdfjs']);
+ $app['conf']->remove(['embed_bundle', 'document', 'enable-pdfjs']);
+ $app['conf']->set(['embed_bundle', 'document', 'enable_pdfjs'], $enablePdfjs);
+ }
+
+ // geoloc section change replace 'name' to 'map-provider'
+ if ($app['conf']->has(['geocoding-providers', 0, 'name'])) {
+ $geocodingName = $app['conf']->get(['geocoding-providers', 0, 'name']);
+ $app['conf']->remove(['geocoding-providers', 0, 'name']);
+ $app['conf']->set(['geocoding-providers', 0, 'map-provider'], $geocodingName);
+ }
+
+ // video-editor section change, replace 'vttFieldName' to 'ChapterVttFieldName'
+ if ($app['conf']->has(['video-editor', 'vttFieldName'])) {
+ $chapterVttFieldName = $app['conf']->get(['video-editor', 'vttFieldName']);
+ $app['conf']->remove(['video-editor', 'vttFieldName']);
+ $app['conf']->set(['video-editor', 'ChapterVttFieldName'], $chapterVttFieldName);
+ }
+
+ // remove registry classic section if exist
+ if ($app['conf']->has(['registry', 'classic'])) {
+ $app['conf']->remove(['registry', 'classic']);
+ }
+
+ // remove bridge section if exist
+ if ($app['conf']->has(['main', 'bridge'])) {
+ $app['conf']->remove(['main', 'bridge']);
+ }
+
+ // insert RGPD bloc if not exist
+ if (!$app['conf']->has(['user_account', 'deleting_policies', 'email_confirmation'])) {
+ $app['conf']->set(['user_account', 'deleting_policies', 'email_confirmation'], true);
+ }
+
+ return true;
+ }
+}
diff --git a/lib/classes/record/adapter.php b/lib/classes/record/adapter.php
index e544dae308..8e181c5d2e 100644
--- a/lib/classes/record/adapter.php
+++ b/lib/classes/record/adapter.php
@@ -1722,17 +1722,20 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
}
/**
+ * @param int $offset
+ * @param null|int $max_items
+ *
* @return set_selection|record_adapter[]
* @throws Exception
* @throws \Doctrine\DBAL\DBALException
*/
- public function getChildren()
+ public function getChildren($offset = 1, $max_items = null)
{
if (!$this->isStory()) {
throw new Exception('This record is not a grouping');
}
- $selections = $this->getDatabox()->getRecordRepository()->findChildren([$this->getRecordId()]);
+ $selections = $this->getDatabox()->getRecordRepository()->findChildren([$this->getRecordId()], null, $offset, $max_items);
return reset($selections);
}
diff --git a/lib/conf.d/configuration.yml b/lib/conf.d/configuration.yml
index 0e13eba50c..f237b8318f 100644
--- a/lib/conf.d/configuration.yml
+++ b/lib/conf.d/configuration.yml
@@ -39,21 +39,37 @@ main:
populate_order: RECORD_ID
populate_direction: DESC
activeTab: '#elastic-search'
- base_aggregate_limit: 10
- collection_aggregate_limit: 10
- doctype_aggregate_limit: 0
- camera_model_aggregate_limit: 0
- iso_aggregate_limit: 0
- aperture_aggregate_limit: 0
- shutterspeed_aggregate_limit: 0
- flashfired_aggregate_limit: 0
- framerate_aggregate_limit: 0
- audiosamplerate_aggregate_limit: 0
- videocodec_aggregate_limit: 0
- audiocodec_aggregate_limit: 0
- orientation_aggregate_limit: 0
- colorspace_aggregate_limit: 0
- mimetype_aggregate_limit: 0
+ facets:
+ _base:
+ limit: 10
+ _collection:
+ limit: 10
+ _doctype:
+ limit: 10
+ _camera_model:
+ limit: 0
+ _iso:
+ limit: 0
+ _aperture:
+ limit: 0
+ _shutterspeed:
+ limit: 0
+ _flashfired:
+ limit: 0
+ _framerate:
+ limit: 0
+ _audiosamplerate:
+ limit: 0
+ _videocodec:
+ limit: 0
+ _audiocodec:
+ limit: 0
+ _orientation:
+ limit: 0
+ _colorspace:
+ limit: 0
+ _mimetype:
+ limit: 0
task-manager:
status: started
enabled: true
@@ -87,6 +103,7 @@ main:
mp4box_timeout: 60
swftools_timeout: 60
unoconv_timeout: 60
+ exiftool_timeout: 60
storage:
subdefs: null
cache: null
@@ -94,6 +111,7 @@ main:
download: null
lazaret: null
caption: null
+ tmp_files: null
trusted-proxies: []
debugger:
@@ -241,7 +259,7 @@ embed_bundle:
geocoding-providers:
-
map-provider: 'mapboxWebGL'
- enabled: true
+ enabled: false
public-key: ''
map-layers:
-
@@ -284,7 +302,7 @@ geocoding-providers:
provincefields: Province
countryfields: 'Country, Pays'
video-editor:
- vttFieldName: VideoTextTrackChapters
+ ChapterVttFieldName: VideoTextTrackChapters
seekBackwardStep: 500 # in ms
seekForwardStep: 500 # in ms
playbackRates:
diff --git a/package.json b/package.json
index 7525421e67..8ac01be75a 100644
--- a/package.json
+++ b/package.json
@@ -65,7 +65,7 @@
"normalize-css": "^2.1.0",
"npm": "^6.0.0",
"npm-modernizr": "^2.8.3",
- "phraseanet-production-client": "^0.34.86-d",
+ "phraseanet-production-client": "0.34.139-d",
"requirejs": "^2.3.5",
"tinymce": "^4.0.28",
"underscore": "^1.8.3",
diff --git a/resources/ansible/roles/app/tasks/main.yml b/resources/ansible/roles/app/tasks/main.yml
index 623d28d124..9c00f7171e 100644
--- a/resources/ansible/roles/app/tasks/main.yml
+++ b/resources/ansible/roles/app/tasks/main.yml
@@ -66,5 +66,5 @@
- name: Make exiftool executable
file:
- path: /vagrant/vendor/phpexiftool/exiftool/exiftool
+ path: /vagrant/vendor/exiftool/exiftool/exiftool
mode: 0755
diff --git a/resources/locales/messages.de.xlf b/resources/locales/messages.de.xlf
index f6f73c85c8..cb9c16cbbd 100644
--- a/resources/locales/messages.de.xlf
+++ b/resources/locales/messages.de.xlf
@@ -1,6 +1,6 @@
-
+
The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.
@@ -12,9 +12,9 @@
Form/Login/PhraseaAuthenticationForm.php
Form/Configuration/EmailFormType.php
-
+
Add
- Add
+ Hinzufügen
admin/fields/templates.html.twig
@@ -24,7 +24,7 @@
url through a forwarded mail for example.
Parameter "Authentifizierung erzwingen" erzwingt den Push Empfänger, ein Phraseanet Konto zu haben, um den Inhalt anzuschauen. Es vermeidet, unautorisierte Benutzer dem Push Inhalt zuzugreifen, falls sie die URL bekämen (Email wurde weitergeleitet, zum Beispiel).
- prod/templates/push.html.twig
+ prod/templates/push.html.twig
{0} No results|{1} Result|]1,Inf[ Results
@@ -117,9 +117,9 @@
%basket_length% documents
%basket_length% Dokument(e)
- mobile/lightbox/validate.html.twig
- web/lightbox/index.html.twig
- web/lightbox/index.html.twig
+ mobile/lightbox/validate.html.twig
+ web/lightbox/index.html.twig
+ web/lightbox/index.html.twig
%countable% documents can not be modified.
@@ -211,7 +211,7 @@
selectionnes]]>
- ausgewählt]]>
+ ausgewählt]]>
Controller/Prod/QueryController.php
@@ -278,7 +278,7 @@
%record_count% records match the unique identifier :
%record_count% Datensätze entsprechen dem eindeutigen Bezeichner:
- prod/upload/lazaret.html.twig
+ prod/upload/lazaret.html.twig
%s field has been created with success.
@@ -383,17 +383,17 @@
(validation) a envoyer
zu senden
- web/lightbox/index.html.twig
+ web/lightbox/index.html.twig
(validation) envoyee
gesendet
- web/lightbox/index.html.twig
+ web/lightbox/index.html.twig
(validation) session terminee
Sitzung beendet
- web/lightbox/index.html.twig
+ web/lightbox/index.html.twig
*Phraseanet Navigator* is a smartphone application that allow user to connect on this instance
@@ -474,22 +474,22 @@
A file with the same UUID already exists in database
Eine Datei mit ähnlichen UUID ist schon in der Datenbank
- Border/Checker/UUID.php
+ Border/Checker/UUID.php
A file with the same checksum already exists in database
Eine Datei mit selber Checksumme ist schon in der Datenbank
- Border/Checker/Sha256.php
+ Border/Checker/Sha256.php
A file with the same filename already exists in database
Eine Datei mit dem selben Dateiname befindet sich schon in der Datenbank
- Border/Checker/Filename.php
+ Border/Checker/Filename.php
A record matches the unique identifier :
Ein Datensatz entspricht dem eindeutigen Bezeichner :
- prod/upload/lazaret.html.twig
+ prod/upload/lazaret.html.twig
A required field is missing or has an empty value
@@ -617,7 +617,7 @@
Accuse de reception
Empfangsbestätigung
Controller/Prod/LanguageController.php
- prod/templates/push.html.twig
+ prod/templates/push.html.twig
Accuse de reception indisponible, vous n'avez pas declare d'adresse email
@@ -627,7 +627,7 @@
Action Forbidden : You are not the publisher
Aktion verboten: Sie sind nicht der Veröffentlicher
- Controller/Prod/FeedController.php
+ Controller/Prod/FeedController.php
Actions
@@ -642,7 +642,7 @@
Activate highlight
Highlight aktivieren
- SearchEngine/Elastic/ElasticsearchSettingsFormType.php
+ SearchEngine/Elastic/ElasticsearchSettingsFormType.php
web/setup/step2.html.twig
@@ -667,29 +667,28 @@
eine Kollektion aktivieren
admin/databox/databox.html.twig
-
+
Activity
- Activity
+ Aktivität
actions/Feedback/list.html.twig
Add
Hinzufügen
prod/actions/Push.html.twig
- prod/upload/lazaret.html.twig
- prod/upload/lazaret.html.twig
- prod/User/Add.html.twig
+ prod/upload/lazaret.html.twig
+ prod/upload/lazaret.html.twig
+ prod/User/Add.html.twig
-
+
Add a
new field
- Add a
- new field
+ Fügen Sie ein neues Feld hinzu
admin/fields/templates.html.twig
-
+
Add a list
- Add a list
+ Fügen Sie eine Liste hinzu
actions/Feedback/lists-all.html.twig
@@ -707,19 +706,19 @@
einen Administrator hinzufügen
web/admin/dashboard.html.twig
-
+
Add an end point
- Add an end point
+ Fügen Sie einen Endpunkt hinzu
Controller/Prod/LanguageController.php
-
+
Add an entry point
- Add an entry point
+ Fügen Sie einen Einstiegspunkt hinzu
Controller/Prod/LanguageController.php
-
+
Add new range
- Add new range
+ Fügen Sie ein neues Kapitel hinzu
Controller/Prod/LanguageController.php
@@ -761,53 +760,58 @@
Advanced Search
Erweiterte Suche
- web/prod/index.html.twig
- web/prod/index.html.twig
+ web/prod/index.html.twig
+ web/prod/index.html.twig
-
+
Advanced mode
- Advanced mode
+ Erweiterter Modus
actions/Feedback/list.html.twig
-
+
Advanced settings
- Advanced settings
+ Erweiterte Einstellungen
web/admin/subdefs.html.twig
Affichage
Anzeige
- web/prod/index.html.twig
+ web/prod/index.html.twig
Affichage au demarrage
beim Start anzeigen
- web/prod/index.html.twig
+ web/prod/index.html.twig
Afficher la fiche descriptive
das beschriftliche Blatt anzeigen
- web/prod/index.html.twig
+ web/prod/index.html.twig
Afficher le titre
den Titel anzeigen
- web/prod/index.html.twig
+ web/prod/index.html.twig
Afficher les status
die Status anzeigen
- web/prod/index.html.twig
+ web/prod/index.html.twig
Afficher une icone
eine Ikone anzeigen
- web/prod/index.html.twig
+ web/prod/index.html.twig
After metadata
Nach Metadaten
- web/prod/index.html.twig
+ web/prod/index.html.twig
+
+
+ Aggregated
+ Aggregated
+ admin/search-engine/general-aggregation.html.twig
Aggregation
@@ -817,7 +821,7 @@
Aide
Hilfe
- web/prod/index.html.twig
+ web/prod/index.html.twig
Aide sur les expressions regulieres
@@ -869,12 +873,7 @@
All these conditions
Alle Bedingungen
- web/prod/index.html.twig
-
-
- All values
- Alle Werte
- admin/fields/templates.html.twig
+ web/prod/index.html.twig
Aller a
@@ -936,17 +935,18 @@
Push wird erlaubt
web/admin/editusers.html.twig
-
+
Alphabetic asc
- Alphabetic asc
- web/prod/index.html.twig
- web/prod/index.html.twig
- web/prod/index.html.twig
+ aufsteigender alphabetischer Reihenfolge
+ web/prod/index.html.twig
+ web/prod/index.html.twig
+ web/prod/index.html.twig
-
+
Alphabetic desc
- Alphabetic desc
- web/prod/index.html.twig
+ absteigender alphabetischer Reihenfolge
+ web/prod/index.html.twig
+ web/prod/index.html.twig
Also delete records that rely on groupings.
@@ -992,9 +992,9 @@
admin/collection/suggested_value.html.twig
task-manager/task-editor/task.html.twig
-
+
An error occured when wanting to change status!
- An error occured when wanting to change status!
+ Beim Ändern des Status ist ein Fehler aufgetreten!
Controller/Prod/LazaretController.php
@@ -1033,9 +1033,10 @@
Ein Fehler ist aufgetreten
Order/Controller/ProdOrderController.php
Controller/Admin/DataboxController.php
- Controller/Admin/SearchEngineController.php
+ Controller/Admin/SearchEngineController.php
Controller/Admin/CollectionController.php
Controller/Prod/BasketController.php
+ Controller/Api/V3Controller.php
Controller/Api/V1Controller.php
Controller/Api/V1Controller.php
web/admin/statusbit.html.twig
@@ -1068,7 +1069,7 @@
Aperture
Blende
- SearchEngine/Elastic/ElasticsearchOptions.php
+ SearchEngine/Elastic/ElasticsearchOptions.php
web/common/technical_datas.html.twig
@@ -1156,8 +1157,8 @@
Archive
Archivieren
- prod/WorkZone/Macros.html.twig
- prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
Are you sure you want delete users rights ?
@@ -1265,7 +1266,7 @@
Audio
Audio
- web/prod/index.html.twig
+ web/prod/index.html.twig
Audio Birate
@@ -1281,7 +1282,7 @@
Audio Samplerate
Audio Samplerate
- SearchEngine/Elastic/ElasticsearchOptions.php
+ SearchEngine/Elastic/ElasticsearchOptions.php
Audio channel
@@ -1291,7 +1292,7 @@
Audio codec
Audio-Codec
- SearchEngine/Elastic/ElasticsearchOptions.php
+ SearchEngine/Elastic/ElasticsearchOptions.php
AudioSamplerate
@@ -1395,10 +1396,10 @@
Back
Zurück
- mobile/lightbox/basket_element.html.twig
- mobile/lightbox/index.html.twig
- mobile/lightbox/index.html.twig
- mobile/lightbox/index.html.twig
+ mobile/lightbox/basket_element.html.twig
+ mobile/lightbox/index.html.twig
+ mobile/lightbox/index.html.twig
+ mobile/lightbox/index.html.twig
mobile/lightbox/validate.html.twig
@@ -1451,6 +1452,11 @@
Datenbank Leerung wurde erfolgreich
Controller/Admin/DataboxController.php
+
+ Basket
+ Sammelkorb
+ prod/WorkZone/Macros.html.twig
+
Basket created
Sammelkorb wurde erstellt
@@ -1486,9 +1492,9 @@
Sammelkorb wurde aktualisiert
Controller/Prod/BasketController.php
-
+
Binary data
- Binary data
+ Binärdaten
Controller/Prod/SubdefsController.php
@@ -1519,9 +1525,9 @@
Browse Baskets
Sammelkörbe durchsuchen
- web/prod/index.html.twig
- web/prod/index.html.twig
- web/prod/index.html.twig
+ web/prod/index.html.twig
+ web/prod/index.html.twig
+ web/prod/index.html.twig
Browser
@@ -1546,10 +1552,10 @@
Standardmässig ist es für die Administratoren verfügbar
Form/Configuration/FtpExportFormType.php
-
+
By field
- By field
- web/prod/index.html.twig
+ Nach Feld
+ web/prod/index.html.twig
CHAMPS
@@ -1559,7 +1565,7 @@
Camera Model
Kameramodell
- SearchEngine/Elastic/ElasticsearchOptions.php
+ SearchEngine/Elastic/ElasticsearchOptions.php
web/common/technical_datas.html.twig
@@ -1569,7 +1575,7 @@
prod/actions/delete_records_confirm.html.twig
actions/Property/type.html.twig
actions/Property/index.html.twig
- prod/User/Add.html.twig
+ prod/User/Add.html.twig
task-manager/task-editor/task.html.twig
user/import/view.html.twig
admin/fields/templates.html.twig
@@ -1710,16 +1716,15 @@
meine E-Mail Adresse verändern
web/account/reset-email.html.twig
-
+
Change play speed
- Change play speed
+ Wiedergabegeschwindigkeit ändern
Controller/Prod/LanguageController.php
-
+
Changes for rotation will be applied only on
the sub-definitions of "image" type.
- Changes for rotation will be applied only on
- the sub-definitions of "image" type.
+ Änderungen für Drehung werden nur auf "Bilder" Unterauflösungen verwendet.
actions/Tools/index.html.twig
@@ -1761,11 +1766,6 @@
Wählen Sie den Titel des Dokuments zu exportieren
Form/Configuration/ActionsFormType.php
-
- City
- Stadt
- prod/User/Add.html.twig
-
Civility
Anrede
@@ -1823,7 +1823,7 @@
Collection
Kollektion
prod/Story/Create.html.twig
- prod/upload/lazaret.html.twig
+ prod/upload/lazaret.html.twig
admin/databox/details.html.twig
@@ -1837,10 +1837,10 @@
Die Leerung der Kollektion wurde erfolgreich abgeschlossen
Controller/Admin/CollectionController.php
-
+
Collection order
- Collection order
- web/prod/index.html.twig
+ Kollektionen Ordnung
+ web/prod/index.html.twig
Color Depth
@@ -1855,7 +1855,7 @@
Colorspace
Colorspace
- SearchEngine/Elastic/ElasticsearchOptions.php
+ SearchEngine/Elastic/ElasticsearchOptions.php
Commande
@@ -1911,7 +1911,7 @@
Configuration
Konfiguration
- web/prod/index.html.twig
+ web/prod/index.html.twig
Confirm new email address
@@ -1967,7 +1967,7 @@
Contains
enthält
- web/prod/index.html.twig
+ web/prod/index.html.twig
Continuer ?
@@ -2022,7 +2022,7 @@
Couleur de selection
Farbauswahl
- web/prod/index.html.twig
+ web/prod/index.html.twig
Country
@@ -2030,9 +2030,9 @@
actions/Feedback/list.html.twig
actions/Feedback/ListsMacros.html.twig
-
+
Create a user
- Create a user
+ Einen Benutzer erstellen
actions/Feedback/list.html.twig
@@ -2043,7 +2043,7 @@
Create index
Index erstellen
- SearchEngine/Elastic/ElasticsearchSettingsFormType.php
+ SearchEngine/Elastic/ElasticsearchSettingsFormType.php
Creation date
@@ -2118,9 +2118,9 @@
Erstellen Sie zuerst eine Anwendung, um das Phraseanet API danach zu benutzen.
web/developers/applications.html.twig
-
+
Ctrl
- Ctrl
+ Strg
Controller/Prod/LanguageController.php
@@ -2128,12 +2128,11 @@
Gesamtzahl
admin/databox/details.html.twig
-
+
Current configuration contains some
errors
- Current configuration contains some
- errors
- admin/fields/templates.html.twig
+ Die aktuelle Konfiguration enthält einige Fehler
+ admin/fields/templates.html.twig
Current operations cannot be executed because the site is temporarily in maintenance mode. Wait a few minutes and try your request again
@@ -2150,9 +2149,9 @@
Aktuelle Sitzung
web/account/sessions.html.twig
-
+
Custom
- Custom
+ benutzerdefiniert
web/admin/subdefs.html.twig
web/admin/subdefs.html.twig
@@ -2171,9 +2170,9 @@
DU
Form/Configuration/CustomLinkFormType.php
-
+
Danger zone !
- Danger zone !
+ Gefahrenzone !
admin/fields/index.html.twig
@@ -2231,22 +2230,22 @@
Date
Datum
- prod/upload/lazaret.html.twig
+ prod/upload/lazaret.html.twig
Date Added
Hinzufügungsdatum
- web/prod/index.html.twig
+ web/prod/index.html.twig
Date Creation
Erstellungsdatum
admin/publications/list.html.twig
-
+
Date Updated
- Date Updated
- web/prod/index.html.twig
+ Aktualisierungsdatum
+ web/prod/index.html.twig
Date de connexion
@@ -2275,7 +2274,7 @@
Date(s) from field(s)
Datum vom Feld
- web/prod/index.html.twig
+ web/prod/index.html.twig
De
@@ -2303,7 +2302,7 @@
Deconnexion
Abmeldung
- mobile/lightbox/index.html.twig
+ mobile/lightbox/index.html.twig
Decouvrez la documentation
@@ -2350,10 +2349,10 @@
Eine Webhook URL festlegen
web/developers/application.html.twig
-
+
Defined by admin
- Defined by admin
- web/prod/index.html.twig
+ Von Administrator festgelegt
+ web/prod/index.html.twig
Defined in Apache configuration
@@ -2373,8 +2372,8 @@
Delete
Löschen
- prod/upload/lazaret.html.twig
- prod/upload/lazaret.html.twig
+ prod/upload/lazaret.html.twig
+ prod/upload/lazaret.html.twig
admin/task-manager/templates.html.twig
@@ -2393,9 +2392,9 @@
Sammelkorb löschen
WorkZone/Browser/Results.html.twig
-
+
Delete current
- Delete current
+ Aktuelles löschen
Controller/Prod/LanguageController.php
@@ -2403,14 +2402,14 @@
Datensätze löschen
Controller/Prod/LanguageController.php
-
+
Delete the selection
- Delete the selection
+ Auswahl löschen
actions/Feedback/list.html.twig
-
+
Delete the subview ?
- Delete the subview ?
+ Unteransicht löschen ?
web/admin/subdefs.html.twig
@@ -2531,7 +2530,7 @@
Display technical data
Technische Informationen anzeigen
- web/prod/index.html.twig
+ web/prod/index.html.twig
Display thumbnails
@@ -2541,7 +2540,7 @@
Do not display
Nicht anzeigen
- web/prod/index.html.twig
+ web/prod/index.html.twig
Do not forget to restart the tasks scheduler
@@ -2573,7 +2572,7 @@
Document
Dokument
- web/prod/index.html.twig
+ web/prod/index.html.twig
Document Type Sharing
@@ -2628,9 +2627,9 @@
Download von Dokumenten
actions/Download/prepare.html.twig
-
+
Drag and drop the pin to move position
- Drag and drop the pin to move position
+ Ziehen Sie das Pin-Symbol und legen Sie es ab, um den Standort zu verschieben
Controller/Prod/LanguageController.php
@@ -2641,7 +2640,7 @@
Drop index
Drop index
- SearchEngine/Elastic/ElasticsearchSettingsFormType.php
+ SearchEngine/Elastic/ElasticsearchSettingsFormType.php
Duree
@@ -2659,9 +2658,9 @@
Form/Login/PhraseaForgotPasswordForm.php
Form/Login/PhraseaRegisterForm.php
-
+
E-mail domain
- E-mail domain
+ Mail Domain
actions/Feedback/list.html.twig
@@ -2694,9 +2693,9 @@
Bearbeiten
admin/task-manager/templates.html.twig
-
+
Edit position
- Edit position
+ Standort bearbeiten
Controller/Prod/LanguageController.php
@@ -2749,19 +2748,19 @@
ElasticSearch index name
ElasticSearch Index Name
- SearchEngine/Elastic/ElasticsearchSettingsFormType.php
+ SearchEngine/Elastic/ElasticsearchSettingsFormType.php
web/setup/step2.html.twig
ElasticSearch server host
ElasticSearch Server Host
- SearchEngine/Elastic/ElasticsearchSettingsFormType.php
+ SearchEngine/Elastic/ElasticsearchSettingsFormType.php
web/setup/step2.html.twig
ElasticSearch service port
ElasticSearch Service Schnittstelle
- SearchEngine/Elastic/ElasticsearchSettingsFormType.php
+ SearchEngine/Elastic/ElasticsearchSettingsFormType.php
web/setup/step2.html.twig
@@ -2908,9 +2907,9 @@
HD Ersetzung aktivieren
Form/Configuration/ModulesFormType.php
-
+
Enable Phraseanet Web API
- Enable Phraseanet Web API
+ Phraseanet Web API aktivieren
Form/Configuration/APIClientsFormType.php
@@ -2969,10 +2968,10 @@
web/account/sessions.html.twig
web/account/sessions.html.twig
-
+
End Range
- End Range
- Controller/Prod/LanguageController.php
+ Kapitel beenden
+ Controller/Prod/LanguageController.php
End session activity
@@ -3012,7 +3011,7 @@
Equals
gleicht
- web/prod/index.html.twig
+ web/prod/index.html.twig
Erreur
@@ -3155,7 +3154,7 @@
Ex : Paris, bleu, montagne
Ex : Berlin, blau, Gebirge
- web/prod/index.html.twig
+ web/prod/index.html.twig
Executables externes
@@ -3174,10 +3173,10 @@
Controller/Prod/DoDownloadController.php
Controller/Prod/LanguageController.php
-
+
Export ranges
- Export ranges
- Controller/Prod/LanguageController.php
+ Kapitel exportieren
+ Controller/Prod/LanguageController.php
Export saved in the waiting queue
@@ -3214,9 +3213,9 @@
Feedback
Controller/Prod/LanguageController.php
prod/WorkZone/Story.html.twig
+ prod/WorkZone/Macros.html.twig
prod/WorkZone/Basket.html.twig
- web/prod/toolbar.html.twig
- web/prod/toolbar.html.twig
+ web/prod/toolbar.html.twig
Feeds
@@ -3305,7 +3304,7 @@
Filename
Dateiname
- prod/upload/lazaret.html.twig
+ prod/upload/lazaret.html.twig
Fils disponibles
@@ -3338,13 +3337,13 @@
Flash
Flash
- web/prod/index.html.twig
+ web/prod/index.html.twig
web/common/technical_datas.html.twig
FlashFired
FlashFired
- SearchEngine/Elastic/ElasticsearchOptions.php
+ SearchEngine/Elastic/ElasticsearchOptions.php
Flatten layers
@@ -3360,7 +3359,7 @@
Force authentication
Authentifizierung zwingen
- prod/templates/push.html.twig
+ prod/templates/push.html.twig
Force sending of the document ?
@@ -3403,7 +3402,7 @@
FrameRate
Framerate
- SearchEngine/Elastic/ElasticsearchOptions.php
+ SearchEngine/Elastic/ElasticsearchOptions.php
Frequence d'echantillonage
@@ -3471,10 +3470,10 @@
Media/Subdef/Image.php
Media/Subdef/Unknown.php
-
+
Geo Search
- Geo Search
- web/prod/index.html.twig
+ Lokalisierung
+ web/prod/index.html.twig
Geonames server address
@@ -3488,33 +3487,33 @@
Get setting form index
- Get setting form index
- SearchEngine/Elastic/ElasticsearchSettingsFormType.php
+ Index Daten erhalten
+ SearchEngine/Elastic/ElasticsearchSettingsFormType.php
Gives the option to your application to communicate with Phraseanet. This webhook can be used to trigger some actions on your application side.
Gibt Ihrer Applikation die Möglichkeit, mit Phraseanet zu kommunizieren. Diese Webhook kann benutzt werden, um einige Aktionen auf Ihrer Applikationsseite auszulösen.
web/developers/application.html.twig
-
+
Go 1 frame backward
- Go 1 frame backward
- Controller/Prod/LanguageController.php
-
-
- Go 1 frame forward
- Go 1 frame forward
+ Gehen Sie ein Einzelbild zurück
Controller/Prod/LanguageController.php
-
- Go to end point
- Go to end point
+
+ Go 1 frame forward
+ Gehen Sie ein Einzelbild vorwärts
Controller/Prod/LanguageController.php
-
+
+ Go to end point
+ Gehen Sie zum Endpunkt
+ Controller/Prod/LanguageController.php
+
+
Go to start point
- Go to start point
- Controller/Prod/LanguageController.php
+ Gehen Sie zum Startpunkt
+ Controller/Prod/LanguageController.php
Good
@@ -3549,7 +3548,7 @@
Graphiste (preview au rollover)
Grafiker (Voransicht mit Rollover)
- web/prod/index.html.twig
+ web/prod/index.html.twig
Great
@@ -3564,6 +3563,7 @@
Guest
Gast
+ mobile/common/menubar.html.twig
web/common/menubar.html.twig
web/common/menubar.html.twig
@@ -3577,14 +3577,14 @@
Gast, sie müssen authentifizieren, um die Dateien herunterzuladen.
web/common/dialog_export.html.twig
-
+
Gui-editable
- Gui-editable
+ GUI editierbar
admin/fields/templates.html.twig
-
+
Gui-visible
- Gui-visible
+ GUI sichtbar
admin/fields/templates.html.twig
@@ -3617,7 +3617,7 @@
Home
Hautpseite
- mobile/lightbox/basket_element.html.twig
+ mobile/lightbox/basket_element.html.twig
mobile/lightbox/feed.html.twig
mobile/lightbox/validate.html.twig
login/include/language-block.html.twig
@@ -3647,7 +3647,7 @@
ISO
ISO
- SearchEngine/Elastic/ElasticsearchOptions.php
+ SearchEngine/Elastic/ElasticsearchOptions.php
ISO sensibility
@@ -3657,7 +3657,7 @@
Iconographe (description au rollover)
Bildredakteur (Beschreibung mit Rollover)
- web/prod/index.html.twig
+ web/prod/index.html.twig
Id
@@ -3702,7 +3702,7 @@
Image
Bild
- web/prod/index.html.twig
+ web/prod/index.html.twig
ImageMagick
@@ -3728,7 +3728,7 @@
In the answer grid
In einem Tooltip
- web/prod/index.html.twig
+ web/prod/index.html.twig
Include Business-fields in caption
@@ -3872,9 +3872,9 @@
Synchronisierung zwischen Bridge und Client APIs erhalten.
TaskManager/Job/BridgeJob.php
-
+
Keyboard shortcuts
- Keyboard shortcuts
+ Tastenkombinationen
Controller/Prod/LanguageController.php
@@ -3896,17 +3896,17 @@
L'utilisateur approuve ce document
Benutzer genehmigt dieses Dokument
- prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
L'utilisateur desapprouve ce document
Benutzer lehnt dieses Dokument ab
- prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
L'utilisateur n'a pas encore donne son avis sur ce document
- Benutzer hat seine Meinung nocht nicht gegeben
- prod/WorkZone/Macros.html.twig
+ Benutzer hat seine Meinung noch nicht gegeben
+ prod/WorkZone/Macros.html.twig
La connection vers le serveur distant est OK
@@ -3952,7 +3952,7 @@
Language
Sprache
- web/prod/index.html.twig
+ web/prod/index.html.twig
Last Name
@@ -3982,7 +3982,7 @@
Last uploaded version
zuletzte geladene Version
- prod/upload/lazaret.html.twig
+ prod/upload/lazaret.html.twig
Le bridge Dailymotion ne prend en charge que les videos
@@ -4089,7 +4089,7 @@
Les termes apparaissent dans le(s) champs
Die Begriffe befinden sich in Feld(er):
- web/prod/index.html.twig
+ web/prod/index.html.twig
Light Value
@@ -4099,8 +4099,8 @@
Lightbox
Lightbox
- prod/WorkZone/Macros.html.twig
- prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
Limite temporelle
@@ -4219,7 +4219,7 @@
Ma derniere question
meine letzte Suchabfrage
- web/prod/index.html.twig
+ web/prod/index.html.twig
Mail line %line% is empty
@@ -4305,7 +4305,7 @@
Message
Nachricht
Controller/Prod/LanguageController.php
- prod/templates/push.html.twig
+ prod/templates/push.html.twig
Message automatique de Phraseanet
@@ -4325,7 +4325,7 @@
MimeType
MimeType
- SearchEngine/Elastic/ElasticsearchOptions.php
+ SearchEngine/Elastic/ElasticsearchOptions.php
Minimum number of letters before truncation
@@ -4376,7 +4376,7 @@
Mode de presentation
Anzeigemodus
- web/prod/index.html.twig
+ web/prod/index.html.twig
Modele de donnees
@@ -4415,20 +4415,20 @@
%countable% Datensätze zur ausgewählten Kollektion verschieben
prod/actions/collection_default.html.twig
-
+
Move down range
- Move down range
- Controller/Prod/LanguageController.php
+ Kapitel herunterziehen
+ Controller/Prod/LanguageController.php
Move one record to the chosen collection in the list.
Einen Datensatz zur ausgewählten Kollektion verschieben
prod/actions/collection_default.html.twig
-
+
Move up range
- Move up range
- Controller/Prod/LanguageController.php
+ Kapitel aufrücken
+ Controller/Prod/LanguageController.php
Moves records
@@ -4470,14 +4470,14 @@
Name oder Email
admin/publications/fiche.html.twig
-
+
Navigate to end point
- Navigate to end point
+ Navigieren Sie zum Endpunkt
Controller/Prod/LanguageController.php
-
+
Navigate to entry point
- Navigate to entry point
+ Navigieren Sie zum Startpunkt
Controller/Prod/LanguageController.php
@@ -4577,9 +4577,9 @@
Keine Übereinstimmung gefunden
web/geonames/city_list.html.twig
-
+
No metadata available
- No metadata available
+ Keine Metadaten verfügbar
actions/Tools/metadata.html.twig
@@ -4669,16 +4669,16 @@
None of the selected records can be printed
Keine der ausgewählte Datensätze können gedruckt werden
- prod/actions/printer_default.html.twig
+ prod/actions/printer_default.html.twig
None of the selected records can be pushed.
- Keines der ausgewählten Datensätze können via Push gesendet werden.
+ Keine der ausgewählten Datensätze können via Push gesendet werden.
prod/actions/Push.html.twig
None of the selected records can be sent for feedback.
- Keines der ausgewählten Datensätze können für das Feedback gesendet werden.
+ Keine der ausgewählten Datensätze können für das Feedback gesendet werden.
prod/actions/Push.html.twig
@@ -4689,7 +4689,8 @@
Not aggregated
Nicht aggregiert
- admin/fields/templates.html.twig
+ admin/search-engine/general-aggregation.html.twig
+ admin/fields/templates.html.twig
Notification par email
@@ -4755,13 +4756,13 @@
Number of replicas
Anzahl von Nachbauten
- SearchEngine/Elastic/ElasticsearchSettingsFormType.php
+ SearchEngine/Elastic/ElasticsearchSettingsFormType.php
web/setup/step2.html.twig
Number of shards
Anzahl von Scherben
- SearchEngine/Elastic/ElasticsearchSettingsFormType.php
+ SearchEngine/Elastic/ElasticsearchSettingsFormType.php
web/setup/step2.html.twig
@@ -4786,20 +4787,20 @@
Ein Dokument kann nicht geändert werden
prod/actions/collection_default.html.twig
-
+
One frame backward
- One frame backward
+ Ein Einzelbild zurück
Controller/Prod/LanguageController.php
-
+
One frame forward
- One frame forward
+ Ein Einzelbild vorwärts
Controller/Prod/LanguageController.php
One of these conditions
Eine von diesen Bedingungen
- web/prod/index.html.twig
+ web/prod/index.html.twig
Only %nbEditableDocuments% records can be modified.
@@ -4862,7 +4863,7 @@
Orientation
Ausrichtung
- SearchEngine/Elastic/ElasticsearchOptions.php
+ SearchEngine/Elastic/ElasticsearchOptions.php
Original name
@@ -4891,18 +4892,18 @@
prod/upload/lazaret.html.twig
prod/upload/lazaret.html.twig
-
+
Pages
- Pages
+ Seiten
actions/Feedback/ListsMacros.html.twig
Paniers
Sammelkörbe
- mobile/lightbox/index.html.twig
- mobile/lightbox/index.html.twig
+ mobile/lightbox/index.html.twig
+ mobile/lightbox/index.html.twig
web/account/account.html.twig
- web/lightbox/index.html.twig
+ web/lightbox/index.html.twig
lightbox/IE6/validate.html.twig
web/lightbox/validate.html.twig
@@ -4940,21 +4941,16 @@
Letztes Jahr
WorkZone/Browser/Browser.html.twig
-
+
Path
- Path
+ Pfad
web/admin/subdefs.html.twig
-
+
Pause
- Pause
+ Pause
Controller/Prod/LanguageController.php
-
- Pays
- Pays
- prod/User/Add.html.twig
-
Periodically fetches an FTP repository content locally
Holt regelmässig einen FTP Repository Inhalt lokal
@@ -5011,9 +5007,9 @@
Phraseanet empfiehlt dringend die Benutzung von %link_start%MariaDB%link_end%, um MySQL zu ersetzen
web/setup/step2.html.twig
-
+
Play
- Play
+ Play
Controller/Prod/LanguageController.php
@@ -5147,10 +5143,10 @@
Preferences
Einstellungen
- web/prod/index.html.twig
- web/prod/index.html.twig
- web/prod/index.html.twig
- web/prod/index.html.twig
+ web/prod/index.html.twig
+ web/prod/index.html.twig
+ web/prod/index.html.twig
+ web/prod/index.html.twig
Prefix for notification emails
@@ -5165,16 +5161,16 @@
Presentation de vignettes
Miniaturansichten
- web/prod/index.html.twig
+ web/prod/index.html.twig
Presentation de vignettes de panier
Vorstellung der Voransichten des Sammelkorbes
- web/prod/index.html.twig
+ web/prod/index.html.twig
-
+
Presets
- Presets
+ Voreinstellungen
web/admin/subdefs.html.twig
@@ -5223,7 +5219,7 @@
Publications
Veröffentlichungen
- web/prod/index.html.twig
+ web/prod/index.html.twig
admin/publications/wrapper.html.twig
web/admin/tree.html.twig
web/common/menubar.html.twig
@@ -5249,6 +5245,7 @@
Push
eventsmanager/notify/push.php
Controller/Prod/LanguageController.php
+ prod/WorkZone/Macros.html.twig
Push configuration
@@ -5335,80 +5332,80 @@
Raccourcis claviers de la zone des paniers :
Sammelkörbe und Funktionen Abkürzungen
- web/prod/index.html.twig
+ web/prod/index.html.twig
Raccourcis claviers en cours de editing :
Fenster Abkürzungen bearbeiten
- web/prod/index.html.twig
+ web/prod/index.html.twig
Raccourcis claviers en cours de preview :
Fenster Abkürzungen, Detailansicht
- web/prod/index.html.twig
+ web/prod/index.html.twig
Raccourcis claviers en cours de recherche :
Hauptfenster Abkürzungen
- web/prod/index.html.twig
+ web/prod/index.html.twig
Raccourcis:: ctrl-a : tout selectionner
ctrl-a : alles auswählen
- web/prod/index.html.twig
- web/prod/index.html.twig
+ web/prod/index.html.twig
+ web/prod/index.html.twig
Raccourcis:: ctrl-e : editer la selection
ctrl-e : Auswahl bearbeiten
- web/prod/index.html.twig
- web/prod/index.html.twig
+ web/prod/index.html.twig
+ web/prod/index.html.twig
Raccourcis:: ctrl-p : imprimer la selection
ctrl-p : drucken
- web/prod/index.html.twig
- web/prod/index.html.twig
+ web/prod/index.html.twig
+ web/prod/index.html.twig
Raccourcis::espace : arreter/demarrer le diaporama
Dia-Schau starten
- web/prod/index.html.twig
+ web/prod/index.html.twig
Raccourcis::fleche bas : scroll vertical
Abwärtspfeil: vertikal scrollen
- web/prod/index.html.twig
+ web/prod/index.html.twig
Raccourcis::fleche droite : page suivante
Rechtspfeil: nächste Seite
- web/prod/index.html.twig
+ web/prod/index.html.twig
Raccourcis::fleche gauche : en arriere
Abwärtspfeil: letztes Dokument
- web/prod/index.html.twig
+ web/prod/index.html.twig
Raccourcis::fleche gauche : en avant
Rechtspfeil: nächstes Dokument
- web/prod/index.html.twig
+ web/prod/index.html.twig
Raccourcis::fleche gauche : page precedente
Linkspfeil: vorherige Seite
- web/prod/index.html.twig
+ web/prod/index.html.twig
Raccourcis::fleche haut : scroll vertical
Pfeil oben: vertikal scrollen
- web/prod/index.html.twig
+ web/prod/index.html.twig
Raccourcis::tab/shift-tab se ballade dans les champs
tab/shift-tab : Feld ändern
- web/prod/index.html.twig
+ web/prod/index.html.twig
Rappel : Il vous reste %number% jours pour valider %title% de %user%
@@ -5430,18 +5427,18 @@
Zurücksetzen
prod/Baskets/Reorder.html.twig
prod/Story/Reorder.html.twig
- web/prod/index.html.twig
+ web/prod/index.html.twig
Re-ordonner
wieder ordnen
prod/Baskets/Reorder.html.twig
- prod/WorkZone/Macros.html.twig
- prod/WorkZone/Macros.html.twig
- prod/WorkZone/Macros.html.twig
- prod/WorkZone/Macros.html.twig
- prod/WorkZone/Macros.html.twig
- prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
prod/Story/Reorder.html.twig
@@ -5533,7 +5530,7 @@
Rechercher dans un champ date
im Feld "Datum" suchen
- web/prod/index.html.twig
+ web/prod/index.html.twig
Recommendations
@@ -5624,7 +5621,7 @@
Relevance
Relevanz
- web/prod/index.html.twig
+ web/prod/index.html.twig
Remember me
@@ -5642,10 +5639,10 @@
Media/Subdef/Image.php
Media/Subdef/Unknown.php
-
+
Remove current Range
- Remove current Range
- Controller/Prod/LanguageController.php
+ Aktuelles Kapitel entfernen
+ Controller/Prod/LanguageController.php
Remove from basket
@@ -5858,9 +5855,9 @@
Row Passwort fehlt, Skript wurde gestoppt.
user/import/file.html.twig
-
+
Résultats des derniers envois effectués pour cette application
- Résultats des derniers envois effectués pour cette application
+ Ergebnisse der letzten gesendeten Nachrichten für diese Anwendung
web/developers/application.html.twig
@@ -5903,7 +5900,7 @@
Speichern
actions/Feedback/list.html.twig
web/account/change-password.html.twig
- admin/search-engine/general-aggregation.html.twig
+ admin/search-engine/general-aggregation.html.twig
admin/search-engine/elastic-search.html.twig
task-manager/task-editor/task.html.twig
web/developers/application.html.twig
@@ -5915,9 +5912,14 @@
Alle Änderungen speichern
admin/fields/templates.html.twig
-
+
+ Save as VTT
+ Kapitel speichern
+ Controller/Prod/LanguageController.php
+
+
Save the list
- Save the list
+ Liste speichern
actions/Feedback/list.html.twig
@@ -5940,9 +5942,9 @@
Suchmaschine
Form/Configuration/MainConfigurationFormType.php
-
+
Search for existing user
- Search for existing user
+ Suchen Sie nach bestehende Benutzer
actions/Feedback/List-Share.html.twig
@@ -5959,11 +5961,12 @@
See
Sehen
+ prod/WorkZone/Macros.html.twig
WorkZone/Browser/Browser.html.twig
-
+
See documentation about structure manipulation.
- See documentation about structure manipulation.
+ Für Struktur Veränderungen, Dokumentation sehen
admin/fields/index.html.twig
@@ -5983,9 +5986,9 @@
Andere sehen
prod/actions/Push.html.twig
-
+
See the list
- See the list
+ Die Liste sehen
actions/Feedback/list.html.twig
@@ -5996,7 +5999,7 @@
Select a field
Wählen Sie ein Feld aus
- web/prod/index.html.twig
+ web/prod/index.html.twig
Select a list on the left and edit it !
@@ -6031,7 +6034,7 @@
Selected base(s)
Ausgewählte Datenbank(en) :
- web/prod/index.html.twig
+ web/prod/index.html.twig
Selected files
@@ -6141,9 +6144,9 @@
Verteilen
Controller/Prod/LanguageController.php
-
+
Share my list
- Share my list
+ Meine Liste teilen
actions/Feedback/list.html.twig
@@ -6151,9 +6154,9 @@
Die Liste teilen
actions/Feedback/list.html.twig
-
+
Shift
- Shift
+ Umschalt
Controller/Prod/LanguageController.php
@@ -6165,7 +6168,7 @@
Shutter speed
Verschlusszeit
- SearchEngine/Elastic/ElasticsearchOptions.php
+ SearchEngine/Elastic/ElasticsearchOptions.php
web/common/technical_datas.html.twig
@@ -6268,9 +6271,9 @@
admin/publications/fiche.html.twig
admin/publications/list.html.twig
-
+
Space bar
- Space bar
+ Space-Taste
Controller/Prod/LanguageController.php
@@ -6284,10 +6287,10 @@
admin/task-manager/templates.html.twig
admin/task-manager/templates.html.twig
-
+
Start Range
- Start Range
- Controller/Prod/LanguageController.php
+ Kapitel starten
+ Controller/Prod/LanguageController.php
Start by creating one by using the "add" button on the left !
@@ -6308,7 +6311,7 @@
Status des documents a rechercher
Zustand der Dokumente
- web/prod/index.html.twig
+ web/prod/index.html.twig
Status edition
@@ -6342,10 +6345,12 @@
Stories
Berichte
Form/Configuration/SearchEngineFormType.php
+ prod/WorkZone/Macros.html.twig
Story Not Found
Bericht wurde nicht gefunden
+ Controller/Api/V3Controller.php
Controller/Api/V1Controller.php
@@ -6393,16 +6398,16 @@
Unterauflösung
admin/databox/details.html.twig
-
+
Submit
- Submit
+ Einreichen
Controller/Prod/LanguageController.php
Substitute
Ersatz
- prod/upload/lazaret.html.twig
- prod/upload/lazaret.html.twig
+ prod/upload/lazaret.html.twig
+ prod/upload/lazaret.html.twig
Substitution is not possible for this kind of record
@@ -6446,7 +6451,7 @@
Controller/Admin/CollectionController.php
Controller/Admin/CollectionController.php
Controller/Admin/CollectionController.php
- actions/Tools/videoEditor.html.twig
+ actions/Tools/videoEditor.html.twig
web/admin/databases.html.twig
admin/collection/collection.html.twig
admin/collection/suggested_value.html.twig
@@ -6461,9 +6466,9 @@
Vorschlagswerte
admin/collection/suggested_value.html.twig
-
+
Suppr
- Suppr
+ Entf
Controller/Prod/LanguageController.php
@@ -6589,9 +6594,9 @@
web/login/cgus.html.twig
login/layout/base-layout.html.twig
-
+
The Phraseanet Web API allows other web application to rely on this instance
- The Phraseanet Web API allows other web application to rely on this instance
+ Die Phraseanet Web API ermöglicht, andere Web Anwendungen, auf diese Instanz zu vertrauen
Form/Configuration/APIClientsFormType.php
@@ -6726,7 +6731,7 @@
Theme
Thema
- web/prod/index.html.twig
+ web/prod/index.html.twig
There is no one to validate orders, please contact an administrator
@@ -6746,13 +6751,13 @@
Thesaurus Min score
Thesaurus Hits (minimal)
- SearchEngine/Elastic/ElasticsearchSettingsFormType.php
+ SearchEngine/Elastic/ElasticsearchSettingsFormType.php
web/setup/step2.html.twig
Thesaurus branch
Thesaurus Sprung
- admin/fields/templates.html.twig
+ admin/fields/templates.html.twig
Thesaurus ou CTerms invalide
@@ -6819,7 +6824,7 @@
This user does not participate to the validation but is only viewer.
Dieser Benutzer darf nicht teilnehmen, nur ansehen.
- prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
This user has no rights
@@ -6869,9 +6874,9 @@
admin/publications/list.html.twig
admin/publications/list.html.twig
-
+
Toggle loop
- Toggle loop
+ Wiederholung aktivieren
Controller/Prod/LanguageController.php
@@ -6886,7 +6891,7 @@
Tool box
- Toolbox
+ Werkzeuge
Controller/Prod/LanguageController.php
@@ -6903,7 +6908,7 @@
Tout type
Bildschirmtyp
- web/prod/index.html.twig
+ web/prod/index.html.twig
Toutes les publications
@@ -6929,7 +6934,7 @@
Trier par
Sortieren nach
- web/prod/index.html.twig
+ web/prod/index.html.twig
Try to extract embedded thumbnails
@@ -6954,7 +6959,7 @@
Type de documents
Dokumenttyp
- web/prod/index.html.twig
+ web/prod/index.html.twig
Type nombre
@@ -7077,7 +7082,7 @@
Une question personnelle
eine persönliche Frage
- web/prod/index.html.twig
+ web/prod/index.html.twig
Une selection
@@ -7169,7 +7174,7 @@
Uploaded by : %username%
von: %username% hochgeladen
- prod/upload/lazaret.html.twig
+ prod/upload/lazaret.html.twig
Use Google Chart API
@@ -7181,15 +7186,15 @@
Benutzen Sie einen SMTP Server
Form/Configuration/EmailFormType.php
-
+
Use an existing index
- Use an existing index
+ Benutzen Sie einen bestehenden Index
web/setup/step2.html.twig
Use latest search settings on Production loading
die letzte gestellte Frage in Prod benutzen
- web/prod/index.html.twig
+ web/prod/index.html.twig
Use my Phraseanet account
@@ -7246,10 +7251,10 @@
Controller/Prod/LanguageController.php
prod/templates/push.html.twig
prod/templates/push.html.twig
- prod/templates/push.html.twig
prod/templates/push.html.twig
- prod/templates/push.html.twig
+ prod/templates/push.html.twig
prod/templates/push.html.twig
+ prod/templates/push.html.twig
User can see others choices
@@ -7289,9 +7294,9 @@
Benutzer Vorschlag
prod/actions/Push.html.twig
-
+
Utilisation prevue:
- Utilisation prevue:
+ Verwendungszweck:
prod/orders/order_item.html.twig
@@ -7328,8 +7333,8 @@
Validations
Bestätigung
- mobile/lightbox/index.html.twig
- mobile/lightbox/index.html.twig
+ mobile/lightbox/index.html.twig
+ mobile/lightbox/index.html.twig
web/lightbox/index.html.twig
lightbox/IE6/validate.html.twig
web/lightbox/validate.html.twig
@@ -7367,7 +7372,7 @@
Video
Video
- web/prod/index.html.twig
+ web/prod/index.html.twig
Video Codec
@@ -7377,7 +7382,7 @@
Video codec
Video-Codec
- SearchEngine/Elastic/ElasticsearchOptions.php
+ SearchEngine/Elastic/ElasticsearchOptions.php
Videos
@@ -7398,18 +7403,18 @@
Vocabulary type
Wortschatz Typ
- admin/fields/templates.html.twig
+ admin/fields/templates.html.twig
Voici vos paniers
Ihre Sammelkörbe
- mobile/lightbox/index.html.twig
- web/lightbox/index.html.twig
+ mobile/lightbox/index.html.twig
+ web/lightbox/index.html.twig
Voici vos validations en cours
Hier sind Ihre aktuellen Bewertungen
- mobile/lightbox/index.html.twig
+ mobile/lightbox/index.html.twig
web/lightbox/index.html.twig
@@ -7445,7 +7450,7 @@
Vous avez envoye une demande de validation de document sur ce panier
Sie haben eine Bewertung von Dokumenten angefordert
- prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
Vous avez recu des documents
@@ -7564,7 +7569,7 @@
Vous pouvez quitter la plupart des fenetres survolantes via la touche echap
esc : Sie können die meiste Teile der Overlay Fenster schliessen
- web/prod/index.html.twig
+ web/prod/index.html.twig
Warning !
@@ -7665,8 +7670,8 @@
YYYY/MM/DD
YYYY/MM/DD
- web/prod/index.html.twig
- web/prod/index.html.twig
+ web/prod/index.html.twig
+ web/prod/index.html.twig
Yes
@@ -7974,7 +7979,7 @@
a propos
Über
mobile/lightbox/index.html.twig
- mobile/lightbox/index.html.twig
+ mobile/lightbox/index.html.twig
action : ajouter au panier
@@ -7987,21 +7992,21 @@
action : bridge
Bridge
- web/prod/index.html.twig
+ web/prod/index.html.twig
action : collection
Verschieben
prod/WorkZone/Story.html.twig
prod/WorkZone/Basket.html.twig
- web/prod/toolbar.html.twig
+ web/prod/toolbar.html.twig
action : editer
Bearbeiten
prod/WorkZone/Story.html.twig
prod/WorkZone/Basket.html.twig
- web/prod/toolbar.html.twig
+ web/prod/toolbar.html.twig
prod/preview/caption.html.twig
@@ -8009,12 +8014,12 @@
Exportieren
prod/WorkZone/Story.html.twig
prod/WorkZone/Basket.html.twig
- web/prod/toolbar.html.twig
+ web/prod/toolbar.html.twig
prod/results/record.html.twig
prod/results/record.html.twig
prod/results/record.html.twig
prod/preview/tools.html.twig
- web/prod/index.html.twig
+ web/prod/index.html.twig
web/lightbox/feed.html.twig
lightbox/IE6/feed.html.twig
lightbox/IE6/validate.html.twig
@@ -8025,14 +8030,14 @@
Werkzeuge
prod/WorkZone/Story.html.twig
prod/WorkZone/Basket.html.twig
- web/prod/toolbar.html.twig
+ web/prod/toolbar.html.twig
action : print
Drucken
prod/WorkZone/Story.html.twig
prod/WorkZone/Basket.html.twig
- web/prod/toolbar.html.twig
+ web/prod/toolbar.html.twig
prod/results/record.html.twig
prod/results/record.html.twig
prod/results/record.html.twig
@@ -8043,80 +8048,78 @@
Veröffentlichen
prod/WorkZone/Story.html.twig
prod/WorkZone/Basket.html.twig
- web/prod/toolbar.html.twig
- web/prod/toolbar.html.twig
- web/prod/index.html.twig
+ web/prod/toolbar.html.twig
+ web/prod/index.html.twig
action : push
Push
prod/WorkZone/Story.html.twig
prod/WorkZone/Basket.html.twig
- web/prod/toolbar.html.twig
- web/prod/toolbar.html.twig
+ web/prod/toolbar.html.twig
action : status
Eigenschaften
prod/WorkZone/Story.html.twig
prod/WorkZone/Basket.html.twig
- web/prod/toolbar.html.twig
+ web/prod/toolbar.html.twig
action : supprimer
Löschen
- prod/WorkZone/Macros.html.twig
- prod/WorkZone/Macros.html.twig
- web/prod/toolbar.html.twig
+ prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
+ web/prod/toolbar.html.twig
action:: nouveau panier
Neuer
- web/prod/index.html.twig
- web/prod/index.html.twig
- web/prod/index.html.twig
+ web/prod/index.html.twig
+ web/prod/index.html.twig
+ web/prod/index.html.twig
action:: nouveau reportage
Neuer Bericht
- web/prod/index.html.twig
- web/prod/index.html.twig
- web/prod/index.html.twig
+ web/prod/index.html.twig
+ web/prod/index.html.twig
+ web/prod/index.html.twig
action::Valider
Bestätigen
- prod/WorkZone/Macros.html.twig
- prod/WorkZone/Macros.html.twig
- prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
action::detacher
entfernen
- prod/WorkZone/Macros.html.twig
- prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
action::editer
Bearbeiten
- prod/WorkZone/Macros.html.twig
- prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
action::exporter
Exportieren
- prod/WorkZone/Macros.html.twig
- prod/WorkZone/Macros.html.twig
- prod/WorkZone/Macros.html.twig
- prod/WorkZone/Macros.html.twig
- prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
action::renommer
umbenennen
- prod/WorkZone/Macros.html.twig
- prod/WorkZone/Macros.html.twig
- prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
actual status
@@ -8485,7 +8488,7 @@
admin::compte-utilisateur changer mon mot de passe
- mein Passwort ändern
+ Mein Passwort ändern
web/account/account.html.twig
@@ -8613,7 +8616,7 @@
admin::compte-utilisateur societe
- Firma
+ Unternehmen
Controller/Admin/UserController.php
Core/Provider/RegistrationServiceProvider.php
web/account/account.html.twig
@@ -9059,14 +9062,14 @@
admin::utilisateurs: utilisateurs connectes
- eingeloggte Benutzer
+ Eingeloggte Benutzer
web/admin/tree.html.twig
web/admin/connected-users.html.twig
alert
Vorsicht
- actions/Tools/videoEditor.html.twig
+ actions/Tools/videoEditor.html.twig
actions/Tools/index.html.twig
@@ -9151,12 +9154,12 @@
boutton:: selectionner aucune base
Keine
- web/prod/index.html.twig
+ web/prod/index.html.twig
boutton:: selectionner toutes les bases
Alle
- web/prod/index.html.twig
+ web/prod/index.html.twig
boutton::ajouter
@@ -9287,7 +9290,7 @@
boutton::imprimer
Drucken
- prod/actions/printer_default.html.twig
+ prod/actions/printer_default.html.twig
boutton::modifier
@@ -9326,7 +9329,7 @@
boutton::rechercher
suchen
Controller/Prod/LanguageController.php
- web/prod/index.html.twig
+ web/prod/index.html.twig
boutton::refresh
@@ -9369,7 +9372,7 @@
admin/collection/details.html.twig
user/import/file.html.twig
admin/statusbit/edit.html.twig
- web/developers/application_form.html.twig
+ web/developers/application_form.html.twig
web/developers/application.html.twig
@@ -9417,7 +9420,7 @@
boutton::telecharger
- download
+ Download
web/lightbox/sc_options_box.html.twig
web/lightbox/feed_options_box.html.twig
web/common/dialog_export.html.twig
@@ -9461,7 +9464,7 @@
prod/actions/edit_default.html.twig
prod/actions/edit_default.html.twig
prod/Story/Reorder.html.twig
- web/prod/index.html.twig
+ web/prod/index.html.twig
web/thesaurus/export-text-dialog.html.twig
web/thesaurus/thesaurus.html.twig
web/thesaurus/import-dialog.html.twig
@@ -9489,12 +9492,12 @@
user/import/view.html.twig
admin/user/registrations.html.twig
admin/statusbit/edit.html.twig
- web/developers/application_form.html.twig
+ web/developers/application_form.html.twig
web/report/all_content.html.twig
boutton::vue graphique
- grafische Ansicht
+ Grafische Ansicht
admin/collection/suggested_value.html.twig
task-manager/task-editor/task.html.twig
@@ -9516,7 +9519,7 @@
cancel
- abbrechen
+ Abbrechen
actions/Tools/index.html.twig
actions/Tools/index.html.twig
actions/Tools/index.html.twig
@@ -9544,12 +9547,12 @@
cgus :: accepter
- annehmen
+ Annehmen
classes/databox/cgu.php
cgus :: refuser
- ablehnen
+ Ablehnen
classes/databox/cgu.php
@@ -9575,7 +9578,7 @@
charger d'avantage de publications
- mehr Veröffentlichungen hochladen
+ Mehr Veröffentlichungen hochladen
prod/results/feeds.html.twig
prod/results/feeds.html.twig
@@ -9587,7 +9590,7 @@
choisir
wählen
- web/prod/index.html.twig
+ web/prod/index.html.twig
admin/databox/databox.html.twig
admin/collection/create.html.twig
@@ -9669,7 +9672,7 @@
created_on
erstellt am
- web/prod/index.html.twig
+ web/prod/index.html.twig
dans %category%
@@ -9687,9 +9690,9 @@
hinzugefügtes Datum
SearchEngine/Elastic/ElasticSearchEngine.php
-
+
date de modification
- date de modification
+ Änderungsdatum
SearchEngine/Elastic/ElasticSearchEngine.php
@@ -9700,7 +9703,7 @@
delete
Löschen
- prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
descendant
@@ -9729,7 +9732,7 @@
edit
Bearbeiten
- prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
web/account/account.html.twig
web/account/account.html.twig
web/account/account.html.twig
@@ -9809,7 +9812,7 @@
export:: erreur : aucun document selectionne
Fehler: kein ausgewähltes Dokument
- prod/actions/printer_default.html.twig
+ prod/actions/printer_default.html.twig
export:: telechargement
@@ -9824,7 +9827,7 @@
export::ftp: reglages manuels
- manuelle Einstellungen
+ Manuelle Einstellungen
classes/set/export.php
@@ -9940,20 +9943,16 @@
Änderungen wurden hergestellt
admin/databox/databox.html.twig
-
- generate_cterms
- generate_cterms
- admin/fields/templates.html.twig
+
+ help::help-search: OR
+ help::help-search: OR
+ prod/results/help.html.twig
-
- gui_editable
- gui_editable
- admin/fields/templates.html.twig
-
-
- gui_visible
- gui_visible
- admin/fields/templates.html.twig
+
+ help::help-search: relaunch search without filter
+ help::help-search: relaunch search without filter
+ prod/results/help.html.twig
+ web/prod/index.html.twig
help::help-section-bullet: check-spelling
@@ -10007,7 +10006,7 @@
help::help-section-title: sorry-no-result
- Sorry, Ihre Suche liefert keine Ergebnisse
+ Entschuldigung, Ihre Suche liefert keine Ergebnisse
prod/results/help.html.twig
@@ -10027,45 +10026,50 @@
Bild Werkzeug
actions/Tools/index.html.twig
-
+
index::advance_search: disable-facet
- index::advance_search: disable-facet
- web/prod/index.html.twig
+ Facetten mit nur einem Ergebnis ausblenden (experimentell)
+ web/prod/index.html.twig
-
+
index::advance_search: facet
- index::advance_search: facet
- web/prod/index.html.twig
+ Einstellungen für Facetten
+ web/prod/index.html.twig
index::advance_search: facet-order
Reihenfolge der Facettenanzeige
- web/prod/index.html.twig
+ web/prod/index.html.twig
index::advance_search: facet-tech-order
Standard Reihenfolge
- web/prod/index.html.twig
+ web/prod/index.html.twig
index::advance_search: facet-values-order
Reihenfolge der Facettenwerte
- web/prod/index.html.twig
+ web/prod/index.html.twig
-
+
index::advance_search: hidden-facet-values-order
- index::advance_search: hidden-facet-values-order
- web/prod/index.html.twig
+ Versteckte Facetten
+ web/prod/index.html.twig
index::advance_search: order-by-hits
Nach Hits sortieren
- web/prod/index.html.twig
+ web/prod/index.html.twig
-
+
+ index::advance_search: order-by-hits-asc
+ index::advance_search: order-by-hits-asc
+ web/prod/index.html.twig
+
+
index:advanced-preferences:: use truncation
- index:advanced-preferences:: use truncation
- web/prod/index.html.twig
+ Trunkierung aktivieren
+ web/prod/index.html.twig
invite:: Redirection vers la zone d'authentification, cliquez sur OK pour continuer ou annulez
@@ -10074,7 +10078,7 @@
janvier
- Jänner
+ Januar
classes/module/report.php
@@ -10097,18 +10101,38 @@
Die Dienstleistung wird in einige Minuten wieder verfügbar sein.
actions/Bridge/deactivated.html.twig
+
+ lightbox::See_less_feedback
+ lightbox::See_less_feedback
+ web/lightbox/index.html.twig
+
+
+ lightbox::See_more_feedback
+ lightbox::See_more_feedback
+ web/lightbox/index.html.twig
+
lightbox::list
lightbox::list
- mobile/lightbox/validate.html.twig
+ mobile/lightbox/validate.html.twig
lightbox::recaptitulatif
Übersicht
- mobile/lightbox/validate.html.twig
+ mobile/lightbox/validate.html.twig
web/lightbox/agreement_box.html.twig
web/lightbox/validate.html.twig
+
+ lightbox::see_less_basket
+ lightbox::see_less_basket
+ web/lightbox/index.html.twig
+
+
+ lightbox::see_more_basket
+ lightbox::see_more_basket
+ web/lightbox/index.html.twig
+
login:: Changer mon adresse email
meine E-Mail Adresse ändern
@@ -10127,6 +10151,7 @@
login:: Mon compte
Mein Benutzerkonto
+ mobile/common/menubar.html.twig
web/account/account.html.twig
web/common/menubar.html.twig
web/common/menubar.html.twig
@@ -10263,7 +10288,7 @@
no image selected
Kein Bild wurde ausgewählt
- actions/Tools/videoEditor.html.twig
+ actions/Tools/videoEditor.html.twig
actions/Tools/index.html.twig
@@ -10297,146 +10322,146 @@
or
- Or
+ Oder
Controller/Prod/LanguageController.php
-
+
order-manager::mail: your-order-of
- order-manager::mail: your-order-of
+ Ihre Bestellung von :
prod/orders/order_item.html.twig
-
+
order-manager::order-item: accepted-item
- order-manager::order-item: accepted-item
+ akzeptiert
prod/orders/order_item.html.twig
-
+
order-manager::order-item: address
- order-manager::order-item: address
+ Adresse
prod/orders/order_item.html.twig
-
+
order-manager::order-item: already-validated
- order-manager::order-item: already-validated
+ gesendet
prod/orders/order_item.html.twig
-
+
order-manager::order-item: by
- order-manager::order-item: by
+ von
prod/orders/order_item.html.twig
-
+
order-manager::order-item: company
- order-manager::order-item: company
+ Unternehmen
prod/orders/order_item.html.twig
-
+
order-manager::order-item: country
- order-manager::order-item: country
+ Land
prod/orders/order_item.html.twig
-
+
order-manager::order-item: create
- order-manager::order-item: create
+ OK
prod/orders/order_item.html.twig
-
+
order-manager::order-item: create-basket
- order-manager::order-item: create-basket
+ Neuer Sammelkorb
prod/orders/order_item.html.twig
-
+
order-manager::order-item: for-non-sent-items
- order-manager::order-item: for-non-sent-items
+ Für die Dokumente, die nicht gesendet wurden
prod/orders/order_item.html.twig
-
+
order-manager::order-item: information
- order-manager::order-item: information
+ Information
prod/orders/order_item.html.twig
-
+
order-manager::order-item: item
- order-manager::order-item: item
+ Dokument
prod/orders/order_item.html.twig
-
+
order-manager::order-item: items-already-sent
- order-manager::order-item: items-already-sent
+ Dokument(e) schon gesendet
prod/orders/order_item.html.twig
-
+
order-manager::order-item: items-waiting-validation
- order-manager::order-item: items-waiting-validation
+ Dokumente, die auf eine Bestätigung warten
prod/orders/order_item.html.twig
-
+
order-manager::order-item: less
- order-manager::order-item: less
+ weniger sehen
prod/orders/order_item.html.twig
-
+
order-manager::order-item: more
- order-manager::order-item: more
+ mehr sehen
prod/orders/order_item.html.twig
-
+
order-manager::order-item: number
- order-manager::order-item: number
+ Nummer
prod/orders/order_item.html.twig
-
+
order-manager::order-item: of
- order-manager::order-item: of
+ Von
prod/orders/order_item.html.twig
prod/orders/order_item.html.twig
-
+
order-manager::order-item: refused-previously
- order-manager::order-item: refused-previously
+ zuvor abgelehnt
prod/orders/order_item.html.twig
prod/orders/order_item.html.twig
-
+
order-manager::order-item: rejected-item
- order-manager::order-item: rejected-item
+ abgelehnt
prod/orders/order_item.html.twig
-
+
order-manager::order-item: reset
- order-manager::order-item: reset
+ zurücksetzen
prod/orders/order_item.html.twig
prod/orders/order_item.html.twig
prod/orders/order_item.html.twig
-
+
order-manager::order-item: select-all
- order-manager::order-item: select-all
+ Alle auswählen
prod/orders/order_item.html.twig
-
+
order-manager::order-item: selected-item
- order-manager::order-item: selected-item
+ ausgewählt
prod/orders/order_item.html.twig
-
+
order-manager::order-item: selected-records
- order-manager::order-item: selected-records
+ ausgewählte Datensätze
prod/orders/order_item.html.twig
-
+
order-manager::order-item: submit
- order-manager::order-item: submit
+ Senden
prod/orders/order_item.html.twig
-
+
order-manager::order-item: tel
- order-manager::order-item: tel
+ Telefon
prod/orders/order_item.html.twig
-
+
order-manager::order-item: validate
- order-manager::order-item: validate
+ bestätigen
prod/orders/order_item.html.twig
@@ -10444,104 +10469,104 @@
order-manager::order-item: warning-message-close
prod/orders/order_item.html.twig
-
+
order-manager::order-item: with-denied-items
- order-manager::order-item: with-denied-items
+ Mit der abgelehnten Datensätzen
prod/orders/order_item.html.twig
-
+
order-manager::order-item: with-selected-items
- order-manager::order-item: with-selected-items
+ Mit der Auswahl
prod/orders/order_item.html.twig
-
+
order-manager::order-item: with-validated-items
- order-manager::order-item: with-validated-items
+ Mit gesendete(r) Dokument(en)
prod/orders/order_item.html.twig
-
+
order-manager::order-item: you-have-denied
- order-manager::order-item: you-have-denied
+ Dokument(e) abgelehnt
prod/orders/order_item.html.twig
-
+
order-manager::order-item: you-have-validated
- order-manager::order-item: you-have-validated
+ Dokument(e) gesendet
prod/orders/order_item.html.twig
-
+
order-manager::order-item:Create-Basket
- order-manager::order-item:Create-Basket
+ Sammelkorb erstellen
prod/orders/order_item.html.twig
-
+
order-manager::order-item:Validation
- order-manager::order-item:Validation
+ Bestellübersicht
prod/orders/order_item.html.twig
-
+
order-manager::order-list: after
- order-manager::order-list: after
+ Bestellt nach :
prod/orders/order_box.html.twig
order-manager::order-list: apply
- order-manager::order-list: apply
+ Filter anwenden
prod/orders/order_box.html.twig
-
+
order-manager::order-list: before
- order-manager::order-list: before
+ Bestellt vor:
prod/orders/order_box.html.twig
-
+
order-manager::order-list: last-month
- order-manager::order-list: last-month
+ Letzten Monat
prod/orders/order_box.html.twig
-
+
order-manager::order-list: last-week
- order-manager::order-list: last-week
+ Letzte Woche
prod/orders/order_box.html.twig
-
+
order-manager::order-list: no-filter
- order-manager::order-list: no-filter
+ Kein Filter
prod/orders/order_box.html.twig
prod/orders/order_box.html.twig
-
+
order-manager::order-list: no-result
- order-manager::order-list: no-result
+ Keine Bestellung im Moment sichtbar
prod/orders/order_box.html.twig
prod/orders/order_box.html.twig
-
+
order-manager::order-list: order-id
- order-manager::order-list: order-id
+ Bestellung Nummer
prod/orders/order_item.html.twig
prod/orders/order_item.html.twig
prod/orders/order_box.html.twig
prod/orders/order_box.html.twig
-
+
order-manager::order-list: pending
- order-manager::order-list: pending
+ Bestellung zu verarbeiten
prod/orders/order_box.html.twig
-
+
order-manager::order-list: processed
- order-manager::order-list: processed
+ Verarbeitet
prod/orders/order_box.html.twig
-
+
order-manager::order-list: this-week
- order-manager::order-list: this-week
+ Diese Woche
prod/orders/order_box.html.twig
-
+
order-manager::order-list: treated-documents
- order-manager::order-list: treated-documents
+ Verarbeitete(r) Datensatz(¨e)
prod/orders/order_item.html.twig
prod/orders/order_box.html.twig
prod/orders/order_box.html.twig
@@ -10581,17 +10606,17 @@
panier:: ordre Validation ascendante
gut bewertet
- prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
panier:: ordre Validation descendante
weniger gut bewertet
- prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
panier:: ordre du panier
Sammelkorb Reihenfolge
- prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
panier:: renommer le panier
@@ -10616,7 +10641,7 @@
paniers:: panier recu de %pusher%
Sammelkorb von %pusher% bekommen
- prod/WorkZone/Macros.html.twig
+ prod/WorkZone/Macros.html.twig
paniers::Vous etes sur le point de supprimer ce panier. Cette action est irreversible. Souhaitez-vous continuer ?
@@ -10639,9 +10664,9 @@
pro Monat
web/admin/editusers_quotas.html.twig
-
+
personalize logo
- personalize logo
+ Logo anpassen
Form/Configuration/PersonalisationLogoFormType.php
@@ -10677,7 +10702,7 @@
phraseanet:: Preferences
Einstellungen
- web/prod/index.html.twig
+ web/prod/index.html.twig
phraseanet:: Un email vient de vous etre envoye
@@ -10705,9 +10730,14 @@
web/common/menubar.html.twig
web/common/menubar.html.twig
-
+
+ phraseanet:: basket feedback
+ Sammelkorb Feedback
+ prod/actions/printer_default.html.twig
+
+
phraseanet:: baskets
- phraseanet:: baskets
+ Sammelkörbe
web/prod/tab_headers.html.twig
@@ -10782,7 +10812,7 @@
phraseanet:: preview
Voransicht
prod/actions/edit_default.html.twig
- prod/actions/printer_default.html.twig
+ prod/actions/printer_default.html.twig
phraseanet:: propositions
@@ -10821,17 +10851,17 @@
phraseanet:: tri par date
nach Datum sortieren
- web/prod/index.html.twig
- web/prod/index.html.twig
- web/prod/index.html.twig
+ web/prod/index.html.twig
+ web/prod/index.html.twig
+ web/prod/index.html.twig
web/thesaurus/export-topics-dialog.html.twig
phraseanet:: tri par nom
alphabetische Sortierung
- web/prod/index.html.twig
- web/prod/index.html.twig
- web/prod/index.html.twig
+ web/prod/index.html.twig
+ web/prod/index.html.twig
+ web/prod/index.html.twig
phraseanet:: user
@@ -10910,7 +10940,7 @@
phraseanet::erreur: Une erreur est survenue, si ce probleme persiste, contactez le support technique
- Leider ist ein Fehler aufgetreten. Sollte sich dieser Fehler wiederholen kontaktieren Sie bitte den Administrator
+ Leider ist ein Fehler aufgetreten. Sollte sich dieser Fehler wiederholen, kontaktieren Sie bitte den Administrator
Controller/Prod/LanguageController.php
web/admin/index.html.twig
@@ -10970,7 +11000,7 @@
phraseanet::recherche avancee
- erweiterte Suche
+ Erweiterte Suche
Controller/Prod/LanguageController.php
@@ -11016,12 +11046,12 @@
phraseanet::time:: a
zu
- web/prod/index.html.twig
+ web/prod/index.html.twig
phraseanet::time:: de
von
- web/prod/index.html.twig
+ web/prod/index.html.twig
phraseanet::type:: audios
@@ -11032,7 +11062,7 @@
phraseanet::type:: documents
Dokumente
web/prod/toolbar.html.twig
- web/prod/index.html.twig
+ web/prod/index.html.twig
phraseanet::type:: images
@@ -11042,7 +11072,7 @@
phraseanet::type:: reportages
Berichte
- web/prod/index.html.twig
+ web/prod/index.html.twig
phraseanet::type:: videos
@@ -11067,17 +11097,17 @@
preview:: Description
Beschreibung
- web/prod/index.html.twig
+ web/prod/index.html.twig
preview:: Historique
Historie
- web/prod/index.html.twig
+ web/prod/index.html.twig
preview:: Popularite
Beliebtheit
- web/prod/index.html.twig
+ web/prod/index.html.twig
preview:: arreter le diaporama
@@ -11097,23 +11127,23 @@
prod/preview/result_train_options.html.twig
prod/preview/feed_train.html.twig
-
+
preview::date
- preview::date
+ Datum
prod/preview/popularity.html.twig
prod/preview/popularity.html.twig
prod/preview/popularity.html.twig
prod/preview/popularity.html.twig
-
+
preview::downloads
- preview::downloads
+ Anzahl von Downloads
prod/preview/popularity.html.twig
prod/preview/popularity.html.twig
preview::statistiques de telechargement
- Herunterladen Statistiken
+ Download Statistiken
prod/preview/popularity.html.twig
@@ -11121,9 +11151,9 @@
Ansicht Statistiken
prod/preview/popularity.html.twig
-
+
preview::visualisation
- preview::visualisation
+ Anzahl von Ansichten
prod/preview/popularity.html.twig
prod/preview/popularity.html.twig
@@ -11134,40 +11164,135 @@
prod/Share/record.html.twig
prod/Share/record.html.twig
-
+
+ print:: basket feedback
+ print:: basket feedback
+ prod/actions/printer_default.html.twig
+
+
+ print:: basket feedback only
+ print:: basket feedback only
+ prod/actions/printer_default.html.twig
+
+
print:: description
- print:: description
- prod/actions/printer_default.html.twig
+ Bildunterschrift
+ prod/actions/printer_default.html.twig
print:: image de choix et description
Voransicht und Bildunterschrift
- prod/actions/printer_default.html.twig
+ prod/actions/printer_default.html.twig
print:: image de choix et description avec planche contact
Voransicht und Bildunterschrift mit Mosaikansicht
- prod/actions/printer_default.html.twig
+ prod/actions/printer_default.html.twig
print:: image de choix seulement
Voransicht
- prod/actions/printer_default.html.twig
+ prod/actions/printer_default.html.twig
print:: imagette
Miniaturansicht
- prod/actions/printer_default.html.twig
+ prod/actions/printer_default.html.twig
print:: liste d'imagettes
Miniaturansichten Liste
- prod/actions/printer_default.html.twig
+ prod/actions/printer_default.html.twig
print:: planche contact (mosaique)
Mosaikansicht
- prod/actions/printer_default.html.twig
+ prod/actions/printer_default.html.twig
+
+
+ print_feedback:: Document generated on :
+ print_feedback:: Document generated on :
+ Out/Module/PDFRecords.php
+
+
+ print_feedback:: Feedback active
+ Feedback ist aktiviert
+ Out/Module/PDFRecords.php
+
+
+ print_feedback:: Feedback expired
+ Feedback ist abgelaufen
+ Out/Module/PDFRecords.php
+
+
+ print_feedback:: Feedback expiring on :
+ print_feedback:: Feedback expiring on :
+ Out/Module/PDFRecords.php
+
+
+ print_feedback:: Feedback initiated by :
+ print_feedback:: Feedback initiated by :
+ Out/Module/PDFRecords.php
+
+
+ print_feedback:: Feedback initiated on :
+ print_feedback:: Feedback initiated on :
+ Out/Module/PDFRecords.php
+
+
+ print_feedback:: Feedback on basket %name%
+ Feedback auf Sammelkorb %name%
+ Out/Module/PDFRecords.php
+
+
+ print_feedback:: Non
+ Nein
+ Out/Module/PDFRecords.php
+
+
+ print_feedback:: Oui
+ Ja
+ Out/Module/PDFRecords.php
+
+
+ print_feedback:: Participants :
+ Teilnehmer :
+ Out/Module/PDFRecords.php
+
+
+ print_feedback:: Votes :
+ Zustimmung :
+ Out/Module/PDFRecords.php
+
+
+ print_feedback:: base name:
+ print_feedback:: base name:
+ Out/Module/PDFRecords.php
+
+
+ print_feedback:: document Uuid:
+ print_feedback:: document Uuid:
+ Out/Module/PDFRecords.php
+
+
+ print_feedback:: non voté
+ unausgedrückt
+ Out/Module/PDFRecords.php
+
+
+ print_feedback:: originale filename:
+ print_feedback:: originale filename:
+ Out/Module/PDFRecords.php
+
+
+ print_feedback:: record id:
+ print_feedback:: record id:
+ Out/Module/PDFRecords.php
+
+
+ print_feedback:: record title:
+ print_feedback:: record title:
+ Out/Module/PDFRecords.php
prive
@@ -11184,7 +11309,7 @@
processing
verarbeitend
- actions/Tools/videoEditor.html.twig
+ actions/Tools/videoEditor.html.twig
actions/Tools/index.html.twig
@@ -11201,12 +11326,12 @@
prod::advancesearch:tooltips:datefield_restriction_explanation
Suchergebnisse auf Datum beschränken
- web/prod/index.html.twig
+ web/prod/index.html.twig
-
+
prod::advancesearch:tooltips:field_restriction_explanation
- prod::advancesearch:tooltips:field_restriction_explanation
- web/prod/index.html.twig
+ Suchen Sie den Inhalt der Felder
+ web/prod/index.html.twig
prod::collection deplacer egalement les documents rattaches a ce(s) regroupement(s)
@@ -11220,18 +11345,18 @@
prod::editing valeurs heterogenes, choisir 'remplacer', 'ajouter' ou 'annuler'
- heterogene Werte, bitte wählen Sie "ersetzen", "hinzufügen" oder "abbrechen"
+ Heterogene Werte, bitte wählen Sie "ersetzen", "hinzufügen" oder "abbrechen"
Controller/Prod/LanguageController.php
prod::editing: %not_actionable% documents ne peuvent etre edites car vos droits sont induffisants
%not_actionable% Dokumente können nicht bearbeitet werden, da Sie keine Rechte darauf haben
- prod/actions/edit_default.html.twig
+ prod/actions/edit_default.html.twig
prod::editing: 1 document ne peut etre edite car vos droits sont induffisants
Keine Bearbeitung möglich. Sie haben keinen Zugriff auf die Dokumente
- prod/actions/edit_default.html.twig
+ prod/actions/edit_default.html.twig
prod::editing: aucun documents ne peuvent etre edites car vos droits sont induffisants
@@ -11326,17 +11451,27 @@
prod::facet:base_label
Datenbanken
- SearchEngine/Elastic/ElasticsearchOptions.php
+ SearchEngine/Elastic/ElasticsearchOptions.php
prod::facet:collection_label
Kollektionen
- SearchEngine/Elastic/ElasticsearchOptions.php
+ SearchEngine/Elastic/ElasticsearchOptions.php
prod::facet:doctype_label
Dokumenttyp
- SearchEngine/Elastic/ElasticsearchOptions.php
+ SearchEngine/Elastic/ElasticsearchOptions.php
+
+
+ prod::feedback:feedback_set_title
+ prod::feedback:feedback_set_title
+ prod/templates/push.html.twig
+
+
+ prod::push:push_set_title
+ prod::push:push_set_title
+ prod/templates/push.html.twig
prod::recherche: Attention : la liste des bases selectionnees pour la recherche a ete changee.
@@ -11355,7 +11490,7 @@
prod::thesaurusTab:cmenu:Remplacer par...
- ersetzen durch
+ Ersetzen durch
web/prod/index.html.twig
@@ -11455,13 +11590,13 @@
prod::thesaurusTab:wizard:remplacer par le terme
- ersetzen durch den Begriff
+ Durch den Begriff ersetzen
web/prod/tab_thesaurus.html.twig
-
+
prod::toolbar : video editor
- prod::toolbar : video editor
- web/prod/toolbar.html.twig
+ Video Tools
+ web/prod/toolbar.html.twig
prod::tools: document
@@ -11489,56 +11624,61 @@
Datensatz (¨e) In den Papierkorb verschieben
Controller/Prod/LanguageController.php
-
+
prod:edit: chapters
- prod:edit: chapters
- Controller/Prod/LanguageController.php
-
-
- prod:edit: no overlaps for chapters
- prod:edit: no overlaps for chapters
+ Kapitel Bearbeitung
Controller/Prod/LanguageController.php
-
- prod:edit: only a media of type video can be edited
- prod:edit: only a media of type video can be edited
- Controller/Prod/LanguageController.php
-
-
- prod:edit: suggested_values
- prod:edit: suggested_values
+
+ prod:edit: no overlaps for chapters
+ Keine Überschneidung für die Kapitel
Controller/Prod/LanguageController.php
-
- prod:edit: video-editor
- prod:edit: video-editor
- Controller/Prod/LanguageController.php
+
+ prod:edit: only a media of type video can be edited
+ Nur eine Video kann bearbeitet sein
+ Controller/Prod/LanguageController.php
-
- prod:mapboxgl: description notice
- prod:mapboxgl: description notice
- Controller/Prod/LanguageController.php
-
-
- prod:mapboxgl: title map dialog
- prod:mapboxgl: title map dialog
- Controller/Prod/LanguageController.php
-
-
- prod:mapboxgl: title notice
- prod:mapboxgl: title notice
+
+ prod:edit: suggested_values
+ Vorgeschlagene Werte
Controller/Prod/LanguageController.php
-
- prod:push: create new user
- prod:push: create new user
+
+ prod:edit: video-editor
+ Video Tools
+ Controller/Prod/LanguageController.php
+
+
+ prod:mapboxgl: description notice
+ Machen Sie einen Rechtsklick, um einen Suchbereich zu hinzufügen. Klicken Sie auf den Bereich zu entfernen. Benutzen Sie den Griff, um die Grösse zu ändern oder den Bereich zu verschieben. Es ist auch möglich, mehrere Suchbereiche auszuwählen.
+ Controller/Prod/LanguageController.php
+
+
+ prod:mapboxgl: title map dialog
+ Lokalisierung Suche
Controller/Prod/LanguageController.php
-
+
+ prod:mapboxgl: title notice
+ Suchbereiche Funktionen
+ Controller/Prod/LanguageController.php
+
+
+ prod:push: create new user
+ Einen neuen Benutzer erstellen
+ Controller/Prod/LanguageController.php
+
+
prod:push: delete selection
- prod:push: delete selection
+ Auswahl entfernen
prod/actions/Push.html.twig
+
+ prod:workzone:facetstab:search_and_facets_sort_options
+ prod:workzone:facetstab:search_and_facets_sort_options
+ web/prod/index.html.twig
+
public
öffentlich
@@ -11574,8 +11714,8 @@
publication::Voici votre fil RSS personnel. Il vous permettra d'etre tenu au courrant des publications.
Hier finden Sie Ihr eigenes RSS Feed. Dank des RSS werden Sie über neue Veröffentlichungen automatisch informiert
- Controller/Prod/FeedController.php
- Controller/Prod/FeedController.php
+ Controller/Prod/FeedController.php
+ Controller/Prod/FeedController.php
publications:: s'abonner aux publications
@@ -11585,15 +11725,15 @@
publications::Ne le partagez pas, il est strictement confidentiel
- Dieses RSS nicht weiterleiten - es istvertraulich
- Controller/Prod/FeedController.php
- Controller/Prod/FeedController.php
+ Dieses RSS nicht weiterleiten - es ist vertraulich
+ Controller/Prod/FeedController.php
+ Controller/Prod/FeedController.php
publications::votre rss personnel
Ihr eigenes RSS
- Controller/Prod/FeedController.php
- Controller/Prod/FeedController.php
+ Controller/Prod/FeedController.php
+ Controller/Prod/FeedController.php
push::mail:: Rapport de validation de %user% pour %title%
@@ -11613,16 +11753,16 @@
raccourci :: a propos des raccourcis claviers
Über Abkürzungen
- web/prod/index.html.twig
+ web/prod/index.html.twig
raccourcis :: ne plus montrer cette aide
- diese Hilfe nicht mehr anzeigen
- web/prod/index.html.twig
+ Diese Hilfe nicht mehr anzeigen
+ web/prod/index.html.twig
rafraichir
- aktualisieren
+ Aktualisieren
prod/WorkZone/Story.html.twig
prod/WorkZone/Macros.html.twig
prod/WorkZone/Basket.html.twig
@@ -11687,17 +11827,17 @@
reponses:: images par pages :
Suchergebnisse nach Seite
- web/prod/index.html.twig
+ web/prod/index.html.twig
reponses:: mode liste
Liste
- web/prod/index.html.twig
+ web/prod/index.html.twig
reponses:: mode vignettes
Miniaturansichten
- web/prod/index.html.twig
+ web/prod/index.html.twig
reponses:: partager
@@ -11719,16 +11859,16 @@
reponses:: taille des images :
Miniaturansichtengrösse
- web/prod/index.html.twig
+ web/prod/index.html.twig
reponses::document sans titre
ohne Titel
classes/record/adapter.php
-
+
report:: 1 - Periode
- Zeit
+ Zeit
web/report/form_date_and_base.html.twig
@@ -11741,9 +11881,9 @@
Kollektionen
web/report/form_date_and_base.html.twig
-
+
report:: 3 - Type de report
- Bericht Typ
+ Bericht Typ
web/report/report_layout_child.html.twig
web/report/report_layout_child.html.twig
@@ -11771,12 +11911,12 @@
report:: Detail des connexions
- Verbindungsdetails
+ Verbindungs-Detail
module/report/activity.php
report:: Detail des telechargements
- Downloaddetails
+ Download Detail
module/report/activity.php
@@ -11860,7 +12000,7 @@
report:: document ajoute
- hinzugefügte Dokumente
+ Hinzugefügte Dokumente
module/report/add.php
@@ -11937,7 +12077,7 @@
report:: pays
- Staat
+ Land
classes/module/report.php
@@ -12011,7 +12151,7 @@
report:: type
- Bildschirmtyp
+ Typ
classes/module/report.php
@@ -12026,7 +12166,7 @@
report:: validated documents
- Bestätigte Dokumente
+ Validierte Dokumente
module/report/validate.php
@@ -12048,7 +12188,7 @@
report::Demande de validation vers %n_user% utilisateurs depuis lapplication box %appbox%
- Validierung Abfrage zu %n_user% Benutzer ab ApplicationBox %appbox%
+ Feedback Abfrage zu %n_user% Benutzer ab ApplicationBox %appbox%
prod/preview/short_history.html.twig
@@ -12173,20 +12313,20 @@
90° im Uhrzeigersinn drehen
actions/Tools/index.html.twig
-
+
same UUID
- same UUID
- Border/Checker/UUID.php
+ dieselbe UUID
+ Border/Checker/UUID.php
-
+
same checksum
- same checksum
- Border/Checker/Sha256.php
+ gleiche Prüfsumme
+ Border/Checker/Sha256.php
-
+
same filename
- same filename
- Border/Checker/Filename.php
+ gleiche Dateiname
+ Border/Checker/Filename.php
scheduled status
@@ -12200,7 +12340,7 @@
select at least one user
- Einen user auswählen
+ Einen Benutzer auswählen
web/admin/users.html.twig
@@ -12220,7 +12360,7 @@
setup:: Reinitialisation des droits admins
- die Rechte von Administratoren zurücksetzen
+ Administratoren Rechte zurücksetzen
web/admin/dashboard.html.twig
@@ -12400,9 +12540,9 @@
Archivierung zur Datenbank/Kollektion
task-manager/task-editor/archive.html.twig
-
+
task::archive:copier les fichiers '.phrasea.xml' et '.grouping.xml' dans _archived
- Copy '.phrasea.xml' and 'groupin.xml' files to _archive
+ Copy '.phrasea.xml' and 'groupin.xml' files to _archive
task-manager/task-editor/archive.html.twig
@@ -12726,7 +12866,7 @@
thesaurus:: est candidat en provenance des champs mais ne peut etre accepte a cet emplacement du thesaurus
- ist ein möglicher Begriff aus Felder Ursprung aber kann nicht in diesem Ort des Thesaurus akzeptiert werden
+ ist ein möglicher Begriff aus Felder Ursprung, aber kann an dieser Stelle im Thesaurus nicht akzeptiert werden
web/thesaurus/new-term.html.twig
@@ -12909,7 +13049,7 @@
thesaurus:: recherche fulltext
- volltext
+ volltext Suche
web/thesaurus/export-topics-dialog.html.twig
@@ -12930,7 +13070,7 @@
thesaurus:: reindexer la base apres l'import
- wieder indexieren nach dem Import
+ nach dem Import wieder indexieren
web/thesaurus/import-dialog.html.twig
@@ -13067,7 +13207,7 @@
thumbnail validation
Miniaturansicht Bestätigung
- actions/Tools/videoEditor.html.twig
+ actions/Tools/videoEditor.html.twig
actions/Tools/index.html.twig
@@ -13100,10 +13240,10 @@
Ihre Version ist aktuell
web/admin/databases.html.twig
-
+
updated_on
- updated_on
- web/prod/index.html.twig
+ aktualisiert am
+ web/prod/index.html.twig
upload:: Destination (collection) :
@@ -13116,7 +13256,7 @@
Status
prod/upload/upload.html.twig
prod/upload/upload-flash.html.twig
- prod/upload/lazaret.html.twig
+ prod/upload/lazaret.html.twig
users rights have been reseted
@@ -13126,7 +13266,7 @@
validate
bestätigen
- actions/Tools/videoEditor.html.twig
+ actions/Tools/videoEditor.html.twig
actions/Tools/index.html.twig
actions/Tools/index.html.twig
actions/Tools/index.html.twig
@@ -13135,24 +13275,24 @@
validation:: NON
Nein
- mobile/lightbox/basket_element.html.twig
+ mobile/lightbox/basket_element.html.twig
web/lightbox/agreement_box.html.twig
validation:: OUI
Ja
- mobile/lightbox/basket_element.html.twig
+ mobile/lightbox/basket_element.html.twig
web/lightbox/agreement_box.html.twig
validation:: editer ma note
mein Kommentar verändern
- mobile/lightbox/basket_element.html.twig
+ mobile/lightbox/basket_element.html.twig
validation:: note
Kommentare
- mobile/lightbox/sc_note.html.twig
+ mobile/lightbox/sc_note.html.twig
validation:: votre note
@@ -13162,8 +13302,8 @@
validation::envoyer mon rapport
Meinen Bericht senden
- mobile/lightbox/validate.html.twig
- mobile/lightbox/validate.html.twig
+ mobile/lightbox/validate.html.twig
+ mobile/lightbox/validate.html.twig
web/lightbox/basket_options.html.twig
web/lightbox/basket_options.html.twig
@@ -13183,9 +13323,9 @@
web/admin/subdefs.html.twig
task-manager/task-editor/subdefs.html.twig
-
+
video range extractor
- video range extractor
+ Kapitelunterteilung
actions/Tools/videoEditor.html.twig
diff --git a/resources/locales/messages.en.xlf b/resources/locales/messages.en.xlf
index 2bdfd5b0cd..014648af36 100644
--- a/resources/locales/messages.en.xlf
+++ b/resources/locales/messages.en.xlf
@@ -1,14 +1,14 @@
-
+
-
+