diff --git a/bower.json b/bower.json
index 57e618c2d9..a12a7cfaf9 100644
--- a/bower.json
+++ b/bower.json
@@ -28,7 +28,8 @@
"autobahn": "http://autobahn.s3.amazonaws.com/js/autobahn.min.js",
"when": "~2.7.0",
"web-socket-js": "~1.0.1",
- "jquery.treeview": "1.4.1"
+ "jquery.treeview": "1.4.1",
+ "joyride": "https://github.com/zurb/joyride/archive/v2.0.0.zip"
},
"devDependencies": {
"mocha": "latest",
diff --git a/composer.json b/composer.json
index 2f0cd873d3..f85123d735 100644
--- a/composer.json
+++ b/composer.json
@@ -39,7 +39,7 @@
"gedmo/doctrine-extensions" : "~2.3.0",
"alchemy/google-plus-api-client" : "~0.6.2",
"alchemy/geonames-api-consumer" : "~0.1.0",
- "goodby/csv" : "~1.0",
+ "goodby/csv" : "dev-master",
"guzzle/guzzle" : "~3.0",
"imagine/imagine" : "dev-alchemy-0.6.2 as 0.6.2",
"igorw/get-in" : "~1.0",
diff --git a/composer.lock b/composer.lock
index d6a34f4506..e36ac8637b 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1435,16 +1435,16 @@
},
{
"name": "goodby/csv",
- "version": "1.2.0",
+ "version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/goodby/csv.git",
- "reference": "66c376b3bd51bc90fd680bfdf3708c9a22b9d081"
+ "reference": "b289ca3e3f6ad3c76b7d8c3bef3effd0232ca13a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/goodby/csv/zipball/66c376b3bd51bc90fd680bfdf3708c9a22b9d081",
- "reference": "66c376b3bd51bc90fd680bfdf3708c9a22b9d081",
+ "url": "https://api.github.com/repos/goodby/csv/zipball/b289ca3e3f6ad3c76b7d8c3bef3effd0232ca13a",
+ "reference": "b289ca3e3f6ad3c76b7d8c3bef3effd0232ca13a",
"shasum": ""
},
"require": {
@@ -1488,7 +1488,7 @@
"export",
"import"
],
- "time": "2015-01-14 03:58:50"
+ "time": "2015-02-02 12:29:23"
},
{
"name": "guzzle/guzzle",
@@ -5022,6 +5022,7 @@
],
"minimum-stability": "stable",
"stability-flags": {
+ "goodby/csv": 20,
"alchemy/task-manager": 20,
"alchemy/zippy": 20,
"imagine/imagine": 20,
diff --git a/lib/Alchemy/Phrasea/Application/Api.php b/lib/Alchemy/Phrasea/Application/Api.php
index 4d0102d82b..ee6dedb33f 100644
--- a/lib/Alchemy/Phrasea/Application/Api.php
+++ b/lib/Alchemy/Phrasea/Application/Api.php
@@ -54,7 +54,7 @@ return call_user_func(function ($environment = PhraseaApplication::ENV_PROD) {
$priorities = array('application/json', 'application/yaml', 'text/yaml', 'text/javascript', 'application/javascript');
foreach (V1::$extendedContentTypes['json'] as $priorities[]);
foreach (V1::$extendedContentTypes['yaml'] as $priorities[]);
- $format = $app['format.negociator']->getBest($request->headers->get('accept') ,$priorities);
+ $format = $app['format.negociator']->getBest($request->headers->get('accept', 'application/json') ,$priorities);
// throw unacceptable http error if API can not handle asked format
if (null === $format) {
diff --git a/lib/Alchemy/Phrasea/Command/BuildSubdefs.php b/lib/Alchemy/Phrasea/Command/BuildSubdefs.php
index bcf1abdb82..bc8bc777df 100644
--- a/lib/Alchemy/Phrasea/Command/BuildSubdefs.php
+++ b/lib/Alchemy/Phrasea/Command/BuildSubdefs.php
@@ -11,6 +11,7 @@
namespace Alchemy\Phrasea\Command;
+use Alchemy\Phrasea\Exception\InvalidArgumentException;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\SQLParserUtils;
use Symfony\Component\Console\Input\InputArgument;
@@ -33,6 +34,8 @@ class BuildSubdefs extends Command
$this->addArgument('subdefs', InputArgument::REQUIRED, 'Names of sub-definition to re-build');
$this->addOption('max_record', 'max', InputOption::VALUE_OPTIONAL, 'Max record id');
$this->addOption('min_record', 'min', InputOption::VALUE_OPTIONAL, 'Min record id');
+ $this->addOption('with-substitution', 'wsubstit', InputOption::VALUE_NONE, 'Regenerate subdefs for substituted records as well');
+ $this->addOption('substitution-only', 'substito', InputOption::VALUE_NONE, 'Regenerate subdefs for substituted records only');
return $this;
}
@@ -82,6 +85,7 @@ class BuildSubdefs extends Command
$params[] = (int) $min;
$types[] = \PDO::PARAM_INT;
}
+
if (null !== $max = $input->getOption('max_record')) {
$sqlCount .= " AND (r.record_id <= ?)";
@@ -89,16 +93,28 @@ class BuildSubdefs extends Command
$types[] = \PDO::PARAM_INT;
}
+ $substitutionOnly = $input->getOption('substitution-only');
+ $withSubstitution = $input->getOption('with-substitution');
+
+ if (false === $withSubstitution) {
+ if (true === $substitutionOnly) {
+ $sqlCount .= " AND (s.substit = 1)";
+ } else {
+ $sqlCount .= " AND (s.substit = 0)";
+ }
+ } elseif ($substitutionOnly) {
+ throw new InvalidArgumentException('Conflict, you can not ask for --substituion-only && --with-substitution parameters at the same time');
+ }
+
list($sqlCount, $stmtParams) = SQLParserUtils::expandListParameters($sqlCount, $params, $types);
- $totalRecords = 0;
- foreach ($this->container['phraseanet.appbox']->get_databoxes() as $databox) {
- $connection = $databox->get_connection();
- $stmt = $connection->prepare($sqlCount);
- $stmt->execute($stmtParams);
- $row = $stmt->fetch();
- $totalRecords += $row['nb_records'];
- }
+ $databox = $this->container['phraseanet.appbox']->get_databox($input->getArgument('databox'));
+
+ $connection = $databox->get_connection();
+ $stmt = $connection->prepare($sqlCount);
+ $stmt->execute($stmtParams);
+ $row = $stmt->fetch();
+ $totalRecords = $row['nb_records'];
if ($totalRecords === 0) {
return;
@@ -110,8 +126,6 @@ class BuildSubdefs extends Command
$progress->display();
- $databox = $this->container['phraseanet.appbox']->get_databox($input->getArgument('databox'));
-
$sql = "
SELECT DISTINCT(r.record_id)
FROM record r
@@ -137,6 +151,14 @@ class BuildSubdefs extends Command
$types[] = \PDO::PARAM_INT;
}
+ if (false === $withSubstitution) {
+ if (true === $substitutionOnly) {
+ $sql .= " AND (s.substit = 1)";
+ } else {
+ $sql .= " AND (s.substit = 0)";
+ }
+ }
+
list($sql, $stmtParams) = SQLParserUtils::expandListParameters($sql, $params, $types);
$connection = $databox->get_connection();
@@ -155,6 +177,9 @@ class BuildSubdefs extends Command
foreach ($subdefs as $subdef) {
$subdef->remove_file();
+ if (($withSubstitution && $subdef->is_substituted()) || $substitutionOnly) {
+ $subdef->set_substituted(false);
+ }
}
$record->generate_subdefs($databox, $this->container, $subdefsName);
diff --git a/lib/Alchemy/Phrasea/Controller/Api/V1.php b/lib/Alchemy/Phrasea/Controller/Api/V1.php
index 3aa18f42ac..bcaf3a9154 100644
--- a/lib/Alchemy/Phrasea/Controller/Api/V1.php
+++ b/lib/Alchemy/Phrasea/Controller/Api/V1.php
@@ -1326,19 +1326,6 @@ class V1 implements ControllerProviderInterface
}
}
- if($media->get_name() != 'document') {
- $databox = $record->get_databox();
- try {
- $subDefDefinition = $databox->get_subdef_structure()->get_subdef($record->get_type(), $media->get_name());
- } catch (\Exception_Databox_SubdefNotFound $e) {
- return null;
- }
- }
-
- if ($media->get_name() != 'document' && false === $subDefDefinition->is_downloadable()) {
- return null;
- }
-
if ($media->get_permalink() instanceof \media_Permalink_Adapter) {
$permalink = $this->list_permalink($media->get_permalink());
} else {
diff --git a/lib/Alchemy/Phrasea/Controller/Client/Root.php b/lib/Alchemy/Phrasea/Controller/Client/Root.php
index 039da3711b..be2c4fd72b 100644
--- a/lib/Alchemy/Phrasea/Controller/Client/Root.php
+++ b/lib/Alchemy/Phrasea/Controller/Client/Root.php
@@ -30,16 +30,6 @@ class Root implements ControllerProviderInterface
$controllers = $app['controllers_factory'];
$controllers->before(function (Request $request) use ($app) {
- /**
- * /!\/!\/!\/!\/!\/!\/!\/!\/!\
- *
- * Client is not longer used
- *
- * Redirect to production with a nice message
- */
- $app['session']->getFlashBag()->add('client_deprecated', '');
-
- return $app->redirectPath('prod');
if (!$app['authentication']->isAuthenticated() && null !== $request->query->get('nolog')) {
return $app->redirectPath('login_authenticate_as_guest', ['redirect' => 'client']);
@@ -244,6 +234,8 @@ class Root implements ControllerProviderInterface
*/
public function getClient(Application $app, Request $request)
{
+ $app['session']->getFlashBag()->add('step_by_step', '');
+
try {
\Session_Logger::updateClientInfos($app, 2);
} catch (SessionNotFound $e) {
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Lazaret.php b/lib/Alchemy/Phrasea/Controller/Prod/Lazaret.php
index aa69e478db..25d3e28d51 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/Lazaret.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/Lazaret.php
@@ -319,15 +319,50 @@ class Lazaret implements ControllerProviderInterface
*/
public function emptyLazaret(Application $app, Request $request)
{
- $ret = ['success' => false, 'message' => '', 'result' => []];
+ $ret = array(
+ 'success' => false,
+ 'message' => '',
+ 'result' => array(
+ 'tobedone' => 0,
+ 'done' => 0,
+ 'todo' => 0,
+ 'max' => '',
+ )
+ );
+
+ $maxTodo = -1; // all
+ if($request->get('max') !== null) {
+ $maxTodo = (int)($request->get('max'));
+ $ret['result']['max'] = $maxTodo;
+ if( $maxTodo <= 0) {
+ $maxTodo = -1; // all
+ }
+ }
+ $ret['result']['max'] = $maxTodo;
+
+ $repo = $app['orm.em']->getRepository('Entities\LazaretFile');
+
+ $ret['result']['tobedone'] = $repo->createQueryBuilder('id')
+ ->select('COUNT(id)')
+ ->getQuery()
+ ->getSingleScalarResult();
+
+ if($maxTodo == -1) {
+ // all
+ $lazaretFiles = $repo->findAll();
+ }
+ else {
+ // limit maxTodo
+ $lazaretFiles = $repo->findBy(array(), null, $maxTodo);
+ }
- $lazaretFiles = $app['repo.lazaret-files']->findAll();
$app['orm.em']->beginTransaction();
try {
foreach ($lazaretFiles as $lazaretFile) {
$this->denyLazaretFile($app, $lazaretFile);
+ $ret['result']['done']++;
}
$app['orm.em']->commit();
$ret['success'] = true;
@@ -335,6 +370,7 @@ class Lazaret implements ControllerProviderInterface
$app['orm.em']->rollback();
$ret['message'] = $app->trans('An error occured');
}
+ $ret['result']['todo'] = $ret['result']['tobedone'] - $ret['result']['done'];
return $app->json($ret);
}
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Tools.php b/lib/Alchemy/Phrasea/Controller/Prod/Tools.php
index 1fc478e435..798bac6df2 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/Tools.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/Tools.php
@@ -96,6 +96,11 @@ class Tools implements ControllerProviderInterface
foreach ($record->get_subdefs() as $subdef) {
if ($subdef->is_substituted()) {
$substituted = true;
+
+ if ($force) {
+ // unset flag
+ $subdef->set_substituted(false);
+ }
break;
}
}
diff --git a/lib/Alchemy/Phrasea/SearchEngine/Phrasea/PhraseaEngineQueryParser.php b/lib/Alchemy/Phrasea/SearchEngine/Phrasea/PhraseaEngineQueryParser.php
index 832622b505..98d6c176b7 100644
--- a/lib/Alchemy/Phrasea/SearchEngine/Phrasea/PhraseaEngineQueryParser.php
+++ b/lib/Alchemy/Phrasea/SearchEngine/Phrasea/PhraseaEngineQueryParser.php
@@ -729,8 +729,11 @@ class PhraseaEngineQueryParser
$prophtml = "";
$this->propAsHTML($domthe->documentElement, $prophtml, $path);
$this->proposals["BASES"]["b$bid"]["TERMS"][$path]["HTML"] = $prophtml;
+ } else {
+ $tree = NULL;
}
+
return($ambigus);
}
@@ -1767,7 +1770,7 @@ class PhraseaEngineQueryParser
$c_utf8 = "";
for ($i = 0; $i < $l; $i++) {
if (!$this->app['unicode']->has_indexer_bad_char(($c_utf8 = mb_substr($this->phq, $i, 1, 'UTF-8')))) {
- $t .= $this->app['unicode']->remove_diacritics(mb_strtolower($c_utf8));
+ $t .= mb_strtolower($c_utf8);
} else
break;
}
diff --git a/lib/classes/base.php b/lib/classes/base.php
index ca4ffa23ce..451b3e4502 100644
--- a/lib/classes/base.php
+++ b/lib/classes/base.php
@@ -810,6 +810,9 @@ abstract class base implements cache_cacheableInterface
$success = true;
+ // disable mail
+ $app['swiftmailer.transport'] = null;
+
foreach ($list_patches as $patch) {
// Gets doctrine migrations required for current patch
foreach ($patch->getDoctrineMigrations() as $doctrineVersion) {
diff --git a/lib/classes/p4field.php b/lib/classes/p4field.php
index fc9d9176f2..f3a65d5bf1 100644
--- a/lib/classes/p4field.php
+++ b/lib/classes/p4field.php
@@ -23,6 +23,6 @@ class p4field
{
$v = mb_strtolower(trim($v));
- return($v == '0' || $v == 'n' || $v == 'no' || $v == 'non' || $v = 'off' || $v == 'false');
+ return($v == '0' || $v == 'n' || $v == 'no' || $v == 'non' || $v == 'off' || $v == 'false');
}
}
diff --git a/lib/classes/record/adapter.php b/lib/classes/record/adapter.php
index 92350ed7b5..f5a3999d9e 100644
--- a/lib/classes/record/adapter.php
+++ b/lib/classes/record/adapter.php
@@ -984,14 +984,10 @@ class record_adapter implements record_Interface, cache_cacheableInterface
return $this->get_databox()->get_sbas_id();
}
- public function substitute_subdef($name, MediaInterface $media, Application $app)
+ public function substitute_subdef($name, MediaInterface $media, Application $app, $adapt=true)
{
$newfilename = $this->record_id . '_0_' . $name . '.' . $media->getFile()->getExtension();
- $base_url = '';
-
- $subdef_def = false;
-
if ($name == 'document') {
$baseprefs = $this->get_databox()->get_sxml_structure();
@@ -1021,24 +1017,30 @@ class record_adapter implements record_Interface, cache_cacheableInterface
$path_file_dest = $path . $newfilename;
}
- try {
- $app['media-alchemyst']->turnInto(
- $media->getFile()->getRealPath(),
- $path_file_dest,
- $subdef_def->getSpecs()
- );
- } catch (\MediaAlchemyst\Exception\ExceptionInterface $e) {
- return $this;
- }
+ if($adapt) {
+ try {
+ $app['media-alchemyst']->turnInto(
+ $media->getFile()->getRealPath(),
+ $path_file_dest,
+ $subdef_def->getSpecs()
+ );
+ } catch (\MediaAlchemyst\Exception\ExceptionInterface $e) {
+ return $this;
+ }
- $subdefFile = $path_file_dest;
+ $subdefFile = $path_file_dest;
+ }
+ else{
+ $app['filesystem']->copy($media->getFile()->getRealPath(), $path_file_dest);
+
+ $subdefFile = $path_file_dest;
+ }
$meta_writable = $subdef_def->meta_writeable();
}
$app['filesystem']->chmod($subdefFile, 0760);
$media = $app['mediavorus']->guess($subdefFile);
-
$subdef = media_subdef::create($app, $this, $name, $media);
$subdef->set_substituted(true);
@@ -1048,7 +1050,7 @@ class record_adapter implements record_Interface, cache_cacheableInterface
$this->write_metas();
}
- if ($name == 'document') {
+ if ($name == 'document' && $adapt) {
$this->rebuild_subdefs();
}
diff --git a/lib/conf.d/data_templates/DublinCore.xml b/lib/conf.d/data_templates/DublinCore.xml
new file mode 100644
index 0000000000..5de4f32945
--- /dev/null
+++ b/lib/conf.d/data_templates/DublinCore.xml
@@ -0,0 +1,221 @@
+
+
+ {{ "Pour des raisons techniques cette interface n'est plus maintenue et serta bientôt rendue + inacessible. Nous vous invitons si vous le souhaitez à utiliser production dés maintenant."|trans }} +
+