diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000000..a37aa2475b
--- /dev/null
+++ b/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,16 @@
+## Changelog
+### Changed
+ - Breaking change
+
+### Fixes
+ - PHRAS-XXX: Short description of bug and fix
+ - Short description of bug and fix without issue/ticket
+
+### Adds
+ - PHRAS-XXX: Short feature description
+ - Short feature description without issue/ticket
+
+### Removes
+ - PHRAS-XXX: Short feature removal description
+ - Short feature removal description without issue/ticket
+
diff --git a/composer.json b/composer.json
index efc06b5678..5b8441ae34 100644
--- a/composer.json
+++ b/composer.json
@@ -47,6 +47,7 @@
"dailymotion/sdk": "~1.5",
"data-uri/data-uri": "~0.1.0",
"dflydev/doctrine-orm-service-provider": "~1.0",
+ "doctrine/cache": "^1.6",
"doctrine/dbal": "^2.4.0",
"doctrine/migrations": "^1.0.0",
"doctrine/orm": "^2.4.0",
@@ -61,7 +62,7 @@
"hoa/dispatcher": "~0.0",
"hoa/router": "~2.0",
"igorw/get-in": "~1.0",
- "imagine/imagine": "dev-alchemy-0.6.2 as 0.6.2",
+ "imagine/imagine": "0.6.x-dev",
"ircmaxell/random-lib": "~1.0",
"jms/serializer": "~0.10",
"jms/translation-bundle": "dev-rebase-2015-10-20",
@@ -88,7 +89,7 @@
"simple-bus/jms-serializer-bridge": "^1.0",
"simple-bus/message-bus": "^2.1",
"simple-bus/serialization": "^2.0",
- "sorien/silex-dbal-profiler": "~1.0.0",
+ "sorien/silex-dbal-profiler": "^1.1",
"sorien/silex-pimple-dumper": "^1.0",
"swiftmailer/swiftmailer": "~5.3.0",
"symfony/symfony": "~2.7.10|~2.8.3",
diff --git a/composer.lock b/composer.lock
index 26aafbbcb3..6f103ba897 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,8 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "baf4148980adfb15bed6b72c438da7eb",
- "content-hash": "5d8ffafd15285984d97c82a1e13a697f",
+ "hash": "8db2333764b17b4b04f474a6b9fc2c49",
+ "content-hash": "2961cef34c7a94f9afb11b859781cb65",
"packages": [
{
"name": "alchemy-fr/tcpdf-clone",
@@ -1137,33 +1137,33 @@
},
{
"name": "doctrine/cache",
- "version": "v1.5.1",
+ "version": "v1.6.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/cache.git",
- "reference": "2b9cec5a5e722010cbebc91713d4c11eaa064d5e"
+ "reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/cache/zipball/2b9cec5a5e722010cbebc91713d4c11eaa064d5e",
- "reference": "2b9cec5a5e722010cbebc91713d4c11eaa064d5e",
+ "url": "https://api.github.com/repos/doctrine/cache/zipball/f8af318d14bdb0eff0336795b428b547bd39ccb6",
+ "reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6",
"shasum": ""
},
"require": {
- "php": ">=5.3.2"
+ "php": "~5.5|~7.0"
},
"conflict": {
"doctrine/common": ">2.2,<2.4"
},
"require-dev": {
- "phpunit/phpunit": ">=3.7",
+ "phpunit/phpunit": "~4.8|~5.0",
"predis/predis": "~1.0",
"satooshi/php-coveralls": "~0.6"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.5.x-dev"
+ "dev-master": "1.6.x-dev"
}
},
"autoload": {
@@ -1203,7 +1203,7 @@
"cache",
"caching"
],
- "time": "2015-11-02 18:35:48"
+ "time": "2015-12-31 16:37:02"
},
{
"name": "doctrine/collections",
@@ -2930,7 +2930,7 @@
},
{
"name": "imagine/imagine",
- "version": "dev-alchemy-0.6.2",
+ "version": "0.6.x-dev",
"source": {
"type": "git",
"url": "https://github.com/alchemy-fr/Imagine.git",
@@ -4744,7 +4744,7 @@
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/dcdeb1d923b981a55f0a4ce6c2ceac14cb8476f8",
+ "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/438196c8f66647073bcaf99908b543bda7ffd6d4",
"reference": "c18abc6df90257ddbbe2654a98cc5cc7be804411",
"shasum": ""
},
@@ -5221,22 +5221,28 @@
},
{
"name": "sorien/silex-dbal-profiler",
- "version": "1.0.0",
+ "version": "1.1.2",
"source": {
"type": "git",
"url": "https://github.com/Sorien/silex-dbal-profiler.git",
- "reference": "8cbbef7a8fae53381d9005163070485471089908"
+ "reference": "4d3f642144e96685270f7ffb1648a081d0c5eb7e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Sorien/silex-dbal-profiler/zipball/8cbbef7a8fae53381d9005163070485471089908",
- "reference": "8cbbef7a8fae53381d9005163070485471089908",
+ "url": "https://api.github.com/repos/Sorien/silex-dbal-profiler/zipball/4d3f642144e96685270f7ffb1648a081d0c5eb7e",
+ "reference": "4d3f642144e96685270f7ffb1648a081d0c5eb7e",
"shasum": ""
},
- "require-dev": {
- "silex/silex": "~1.0"
+ "require": {
+ "silex/silex": "~1.0",
+ "silex/web-profiler": "~1.0"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1.x-dev"
+ }
+ },
"autoload": {
"psr-0": {
"Sorien": "src"
@@ -5259,7 +5265,7 @@
"profiler",
"silex"
],
- "time": "2014-02-26 10:01:20"
+ "time": "2015-03-12 09:26:42"
},
{
"name": "sorien/silex-pimple-dumper",
@@ -7389,14 +7395,7 @@
"time": "2015-06-21 13:59:46"
}
],
- "aliases": [
- {
- "alias": "0.6.2",
- "alias_normalized": "0.6.2.0",
- "version": "dev-alchemy-0.6.2",
- "package": "imagine/imagine"
- }
- ],
+ "aliases": [],
"minimum-stability": "stable",
"stability-flags": {
"alchemy/task-manager": 20,
diff --git a/lib/Alchemy/Phrasea/Application.php b/lib/Alchemy/Phrasea/Application.php
index a4fc9e03df..2214926e63 100644
--- a/lib/Alchemy/Phrasea/Application.php
+++ b/lib/Alchemy/Phrasea/Application.php
@@ -73,6 +73,7 @@ use Alchemy\Phrasea\Core\Provider\UnicodeServiceProvider;
use Alchemy\Phrasea\Core\Provider\WebhookServiceProvider;
use Alchemy\Phrasea\Core\Provider\ZippyServiceProvider;
use Alchemy\Phrasea\Core\Provider\WebProfilerServiceProvider as PhraseaWebProfilerServiceProvider;
+use Alchemy\Phrasea\Databox\Subdef\MediaSubdefServiceProvider;
use Alchemy\Phrasea\Exception\InvalidArgumentException;
use Alchemy\Phrasea\Filesystem\FilesystemServiceProvider;
use Alchemy\Phrasea\Filesystem\ApplicationPathServiceGenerator;
@@ -80,6 +81,7 @@ use Alchemy\Phrasea\Form\Extension\HelpTypeExtension;
use Alchemy\Phrasea\Media\DatafilesResolver;
use Alchemy\Phrasea\Media\MediaAccessorResolver;
use Alchemy\Phrasea\Media\PermalinkMediaResolver;
+use Alchemy\Phrasea\Media\TechnicalDataServiceProvider;
use Alchemy\Phrasea\Model\Entities\User;
use Doctrine\DBAL\Event\ConnectionEventArgs;
use MediaVorus\Media\MediaInterface;
@@ -190,6 +192,8 @@ class Application extends SilexApplication
$this->register(new NotificationDelivererServiceProvider());
$this->register(new RepositoriesServiceProvider());
$this->register(new ManipulatorServiceProvider());
+ $this->register(new TechnicalDataServiceProvider());
+ $this->register(new MediaSubdefServiceProvider());
$this->register(new InstallerServiceProvider());
$this->register(new PhraseaVersionServiceProvider());
diff --git a/lib/Alchemy/Phrasea/Border/Attribute/Story.php b/lib/Alchemy/Phrasea/Border/Attribute/Story.php
index b694839e41..6b8e7eabcf 100644
--- a/lib/Alchemy/Phrasea/Border/Attribute/Story.php
+++ b/lib/Alchemy/Phrasea/Border/Attribute/Story.php
@@ -69,7 +69,7 @@ class Story implements AttributeInterface
*/
public function asString()
{
- return $this->story->get_serialize_key();
+ return $this->story->getId();
}
/**
diff --git a/lib/Alchemy/Phrasea/Border/Manager.php b/lib/Alchemy/Phrasea/Border/Manager.php
index 295d46db87..d8abc9ac99 100644
--- a/lib/Alchemy/Phrasea/Border/Manager.php
+++ b/lib/Alchemy/Phrasea/Border/Manager.php
@@ -278,7 +278,7 @@ class Manager
$file->addAttribute(
new MetadataAttr(
new Metadata(
- new TfRecordid(), new MonoValue($element->get_record_id())
+ new TfRecordid(), new MonoValue($element->getRecordId())
)
)
);
@@ -314,7 +314,7 @@ class Manager
break;
case AttributeInterface::NAME_STATUS:
/** @var StatusAttr $attribute */
- $element->set_binary_status(decbin(bindec($element->get_status()) | bindec($attribute->getValue())));
+ $element->setStatus(decbin(bindec($element->getStatus()) | bindec($attribute->getValue())));
break;
case AttributeInterface::NAME_STORY:
diff --git a/lib/Alchemy/Phrasea/Cache/MultiAdapter.php b/lib/Alchemy/Phrasea/Cache/MultiAdapter.php
new file mode 100644
index 0000000000..d9133275a3
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Cache/MultiAdapter.php
@@ -0,0 +1,88 @@
+cache = $cache;
+ }
+
+ public function fetch($id)
+ {
+ return $this->cache->fetch($id);
+ }
+
+ public function contains($id)
+ {
+ return $this->cache->contains($id);
+ }
+
+ public function save($id, $data, $lifeTime = 0)
+ {
+ return $this->cache->save($id, $data, $lifeTime);
+ }
+
+ public function delete($id)
+ {
+ return $this->cache->delete($id);
+ }
+
+ public function getStats()
+ {
+ return $this->cache->getStats();
+ }
+
+ public function fetchMultiple(array $keys)
+ {
+ if ($this->cache instanceof MultiGetCache) {
+ return $this->cache->fetchMultiple($keys);
+ }
+
+ // Pass data by reference to avoid copies of whole array on key add.
+ $data = array_reduce($keys, function (array &$data, $key) {
+ $value = $this->fetch($key);
+
+ if (false !== $value || true === $this->contains($key)) {
+ $data[$key] = $value;
+ }
+
+ return $data;
+ }, []);
+
+ return $data;
+ }
+
+ public function saveMultiple(array $keysAndValues, $lifetime = 0)
+ {
+ if ($this->cache instanceof MultiPutCache) {
+ return $this->cache->saveMultiple($keysAndValues, $lifetime);
+ }
+
+ foreach ($keysAndValues as $key => $value) {
+ if (!$this->cache->save($key, $value, $lifetime)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Collection/CollectionHelper.php b/lib/Alchemy/Phrasea/Collection/CollectionHelper.php
index a56df2e356..4725938d7f 100644
--- a/lib/Alchemy/Phrasea/Collection/CollectionHelper.php
+++ b/lib/Alchemy/Phrasea/Collection/CollectionHelper.php
@@ -12,12 +12,8 @@ namespace Alchemy\Phrasea\Collection;
use Assert\Assertion;
-class CollectionHelper
+final class CollectionHelper
{
- private function __construct()
- {
- }
-
/**
* @param \collection[] $collections
* @return \collection[]
@@ -31,7 +27,11 @@ class CollectionHelper
}
usort($collections, function (\collection $left, \collection $right) {
- return ($left->get_ord() < $right->get_ord()) ? -1 : (($left->get_ord() < $right->get_ord()) ? 1 : 0);
+ if ($left->get_ord() === $right->get_ord()) {
+ return 0;
+ }
+
+ return $left->get_ord() < $right->get_ord() ? -1 : 1;
});
return $collections;
diff --git a/lib/Alchemy/Phrasea/Command/BuildSubdefs.php b/lib/Alchemy/Phrasea/Command/BuildSubdefs.php
index 55446b7de0..b927744c2c 100644
--- a/lib/Alchemy/Phrasea/Command/BuildSubdefs.php
+++ b/lib/Alchemy/Phrasea/Command/BuildSubdefs.php
@@ -179,13 +179,14 @@ class BuildSubdefs extends Command
if($this->databox !== null) {
- foreach ($this->databox->get_subdef_structure() as $sgname=>$sg) {
- if (empty($types) || in_array($sgname, $types)) {
- $this->subdefsNameByType[$sgname] = [];
+ /** @var SubdefGroup $sg */
+ foreach ($this->databox->get_subdef_structure() as $sg) {
+ if (empty($types) || in_array($sg->getName(), $types)) {
+ $this->subdefsNameByType[$sg->getName()] = [];
/** @var databox_subdef $sd */
foreach ($sg as $sd) {
if (empty($names) || in_array($sd->get_name(), $names)) {
- $this->subdefsNameByType[$sgname][] = $sd->get_name();
+ $this->subdefsNameByType[$sg->getName()][] = $sd->get_name();
}
}
}
diff --git a/lib/Alchemy/Phrasea/Command/RecordAdd.php b/lib/Alchemy/Phrasea/Command/RecordAdd.php
index e40514ac4c..47192053af 100644
--- a/lib/Alchemy/Phrasea/Command/RecordAdd.php
+++ b/lib/Alchemy/Phrasea/Command/RecordAdd.php
@@ -61,7 +61,7 @@ class RecordAdd extends Command
if (!$input->getOption('yes')) {
do {
$continue = strtolower($dialog->ask($output, sprintf("Will add record %s (%s) on collection %s\nContinue ? (y/N)", $file, $media->getType(), $collection->get_label($this->container['locale'])), 'N'));
- } while ( ! in_array($continue, ['y', 'n']));
+ } while (!in_array($continue, ['y', 'n']));
if (strtolower($continue) !== 'y') {
$output->writeln('Aborted !');
@@ -112,7 +112,10 @@ class RecordAdd extends Command
if ($elementCreated instanceof \record_adapter) {
$output->writeln(
sprintf(
- "Record id %d on collection `%s` (databox `%s`) has been created", $elementCreated->get_record_id(), $elementCreated->get_collection()->get_label($this->container['locale']), $elementCreated->get_databox()->get_label($this->container['locale'])
+ "Record id %d on collection `%s` (databox `%s`) has been created",
+ $elementCreated->getRecordId(),
+ $elementCreated->getCollection()->get_label($this->container['locale']),
+ $elementCreated->getDatabox()->get_label($this->container['locale'])
)
);
} elseif ($elementCreated instanceof LazaretFile) {
diff --git a/lib/Alchemy/Phrasea/Command/Upgrade/Step35.php b/lib/Alchemy/Phrasea/Command/Upgrade/Step35.php
index 911585335f..c9246cf319 100644
--- a/lib/Alchemy/Phrasea/Command/Upgrade/Step35.php
+++ b/lib/Alchemy/Phrasea/Command/Upgrade/Step35.php
@@ -80,13 +80,13 @@ class Step35 implements DatasUpgraderInterface
try {
$this->updateMetadatas($record, $row['xml']);
} catch (\Exception $e) {
- $this->app['monolog']->addError(sprintf("Error while upgrading metadatas for record %d on databox %d : %s", $record->get_record_id(), $record->get_sbas_id(), $e->getMessage()));
+ $this->app['monolog']->addError(sprintf("Error while upgrading metadatas for record %d on databox %d : %s", $record->getRecordId(), $record->getDataboxId(), $e->getMessage()));
}
try {
- $record->set_binary_status($row['status']);
+ $record->setStatus($row['status']);
} catch (\Exception $e) {
- $this->app['monolog']->addError(sprintf("Error while upgrading status for record %d on databox %d : %s", $record->get_record_id(), $record->get_sbas_id(), $e->getMessage()));
+ $this->app['monolog']->addError(sprintf("Error while upgrading status for record %d on databox %d : %s", $record->getRecordId(), $record->getDataboxId(), $e->getMessage()));
}
unset($record);
}
@@ -131,7 +131,7 @@ class Step35 implements DatasUpgraderInterface
*/
protected function updateMetadatas(\record_adapter $record, $xml)
{
- $metas = $record->get_databox()->get_meta_structure();
+ $metas = $record->getDatabox()->get_meta_structure();
$datas = $metadatas = [];
diff --git a/lib/Alchemy/Phrasea/Controller/AbstractDelivery.php b/lib/Alchemy/Phrasea/Controller/AbstractDelivery.php
index e550c21912..edce950bd1 100644
--- a/lib/Alchemy/Phrasea/Controller/AbstractDelivery.php
+++ b/lib/Alchemy/Phrasea/Controller/AbstractDelivery.php
@@ -62,7 +62,7 @@ abstract class AbstractDelivery
private function logView(\record_adapter $record, Request $request)
{
try {
- $logger = $this->getDataboxLogger($record->get_databox());
+ $logger = $this->getDataboxLogger($record->getDatabox());
$log_id = $logger->get_id();
$record->log_view(
$log_id,
diff --git a/lib/Alchemy/Phrasea/Controller/Admin/FieldsController.php b/lib/Alchemy/Phrasea/Controller/Admin/FieldsController.php
index 12e7703fbb..c13efa100d 100644
--- a/lib/Alchemy/Phrasea/Controller/Admin/FieldsController.php
+++ b/lib/Alchemy/Phrasea/Controller/Admin/FieldsController.php
@@ -12,8 +12,8 @@ namespace Alchemy\Phrasea\Controller\Admin;
use Alchemy\Phrasea\Controller\Controller;
use Alchemy\Phrasea\Metadata\TagProvider;
-use Alchemy\Phrasea\Vocabulary\Controller as VocabularyController;
use Alchemy\Phrasea\Vocabulary\ControlProvider\ControlProviderInterface;
+use Assert\Assertion;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
@@ -96,24 +96,57 @@ class FieldsController extends Controller
public function listVocabularies()
{
- $vocabularies = VocabularyController::getAvailable($this->app);
+ return $this->app->json(array_map(
+ [$this, 'getVocabularyAsArray'],
+ $this->fetchVocabularies()
+ ));
+ }
- return $this->app->json(array_map(function (ControlProviderInterface $vocabulary) {
- return [
- 'type' => $vocabulary->getType(),
- 'name' => $vocabulary->getName(),
- ];
- }, $vocabularies));
+ /**
+ * @return ControlProviderInterface[]
+ */
+ private function fetchVocabularies()
+ {
+ $vocabularies = $this->getVocabularies();
+
+ $instances = array_map(
+ function ($type) use ($vocabularies) {
+ return $vocabularies[$type];
+ },
+ $vocabularies->keys()
+ );
+
+ Assertion::allIsInstanceOf($instances, ControlProviderInterface::class);
+
+ return $instances;
+ }
+
+ /**
+ * @param string $type
+ * @return ControlProviderInterface
+ */
+ private function fetchVocabulary($type)
+ {
+ $vocabularies = $this->getVocabularies();
+
+ $vocabulary = $vocabularies[strtolower($type)];
+
+ Assertion::isInstanceOf($vocabulary, ControlProviderInterface::class);
+
+ return $vocabulary;
+ }
+
+ private function getVocabularyAsArray(ControlProviderInterface $vocabulary)
+ {
+ return [
+ 'type' => $vocabulary->getType(),
+ 'name' => $vocabulary->getName(),
+ ];
}
public function getVocabulary($type)
{
- $vocabulary = VocabularyController::get($this->app, $type);
-
- return $this->app->json([
- 'type' => $vocabulary->getType(),
- 'name' => $vocabulary->getName(),
- ]);
+ return $this->app->json($this->getVocabularyAsArray($this->fetchVocabulary($type)));
}
public function searchTag(Request $request)
@@ -293,11 +326,11 @@ class FieldsController extends Controller
}
try {
- $vocabulary = VocabularyController::get($this->app, $data['vocabulary-type']);
+ $vocabulary = $this->fetchVocabulary($data['vocabulary-type']);
$field->setVocabularyControl($vocabulary);
$field->setVocabularyRestricted($data['vocabulary-restricted']);
} catch (\InvalidArgumentException $e) {
-
+ // Invalid vocabulary requested
}
if ('' !== $dcesElement = (string) $data['dces-element']) {
@@ -347,4 +380,12 @@ class FieldsController extends Controller
return $data;
}
+
+ /**
+ * @return ControlProviderInterface[]|\Pimple
+ */
+ private function getVocabularies()
+ {
+ return $this->app['vocabularies'];
+ }
}
diff --git a/lib/Alchemy/Phrasea/Controller/Admin/SearchEngineController.php b/lib/Alchemy/Phrasea/Controller/Admin/SearchEngineController.php
index 2c0a3be48e..30b4b84782 100644
--- a/lib/Alchemy/Phrasea/Controller/Admin/SearchEngineController.php
+++ b/lib/Alchemy/Phrasea/Controller/Admin/SearchEngineController.php
@@ -38,9 +38,28 @@ class SearchEngineController extends Controller
return $this->render('admin/search-engine/elastic-search.html.twig', [
'form' => $form->createView(),
+ 'indexer' => $this->app['elasticsearch.indexer']
]);
}
+ public function dropIndexAction(Request $request)
+ {
+ $indexer = $this->app['elasticsearch.indexer'];
+ if ($indexer->indexExists()) {
+ $indexer->deleteIndex();
+ }
+ return $this->app->redirectPath('admin_searchengine_form');
+ }
+
+ public function createIndexAction(Request $request)
+ {
+ $indexer = $this->app['elasticsearch.indexer'];
+ if (!$indexer->indexExists()) {
+ $indexer->createIndex();
+ }
+ return $this->app->redirectPath('admin_searchengine_form');
+ }
+
/**
* @return ElasticsearchOptions
*/
diff --git a/lib/Alchemy/Phrasea/Controller/Api/SearchController.php b/lib/Alchemy/Phrasea/Controller/Api/SearchController.php
index 9a8ca841eb..e1113b3919 100644
--- a/lib/Alchemy/Phrasea/Controller/Api/SearchController.php
+++ b/lib/Alchemy/Phrasea/Controller/Api/SearchController.php
@@ -1,5 +1,5 @@
app, $request);
-
- $offsetStart = (int) ($request->get('offset_start') ?: 0);
- $perPage = (int) $request->get('per_page') ?: 10;
+ $options->setFirstResult($request->get('offset_start') ?: 0);
+ $options->setMaxResults($request->get('per_page') ?: 10);
$query = (string) $request->get('query');
$this->getSearchEngine()->resetCache();
- $search_result = $this->getSearchEngine()->query($query, $offsetStart, $perPage, $options);
+ $search_result = $this->getSearchEngine()->query($query, $options);
$this->getUserManipulator()->logQuery($this->getAuthenticatedUser(), $search_result->getQuery());
@@ -74,8 +73,8 @@ class SearchController extends Controller
$this->getSearchEngine()->clearCache();
$ret = [
- 'offset_start' => $offsetStart,
- 'per_page' => $perPage,
+ 'offset_start' => $options->getFirstResult(),
+ 'per_page' => $options->getMaxResults(),
'available_results' => $search_result->getAvailable(),
'total_results' => $search_result->getTotal(),
'error' => (string)$search_result->getError(),
diff --git a/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php b/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php
index b98ee254d2..add7eccc8c 100644
--- a/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php
+++ b/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php
@@ -47,7 +47,7 @@ use Alchemy\Phrasea\Model\Entities\ValidationData;
use Alchemy\Phrasea\Model\Entities\ValidationParticipant;
use Alchemy\Phrasea\Model\Manipulator\TaskManipulator;
use Alchemy\Phrasea\Model\Manipulator\UserManipulator;
-use Alchemy\Phrasea\Model\Provider\SecretProvider;
+use Alchemy\Phrasea\Model\RecordReferenceInterface;
use Alchemy\Phrasea\Model\Repositories\BasketRepository;
use Alchemy\Phrasea\Model\Repositories\FeedEntryRepository;
use Alchemy\Phrasea\Model\Repositories\FeedRepository;
@@ -61,8 +61,8 @@ use Alchemy\Phrasea\SearchEngine\SearchEngineResult;
use Alchemy\Phrasea\SearchEngine\SearchEngineSuggestion;
use Alchemy\Phrasea\Status\StatusStructure;
use Alchemy\Phrasea\TaskManager\LiveInformation;
+use Alchemy\Phrasea\Utilities\NullableDateTime;
use Doctrine\ORM\EntityManager;
-use Firebase\JWT\JWT;
use Symfony\Component\Form\Form;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request;
@@ -139,10 +139,10 @@ class V1Controller extends Controller
'pid' => $data['process-id'],
'jobId' => $task->getJobId(),
'period' => $task->getPeriod(),
- 'last_exec_time' => $task->getLastExecution() ? $task->getLastExecution()->format(DATE_ATOM) : null,
- 'last_execution' => $task->getLastExecution() ? $task->getLastExecution()->format(DATE_ATOM) : null,
- 'updated' => $task->getUpdated() ? $task->getUpdated()->format(DATE_ATOM) : null,
- 'created' => $task->getCreated() ? $task->getCreated()->format(DATE_ATOM) : null,
+ 'last_exec_time' => NullableDateTime::format($task->getLastExecution()),
+ 'last_execution' => NullableDateTime::format($task->getLastExecution()),
+ 'updated' => NullableDateTime::format($task->getUpdated()),
+ 'created' => NullableDateTime::format($task->getCreated()),
'auto_start' => $task->getStatus() === Task::STATUS_STARTED,
'crashed' => $task->getCrashed(),
];
@@ -710,9 +710,9 @@ class V1Controller extends Controller
'position' => $user->getActivity() ?: null,
'company' => $user->getCompany() ?: null,
'geoname_id' => $user->getGeonameId() ?: null,
- 'last_connection' => $user->getLastConnection() ? $user->getLastConnection()->format(DATE_ATOM) : null,
- 'created_on' => $user->getCreated() ? $user->getCreated()->format(DATE_ATOM) : null,
- 'updated_on' => $user->getUpdated() ? $user->getUpdated()->format(DATE_ATOM) : null,
+ 'last_connection' => NullableDateTime::format($user->getLastConnection()),
+ 'created_on' => NullableDateTime::format($user->getCreated()),
+ 'updated_on' => NullableDateTime::format($user->getUpdated()),
'locale' => $user->getLocale() ?: null,
];
}
@@ -1003,37 +1003,11 @@ class V1Controller extends Controller
'substituted' => $media->is_substituted(),
'created_on' => $media->get_creation_date()->format(DATE_ATOM),
'updated_on' => $media->get_modification_date()->format(DATE_ATOM),
- 'url' => $this->generateSubDefinitionUrl($issuer, $media, $urlTTL),
+ 'url' => $this->app['media_accessor.subdef_url_generator']->generate($issuer, $media, $urlTTL),
'url_ttl' => $urlTTL,
];
}
- /**
- * @param User $issuer
- * @param \media_subdef $subdef
- * @param int $url_ttl
- * @return string
- */
- private function generateSubDefinitionUrl(User $issuer, \media_subdef $subdef, $url_ttl)
- {
- $payload = [
- 'iat' => time(),
- 'iss' => $issuer->getId(),
- 'sdef' => [$subdef->get_sbas_id(), $subdef->get_record_id(), $subdef->get_name()],
- ];
- if ($url_ttl >= 0) {
- $payload['exp'] = $payload['iat'] + $url_ttl;
- }
-
- /** @var SecretProvider $provider */
- $provider = $this->app['provider.secrets'];
- $secret = $provider->getSecretForUser($issuer);
-
- return $this->app->url('media_accessor', [
- 'token' => JWT::encode($payload, $secret->getToken(), 'HS256', $secret->getId()),
- ]);
- }
-
private function listPermalink(\media_Permalink_Adapter $permalink)
{
$downloadUrl = $permalink->get_url();
@@ -1063,19 +1037,23 @@ class V1Controller extends Controller
{
list($ret, $search_result) = $this->prepareSearchRequest($request);
- $ret['results'] = ['records' => [], 'stories' => []];
+ $records = [];
+ $stories = [];
/** @var SearchEngineResult $search_result */
- $references = new RecordReferenceCollection($search_result->getResults());
-
- foreach ($references->toRecords($this->getApplicationBox()) as $record) {
+ foreach ($search_result->getResults() as $record) {
if ($record->isStory()) {
- $ret['results']['stories'][] = $this->listStory($request, $record);
+ $stories[] = $record;
} else {
- $ret['results']['records'][] = $this->listRecord($request, $record);
+ $records[] = $record;
}
}
+ $ret['results'] = [
+ 'records' => $this->listRecords($request, $records),
+ 'stories' => $this->listStories($request, $stories),
+ ];
+
return Result::create($request, $ret)->createResponse();
}
@@ -1110,13 +1088,13 @@ class V1Controller extends Controller
{
$options = SearchEngineOptions::fromRequest($this->app, $request);
- $offsetStart = (int) ($request->get('offset_start') ?: 0);
- $perPage = (int) $request->get('per_page') ?: 10;
+ $options->setFirstResult((int) ($request->get('offset_start') ?: 0));
+ $options->setMaxResults((int) $request->get('per_page') ?: 10);
$query = (string) $request->get('query');
$this->getSearchEngine()->resetCache();
- $search_result = $this->getSearchEngine()->query($query, $offsetStart, $perPage, $options);
+ $search_result = $this->getSearchEngine()->query($query, $options);
$this->getUserManipulator()->logQuery($this->getAuthenticatedUser(), $search_result->getQuery());
@@ -1134,8 +1112,8 @@ class V1Controller extends Controller
$this->getSearchEngine()->clearCache();
$ret = [
- 'offset_start' => $offsetStart,
- 'per_page' => $perPage,
+ 'offset_start' => $options->getFirstResult(),
+ 'per_page' => $options->getMaxResults(),
'available_results' => $search_result->getAvailable(),
'total_results' => $search_result->getTotal(),
'error' => (string)$search_result->getError(),
@@ -1154,6 +1132,30 @@ class V1Controller extends Controller
return [$ret, $search_result];
}
+ /**
+ * @param Request $request
+ * @param RecordReferenceInterface[]|RecordReferenceCollection $records
+ * @return array
+ */
+ public 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
*
@@ -1197,6 +1199,27 @@ class V1Controller extends Controller
return $data;
}
+ /**
+ * @param Request $request
+ * @param RecordReferenceInterface[]|RecordReferenceCollection $stories
+ * @return array
+ * @throws \Exception
+ */
+ public function listStories(Request $request, $stories)
+ {
+ if (!$stories instanceof RecordReferenceCollection) {
+ $stories = new RecordReferenceCollection($stories);
+ }
+
+ $data = [];
+
+ foreach ($stories->toRecords($this->getApplicationBox()) as $story) {
+ $data[] = $this->listStory($request, $story);
+ }
+
+ return $data;
+ }
+
/**
* Retrieve detailed information about one story
*
@@ -1211,10 +1234,6 @@ class V1Controller extends Controller
return Result::createError($request, 404, 'Story not found')->createResponse();
}
- $records = array_map(function (\record_adapter $record) use ($request) {
- return $this->listRecord($request, $record);
- }, array_values($story->get_children()->get_elements()));
-
$caption = $story->get_caption();
$format = function (\caption_record $caption, $dcField) {
@@ -1256,7 +1275,7 @@ class V1Controller extends Controller
'dc:title' => $format($caption, \databox_Field_DCESAbstract::Title),
'dc:type' => $format($caption, \databox_Field_DCESAbstract::Type),
],
- 'records' => $records,
+ 'records' => $this->listRecords($request, $story->getChildren()->get_elements()),
];
}
@@ -1448,11 +1467,7 @@ class V1Controller extends Controller
];
}, iterator_to_array($basket->getValidation()->getParticipants()));
- $expires_on_atom = $basket->getValidation()->getExpires();
-
- if ($expires_on_atom instanceof \DateTime) {
- $expires_on_atom = $expires_on_atom->format(DATE_ATOM);
- }
+ $expires_on_atom = NullableDateTime::format($basket->getValidation()->getExpires());
$ret = array_merge([
'validation_users' => $users,
@@ -1530,7 +1545,7 @@ class V1Controller extends Controller
$status = $request->get('status');
- $datas = strrev($record->get_status());
+ $datas = strrev($record->getStatus());
if (!is_array($status)) {
return $this->getBadRequestAction($request);
@@ -1549,7 +1564,7 @@ class V1Controller extends Controller
$datas = substr($datas, 0, ($n)) . $value . substr($datas, ($n + 2));
}
- $record->set_binary_status(strrev($datas));
+ $record->setStatus(strrev($datas));
// @todo Move event dispatch inside record_adapter class (keeps things encapsulated)
$this->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($record));
@@ -2170,7 +2185,7 @@ class V1Controller extends Controller
$story->removeChild($record);
}
- return $record->get_serialize_key();
+ return $record->getId();
}
public function addRecordsToStoryAction(Request $request, $databox_id, $story_id)
@@ -2232,7 +2247,7 @@ class V1Controller extends Controller
$this->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($story));
- return $record->get_serialize_key();
+ return $record->getId();
}
public function getCurrentUserAction(Request $request)
diff --git a/lib/Alchemy/Phrasea/Controller/DatafileController.php b/lib/Alchemy/Phrasea/Controller/DatafileController.php
index e76e6952cb..c6449111ae 100644
--- a/lib/Alchemy/Phrasea/Controller/DatafileController.php
+++ b/lib/Alchemy/Phrasea/Controller/DatafileController.php
@@ -68,7 +68,7 @@ class DatafileController extends AbstractDelivery
$stamp = false;
$watermark = !$this->acl->get($this->authentication->getUser())
- ->has_right_on_base($record->get_base_id(), 'nowatermark');
+ ->has_right_on_base($record->getBaseId(), 'nowatermark');
if ($watermark && !$all_access) {
$subdef_class = null;
diff --git a/lib/Alchemy/Phrasea/Controller/PermalinkController.php b/lib/Alchemy/Phrasea/Controller/PermalinkController.php
index 04aed5ec2c..6850439985 100644
--- a/lib/Alchemy/Phrasea/Controller/PermalinkController.php
+++ b/lib/Alchemy/Phrasea/Controller/PermalinkController.php
@@ -122,7 +122,7 @@ class PermalinkController extends AbstractDelivery
$watermark = $stamp = false;
if ($this->authentication->isAuthenticated()) {
- $watermark = !$this->acl->get($this->authentication->getUser())->has_right_on_base($record->get_base_id(), 'nowatermark');
+ $watermark = !$this->acl->get($this->authentication->getUser())->has_right_on_base($record->getBaseId(), 'nowatermark');
if ($watermark) {
/** @var BasketElementRepository $repository */
@@ -138,7 +138,7 @@ class PermalinkController extends AbstractDelivery
return $this->deliverContentWithCaptionLink($request, $record, $subdef, $watermark, $stamp, $token);
}
- $collection = \collection::getByBaseId($this->app, $record->get_base_id());
+ $collection = \collection::getByBaseId($this->app, $record->getBaseId());
switch ($collection->get_pub_wm()) {
default:
case 'none':
@@ -169,8 +169,8 @@ class PermalinkController extends AbstractDelivery
$response = $this->deliverContent($request, $record, $subdef, $watermark, $stamp);
$response->headers->set('Link', $this->app->url("permalinks_caption", [
- 'sbas_id' => $record->get_sbas_id(),
- 'record_id' => $record->get_record_id(),
+ 'sbas_id' => $record->getDataboxId(),
+ 'record_id' => $record->getRecordId(),
'token' => $token,
]));
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/EditController.php b/lib/Alchemy/Phrasea/Controller/Prod/EditController.php
index d935211685..d33284d5d2 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/EditController.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/EditController.php
@@ -20,7 +20,7 @@ use Alchemy\Phrasea\Model\Entities\Preset;
use Alchemy\Phrasea\Model\Entities\User;
use Alchemy\Phrasea\Model\Manipulator\PresetManipulator;
use Alchemy\Phrasea\Model\Repositories\PresetRepository;
-use Alchemy\Phrasea\Vocabulary\Controller as VocabularyController;
+use Alchemy\Phrasea\Vocabulary\ControlProvider\ControlProviderInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -146,17 +146,17 @@ class EditController extends Controller
foreach ($records as $record) {
$indice = $record->getNumber();
$elements[$indice] = [
- 'bid' => $record->get_base_id(),
- 'rid' => $record->get_record_id(),
+ 'bid' => $record->getBaseId(),
+ 'rid' => $record->getRecordId(),
'sselcont_id' => null,
'_selected' => false,
'fields' => $databox_fields,
];
$elements[$indice]['statbits'] = [];
- if ($this->getAclForUser()->has_right_on_base($record->get_base_id(), 'chgstatus')) {
+ if ($this->getAclForUser()->has_right_on_base($record->getBaseId(), 'chgstatus')) {
foreach ($status as $n => $s) {
- $tmp_val = substr(strrev($record->get_status()), $n, 1);
+ $tmp_val = substr(strrev($record->getStatus()), $n, 1);
$elements[$indice]['statbits'][$n]['value'] = ($tmp_val == '1') ? '1' : '0';
$elements[$indice]['statbits'][$n]['dirty'] = false;
}
@@ -209,7 +209,7 @@ class EditController extends Controller
['record' => $record]
);
- $elements[$indice]['type'] = $record->get_type();
+ $elements[$indice]['type'] = $record->getType();
}
}
@@ -231,7 +231,7 @@ class EditController extends Controller
}
public function searchVocabularyAction(Request $request, $vocabulary) {
- $datas = ['success' => false, 'message' => '', 'results' => []];
+ $data = ['success' => false, 'message' => '', 'results' => []];
$sbas_id = (int) $request->query->get('sbas_id');
@@ -240,33 +240,33 @@ class EditController extends Controller
throw new \Exception('Invalid sbas_id');
}
- $VC = VocabularyController::get($this->app, $vocabulary);
+ /** @var ControlProviderInterface $vocabularyProvider */
+ $vocabularyProvider = $this->app['vocabularies'][strtolower($vocabulary)];
$databox = $this->findDataboxById($sbas_id);
} catch (\Exception $e) {
- $datas['message'] = $this->app->trans('Vocabulary not found');
+ $data['message'] = $this->app->trans('Vocabulary not found');
- return $this->app->json($datas);
+ return $this->app->json($data);
}
$query = $request->query->get('query');
- $results = $VC->find($query, $this->getAuthenticatedUser(), $databox);
+ $results = $vocabularyProvider->find($query, $this->getAuthenticatedUser(), $databox);
$list = [];
- foreach ($results as $Term) {
- /* @var \Alchemy\Phrasea\Vocabulary\Term $Term */
+ foreach ($results as $term) {
$list[] = [
- 'id' => $Term->getId(),
- 'context' => $Term->getContext(),
- 'value' => $Term->getValue(),
+ 'id' => $term->getId(),
+ 'context' => $term->getContext(),
+ 'value' => $term->getValue(),
];
}
- $datas['success'] = true;
- $datas['results'] = $list;
+ $data['success'] = true;
+ $data['results'] = $list;
- return $this->app->json($datas);
+ return $this->app->json($data);
}
public function applyAction(Request $request) {
@@ -287,7 +287,7 @@ class EditController extends Controller
try {
$reg_record = $records->singleStory();
- $newsubdef_reg = new \record_adapter($this->app, $reg_record->get_sbas_id(), $request->request->get('newrepresent'));
+ $newsubdef_reg = new \record_adapter($this->app, $reg_record->getDataboxId(), $request->request->get('newrepresent'));
foreach ($newsubdef_reg->get_subdefs() as $name => $value) {
if (!in_array($name, ['thumbnail', 'preview'])) {
@@ -300,7 +300,7 @@ class EditController extends Controller
$media = $this->app->getMediaFromUri($value->getRealPath());
$this->getSubDefinitionSubstituer()->substitute($reg_record, $name, $media);
$this->getDispatcher()->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($reg_record));
- $this->getDataboxLogger($reg_record->get_databox())->log(
+ $this->getDataboxLogger($reg_record->getDatabox())->log(
$reg_record,
\Session_Logger::EVENT_SUBSTITUTE,
$name == 'document' ? 'HD' : $name,
@@ -325,7 +325,7 @@ class EditController extends Controller
continue;
}
- $key = $record->get_serialize_key();
+ $key = $record->getId();
if (!array_key_exists($key, $elements)) {
continue;
@@ -345,7 +345,7 @@ class EditController extends Controller
$this->getDispatcher()->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($record));
}
- $newstat = $record->get_status();
+ $newstat = $record->getStatus();
$statbits = ltrim($statbits, 'x');
if (!in_array($statbits, ['', 'null'])) {
$mask_and = ltrim(str_replace(['x', '0', '1', 'z'], ['1', 'z', '0', '1'], $statbits), '0');
@@ -359,13 +359,13 @@ class EditController extends Controller
$newstat = \databox_status::operation_or($newstat, $mask_or);
}
- $record->set_binary_status($newstat);
+ $record->setStatus($newstat);
}
$record
->write_metas()
- ->get_collection()
- ->reset_stamp($record->get_record_id());
+ ->getCollection()
+ ->reset_stamp($record->getRecordId());
if ($statbits != '') {
$this->getDataboxLogger($databox)
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/FeedController.php b/lib/Alchemy/Phrasea/Controller/Prod/FeedController.php
index 084c317aee..6c51b0fe5c 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/FeedController.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/FeedController.php
@@ -81,8 +81,8 @@ class FeedController extends Controller
foreach ($publishing as $record) {
$item = new FeedItem();
$item->setEntry($entry)
- ->setRecordId($record->get_record_id())
- ->setSbasId($record->get_sbas_id());
+ ->setRecordId($record->getRecordId())
+ ->setSbasId($record->getDataboxId());
$entry->addItem($item);
$manager->persist($item);
}
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/LazaretController.php b/lib/Alchemy/Phrasea/Controller/Prod/LazaretController.php
index c146c428b8..465687a060 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/LazaretController.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/LazaretController.php
@@ -206,7 +206,7 @@ class LazaretController extends Controller
//Check if the chosen record is eligible to the substitution
foreach ($lazaretFile->getRecordsToSubstitute($this->app) as $record) {
- if ($record->get_record_id() !== (int) $recordId) {
+ if ($record->getRecordId() !== (int) $recordId) {
continue;
}
@@ -230,7 +230,7 @@ class LazaretController extends Controller
$record = $lazaretFile->getCollection($this->app)->get_databox()->get_record($recordId);
$this->getSubDefinitionSubstituer()
->substitute($record, 'document', $media);
- $this->getDataboxLogger($record->get_databox())->log(
+ $this->getDataboxLogger($record->getDatabox())->log(
$record,
\Session_Logger::EVENT_SUBSTITUTE,
'HD',
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/MoveCollectionController.php b/lib/Alchemy/Phrasea/Controller/Prod/MoveCollectionController.php
index 74c8378e84..14833a2edb 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/MoveCollectionController.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/MoveCollectionController.php
@@ -70,8 +70,8 @@ class MoveCollectionController extends Controller
if ($request->request->get("chg_coll_son") == "1") {
/** @var \record_adapter $child */
- foreach ($record->get_children() as $child) {
- if ($this->getAclForUser()->has_right_on_base($child->get_base_id(), 'candeleterecord')) {
+ foreach ($record->getChildren() as $child) {
+ if ($this->getAclForUser()->has_right_on_base($child->getBaseId(), 'candeleterecord')) {
$child->move_to_collection($collection, $this->getApplicationBox());
}
}
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/PrinterController.php b/lib/Alchemy/Phrasea/Controller/Prod/PrinterController.php
index 968e6b23b9..d2bc03b190 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/PrinterController.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/PrinterController.php
@@ -34,7 +34,7 @@ class PrinterController extends Controller
$layout = $request->request->get('lay');
foreach ($printer->get_elements() as $record) {
- $this->getDataboxLogger($record->get_databox())->log($record, \Session_Logger::EVENT_PRINT, $layout, '');
+ $this->getDataboxLogger($record->getDatabox())->log($record, \Session_Logger::EVENT_PRINT, $layout, '');
}
$PDF = new PDFExport($this->app, $printer->get_elements(), $layout);
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/PropertyController.php b/lib/Alchemy/Phrasea/Controller/Prod/PropertyController.php
index f368b24046..317aeb7cb7 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/PropertyController.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/PropertyController.php
@@ -87,17 +87,17 @@ class PropertyController extends Controller
foreach ($records as $record) {
//perform logic
- $sbasId = $record->get_databox()->get_sbas_id();
+ $sbasId = $record->getDataboxId();
if (!isset($recordsType[$sbasId])) {
$recordsType[$sbasId] = [];
}
- if (!isset($recordsType[$sbasId][$record->get_type()])) {
- $recordsType[$sbasId][$record->get_type()] = [];
+ if (!isset($recordsType[$sbasId][$record->getType()])) {
+ $recordsType[$sbasId][$record->getType()] = [];
}
- $recordsType[$sbasId][$record->get_type()][] = $record;
+ $recordsType[$sbasId][$record->getType()][] = $record;
}
return new Response($this->render('prod/actions/Property/type.html.twig', [
@@ -120,18 +120,18 @@ class PropertyController extends Controller
$postStatus = (array) $request->request->get('status');
foreach ($records as $record) {
- $sbasId = $record->get_databox()->get_sbas_id();
+ $sbasId = $record->getDataboxId();
//update record
if (null !== $updatedStatus = $this->updateRecordStatus($record, $postStatus)) {
- $updated[$record->get_serialize_key()] = $updatedStatus;
+ $updated[$record->getId()] = $updatedStatus;
}
//update children if current record is a story
if (isset($applyStatusToChildren[$sbasId]) && $record->isStory()) {
- foreach ($record->get_children() as $child) {
+ foreach ($record->getChildren() as $child) {
if (null !== $updatedStatus = $this->updateRecordStatus($child, $postStatus)) {
- $updated[$record->get_serialize_key()] = $updatedStatus;
+ $updated[$record->getId()] = $updatedStatus;
}
}
}
@@ -156,17 +156,17 @@ class PropertyController extends Controller
foreach ($records as $record) {
try {
- $recordType = !empty($forceType) ? $forceType : (isset($typeLst[$record->get_serialize_key()]) ? $typeLst[$record->get_serialize_key()] : null);
- $mimeType = isset($mimeLst[$record->get_serialize_key()]) ? $mimeLst[$record->get_serialize_key()] : null;
+ $recordType = !empty($forceType) ? $forceType : (isset($typeLst[$record->getId()]) ? $typeLst[$record->getId()] : null);
+ $mimeType = isset($mimeLst[$record->getId()]) ? $mimeLst[$record->getId()] : null;
if ($recordType) {
- $record->set_type($recordType);
- $updated[$record->get_serialize_key()]['record_type'] = $recordType;
+ $record->setType($recordType);
+ $updated[$record->getId()]['record_type'] = $recordType;
}
if ($mimeType) {
- $record->set_mime($mimeType);
- $updated[$record->get_serialize_key()]['mime_type'] = $mimeType;
+ $record->setMimeType($mimeType);
+ $updated[$record->getId()]['mime_type'] = $mimeType;
}
} catch (\Exception $e) {
@@ -185,18 +185,18 @@ class PropertyController extends Controller
*/
private function updateRecordStatus(\record_adapter $record, array $postStatus)
{
- $sbasId = $record->get_databox()->get_sbas_id();
+ $sbasId = $record->getDataboxId();
if (isset($postStatus[$sbasId]) && is_array($postStatus[$sbasId])) {
$postStatus = $postStatus[$sbasId];
- $currentStatus = strrev($record->get_status());
+ $currentStatus = strrev($record->getStatus());
$newStatus = '';
foreach (range(0, 31) as $i) {
$newStatus .= isset($postStatus[$i]) ? ($postStatus[$i] ? '1' : '0') : $currentStatus[$i];
}
- $record->set_binary_status(strrev($newStatus));
+ $record->setStatus(strrev($newStatus));
return [
'current_status' => $currentStatus,
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/PushController.php b/lib/Alchemy/Phrasea/Controller/Prod/PushController.php
index e666350fa8..90abd15573 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/PushController.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/PushController.php
@@ -124,7 +124,7 @@ class PushController extends Controller
);
}
- $this->getDataboxLogger($element->get_databox())->log(
+ $this->getDataboxLogger($element->getDatabox())->log(
$element,
\Session_Logger::EVENT_VALIDATE,
$user_receiver->getId(),
@@ -322,7 +322,7 @@ class PushController extends Controller
$manager->merge($basketElement);
$manager->persist($validationData);
- $this->getDataboxLogger($basketElement->getRecord($this->app)->get_databox())->log(
+ $this->getDataboxLogger($basketElement->getRecord($this->app)->getDatabox())->log(
$basketElement->getRecord($this->app),
\Session_Logger::EVENT_PUSH,
$participantUser->getId(),
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/QueryController.php b/lib/Alchemy/Phrasea/Controller/Prod/QueryController.php
index 839fa0f2dc..154ca2389c 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/QueryController.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/QueryController.php
@@ -43,8 +43,6 @@ class QueryController extends Controller
$options = SearchEngineOptions::fromRequest($this->app, $request);
- $form = $options->serialize();
-
$perPage = (int) $this->getSettings()->getUserSetting($this->getAuthenticatedUser(), 'images_per_page');
$page = (int) $request->request->get('pag');
@@ -56,13 +54,15 @@ class QueryController extends Controller
$page = 1;
}
+ $options->setFirstResult(($page - 1) * $perPage);
+ $options->setMaxResults($perPage);
+
$user = $this->getAuthenticatedUser();
$userManipulator = $this->getUserManipulator();
$userManipulator->logQuery($user, $query);
try {
- /** @var SearchEngineResult $result */
- $result = $engine->query($query, (($page - 1) * $perPage), $perPage, $options);
+ $result = $engine->query($query, $options);
if ($this->getSettings()->getUserSetting($user, 'start_page') === 'LAST_QUERY') {
$userManipulator->setUserSetting($user, 'start_page_query', $query);
@@ -216,7 +216,7 @@ class QueryController extends Controller
$json['total_answers'] = (int) $result->getAvailable();
$json['next_page'] = ($page < $npages && $result->getAvailable() > 0) ? ($page + 1) : false;
$json['prev_page'] = ($page > 1 && $result->getAvailable() > 0) ? ($page - 1) : false;
- $json['form'] = $form;
+ $json['form'] = $options->serialize();
}
catch(\Exception $e) {
// we'd like a message from the parser so get all the exceptions messages
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/RecordController.php b/lib/Alchemy/Phrasea/Controller/Prod/RecordController.php
index cc8f86c7e9..d378691b84 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/RecordController.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/RecordController.php
@@ -106,8 +106,8 @@ class RecordController extends Controller
]),
"pos" => $record->getNumber(),
"title" => str_replace(array('[[em]]', '[[/em]]'), array('', ''), $record->get_title($query, $searchEngine)),
- "collection_name" => $record->get_collection()->get_name(),
- "collection_logo" => $record->get_collection()->getLogo($record->get_base_id(), $this->app),
+ "collection_name" => $record->getCollection()->get_name(),
+ "collection_logo" => $record->getCollection()->getLogo($record->getBaseId(), $this->app),
]);
}
@@ -119,7 +119,8 @@ class RecordController extends Controller
*/
public function doDeleteRecords(Request $request)
{
- $records = RecordsRequest::fromRequest($this->app, $request, !!$request->request->get('del_children'), [
+ $flatten = (bool)($request->request->get('del_children')) ? RecordsRequest::FLATTEN_YES_PRESERVE_STORIES : RecordsRequest::FLATTEN_NO;
+ $records = RecordsRequest::fromRequest($this->app, $request, $flatten, [
'candeleterecord'
]);
@@ -135,7 +136,7 @@ class RecordController extends Controller
foreach ($basketElements as $element) {
$manager->remove($element);
- $deleted[] = $element->getRecord($this->app)->get_serialize_key();
+ $deleted[] = $element->getRecord($this->app)->getId();
}
$attachedStories = $StoryWZRepository->findByRecord($this->app, $record);
@@ -144,7 +145,7 @@ class RecordController extends Controller
$manager->remove($attachedStory);
}
- $deleted[] = $record->get_serialize_key();
+ $deleted[] = $record->getId();
$record->delete();
} catch (\Exception $e) {
@@ -186,7 +187,7 @@ class RecordController extends Controller
$renewed = [];
foreach ($records as $record) {
- $renewed[$record->get_serialize_key()] = (string) $record->get_preview()->renew_url();
+ $renewed[$record->getId()] = (string) $record->get_preview()->renew_url();
};
return $this->app->json($renewed);
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/StoryController.php b/lib/Alchemy/Phrasea/Controller/Prod/StoryController.php
index e8efc59e47..39ffb95bf9 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/StoryController.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/StoryController.php
@@ -84,8 +84,8 @@ class StoryController extends Controller
'message' => $this->app->trans('Story created'),
'WorkZone' => $storyWZ->getId(),
'story' => [
- 'sbas_id' => $story->get_sbas_id(),
- 'record_id' => $story->get_record_id(),
+ 'sbas_id' => $story->getDataboxId(),
+ 'record_id' => $story->getRecordId(),
],
];
@@ -109,7 +109,7 @@ class StoryController extends Controller
{
$Story = new \record_adapter($this->app, $sbas_id, $record_id);
- if (!$this->getAclForUser()->has_right_on_base($Story->get_base_id(), 'canmodifrecord')) {
+ if (!$this->getAclForUser()->has_right_on_base($Story->getBaseId(), 'canmodifrecord')) {
throw new AccessDeniedHttpException('You can not add document to this Story');
}
@@ -145,7 +145,7 @@ class StoryController extends Controller
$story = new \record_adapter($this->app, $sbas_id, $record_id);
$record = new \record_adapter($this->app, $child_sbas_id, $child_record_id);
- if (!$this->getAclForUser()->has_right_on_base($story->get_base_id(), 'canmodifrecord')) {
+ if (!$this->getAclForUser()->has_right_on_base($story->getBaseId(), 'canmodifrecord')) {
throw new AccessDeniedHttpException('You can not add document to this Story');
}
@@ -188,17 +188,17 @@ class StoryController extends Controller
throw new \Exception('This is not a story');
}
- if (!$this->getAclForUser()->has_right_on_base($story->get_base_id(), 'canmodifrecord')) {
+ if (!$this->getAclForUser()->has_right_on_base($story->getBaseId(), 'canmodifrecord')) {
throw new ControllerException($this->app->trans('You can not edit this story'));
}
$sql = 'UPDATE regroup SET ord = :ord WHERE rid_parent = :parent_id AND rid_child = :children_id';
- $stmt = $story->get_databox()->get_connection()->prepare($sql);
+ $stmt = $story->getDatabox()->get_connection()->prepare($sql);
foreach ($request->request->get('element') as $record_id => $ord) {
$params = [
':ord' => $ord,
- ':parent_id' => $story->get_record_id(),
+ ':parent_id' => $story->getRecordId(),
':children_id' => $record_id
];
$stmt->execute($params);
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/ToolsController.php b/lib/Alchemy/Phrasea/Controller/Prod/ToolsController.php
index 4579c8a676..da497eb9ec 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/ToolsController.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/ToolsController.php
@@ -68,7 +68,7 @@ class ToolsController extends Controller
continue;
}
$label = $this->app->trans('prod::tools: document');
- } elseif (isset($databoxSubdefs[$subdefName])) {
+ } elseif ($databoxSubdefs->hasSubdef($subdefName)) {
if (!$acl->has_access_to_subdef($record, $subdefName)) {
continue;
}
@@ -202,7 +202,7 @@ class ToolsController extends Controller
$record->insertTechnicalDatas($this->getMediaVorus());
$this->getMetadataSetter()->replaceMetadata($this->getMetadataReader() ->read($media), $record);
- $this->getDataboxLogger($record->get_databox())
+ $this->getDataboxLogger($record->getDatabox())
->log($record, \Session_Logger::EVENT_SUBSTITUTE, 'HD', '' );
if ((int) $request->request->get('ccfilename') === 1) {
@@ -259,7 +259,7 @@ class ToolsController extends Controller
$media = $this->app->getMediaFromUri($tempoFile);
$this->getSubDefinitionSubstituer()->substitute($record, 'thumbnail', $media);
- $this->getDataboxLogger($record->get_databox())
+ $this->getDataboxLogger($record->getDatabox())
->log($record, \Session_Logger::EVENT_SUBSTITUTE, 'thumbnail', '');
unlink($tempoFile);
@@ -415,7 +415,7 @@ class ToolsController extends Controller
{
$dataUri = Parser::parse($subDefDataUri);
- $name = sprintf('extractor_thumb_%s', $record->get_serialize_key());
+ $name = sprintf('extractor_thumb_%s', $record->getId());
$fileName = sprintf('%s/%s.png', sys_get_temp_dir(), $name);
file_put_contents($fileName, $dataUri->getData());
@@ -423,7 +423,7 @@ class ToolsController extends Controller
$media = $this->app->getMediaFromUri($fileName);
$this->getSubDefinitionSubstituer()->substitute($record, $subDefName, $media);
- $this->getDataboxLogger($record->get_databox())
+ $this->getDataboxLogger($record->getDatabox())
->log($record, \Session_Logger::EVENT_SUBSTITUTE, $subDefName, '');
unset($media);
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/UploadController.php b/lib/Alchemy/Phrasea/Controller/Prod/UploadController.php
index 1c04bfd251..d800aacdb9 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/UploadController.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/UploadController.php
@@ -178,7 +178,7 @@ class UploadController extends Controller
}
if ($elementCreated instanceof \record_adapter) {
- $id = $elementCreated->get_serialize_key();
+ $id = $elementCreated->getId();
$element = 'record';
$message = $this->app->trans('The record was successfully created');
@@ -194,7 +194,7 @@ class UploadController extends Controller
$media = $this->app->getMediaFromUri($fileName);
$this->getSubDefinitionSubstituer()->substitute($elementCreated, 'thumbnail', $media);
- $this->getDataboxLogger($elementCreated->get_databox())
+ $this->getDataboxLogger($elementCreated->getDatabox())
->log($elementCreated, \Session_Logger::EVENT_SUBSTITUTE, 'thumbnail', '');
unset($media);
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/WorkzoneController.php b/lib/Alchemy/Phrasea/Controller/Prod/WorkzoneController.php
index 696c47b3d1..98b87bd732 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/WorkzoneController.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/WorkzoneController.php
@@ -100,7 +100,7 @@ class WorkzoneController extends Controller
throw new \Exception('You can only attach stories');
}
- if (!$acl->has_access_to_base($story->get_base_id())) {
+ if (!$acl->has_access_to_base($story->getBaseId())) {
throw new AccessDeniedHttpException('You do not have access to this Story');
}
diff --git a/lib/Alchemy/Phrasea/Controller/RecordsRequest.php b/lib/Alchemy/Phrasea/Controller/RecordsRequest.php
index 1e255c41b2..7768a30b15 100644
--- a/lib/Alchemy/Phrasea/Controller/RecordsRequest.php
+++ b/lib/Alchemy/Phrasea/Controller/RecordsRequest.php
@@ -14,6 +14,7 @@ namespace Alchemy\Phrasea\Controller;
use Alchemy\Phrasea\Model\Entities\Basket;
use Doctrine\Common\Collections\ArrayCollection;
use Alchemy\Phrasea\Application;
+use record_adapter;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
@@ -46,13 +47,14 @@ class RecordsRequest extends ArrayCollection
if (self::FLATTEN_NO !== $flatten) {
$to_remove = [];
+ /** @var record_adapter $record */
foreach ($this as $key => $record) {
if ($record->isStory()) {
if (self::FLATTEN_YES === $flatten) {
$to_remove[] = $key;
}
- foreach ($record->get_children() as $child) {
- $this->set($child->get_serialize_key(), $child);
+ foreach ($record->getChildren() as $child) {
+ $this->set($child->getId(), $child);
}
}
}
@@ -180,7 +182,7 @@ class RecordsRequest extends ArrayCollection
public function serializedList()
{
if ($this->isSingleStory()) {
- return $this->singleStory()->get_serialize_key();
+ return $this->singleStory()->getId();
}
$basrec = [];
@@ -211,7 +213,7 @@ class RecordsRequest extends ArrayCollection
$app['acl.basket']->hasAccess($basket, $app->getAuthenticatedUser());
foreach ($basket->getElements() as $basket_element) {
- $received[$basket_element->getRecord($app)->get_serialize_key()] = $basket_element->getRecord($app);
+ $received[$basket_element->getRecord($app)->getId()] = $basket_element->getRecord($app);
}
} elseif ($request->get('story')) {
$repository = $app['repo.story-wz'];
@@ -230,7 +232,7 @@ class RecordsRequest extends ArrayCollection
}
try {
$record = new \record_adapter($app, (int) $basrec[0], (int) $basrec[1]);
- $received[$record->get_serialize_key()] = $record;
+ $received[$record->getId()] = $record;
unset($record);
} catch (NotFoundHttpException $e) {
continue;
diff --git a/lib/Alchemy/Phrasea/Controller/Report/InformationController.php b/lib/Alchemy/Phrasea/Controller/Report/InformationController.php
index 4b9bf720f1..6868292743 100644
--- a/lib/Alchemy/Phrasea/Controller/Report/InformationController.php
+++ b/lib/Alchemy/Phrasea/Controller/Report/InformationController.php
@@ -325,8 +325,8 @@ class InformationController extends Controller
/** @var \record_adapter $record */
$reportArray = $what->buildTabUserWhat(
- $record->get_base_id(),
- $record->get_record_id(),
+ $record->getBaseId(),
+ $record->getRecordId(),
$config
);
@@ -393,7 +393,7 @@ class InformationController extends Controller
}
}
- $filter->addfilter('record_id', '=', $record->get_record_id());
+ $filter->addfilter('record_id', '=', $record->getRecordId());
$download->setFilter($filter->getTabFilter());
$download->setOrder('ddate', 'DESC');
diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Fields.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Fields.php
index 155fbe132c..b6f111a37a 100644
--- a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Fields.php
+++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Fields.php
@@ -14,6 +14,7 @@ namespace Alchemy\Phrasea\ControllerProvider\Admin;
use Alchemy\Phrasea\Application as PhraseaApplication;
use Alchemy\Phrasea\Controller\Admin\FieldsController;
use Alchemy\Phrasea\ControllerProvider\ControllerProviderTrait;
+use Alchemy\Phrasea\Vocabulary\ControlProvider\UserProvider;
use Silex\Application;
use Silex\ControllerProviderInterface;
use Silex\ServiceProviderInterface;
@@ -24,6 +25,15 @@ class Fields implements ControllerProviderInterface, ServiceProviderInterface
public function register(Application $app)
{
+ $app['vocabularies'] = $app->share(function (PhraseaApplication $app) {
+ $vocabularies = new \Pimple();
+
+ $vocabularies['user'] = $vocabularies->share(function () use ($app) {
+ return new UserProvider($app);
+ });
+
+ return $vocabularies;
+ });
$app['controller.admin.fields'] = $app->share(function (PhraseaApplication $app) {
return new FieldsController($app);
});
diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/SearchEngine.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/SearchEngine.php
index b2da35b10b..139e133d09 100644
--- a/lib/Alchemy/Phrasea/ControllerProvider/Admin/SearchEngine.php
+++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/SearchEngine.php
@@ -37,9 +37,15 @@ class SearchEngine implements ControllerProviderInterface, ServiceProviderInterf
/** @var ControllerCollection $controllers */
$controllers = $app['controllers_factory'];
+ $controllers->post('/drop_index', 'controller.admin.search-engine:dropIndexAction')
+ ->bind("admin_searchengine_drop_index");
+
+ $controllers->post('/create_index', 'controller.admin.search-engine:createIndexAction')
+ ->bind("admin_searchengine_create_index");
+
$controllers->match('/', 'controller.admin.search-engine:formConfigurationPanelAction')
- ->method('GET|POST')
- ->bind('admin_searchengine_form');
+ ->method('GET|POST')
+ ->bind('admin_searchengine_form');
return $controllers;
}
diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Api/V2.php b/lib/Alchemy/Phrasea/ControllerProvider/Api/V2.php
index f878b46b17..f5ff897179 100644
--- a/lib/Alchemy/Phrasea/ControllerProvider/Api/V2.php
+++ b/lib/Alchemy/Phrasea/ControllerProvider/Api/V2.php
@@ -13,8 +13,10 @@ use Alchemy\Phrasea\Application as PhraseaApplication;
use Alchemy\Phrasea\Controller\Api\BasketController;
use Alchemy\Phrasea\Controller\Api\LazaretController;
use Alchemy\Phrasea\Controller\Api\SearchController;
+use Alchemy\Phrasea\Controller\LazyLocator;
use Alchemy\Phrasea\ControllerProvider\ControllerProviderTrait;
use Alchemy\Phrasea\Core\Event\Listener\OAuthListener;
+use Alchemy\Phrasea\Order\Controller\ApiOrderController;
use Silex\Application;
use Silex\Controller;
use Silex\ControllerProviderInterface;
@@ -48,6 +50,15 @@ class V2 implements ControllerProviderInterface, ServiceProviderInterface
return new SearchController($app);
}
);
+
+ $app['controller.api.v2.orders'] = $app->share(
+ function (PhraseaApplication $app) {
+ return (new ApiOrderController($app))
+ ->setDispatcher($app['dispatcher'])
+ ->setEntityManagerLocator(new LazyLocator($app, 'orm.em'))
+ ->setJsonBodyHelper($app['json.body_helper']);
+ }
+ );
}
public function boot(Application $app)
@@ -89,6 +100,22 @@ class V2 implements ControllerProviderInterface, ServiceProviderInterface
->bind('api_v2_quarantine_item_add');
$this->addQuarantineMiddleware($controller);
+ $controllers->post('/orders/', 'controller.api.v2.orders:createAction')
+ ->bind('api_v2_orders_create');
+ $controllers->get('/orders/', 'controller.api.v2.orders:indexAction')
+ ->bind('api_v2_orders_index');
+ $controllers->get('/orders/{orderId}', 'controller.api.v2.orders:showAction')
+ ->assert('orderId', '\d+')
+ ->bind('api_v2_orders_show');
+
+ $controllers->post('/orders/{orderId}/accept', 'controller.api.v2.orders:acceptElementsAction')
+ ->assert('orderId', '\d+')
+ ->bind('api_v2_orders_accept');
+
+ $controllers->post('/orders/{orderId}/deny', 'controller.api.v2.orders:denyElementsAction')
+ ->assert('orderId', '\d+')
+ ->bind('api_v2_orders_deny');
+
return $controllers;
}
diff --git a/lib/Alchemy/Phrasea/ControllerProvider/MediaAccessor.php b/lib/Alchemy/Phrasea/ControllerProvider/MediaAccessor.php
index a9987bf7e5..44b7fe658f 100644
--- a/lib/Alchemy/Phrasea/ControllerProvider/MediaAccessor.php
+++ b/lib/Alchemy/Phrasea/ControllerProvider/MediaAccessor.php
@@ -10,6 +10,7 @@
namespace Alchemy\Phrasea\ControllerProvider;
use Alchemy\Phrasea\Controller\MediaAccessorController;
+use Alchemy\Phrasea\Media\MediaSubDefinitionUrlGenerator;
use Alchemy\Phrasea\Model\Entities\Secret;
use Alchemy\Phrasea\Model\Provider\DefaultSecretProvider;
use Doctrine\ORM\EntityManagerInterface;
@@ -33,6 +34,13 @@ class MediaAccessor implements ServiceProviderInterface, ControllerProviderInter
return new DefaultSecretProvider($app['repo.secrets'], $app['random.medium']);
});
+ $app['media_accessor.subdef_url_generator'] = $app->share(function (Application $app) {
+ $defaultTTL = (int)$app['conf']->get(['registry', 'general', 'default-subdef-url-ttl'], 0);
+
+ return new MediaSubDefinitionUrlGenerator($app['url_generator'], $app['provider.secrets'], $defaultTTL);
+ });
+
+
$app['controller.media_accessor'] = $app->share(function (Application $app) {
return (new MediaAccessorController($app))
->setAllowedAlgorithms(['HS256'])
diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Permalink.php b/lib/Alchemy/Phrasea/ControllerProvider/Permalink.php
index 619c7526c9..b6339e786d 100644
--- a/lib/Alchemy/Phrasea/ControllerProvider/Permalink.php
+++ b/lib/Alchemy/Phrasea/ControllerProvider/Permalink.php
@@ -14,6 +14,7 @@ namespace Alchemy\Phrasea\ControllerProvider;
use Alchemy\Phrasea\Application as PhraseaApplication;
use Alchemy\Phrasea\Controller\LazyLocator;
use Alchemy\Phrasea\Controller\PermalinkController;
+use Alchemy\Phrasea\Core\Event\Listener\OAuthListener;
use Silex\Application;
use Silex\ControllerCollection;
use Silex\ControllerProviderInterface;
@@ -69,6 +70,7 @@ class Permalink implements ControllerProviderInterface, ServiceProviderInterface
->bind('permalinks_permaview_old');
$controllers->get('/v1/{sbas_id}/{record_id}/{subdef}/{label}', 'controller.permalink:deliverPermalink')
+ ->before(new OAuthListener(['exit_not_present' => false]))
->bind('permalinks_permalink');
$controllers->match('/v1/{sbas_id}/{record_id}/{subdef}/{label}', 'controller.permalink:getOptionsResponse')
diff --git a/lib/Alchemy/Phrasea/Core/Configuration/Configuration.php b/lib/Alchemy/Phrasea/Core/Configuration/Configuration.php
index d62fa8d52d..6457dc2187 100644
--- a/lib/Alchemy/Phrasea/Core/Configuration/Configuration.php
+++ b/lib/Alchemy/Phrasea/Core/Configuration/Configuration.php
@@ -212,6 +212,9 @@ class Configuration implements ConfigurationInterface
private function writeCacheConfig($content)
{
$this->dumpFile($this->compiled, $content, 0600);
+ if(function_exists("opcache_invalidate")) {
+ opcache_invalidate($this->compiled);
+ }
}
private function isConfigFresh()
diff --git a/lib/Alchemy/Phrasea/Core/Connection/ConnectionPoolManager.php b/lib/Alchemy/Phrasea/Core/Connection/ConnectionPoolManager.php
index 79cfa88a64..4953f85f3d 100644
--- a/lib/Alchemy/Phrasea/Core/Connection/ConnectionPoolManager.php
+++ b/lib/Alchemy/Phrasea/Core/Connection/ConnectionPoolManager.php
@@ -1,9 +1,8 @@
closeAll();
- $this->connections = [];
}
public function closeAll()
{
- foreach ($this->connections as $key => $conn) {
+ foreach ($this->connections as $conn) {
$conn->close();
}
}
@@ -88,4 +84,9 @@ class ConnectionPoolManager
return $this->connections[$key] = DriverManager::getConnection($params);
}
+
+ public function all()
+ {
+ return $this->connections;
+ }
}
diff --git a/lib/Alchemy/Phrasea/Core/Event/Subscriber/BridgeSubscriber.php b/lib/Alchemy/Phrasea/Core/Event/Subscriber/BridgeSubscriber.php
index 1e39bf68d7..0de92461df 100644
--- a/lib/Alchemy/Phrasea/Core/Event/Subscriber/BridgeSubscriber.php
+++ b/lib/Alchemy/Phrasea/Core/Event/Subscriber/BridgeSubscriber.php
@@ -26,8 +26,8 @@ class BridgeSubscriber extends AbstractNotificationSubscriber
'usr_id' => $user->getId(),
'reason' => $event->getReason(),
'account_id' => $account->get_id(),
- 'sbas_id' => $event->getElement()->get_record()->get_sbas_id(),
- 'record_id' => $event->getElement()->get_record()->get_record_id(),
+ 'sbas_id' => $event->getElement()->get_record()->getDataboxId(),
+ 'record_id' => $event->getElement()->get_record()->getRecordId(),
];
$datas = json_encode($params);
diff --git a/lib/Alchemy/Phrasea/Core/Event/Subscriber/DoctrineQueriesLoggerSubscriber.php b/lib/Alchemy/Phrasea/Core/Event/Subscriber/DoctrineQueriesLoggerSubscriber.php
deleted file mode 100644
index eadbaf0bf3..0000000000
--- a/lib/Alchemy/Phrasea/Core/Event/Subscriber/DoctrineQueriesLoggerSubscriber.php
+++ /dev/null
@@ -1,53 +0,0 @@
-app = $app;
- }
-
- public static function getSubscribedEvents()
- {
- return [
- KernelEvents::RESPONSE => [
- ['logQueries', -255],
- ],
- ];
- }
-
- public function logQueries(GetResponseEvent $event)
- {
- if (Application::ENV_DEV !== $this->app->getEnvironment()) {
- return;
- }
-
- foreach ($this->app['orm.query.logger']->queries as $query ) {
- $this->app['orm.sql-logger']->debug($query['sql'], array(
- 'params' => $query['params'],
- 'types' => $query['types'],
- 'time' => $query['executionMS']
- ));
- }
-
- }
-}
diff --git a/lib/Alchemy/Phrasea/Core/MetaProvider/DatabaseMetaProvider.php b/lib/Alchemy/Phrasea/Core/MetaProvider/DatabaseMetaProvider.php
index 84ecea5311..8ce614c119 100644
--- a/lib/Alchemy/Phrasea/Core/MetaProvider/DatabaseMetaProvider.php
+++ b/lib/Alchemy/Phrasea/Core/MetaProvider/DatabaseMetaProvider.php
@@ -1,4 +1,12 @@
share($app->extend('dbs.config', function ($configs, $app) {
- if (! $app->isDebug()) {
+ if (!isset($app['dbal.config.register.loggers'])) {
return $configs;
}
- foreach($configs->keys() as $service) {
- $app['dbal.config.register.loggers']($configs[$service]);
+ $loggerRegisterCallable = $app['dbal.config.register.loggers'];
+
+ foreach ($configs->keys() as $service) {
+ $loggerRegisterCallable($configs[$service], $service);
}
return $configs;
@@ -56,7 +67,7 @@ class DatabaseMetaProvider implements ServiceProviderInterface
{
// Override "orm.cache.configurer" service provided for benefiting
// of "phraseanet.cache-service"
- $app['orm.cache.configurer'] = $app->protect(function($name, Configuration $config, $options) use ($app) {
+ $app['orm.cache.configurer'] = $app->protect(function ($name, Configuration $config, $options) use ($app) {
/** @var Manager $service */
$service = $app['phraseanet.cache-service'];
@@ -74,7 +85,7 @@ class DatabaseMetaProvider implements ServiceProviderInterface
);
});
- $app['orm.proxies_dir'] = $app['root.path'].'/resources/proxies';
+ $app['orm.proxies_dir'] = $app['root.path'] . '/resources/proxies';
$app['orm.auto_generate_proxies'] = $app['debug'];
$app['orm.proxies_namespace'] = 'Alchemy\Phrasea\Model\Proxies';
diff --git a/lib/Alchemy/Phrasea/Core/Provider/ORMServiceProvider.php b/lib/Alchemy/Phrasea/Core/Provider/ORMServiceProvider.php
index 91e4544cbd..77a2a7a9f0 100644
--- a/lib/Alchemy/Phrasea/Core/Provider/ORMServiceProvider.php
+++ b/lib/Alchemy/Phrasea/Core/Provider/ORMServiceProvider.php
@@ -22,7 +22,6 @@ use Alchemy\Phrasea\Model\NativeQueryProvider;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Annotations\CachedReader;
use Doctrine\Common\Cache\ArrayCache;
-use Doctrine\DBAL\Logging\DebugStack;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\Configuration as ORMConfig;
use Doctrine\ORM\EntityManager;
@@ -37,10 +36,11 @@ class ORMServiceProvider implements ServiceProviderInterface
public function register(Application $app)
{
// Provides DSN string using database information
- $app['db.dsn'] = $app->protect(function(array $params) use ($app) {
+ $app['db.dsn'] = $app->protect(function (array $params) use ($app) {
$params = $app['db.info']($params);
- switch ($params['driver']) {
+ switch ($params['driver'])
+ {
case 'pdo_mysql':
return sprintf('%s://%s:%s@%s:%s/%s',
$params['driver'],
@@ -61,22 +61,22 @@ class ORMServiceProvider implements ServiceProviderInterface
});
// Hash a DSN string
- $app['hash.dsn'] = $app->protect(function($dsn) {
+ $app['hash.dsn'] = $app->protect(function ($dsn) {
return md5($dsn);
});
// Return database test configuration
- $app['db.test.info'] = $app->share(function() use ($app) {
+ $app['db.test.info'] = $app->share(function () use ($app) {
return $app['conf']->get(['main', 'database-test'], array());
});
// Return application box database configuration
- $app['db.appbox.info'] = $app->share(function() use ($app) {
+ $app['db.appbox.info'] = $app->share(function () use ($app) {
return $app['conf']->get(['main', 'database'], array());
});
// Return database fixture configuration
- $app['db.fixture.info'] = $app->share(function() use ($app) {
+ $app['db.fixture.info'] = $app->share(function () use ($app) {
return [
'driver' => 'pdo_sqlite',
'path' => sprintf('%s/%s', $app['tmp.path'], 'db-ref.sqlite'),
@@ -85,7 +85,7 @@ class ORMServiceProvider implements ServiceProviderInterface
});
// Return databox database configuration
- $app['db.databox.info'] = $app->share(function() use ($app) {
+ $app['db.databox.info'] = $app->share(function () use ($app) {
if (false === $app['phraseanet.configuration']->isSetup()) {
return array();
}
@@ -101,46 +101,46 @@ class ORMServiceProvider implements ServiceProviderInterface
});
// Return unique key for fixture database
- $app['db.fixture.hash.key'] = $app->share(function() use ($app) {
+ $app['db.fixture.hash.key'] = $app->share(function () use ($app) {
$info = $app['db.fixture.info'];
return $app['hash.dsn']($app['db.dsn']($info));
});
// Return unique key for test database
- $app['db.test.hash.key'] = $app->share(function() use ($app) {
+ $app['db.test.hash.key'] = $app->share(function () use ($app) {
$info = $app['db.test.info'];
return $app['hash.dsn']($app['db.dsn']($info));
});
// Return unique for appbox database
- $app['db.appbox.hash.key'] = $app->share(function() use ($app) {
+ $app['db.appbox.hash.key'] = $app->share(function () use ($app) {
$info = $app['db.appbox.info'];
return $app['hash.dsn']($app['db.dsn']($info));
});
// Return configuration option for test database in DoctrineServiceProvider
- $app['db.test.options'] = $app->share(function() use ($app) {
+ $app['db.test.options'] = $app->share(function () use ($app) {
return array($app['db.test.hash.key'] => $app['db.test.info']);
});
// Return configuration option for test database in DoctrineServiceProvider
- $app['db.fixture.options'] = $app->share(function() use ($app) {
+ $app['db.fixture.options'] = $app->share(function () use ($app) {
return array($app['db.fixture.hash.key'] => $app['db.fixture.info']);
});
// Return configuration option for appbox database in DoctrineServiceProvider
- $app['db.appbox.options'] = $app->share(function() use ($app) {
+ $app['db.appbox.options'] = $app->share(function () use ($app) {
return array($app['db.appbox.hash.key'] => $app['db.appbox.info']);
});
// Return configuration option for databox databases in DoctrineServiceProvider
- $app['dbs.databox.options'] = $app->share(function() use ($app) {
+ $app['dbs.databox.options'] = $app->share(function () use ($app) {
$options = array();
- foreach($app['db.databox.info'] as $info) {
+ foreach ($app['db.databox.info'] as $info) {
$info = $app['db.info']($info);
$key = $app['hash.dsn']($app['db.dsn']($info));
@@ -153,7 +153,7 @@ class ORMServiceProvider implements ServiceProviderInterface
// Return DoctrineServiceProvider database options, it merges all previous
// set database configuration
- $app['dbs.options'] = $app->share(function() use ($app) {
+ $app['dbs.options'] = $app->share(function () use ($app) {
if (false === $app['phraseanet.configuration']->isSetup()) {
return [];
}
@@ -167,7 +167,7 @@ class ORMServiceProvider implements ServiceProviderInterface
});
// Return DoctrineORMServiceProvider information for a database from its parameters
- $app['orm.em.options.from_info'] = $app->protect(function(array $info) use ($app) {
+ $app['orm.em.options.from_info'] = $app->protect(function (array $info) use ($app) {
$info = $app['db.info']($info);
$key = $app['hash.dsn']($app['db.dsn']($info));
@@ -176,7 +176,7 @@ class ORMServiceProvider implements ServiceProviderInterface
});
//Return DoctrineServiceProvider information for a database from its parameters
- $app['db.options.from_info'] = $app->protect(function(array $info) use ($app) {
+ $app['db.options.from_info'] = $app->protect(function (array $info) use ($app) {
$info = $app['db.info']($info);
$key = $app['hash.dsn']($app['db.dsn']($info));
@@ -188,7 +188,7 @@ class ORMServiceProvider implements ServiceProviderInterface
* Add orm on the fly, used only when a new databox is mounted.
* This allow to use new EM instance right after the database is mounted.
*/
- $app['orm.add'] = $app->protect(function($info) use ($app) {
+ $app['orm.add'] = $app->protect(function ($info) use ($app) {
$info = $app['db.info']($info);
$key = $app['hash.dsn']($app['db.dsn']($info));
@@ -200,7 +200,7 @@ class ORMServiceProvider implements ServiceProviderInterface
$app['dbs.config'][$key] = new Configuration();
$app['dbs'][$key] = $app['dbs']->share(function () use ($app, $info, $key) {
- return DriverManager::getConnection($info,$app['dbs.config'][$key] ,$app['dbs.event_manager'][$key]);
+ return DriverManager::getConnection($info, $app['dbs.config'][$key], $app['dbs.event_manager'][$key]);
});
$options = $app['orm.options']($key);
@@ -230,7 +230,7 @@ class ORMServiceProvider implements ServiceProviderInterface
return new \SplObjectStorage();
});
- $app['dbal.evm.register.listeners'] = $app->protect(function(EventManager $evm) use ($app) {
+ $app['dbal.evm.register.listeners'] = $app->protect(function (EventManager $evm) use ($app) {
$evm->addEventSubscriber(new TimestampableListener());
/** @var \SplObjectStorage $listeners */
$listeners = $app['dbal.evm.listeners'];
@@ -239,23 +239,17 @@ class ORMServiceProvider implements ServiceProviderInterface
}
});
- $app['dbal.config.register.loggers'] = $app->protect(function(Configuration $config) use ($app) {
- if ($app->getEnvironment() === PhraseaApplication::ENV_DEV) {
- $config->setSQLLogger($app['orm.query.logger']);
- }
- });
-
- $app['orm.annotation.register'] = $app->protect(function($key) use($app) {
+ $app['orm.annotation.register'] = $app->protect(function ($key) use($app) {
$driver = new AnnotationDriver($app['orm.annotation.reader'], array(
- $app['root.path'].'/vendor/gedmo/doctrine-extensions/lib/Gedmo/Translatable/Entity/MappedSuperclass',
- $app['root.path'].'/vendor/gedmo/doctrine-extensions/lib/Gedmo/Loggable/Entity/MappedSuperclass',
- $app['root.path'].'/vendor/gedmo/doctrine-extensions/lib/Gedmo/Tree/Entity/MappedSuperclass',
+ $app['root.path'] . '/vendor/gedmo/doctrine-extensions/lib/Gedmo/Translatable/Entity/MappedSuperclass',
+ $app['root.path'] . '/vendor/gedmo/doctrine-extensions/lib/Gedmo/Loggable/Entity/MappedSuperclass',
+ $app['root.path'] . '/vendor/gedmo/doctrine-extensions/lib/Gedmo/Tree/Entity/MappedSuperclass',
));
$app['orm.add_mapping_driver']($driver, 'Gedmo', $key);
});
- $app['dbal.type.register'] = $app->protect(function(Connection $connection, $types) {
+ $app['dbal.type.register'] = $app->protect(function (Connection $connection, $types) {
$platform = $connection->getDatabasePlatform();
foreach (array_keys((array) $types) as $type) {
@@ -263,7 +257,7 @@ class ORMServiceProvider implements ServiceProviderInterface
}
});
- $app['orm.config.new'] = $app->protect(function($key, $options) use($app) {
+ $app['orm.config.new'] = $app->protect(function ($key, $options) use($app) {
$config = new ORMConfig();
$app['orm.cache.configurer']($key, $config, $options);
@@ -287,7 +281,7 @@ class ORMServiceProvider implements ServiceProviderInterface
$chain = $app['orm.mapping_driver_chain.locator']($key);
- foreach ((array)$options['mappings'] as $entity) {
+ foreach ((array) $options['mappings'] as $entity) {
if (!is_array($entity)) {
throw new \InvalidArgumentException(
"The 'orm.em.options' option 'mappings' should be an array of arrays."
@@ -302,7 +296,8 @@ class ORMServiceProvider implements ServiceProviderInterface
$config->addEntityNamespace($entity['alias'], $entity['namespace']);
}
- switch ($entity['type']) {
+ switch ($entity['type'])
+ {
case 'annotation':
$useSimpleAnnotationReader =
isset($entity['use_simple_annotation_reader'])
@@ -349,7 +344,7 @@ class ORMServiceProvider implements ServiceProviderInterface
return $config;
});
- $app['orm.ems.options'] = $app->share(function() use ($app) {
+ $app['orm.ems.options'] = $app->share(function () use ($app) {
if (false === $app['phraseanet.configuration']->isSetup()) {
return [];
}
@@ -366,7 +361,7 @@ class ORMServiceProvider implements ServiceProviderInterface
/**
* Check database connection information
*/
- $app['db.info'] = $app->protect(function(array $info){
+ $app['db.info'] = $app->protect(function (array $info) {
if (!isset($info['driver'])) {
$info['driver'] = 'pdo_mysql';
}
@@ -375,7 +370,8 @@ class ORMServiceProvider implements ServiceProviderInterface
$info['charset'] = 'utf8';
}
- switch ($info['driver']) {
+ switch ($info['driver'])
+ {
case 'pdo_mysql':
foreach (array('user', 'password', 'host', 'dbname', 'port') as $param) {
if (!array_key_exists($param, $info)) {
@@ -396,8 +392,8 @@ class ORMServiceProvider implements ServiceProviderInterface
/**
* Return configuration option for appbox database in DoctrineORMServiceProvider
*/
- $app['orm.em.appbox.options'] = $app->share(function() use ($app) {
- $key = $app['db.appbox.hash.key'];
+ $app['orm.em.appbox.options'] = $app->share(function () use ($app) {
+ $key = $app['db.appbox.hash.key'];
return array($key => $app['orm.options']($key));
});
@@ -405,8 +401,8 @@ class ORMServiceProvider implements ServiceProviderInterface
/**
* Return configuration option for fixture database in DoctrineORMServiceProvider
*/
- $app['orm.em.fixture.options'] = $app->share(function() use ($app) {
- $key = $app['db.fixture.hash.key'];
+ $app['orm.em.fixture.options'] = $app->share(function () use ($app) {
+ $key = $app['db.fixture.hash.key'];
return array($key => $app['orm.options']($key));
});
@@ -414,8 +410,8 @@ class ORMServiceProvider implements ServiceProviderInterface
/**
* Return configuration option for test database in DoctrineORMServiceProvider
*/
- $app['orm.em.test.options'] = $app->share(function() use ($app) {
- $key = $app['db.test.hash.key'];
+ $app['orm.em.test.options'] = $app->share(function () use ($app) {
+ $key = $app['db.test.hash.key'];
return array($key => $app['orm.options']($key));
});
@@ -423,7 +419,7 @@ class ORMServiceProvider implements ServiceProviderInterface
/**
* Return configuration option for databox databases in DoctrineORMServiceProvider
*/
- $app['orm.ems.databox.options'] = $app->share(function() use ($app) {
+ $app['orm.ems.databox.options'] = $app->share(function () use ($app) {
$options = array();
foreach ($app['db.databox.info'] as $base) {
@@ -444,13 +440,13 @@ class ORMServiceProvider implements ServiceProviderInterface
"alias" => "Phraseanet",
"use_simple_annotation_reader" => false,
"namespace" => 'Alchemy\Phrasea\Model\Entities',
- "path" => $app['root.path'].'/lib/Alchemy/Phrasea/Model/Entities',
+ "path" => $app['root.path'] . '/lib/Alchemy/Phrasea/Model/Entities',
)
);
});
// Return orm configuration for a connection given its unique id
- $app['orm.options'] = $app->protect(function($connection) use ($app) {
+ $app['orm.options'] = $app->protect(function ($connection) use ($app) {
return array(
"connection" => $connection,
"mappings" => $app['orm.options.mappings'],
@@ -469,7 +465,7 @@ class ORMServiceProvider implements ServiceProviderInterface
* Path to doctrine log file
*/
$app['orm.monolog.handler.file'] = $app->share(function (Application $app) {
- return $app['log.path'].'/doctrine.log';
+ return $app['log.path'] . '/doctrine.log';
});
/**
@@ -480,7 +476,7 @@ class ORMServiceProvider implements ServiceProviderInterface
/**
* Monolog handler for doctrine
*/
- $app['orm.monolog.handler'] = $app->share(function(Application $app) {
+ $app['orm.monolog.handler'] = $app->share(function (Application $app) {
return new RotatingFileHandler($app['orm.monolog.handler.file'], $app['orm.monolog.handler.file.max-files']);
});
@@ -495,13 +491,6 @@ class ORMServiceProvider implements ServiceProviderInterface
return $logger;
});
- /**
- * Doctrine query logger
- */
- $app['orm.query.logger'] = $app->share(function () {
- return new DebugStack();
- });
-
/**
* Return cache driver
*/
@@ -548,7 +537,7 @@ class ORMServiceProvider implements ServiceProviderInterface
return $manager->get($info);
});
- $app['connection.pool.manager'] = $app->share(function() {
+ $app['connection.pool.manager'] = $app->share(function () {
return new ConnectionPoolManager();
});
@@ -563,7 +552,7 @@ class ORMServiceProvider implements ServiceProviderInterface
/**
* Return an instance of annotation cache reader
*/
- $app['orm.annotation.reader'] = $app->share(function() use ($app) {
+ $app['orm.annotation.reader'] = $app->share(function () use ($app) {
$cache = new ArrayCache();
if ($app->getEnvironment() !== PhraseaApplication::ENV_DEV) {
$cache = $app['phraseanet.cache-service']->factory(
diff --git a/lib/Alchemy/Phrasea/Core/Provider/RepositoriesServiceProvider.php b/lib/Alchemy/Phrasea/Core/Provider/RepositoriesServiceProvider.php
index 61d2fbbd83..be6bae51d3 100644
--- a/lib/Alchemy/Phrasea/Core/Provider/RepositoriesServiceProvider.php
+++ b/lib/Alchemy/Phrasea/Core/Provider/RepositoriesServiceProvider.php
@@ -1,5 +1,5 @@
share(function (Application $app) {
- return new CaptionSerializer();
+ return new CaptionSerializer(new LazyLocator($app, 'service.technical_data'));
});
- $app['serializer.es-record'] = $app->share(function (Application $app) {
+ $app['serializer.es-record'] = $app->share(function () {
return new ESRecordSerializer();
});
}
public function boot(Application $app)
{
+ // No-op
}
}
diff --git a/lib/Alchemy/Phrasea/Core/Provider/WebProfilerServiceProvider.php b/lib/Alchemy/Phrasea/Core/Provider/WebProfilerServiceProvider.php
index d6fd0d25f8..633dc4cc37 100644
--- a/lib/Alchemy/Phrasea/Core/Provider/WebProfilerServiceProvider.php
+++ b/lib/Alchemy/Phrasea/Core/Provider/WebProfilerServiceProvider.php
@@ -2,11 +2,13 @@
namespace Alchemy\Phrasea\Core\Provider;
+use Alchemy\Phrasea\Controller\LazyLocator;
use Alchemy\Phrasea\Core\Event\Subscriber\CacheStatisticsSubscriber;
use Alchemy\Phrasea\Core\Profiler\CacheDataCollector;
use Alchemy\Phrasea\Core\Profiler\TraceableCache;
+use Alchemy\Phrasea\Utilities\LazyArrayAccess;
use Doctrine\Common\Cache\Cache;
-use Doctrine\DBAL\Connection;
+use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\Logging\DebugStack;
use Doctrine\DBAL\Logging\LoggerChain;
use Silex\Application;
@@ -47,19 +49,33 @@ class WebProfilerServiceProvider implements ServiceProviderInterface
return $templates;
}));
- $app['data_collectors'] = $app->share($app->extend('data_collectors', function ($collectors) use ($app) {
- $collectors['ajax'] = function () {
+ $app['data_collectors'] = $app->share($app->extend('data_collectors', function (array $collectors, $app) {
+ $collectors['ajax'] = $app->share(function () {
return new AjaxDataCollector();
- };
+ });
return $collectors;
}));
}
+ $app['dbal.config.register.loggers'] = $app->protect(function (Configuration $config, $name) use ($app) {
+ $debugLogger = new DebugStack();
+
+ $loggerChain = new LoggerChain();
+ $loggerChain->addLogger($debugLogger);
+ $loggerChain->addLogger($app['data_collectors.doctrine.logger']);
+
+ $app['data_collectors.doctrine']->addLogger($name, $debugLogger);
+
+ $config->setSQLLogger($loggerChain);
+ });
+
+ $app['data_collectors.doctrine.logger'] = $app->share(function ($app) {
+ return new DbalLogger($app['logger'], $app['stopwatch']);
+ });
+
$app['data_collectors.doctrine'] = $app->share(function ($app) {
- /** @var Connection $db */
- $db = $app['db'];
- return new DoctrineDataCollector($db);
+ return new DoctrineDataCollector(new LazyArrayAccess(new LazyLocator($app, 'dbs')));
});
$app['cache'] = $app->share($app->extend('cache', function (Cache $cache, $app) {
@@ -75,24 +91,9 @@ class WebProfilerServiceProvider implements ServiceProviderInterface
return new CacheStatisticsSubscriber($app['cache']);
});
- $app['data_collectors'] = $app->share($app->extend('data_collectors', function ($collectors) use ($app) {
+ $app['data_collectors'] = $app->share($app->extend('data_collectors', function (array $collectors, $app) {
$collectors['db'] = $app->share(function ($app) {
- /** @var DoctrineDataCollector $collector */
- $collector = $app['data_collectors.doctrine'];
-
- $loggerChain = new LoggerChain();
- $logger = new DebugStack();
-
- $loggerChain->addLogger($logger);
- $loggerChain->addLogger(new DbalLogger($app['logger'], $app['stopwatch']));
-
- /** @var Connection $db */
- $db = $app['db'];
- $db->getConfiguration()->setSQLLogger($loggerChain);
-
- $collector->addLogger($logger);
-
- return $collector;
+ return $app['data_collectors.doctrine'];
});
$collectors['cache'] = $app->share(function ($app) {
diff --git a/lib/Alchemy/Phrasea/Databox/DataboxBoundRepositoryFactory.php b/lib/Alchemy/Phrasea/Databox/DataboxBoundRepositoryFactory.php
new file mode 100644
index 0000000000..74662001f8
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Databox/DataboxBoundRepositoryFactory.php
@@ -0,0 +1,22 @@
+factory = $factory;
+ }
+
+ /**
+ * @param int $databoxId
+ * @return object
+ */
+ public function getRepositoryForDatabox($databoxId)
+ {
+ if (!isset($this->repositories[$databoxId])) {
+ $this->repositories[$databoxId] = $this->factory->createRepositoryFor($databoxId);
+ }
+
+ return $this->repositories[$databoxId];
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Databox/DataboxConnectionProvider.php b/lib/Alchemy/Phrasea/Databox/DataboxConnectionProvider.php
index a1601dd00d..f1e8c160e7 100644
--- a/lib/Alchemy/Phrasea/Databox/DataboxConnectionProvider.php
+++ b/lib/Alchemy/Phrasea/Databox/DataboxConnectionProvider.php
@@ -1,10 +1,20 @@
quoteIdentifier('type'),
'originalname AS originalName',
'sha256',
- 'mime'
+ 'mime',
+ 'LPAD(BIN(status), 32, \'0\') as status'
)
->from('record', 'r');
}
diff --git a/lib/Alchemy/Phrasea/Databox/Subdef/CachedMediaSubdefDataRepository.php b/lib/Alchemy/Phrasea/Databox/Subdef/CachedMediaSubdefDataRepository.php
new file mode 100644
index 0000000000..712575c628
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Databox/Subdef/CachedMediaSubdefDataRepository.php
@@ -0,0 +1,244 @@
+decorated = $decorated;
+ $this->cache = $cache instanceof MultiGetCache && $cache instanceof MultiPutCache
+ ? $cache
+ : new MultiAdapter($cache);
+ $this->baseKey = $baseKey;
+ }
+
+ /**
+ * @return int
+ */
+ public function getLifeTime()
+ {
+ return $this->lifeTime;
+ }
+
+ /**
+ * @param int $lifeTime
+ */
+ public function setLifeTime($lifeTime)
+ {
+ $this->lifeTime = (int)$lifeTime;
+ }
+
+ /**
+ * @param int[] $recordIds
+ * @param string[]|null $names
+ * @return array
+ */
+ public function findByRecordIdsAndNames(array $recordIds, array $names = null)
+ {
+ $keys = $this->computeKeys($recordIds, $names);
+
+ if ($keys) {
+ $data = $this->cache->fetchMultiple($keys);
+
+ if (count($keys) === count($data)) {
+ return $this->filterNonNull($data);
+ }
+ }
+
+ return $this->fetchAndSave($recordIds, $names, $keys);
+ }
+
+ /**
+ * @param array $data
+ * @return array
+ */
+ private function filterNonNull(array $data)
+ {
+ return array_values(array_filter($data, function ($value) {
+ return null !== $value;
+ }));
+ }
+
+ public function delete(array $subdefIds)
+ {
+ $deleted = $this->decorated->delete($subdefIds);
+
+ $keys = array_map([$this, 'dataToKey'], $subdefIds);
+
+ $this->cache->saveMultiple(array_fill_keys($keys, null), $this->lifeTime);
+
+ return $deleted;
+ }
+
+ public function save(array $data)
+ {
+ $this->decorated->save($data);
+
+ // all saved keys are now stalled. decorated repository could modify values on store (update time for example)
+ $recordIds = [];
+
+ foreach ($data as $item) {
+ $recordIds[] = $item['record_id'];
+ }
+
+ $keys = array_merge(array_map([$this, 'dataToKey'], $data), $this->generateAllCacheKeys($recordIds));
+
+ array_walk($keys, [$this->cache, 'delete']);
+ }
+
+ /**
+ * @param array $data
+ * @return string
+ */
+ private function dataToKey(array $data)
+ {
+ return $this->getCacheKey($data['record_id'], $data['name']);
+ }
+
+ /**
+ * @param int $recordId
+ * @param string|null $name
+ * @return string
+ */
+ private function getCacheKey($recordId, $name = null)
+ {
+ return $this->baseKey . 'media_subdef' . json_encode([(int)$recordId, $name]);
+ }
+
+ /**
+ * @param int[] $recordIds
+ * @param string[] $names
+ * @return string[]
+ */
+ private function generateCacheKeys(array $recordIds, array $names)
+ {
+ $namesCount = count($names);
+
+ $keys = array_map(function ($recordId) use ($namesCount, $names) {
+ return array_map([$this, 'getCacheKey'], array_fill(0, $namesCount, $recordId), $names);
+ }, $recordIds);
+
+ return $keys ? call_user_func_array('array_merge', $keys) : [];
+ }
+
+ /**
+ * @param int[] $recordIds
+ * @return string[]
+ */
+ private function generateAllCacheKeys(array $recordIds)
+ {
+ $recordIds = array_unique($recordIds);
+
+ return array_map([$this, 'getCacheKey'], $recordIds, array_fill(0, count($recordIds), null));
+ }
+
+ /**
+ * @param int[] $recordIds
+ * @param string[]|null $names
+ * @param string[] $keys Known keys supposed to be fetched
+ * @return array
+ */
+ private function fetchAndSave(array $recordIds, array $names = null, array $keys = [])
+ {
+ $retrieved = $this->decorated->findByRecordIdsAndNames($recordIds, $names);
+
+ $data = $this->normalizeRetrievedData($retrieved, $keys);
+
+ $toCache = null === $names ? $this->appendCacheExtraData($data, $retrieved, $recordIds) : $data;
+
+ $this->cache->saveMultiple($toCache, $this->lifeTime);
+
+ return $this->filterNonNull($data);
+ }
+
+ /**
+ * @param int[] $recordIds
+ * @param string[]|null $names
+ * @return string[]
+ */
+ private function computeKeys(array $recordIds, array $names = null)
+ {
+ if (!$recordIds) {
+ return [];
+ } elseif (null !== $names) {
+ return $this->generateCacheKeys($recordIds, $names);
+ }
+
+ $keys = $this->generateAllCacheKeys($recordIds);
+ $data = $this->cache->fetchMultiple($keys);
+
+ return count($keys) === count($data) ? call_user_func_array('array_merge', $data) : [];
+ }
+
+ /**
+ * @param array $retrieved
+ * @param array $keys
+ * @return array
+ */
+ private function normalizeRetrievedData(array $retrieved, array $keys)
+ {
+ $data = array_fill_keys($keys, null);
+
+ foreach ($retrieved as $item) {
+ $data[$this->dataToKey($item)] = $item;
+ }
+
+ return $data;
+ }
+
+ /**
+ * @param array $data
+ * @param array $retrieved
+ * @param array $recordIds
+ * @return array
+ */
+ private function appendCacheExtraData(array $data, array $retrieved, array $recordIds)
+ {
+ $extra = array_fill_keys($this->generateAllCacheKeys($recordIds), []);
+
+ foreach ($retrieved as $item) {
+ $extra[$this->getCacheKey($item['record_id'])][] = $this->getCacheKey($item['record_id'], $item['name']);
+ }
+
+ return array_merge($data, $extra);
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Databox/Subdef/DbalMediaSubdefDataRepository.php b/lib/Alchemy/Phrasea/Databox/Subdef/DbalMediaSubdefDataRepository.php
new file mode 100644
index 0000000000..baf8f9c519
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Databox/Subdef/DbalMediaSubdefDataRepository.php
@@ -0,0 +1,280 @@
+connection = $connection;
+ }
+
+ /**
+ * @param int[] $recordIds
+ * @param string[]|null $names
+ * @return array[]
+ */
+ public function findByRecordIdsAndNames(array $recordIds, array $names = null)
+ {
+ if (!$recordIds || (null !== $names && !$names)) {
+ return [];
+ }
+
+ $sql = $this->getSelectSQL() . ' WHERE record_id IN (:recordIds)';
+ $params = ['recordIds' => $recordIds];
+ $types = ['recordIds' => Connection::PARAM_INT_ARRAY];
+
+ if ($names) {
+ $sql .= ' AND name IN (:names)';
+ $params['names'] = $names;
+ $types['names'] = Connection::PARAM_STR_ARRAY;
+ }
+
+ return array_map([$this, 'sqlToPhp'], $this->connection->fetchAll($sql, $params, $types));
+ }
+
+ /**
+ * @param array[] $subdefIds
+ * @return int The number of affected rows
+ * @throws \Exception
+ */
+ public function delete(array $subdefIds)
+ {
+ if (!$subdefIds) {
+ return 0;
+ }
+
+ $statement = $this->connection->prepare('DELETE FROM subdef WHERE record_id = :record_id AND name = :name');
+
+ $this->connection->beginTransaction();
+
+ try {
+ $deleted = array_reduce($subdefIds, function ($carry, $data) use ($statement) {
+ $carry += $statement->execute([
+ 'record_id' => $data['record_id'],
+ 'name' => $data['name'],
+ ]);
+
+ return $carry;
+ }, 0);
+
+ $this->connection->commit();
+ } catch (\Exception $exception) {
+ $this->connection->rollBack();
+
+ throw $exception;
+ }
+
+ return $deleted;
+ }
+
+ /**
+ * @param array $data
+ * @throws \Exception
+ */
+ public function save(array $data)
+ {
+ $this->connection->transactional(function () use ($data) {
+ $partitions = $this->partitionInsertAndUpdate($data);
+
+ $updateNeeded = $this->createMissing($partitions['insert']);
+
+ $this->updatePresent($partitions['update'] + $updateNeeded);
+ });
+ }
+
+ /**
+ * @param array $data
+ * @return array
+ */
+ private function partitionInsertAndUpdate(array $data)
+ {
+ $partitions = [
+ 'insert' => [],
+ 'update' => [],
+ ];
+
+ foreach ($data as $index => $item) {
+ $partitions[isset($item['subdef_id']) ? 'update' : 'insert'][$index] = $item;
+ }
+
+ return $partitions;
+ }
+
+ /**
+ * @param array $toInsert
+ * @return array
+ * @throws DBALException
+ */
+ private function createMissing(array $toInsert)
+ {
+ if (!$toInsert) {
+ return [];
+ }
+
+ $statement = $this->connection->prepare($this->getInsertSql());
+
+ $updateNeeded = [];
+
+ foreach ($toInsert as $index => $data) {
+ try {
+ $statement->execute($this->phpToSql($data));
+ } catch (DriverException $exception) {
+ $updateNeeded[$index] = $data;
+ }
+ }
+
+ return $updateNeeded;
+ }
+
+ /**
+ * @param array $toUpdate
+ * @throws DBALException
+ */
+ private function updatePresent(array $toUpdate)
+ {
+ if (!$toUpdate) {
+ return;
+ }
+
+ $statement = $this->connection->prepare($this->getUpdateSql());
+
+ foreach ($toUpdate as $data) {
+ $statement->execute($this->phpToSql($data));
+ }
+ }
+
+ private function getSelectSQL()
+ {
+ return <<<'SQL'
+SELECT subdef_id, record_id, name, path, file, width, height, mime, size, substit, etag, created_on, updated_on
+FROM subdef
+SQL;
+ }
+
+ /**
+ * @param array $data
+ * @return array
+ */
+ private function phpToSql(array $data)
+ {
+ return [
+ 'record_id' => $data['record_id'],
+ 'name' => $data['name'],
+ 'path' => $data['path'],
+ 'file' => $data['file'],
+ 'width' => $data['width'],
+ 'height' => $data['height'],
+ 'mime' => $data['mime'],
+ 'size' => $data['size'],
+ 'substit' => $data['is_substituted'],
+ 'etag' => $data['etag'],
+ ];
+ }
+
+ private function sqlToPhp(array $data)
+ {
+ return [
+ 'subdef_id' => (int)$data['subdef_id'],
+ 'record_id' => (int)$data['record_id'],
+ 'name' => $data['name'],
+ 'path' => $data['path'],
+ 'file' => $data['file'],
+ 'width' => (int)$data['width'],
+ 'height' => (int)$data['height'],
+ 'mime' => $data['mime'],
+ 'size' => (int)$data['size'],
+ 'is_substituted' => (bool)$data['substit'],
+ 'etag' => $data['etag'],
+ 'created_on' => $data['created_on'],
+ 'updated_on' => $data['updated_on'],
+ 'physically_present' => true,
+ ];
+ }
+
+ /**
+ * @return string
+ */
+ private function getInsertSql()
+ {
+ static $sql;
+
+ if (null !== $sql) {
+ return $sql;
+ }
+
+ $values = [
+ 'record_id' => ':record_id',
+ 'name' => ':name',
+ 'path' => ':path',
+ 'file' => ':file',
+ 'width' => ':width',
+ 'height' => ':height',
+ 'mime' => ':mime',
+ 'size' => ':size',
+ 'substit' => ':substit',
+ 'etag' => ':etag',
+ 'created_on' => 'NOW()',
+ 'updated_on' => 'NOW()',
+ 'dispatched' => '1',
+ ];
+
+ $sql = sprintf(
+ 'INSERT INTO subdef (%s) VALUES (%s)',
+ implode(', ', array_keys($values)),
+ implode(', ', array_values($values))
+ );
+
+ return $sql;
+ }
+
+ /**
+ * @return string
+ */
+ private function getUpdateSql()
+ {
+ static $sql;
+
+ if (null !== $sql) {
+ return $sql;
+ }
+
+ $values = [
+ 'path = :path',
+ 'file = :file',
+ 'width = :width',
+ 'height = :height',
+ 'mime = :mime',
+ 'size = :size',
+ 'substit = :substit',
+ 'etag = :etag',
+ 'updated_on = NOW()',
+ ];
+
+ $where = [
+ 'record_id = :record_id',
+ 'name = :name',
+ ];
+
+ $sql = sprintf('UPDATE subdef SET %s WHERE %s', implode(', ', $values), implode(' AND ', $where));
+
+ return $sql;
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Databox/Subdef/MediaSubdefDataRepository.php b/lib/Alchemy/Phrasea/Databox/Subdef/MediaSubdefDataRepository.php
new file mode 100644
index 0000000000..c97f4dc6fc
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Databox/Subdef/MediaSubdefDataRepository.php
@@ -0,0 +1,33 @@
+loadFromArray($data);
+ }, $instance, \media_subdef::class);
+
+ $closure($data);
+ }
+
+ /**
+ * @param \media_subdef $instance
+ * @return array
+ * @throws \Assert\AssertionFailedException
+ */
+ public function extract($instance)
+ {
+ Assertion::isInstanceOf($instance, \media_subdef::class);
+
+ $closure = \Closure::bind(function () {
+ return $this->toArray();
+ }, $instance, \media_subdef::class);
+
+ return $closure();
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Databox/Subdef/MediaSubdefRepository.php b/lib/Alchemy/Phrasea/Databox/Subdef/MediaSubdefRepository.php
new file mode 100644
index 0000000000..aba28b6fd1
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Databox/Subdef/MediaSubdefRepository.php
@@ -0,0 +1,138 @@
+repository = $repository;
+ $this->subdefFactory = $subdefFactory;
+ $this->hydrator = $hydrator ?: new MediaSubdefHydrator();
+ }
+
+ /**
+ * @param int $recordId
+ * @param string $name
+ * @return \media_subdef|null
+ */
+ public function findOneByRecordIdAndName($recordId, $name)
+ {
+ $subdefs = $this->repository->findByRecordIdsAndNames([$recordId], [$name]);
+
+ if (!$subdefs) {
+ return null;
+ }
+
+ $instances = $this->hydrateAll($subdefs);
+
+ return reset($instances);
+ }
+
+ /**
+ * @param int[] $recordIds
+ * @param string[] $names
+ * @return \media_subdef[]
+ */
+ public function findByRecordIdsAndNames(array $recordIds, array $names = null)
+ {
+ if (!$recordIds) {
+ return [];
+ }
+
+ $data = $this->repository->findByRecordIdsAndNames($recordIds, $names);
+
+ return $this->hydrateAll($data);
+ }
+
+ /**
+ * @param \media_subdef|\media_subdef[] $subdefs
+ */
+ public function save($subdefs)
+ {
+ if (!is_array($subdefs) || !$subdefs instanceof \Traversable) {
+ $subdefs = [$subdefs];
+ } elseif ($subdefs instanceof \Traversable) {
+ $subdefs = iterator_to_array($subdefs);
+ }
+ Assertion::allIsInstanceOf($subdefs, \media_subdef::class);
+
+ $data = array_map([$this->hydrator, 'extract'], $subdefs);
+
+ $this->repository->save($data);
+ }
+
+ public function clear()
+ {
+ $this->idMap = [];
+ }
+
+ /**
+ * @param string $index
+ * @param array $data
+ * @return \media_subdef
+ */
+ private function hydrate($index, array $data)
+ {
+ if (isset($this->idMap[$index])) {
+ $this->hydrator->hydrate($this->idMap[$index], $data);
+
+ return $this->idMap[$index];
+ }
+
+ $factory = $this->subdefFactory;
+
+ $instance = $factory($data);
+ Assertion::isInstanceOf($instance, \media_subdef::class);
+
+ $this->idMap[$index] = $instance;
+
+ return $instance;
+ }
+
+ /**
+ * @param array $data
+ * @return \media_subdef[]
+ */
+ private function hydrateAll(array $data)
+ {
+ $instances = [];
+
+ foreach ($data as $item) {
+ $instances[] = $this->hydrate(json_encode([$item['record_id'], $item['name']]), $item);
+ }
+
+ return $instances;
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Databox/Subdef/MediaSubdefRepositoryFactory.php b/lib/Alchemy/Phrasea/Databox/Subdef/MediaSubdefRepositoryFactory.php
new file mode 100644
index 0000000000..e2d1d14265
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Databox/Subdef/MediaSubdefRepositoryFactory.php
@@ -0,0 +1,60 @@
+connectionProvider = $connectionProvider;
+ $this->cache = $cache;
+ $this->mediaSubdefFactoryProvider = $mediaSubdefFactoryProvider;
+ }
+
+ public function createRepositoryFor($databoxId)
+ {
+ $connection = $this->connectionProvider->getConnection($databoxId);
+
+ $dbalRepository = new DbalMediaSubdefDataRepository($connection);
+ $dataRepository = new CachedMediaSubdefDataRepository($dbalRepository, $this->cache, sprintf('databox%d:', $databoxId));
+
+ $provider = $this->mediaSubdefFactoryProvider;
+ $factory = $provider($databoxId);
+
+ if (!is_callable($factory)) {
+ throw new \UnexpectedValueException(sprintf(
+ 'Media subdef factory is expected to be callable, got %s',
+ is_object($factory) ? get_class($factory) : gettype($factory)
+ ));
+ }
+
+ return new MediaSubdefRepository($dataRepository, $factory);
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Databox/Subdef/MediaSubdefService.php b/lib/Alchemy/Phrasea/Databox/Subdef/MediaSubdefService.php
new file mode 100644
index 0000000000..60a3c9d9d8
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Databox/Subdef/MediaSubdefService.php
@@ -0,0 +1,120 @@
+repositoryProvider = $repositoryProvider;
+ }
+
+ /**
+ * Returns all available subdefs grouped by each record reference and by its name
+ *
+ * @param RecordReferenceInterface[]|RecordReferenceCollection $records
+ * @return \media_subdef[][]
+ */
+ public function findSubdefsByRecordReferenceFromCollection($records)
+ {
+ $subdefs = $this->reduceRecordReferenceCollection(
+ $records,
+ function (array &$carry, array $subdefs, array $indexes) {
+ /** @var \media_subdef $subdef */
+ foreach ($subdefs as $subdef) {
+ $index = $indexes[$subdef->get_record_id()];
+
+ $carry[$index][$subdef->get_name()] = $subdef;
+ }
+ },
+ array_fill_keys(array_keys(iterator_to_array($records)), [])
+ );
+
+ ksort($subdefs);
+
+ return $subdefs;
+ }
+
+ /**
+ * @param RecordReferenceInterface[]|RecordReferenceCollection $records
+ * @return \media_subdef[]
+ */
+ public function findSubdefsFromRecordReferenceCollection($records)
+ {
+ $groups = $this->reduceRecordReferenceCollection(
+ $records,
+ function (array &$carry, array $subdefs) {
+ $carry[] = $subdefs;
+
+ return $carry;
+ },
+ []
+ );
+
+ if ($groups) {
+ return call_user_func_array('array_merge', $groups);
+ }
+
+ return [];
+ }
+
+ /**
+ * @param RecordReferenceInterface[]|RecordReferenceCollection $records
+ * @param callable $process
+ * @param mixed $initialValue
+ * @return mixed
+ */
+ private function reduceRecordReferenceCollection($records, callable $process, $initialValue)
+ {
+ $records = $this->normalizeRecordCollection($records);
+
+ $carry = $initialValue;
+
+ foreach ($records->groupPerDataboxId() as $databoxId => $indexes) {
+ $subdefs = $this->getRepositoryForDatabox($databoxId)->findByRecordIdsAndNames(array_keys($indexes));
+
+ $carry = $process($carry, $subdefs, $indexes, $databoxId);
+ }
+
+ return $carry;
+ }
+
+ /**
+ * @param int $databoxId
+ * @return MediaSubdefRepository
+ */
+ private function getRepositoryForDatabox($databoxId)
+ {
+ return $this->repositoryProvider->getRepositoryForDatabox($databoxId);
+ }
+
+ /**
+ * @param RecordReferenceInterface[]|RecordReferenceCollection $records
+ * @return RecordReferenceCollection
+ */
+ private function normalizeRecordCollection($records)
+ {
+ if ($records instanceof RecordReferenceCollection) {
+ return $records;
+ }
+
+ return new RecordReferenceCollection($records);
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Databox/Subdef/MediaSubdefServiceProvider.php b/lib/Alchemy/Phrasea/Databox/Subdef/MediaSubdefServiceProvider.php
new file mode 100644
index 0000000000..a9ae274166
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Databox/Subdef/MediaSubdefServiceProvider.php
@@ -0,0 +1,49 @@
+protect(function ($databoxId) use ($app) {
+ return function (array $data) use ($app, $databoxId) {
+ $recordReference = RecordReference::createFromDataboxIdAndRecordId($databoxId, $data['record_id']);
+
+ return new \media_subdef($app, $recordReference, $data['name'], false, $data);
+ };
+ });
+
+ $app['provider.repo.media_subdef'] = $app->share(function (Application $app) {
+ $connectionProvider = new DataboxConnectionProvider($app['phraseanet.appbox']);
+ $factoryProvider = $app['provider.factory.media_subdef'];
+
+ $repositoryFactory = new MediaSubdefRepositoryFactory($connectionProvider, $app['cache'], $factoryProvider);
+
+ return new DataboxBoundRepositoryProvider($repositoryFactory);
+ });
+
+ $app['service.media_subdef'] = $app->share(function (Application $app) {
+ return new MediaSubdefService($app['provider.repo.media_subdef']);
+ });
+ }
+
+ public function boot(Application $app)
+ {
+ // no-op
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Feed/Formatter/AtomFormatter.php b/lib/Alchemy/Phrasea/Feed/Formatter/AtomFormatter.php
index be7533249d..5371f97a41 100644
--- a/lib/Alchemy/Phrasea/Feed/Formatter/AtomFormatter.php
+++ b/lib/Alchemy/Phrasea/Feed/Formatter/AtomFormatter.php
@@ -17,6 +17,7 @@ use Alchemy\Phrasea\Feed\FeedInterface;
use Alchemy\Phrasea\Feed\Link\FeedLink;
use Alchemy\Phrasea\Feed\Link\LinkGeneratorCollection;
use Alchemy\Phrasea\Model\Entities\User;
+use Alchemy\Phrasea\Utilities\NullableDateTime;
use Symfony\Component\HttpFoundation\Response;
class AtomFormatter extends FeedFormatterAbstract implements FeedFormatterInterface
@@ -48,8 +49,6 @@ class AtomFormatter extends FeedFormatterAbstract implements FeedFormatterInterf
*/
public function format(FeedInterface $feed, $page, User $user = null, $generator = 'Phraseanet', Application $app = null)
{
- $updated_on = $feed->getUpdatedOn();
-
$document = new \DOMDocument('1.0', 'UTF-8');
$document->formatOutput = true;
$document->standalone = true;
@@ -59,8 +58,7 @@ class AtomFormatter extends FeedFormatterAbstract implements FeedFormatterInterf
$root->setAttribute('xmlns:media', 'http://search.yahoo.com/mrss/');
$this->addTag($document, $root, 'title', $feed->getTitle());
- if ($updated_on instanceof \DateTime) {
- $updated_on = $updated_on->format(DATE_ATOM);
+ if (null !== $updated_on = NullableDateTime::format($feed->getUpdatedOn())) {
$this->addTag($document, $root, 'updated', $updated_on);
}
diff --git a/lib/Alchemy/Phrasea/Feed/Formatter/CoolirisFormatter.php b/lib/Alchemy/Phrasea/Feed/Formatter/CoolirisFormatter.php
index 1b00e8a779..a7f81addf9 100644
--- a/lib/Alchemy/Phrasea/Feed/Formatter/CoolirisFormatter.php
+++ b/lib/Alchemy/Phrasea/Feed/Formatter/CoolirisFormatter.php
@@ -19,6 +19,7 @@ use Alchemy\Phrasea\Model\Entities\FeedEntry;
use Alchemy\Phrasea\Model\Entities\FeedItem;
use Alchemy\Phrasea\Feed\Link\LinkGeneratorCollection;
use Alchemy\Phrasea\Model\Entities\User;
+use Alchemy\Phrasea\Utilities\NullableDateTime;
use DateTime;
use Symfony\Component\HttpFoundation\Response;
@@ -52,8 +53,6 @@ class CoolirisFormatter extends FeedFormatterAbstract implements FeedFormatterIn
*/
public function format(FeedInterface $feed, $page, User $user = null, $generator = 'Phraseanet', Application $app = null)
{
- $updated_on = $feed->getUpdatedOn();
-
$doc = new \DOMDocument('1.0', 'UTF-8');
$doc->formatOutput = true;
$doc->standalone = true;
@@ -89,8 +88,7 @@ class CoolirisFormatter extends FeedFormatterAbstract implements FeedFormatterIn
$this->addTag($doc, $channel, 'managingEditor', $this->managingEditor);
if (isset($this->webMaster))
$this->addTag($doc, $channel, 'webMaster', $this->webMaster);
- if ($updated_on instanceof DateTime) {
- $updated_on = $updated_on->format(DATE_RFC2822);
+ if (null !== $updated_on = NullableDateTime::format($feed->getUpdatedOn(), DATE_RFC2822)) {
$this->addTag($doc, $channel, 'pubDate', $updated_on);
}
if (isset($this->lastBuildDate) && $this->lastBuildDate instanceof DateTime) {
@@ -191,7 +189,7 @@ class CoolirisFormatter extends FeedFormatterAbstract implements FeedFormatterIn
$thumbnail_sd = $content->getRecord($app)->get_thumbnail();
$thumbnail_permalink = $thumbnail_sd->get_permalink();
- $medium = strtolower($content->getRecord($app)->get_type());
+ $medium = strtolower($content->getRecord($app)->getType());
if ( ! in_array($medium, ['image', 'audio', 'video'])) {
return $this;
diff --git a/lib/Alchemy/Phrasea/Feed/Formatter/FeedFormatterAbstract.php b/lib/Alchemy/Phrasea/Feed/Formatter/FeedFormatterAbstract.php
index 948dd3021d..4024a9157f 100644
--- a/lib/Alchemy/Phrasea/Feed/Formatter/FeedFormatterAbstract.php
+++ b/lib/Alchemy/Phrasea/Feed/Formatter/FeedFormatterAbstract.php
@@ -52,7 +52,7 @@ abstract class FeedFormatterAbstract
$thumbnail_sd = $content->getRecord($app)->get_thumbnail();
$thumbnail_permalink = $thumbnail_sd->get_permalink();
- $medium = strtolower($content->getRecord($app)->get_type());
+ $medium = strtolower($content->getRecord($app)->getType());
if ( ! in_array($medium, ['image', 'audio', 'video'])) {
return $this;
diff --git a/lib/Alchemy/Phrasea/Feed/Formatter/RssFormatter.php b/lib/Alchemy/Phrasea/Feed/Formatter/RssFormatter.php
index ec892d2fc3..9e5a923470 100644
--- a/lib/Alchemy/Phrasea/Feed/Formatter/RssFormatter.php
+++ b/lib/Alchemy/Phrasea/Feed/Formatter/RssFormatter.php
@@ -17,6 +17,7 @@ use Alchemy\Phrasea\Feed\Link\FeedLink;
use Alchemy\Phrasea\Feed\Link\LinkGeneratorCollection;
use Alchemy\Phrasea\Feed\RSS\FeedRSSImage;
use Alchemy\Phrasea\Model\Entities\User;
+use Alchemy\Phrasea\Utilities\NullableDateTime;
use Symfony\Component\HttpFoundation\Response;
use Alchemy\Phrasea\Model\Entities\FeedEntry;
use Alchemy\Phrasea\Feed\Link\FeedLinkGenerator;
@@ -51,8 +52,6 @@ class RssFormatter extends FeedFormatterAbstract implements FeedFormatterInterfa
*/
public function format(FeedInterface $feed, $page, User $user = null, $generator = 'Phraseanet', Application $app = null)
{
- $updated_on = $feed->getUpdatedOn();
-
$next = $prev = null;
if ($feed->hasPage($page + 1, self::PAGE_SIZE)) {
@@ -104,11 +103,10 @@ class RssFormatter extends FeedFormatterAbstract implements FeedFormatterInterfa
$this->addTag($doc, $channel, 'managingEditor', $this->managingEditor);
if (isset($this->webMaster))
$this->addTag($doc, $channel, 'webMaster', $this->webMaster);
- if ($updated_on instanceof \DateTime) {
- $updated_on = $updated_on->format(DATE_RFC2822);
+ if (null !== $updated_on = NullableDateTime::format($feed->getUpdatedOn(), DATE_RFC2822)) {
$this->addTag($doc, $channel, 'pubDate', $updated_on);
}
- if (isset($this->lastBuildDate) && $this->lastBuildDate instanceof DateTime) {
+ if (isset($this->lastBuildDate) && $this->lastBuildDate instanceof \DateTime) {
$last_build = $this->lastBuildDate->format(DATE_RFC2822);
$this->addTag($doc, $channel, 'lastBuildDate', $last_build);
}
diff --git a/lib/Alchemy/Phrasea/Helper/Record/Helper.php b/lib/Alchemy/Phrasea/Helper/Record/Helper.php
index 5e04bab6d1..853e5d0f3b 100644
--- a/lib/Alchemy/Phrasea/Helper/Record/Helper.php
+++ b/lib/Alchemy/Phrasea/Helper/Record/Helper.php
@@ -284,7 +284,7 @@ class Helper extends \Alchemy\Phrasea\Helper\Helper
public function get_serialize_list()
{
if ($this->is_single_grouping()) {
- return $this->get_grouping_head()->get_serialize_key();
+ return $this->get_grouping_head()->getId();
} else {
return $this->selection->serialize_list();
}
diff --git a/lib/Alchemy/Phrasea/Hydration/Hydrator.php b/lib/Alchemy/Phrasea/Hydration/Hydrator.php
new file mode 100644
index 0000000000..ac248f7513
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Hydration/Hydrator.php
@@ -0,0 +1,31 @@
+hydrator = $hydrator;
+ $this->prototype = $prototype;
+ }
+
+ /**
+ * @param string|int $index
+ * @param array $data
+ * @return object
+ */
+ public function hydrate($index, array $data)
+ {
+ if (!isset($this->entities[$index])) {
+ $this->entities[$index] = clone $this->prototype;
+ }
+
+ $instance = $this->entities[$index];
+
+ $this->hydrator->hydrate($instance, $data);
+
+ return $instance;
+ }
+
+ /**
+ * @param array[] $data
+ * @return object[]
+ */
+ public function hydrateAll(array $data)
+ {
+ Assertion::allIsArray($data);
+
+ $instances = [];
+
+ foreach ($data as $index => $item) {
+ $instances[$index] = $this->hydrate($index, $item);
+ }
+
+ return $instances;
+ }
+
+ public function clear()
+ {
+ $this->entities = [];
+ }
+
+ public function getIterator()
+ {
+ return new \ArrayIterator($this->entities);
+ }
+
+ public function offsetExists($offset)
+ {
+ return isset($this->entities[$offset]);
+ }
+
+ public function offsetGet($offset)
+ {
+ return $this->entities[$offset];
+ }
+
+ public function offsetSet($offset, $value)
+ {
+ Assertion::notNull($offset);
+ Assertion::isArray($value);
+
+ $this->hydrate($offset, $value);
+ }
+
+ public function offsetUnset($offset)
+ {
+ unset($this->entities[$offset]);
+ }
+
+ public function count()
+ {
+ return count($this->entities);
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Hydration/ReflectionHydrator.php b/lib/Alchemy/Phrasea/Hydration/ReflectionHydrator.php
new file mode 100644
index 0000000000..5a635e8eb6
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Hydration/ReflectionHydrator.php
@@ -0,0 +1,130 @@
+className = $className;
+ $this->properties = $properties;
+ }
+
+ /**
+ * @param array $data
+ * @param object $instance
+ * @throws \Assert\AssertionFailedException
+ */
+ public function hydrate($instance, array $data)
+ {
+ Assertion::isInstanceOf($instance, $this->className);
+
+ foreach ($data as $key => $value) {
+ $this->getReflectionProperty($key)->setValue($instance, $value);
+ }
+ }
+
+ /**
+ * @param object $instance
+ * @return array
+ * @throws \Assert\AssertionFailedException
+ */
+ public function extract($instance)
+ {
+ Assertion::isInstanceOf($instance, $this->className);
+
+ $data = [];
+
+ foreach ($this->getReflectionProperties() as $name => $property) {
+ $data[$name] = $property->getValue($instance);
+ }
+
+ return $data;
+ }
+
+ /**
+ * @return \ReflectionClass
+ */
+ private function getReflectionClass()
+ {
+ if (null === $this->reflectionClass) {
+ $this->reflectionClass = new \ReflectionClass($this->className);
+ }
+
+ return $this->reflectionClass;
+ }
+
+ /**
+ * @param string $name
+ * @return \ReflectionProperty
+ * @throws \RuntimeException
+ */
+ private function getReflectionProperty($name)
+ {
+ $this->loadReflectionProperties();
+
+ return $this->reflectionProperties[$name];
+ }
+
+ /**
+ * @return \ReflectionProperty[]
+ */
+ private function getReflectionProperties()
+ {
+ $this->loadReflectionProperties();
+
+ return $this->reflectionProperties;
+ }
+
+ private function loadReflectionProperties()
+ {
+ if (null !== $this->reflectionProperties) {
+ return;
+ }
+
+ $class = $this->getReflectionClass();
+ $properties = [];
+
+ foreach ($this->properties as $name) {
+ $property = $class->getProperty($name);
+ $property->setAccessible(true);
+
+ $properties[$name] = $property;
+ }
+
+ $this->reflectionProperties = $properties;
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Media/ArrayTechnicalDataSet.php b/lib/Alchemy/Phrasea/Media/ArrayTechnicalDataSet.php
index 4809823fe8..e4ab83baf1 100644
--- a/lib/Alchemy/Phrasea/Media/ArrayTechnicalDataSet.php
+++ b/lib/Alchemy/Phrasea/Media/ArrayTechnicalDataSet.php
@@ -11,22 +11,20 @@ namespace Alchemy\Phrasea\Media;
use Assert\Assertion;
-final class ArrayTechnicalDataSet implements \IteratorAggregate, TechnicalDataSet
+class ArrayTechnicalDataSet implements \IteratorAggregate, TechnicalDataSet
{
/** @var TechnicalData[] */
- private $data;
+ private $data = [];
/**
* @param TechnicalData[] $data
*/
public function __construct($data = [])
{
- Assertion::allIsInstanceOf($data, TechnicalData::class);
-
- $this->data = [];
+ Assertion::isTraversable($data);
foreach ($data as $technicalData) {
- $this->data[$technicalData->getName()] = $technicalData;
+ $this[] = $technicalData;
}
}
@@ -41,7 +39,7 @@ final class ArrayTechnicalDataSet implements \IteratorAggregate, TechnicalDataSe
$offset = $offset->getName();
}
- return isset($this->data[$offset]) || array_key_exists($offset, $this->data);
+ return isset($this->data[$offset]);
}
public function offsetGet($offset)
@@ -50,7 +48,7 @@ final class ArrayTechnicalDataSet implements \IteratorAggregate, TechnicalDataSe
}
/**
- * @param string $offset
+ * @param null|string $offset
* @param TechnicalData $value
*/
public function offsetSet($offset, $value)
@@ -58,6 +56,7 @@ final class ArrayTechnicalDataSet implements \IteratorAggregate, TechnicalDataSe
Assertion::isInstanceOf($value, TechnicalData::class);
$name = $value->getName();
+
if (null !== $offset) {
Assertion::eq($name, $offset);
}
@@ -82,6 +81,7 @@ final class ArrayTechnicalDataSet implements \IteratorAggregate, TechnicalDataSe
public function getValues()
{
$values = [];
+
foreach ($this->data as $key => $value) {
$values[$key] = $value->getValue();
}
diff --git a/lib/Alchemy/Phrasea/Media/Factory/DbalRepositoryFactory.php b/lib/Alchemy/Phrasea/Media/Factory/DbalRepositoryFactory.php
new file mode 100644
index 0000000000..5ec88a6433
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Media/Factory/DbalRepositoryFactory.php
@@ -0,0 +1,36 @@
+connectionProvider = $connectionProvider;
+ }
+
+ public function createRepositoryForDatabox($databoxId)
+ {
+ return new DbalRecordTechnicalDataSetRepository(
+ $this->connectionProvider->getConnection($databoxId),
+ new TechnicalDataFactory()
+ );
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Media/Factory/TechnicalDataFactory.php b/lib/Alchemy/Phrasea/Media/Factory/TechnicalDataFactory.php
new file mode 100644
index 0000000000..c03f80e911
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Media/Factory/TechnicalDataFactory.php
@@ -0,0 +1,35 @@
+urlGenerator = $urlGenerator;
+ $this->secretProvider = $secretProvider;
+ $this->defaultTTL = (int)$defaultTTL;
+ }
+
+ /**
+ * @return int
+ */
+ public function getDefaultTTL()
+ {
+ return $this->defaultTTL;
+ }
+
+ /**
+ * @param User $issuer
+ * @param \media_subdef $subdef
+ * @param int $url_ttl
+ * @return string
+ */
+ public function generate(User $issuer, \media_subdef $subdef, $url_ttl = null)
+ {
+ $url_ttl = $url_ttl ?: $this->defaultTTL;
+
+ $payload = [
+ 'iat' => time(),
+ 'iss' => $issuer->getId(),
+ 'sdef' => [$subdef->get_sbas_id(), $subdef->get_record_id(), $subdef->get_name()],
+ ];
+
+ if ($url_ttl > 0) {
+ $payload['exp'] = $payload['iat'] + $url_ttl;
+ }
+
+ $secret = $this->secretProvider->getSecretForUser($issuer);
+
+ return $this->urlGenerator->generate('media_accessor', [
+ 'token' => JWT::encode($payload, $secret->getToken(), 'HS256', $secret->getId()),
+ ], UrlGeneratorInterface::ABSOLUTE_URL);
+ }
+
+ /**
+ * @param User $issuer
+ * @param \media_subdef[] $subdefs
+ * @param int $url_ttl
+ * @return string[]
+ */
+ public function generateMany(User $issuer, $subdefs, $url_ttl = null)
+ {
+ Assertion::allIsInstanceOf($subdefs, \media_subdef::class);
+ $url_ttl = $url_ttl ?: $this->defaultTTL;
+
+ $payloads = [];
+
+ $payload = [
+ 'iat' => time(),
+ 'iss' => $issuer->getId(),
+ 'sdef' => null,
+ ];
+
+ if ($url_ttl > 0) {
+ $payload['exp'] = $payload['iat'] + $url_ttl;
+ }
+
+ foreach ($subdefs as $index => $subdef) {
+ $payload['sdef'] = [$subdef->get_sbas_id(), $subdef->get_record_id(), $subdef->get_name()];
+
+ $payloads[$index] = $payload;
+ }
+
+ $secret = $this->secretProvider->getSecretForUser($issuer);
+
+ return array_map(function ($payload) use ($secret) {
+ return $this->urlGenerator->generate('media_accessor', [
+ 'token' => JWT::encode($payload, $secret->getToken(), 'HS256', $secret->getId()),
+ ], UrlGeneratorInterface::ABSOLUTE_URL);
+ }, $payloads);
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Media/RecordTechnicalDataSet.php b/lib/Alchemy/Phrasea/Media/RecordTechnicalDataSet.php
new file mode 100644
index 0000000000..df7caa70c6
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Media/RecordTechnicalDataSet.php
@@ -0,0 +1,37 @@
+recordId = (int)$recordId;
+ parent::__construct($technicalData);
+ }
+
+ /**
+ * @return int
+ */
+ public function getRecordId()
+ {
+ return $this->recordId;
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Media/RecordTechnicalDataSetRepository.php b/lib/Alchemy/Phrasea/Media/RecordTechnicalDataSetRepository.php
new file mode 100644
index 0000000000..46d388f29f
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Media/RecordTechnicalDataSetRepository.php
@@ -0,0 +1,20 @@
+factory = $factory;
+ }
+
+ /**
+ * @param int $databoxId
+ * @return RecordTechnicalDataSetRepository
+ */
+ public function getRepositoryFor($databoxId)
+ {
+ if (!isset($this->repositories[$databoxId])) {
+ $this->repositories[$databoxId] = $this->factory->createRepositoryForDatabox($databoxId);
+ }
+
+ return $this->repositories[$databoxId];
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Media/Repository/DbalRecordTechnicalDataSetRepository.php b/lib/Alchemy/Phrasea/Media/Repository/DbalRecordTechnicalDataSetRepository.php
new file mode 100644
index 0000000000..5c1e035f11
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Media/Repository/DbalRecordTechnicalDataSetRepository.php
@@ -0,0 +1,75 @@
+connection = $connection;
+ $this->dataFactory = $dataFactory;
+ }
+
+ /**
+ * @param int[] $recordIds
+ * @return RecordTechnicalDataSet[]
+ */
+ public function findByRecordIds(array $recordIds)
+ {
+ if (empty($recordIds)) {
+ return [];
+ }
+
+ $data = $this->connection->fetchAll(
+ 'SELECT record_id, name, value FROM technical_datas WHERE record_id IN (:recordIds)',
+ ['recordIds' => $recordIds],
+ ['recordIds' => Connection::PARAM_INT_ARRAY]
+ );
+
+ return $this->mapSetsFromDatabaseResult($recordIds, $data);
+ }
+
+ /**
+ * @param array $recordIds
+ * @param array $data
+ * @return RecordTechnicalDataSet[]
+ */
+ private function mapSetsFromDatabaseResult(array $recordIds, array $data)
+ {
+ $groups = [];
+
+ foreach ($recordIds as $recordId) {
+ $groups[$recordId] = new RecordTechnicalDataSet($recordId);
+ }
+
+ foreach ($data as $item) {
+ $group =& $groups[$item['record_id']];
+ $group[] = $this->dataFactory->createFromNameAndValue($item['name'], $item['value']);
+ }
+
+ return array_values($groups);
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Media/TechnicalDataService.php b/lib/Alchemy/Phrasea/Media/TechnicalDataService.php
new file mode 100644
index 0000000000..da1449cfc2
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Media/TechnicalDataService.php
@@ -0,0 +1,52 @@
+provider = $provider;
+ }
+
+ /**
+ * @param RecordReference[] $references
+ * @return RecordTechnicalDataSet[]
+ */
+ public function fetchRecordsTechnicalData($references)
+ {
+ if (!$references instanceof RecordReferenceCollection) {
+ $references = new RecordReferenceCollection($references);
+ }
+
+ $sets = [];
+
+ foreach ($references->groupPerDataboxId() as $databoxId => $indexes) {
+ foreach ($this->provider->getRepositoryFor($databoxId)->findByRecordIds(array_keys($indexes)) as $set) {
+ $index = $indexes[$set->getRecordId()];
+
+ $sets[$index] = $set;
+ }
+ }
+
+ ksort($sets);
+
+ return $sets;
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Media/TechnicalDataServiceProvider.php b/lib/Alchemy/Phrasea/Media/TechnicalDataServiceProvider.php
new file mode 100644
index 0000000000..d0f19e3159
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Media/TechnicalDataServiceProvider.php
@@ -0,0 +1,34 @@
+share(function (Application $app) {
+ $connectionProvider = new DataboxConnectionProvider($app['phraseanet.appbox']);
+ $repositoryFactory = new DbalRepositoryFactory($connectionProvider);
+
+ return new TechnicalDataService(new RecordTechnicalDataSetRepositoryProvider($repositoryFactory));
+ });
+ }
+
+ public function boot(Application $app)
+ {
+ // no-op
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Model/Entities/Basket.php b/lib/Alchemy/Phrasea/Model/Entities/Basket.php
index ae7e087a27..c25b074634 100644
--- a/lib/Alchemy/Phrasea/Model/Entities/Basket.php
+++ b/lib/Alchemy/Phrasea/Model/Entities/Basket.php
@@ -460,8 +460,8 @@ class Basket
foreach ($this->getElements() as $basket_element) {
$bask_record = $basket_element->getRecord($app);
- if ($bask_record->get_record_id() == $record->get_record_id()
- && $bask_record->get_sbas_id() == $record->get_sbas_id()) {
+ if ($bask_record->getRecordId() == $record->getRecordId()
+ && $bask_record->getDataboxId() == $record->getDataboxId()) {
return true;
}
}
diff --git a/lib/Alchemy/Phrasea/Model/Entities/BasketElement.php b/lib/Alchemy/Phrasea/Model/Entities/BasketElement.php
index 45c5598696..80af7802fc 100644
--- a/lib/Alchemy/Phrasea/Model/Entities/BasketElement.php
+++ b/lib/Alchemy/Phrasea/Model/Entities/BasketElement.php
@@ -138,8 +138,8 @@ class BasketElement
public function setRecord(\record_adapter $record)
{
- $this->setRecordId($record->get_record_id());
- $this->setSbasId($record->get_sbas_id());
+ $this->setRecordId($record->getRecordId());
+ $this->setSbasId($record->getDataboxId());
}
/**
diff --git a/lib/Alchemy/Phrasea/Model/Entities/FeedEntry.php b/lib/Alchemy/Phrasea/Model/Entities/FeedEntry.php
index b8fe006db2..bbd33b2be5 100644
--- a/lib/Alchemy/Phrasea/Model/Entities/FeedEntry.php
+++ b/lib/Alchemy/Phrasea/Model/Entities/FeedEntry.php
@@ -259,7 +259,7 @@ class FeedEntry
/**
* Get items
*
- * @return \Doctrine\Common\Collections\Collection
+ * @return FeedItem[]|\Doctrine\Common\Collections\Collection
*/
public function getItems()
{
diff --git a/lib/Alchemy/Phrasea/Model/Entities/OrderElement.php b/lib/Alchemy/Phrasea/Model/Entities/OrderElement.php
index d232795067..010049ab98 100644
--- a/lib/Alchemy/Phrasea/Model/Entities/OrderElement.php
+++ b/lib/Alchemy/Phrasea/Model/Entities/OrderElement.php
@@ -80,7 +80,7 @@ class OrderElement
}
/**
- * @return mixed
+ * @return User|null
*/
public function getOrderMaster()
{
diff --git a/lib/Alchemy/Phrasea/Model/Entities/StoryWZ.php b/lib/Alchemy/Phrasea/Model/Entities/StoryWZ.php
index c7fdd93a3a..8761a77865 100644
--- a/lib/Alchemy/Phrasea/Model/Entities/StoryWZ.php
+++ b/lib/Alchemy/Phrasea/Model/Entities/StoryWZ.php
@@ -116,8 +116,8 @@ class StoryWZ
public function setRecord(\record_adapter $record)
{
- $this->setRecordId($record->get_record_id());
- $this->setSbasId($record->get_sbas_id());
+ $this->setRecordId($record->getRecordId());
+ $this->setSbasId($record->getDataboxId());
}
/**
* @param User $user
diff --git a/lib/Alchemy/Phrasea/Model/Manipulator/LazaretManipulator.php b/lib/Alchemy/Phrasea/Model/Manipulator/LazaretManipulator.php
index 6980775102..7febfbc983 100644
--- a/lib/Alchemy/Phrasea/Model/Manipulator/LazaretManipulator.php
+++ b/lib/Alchemy/Phrasea/Model/Manipulator/LazaretManipulator.php
@@ -8,6 +8,7 @@
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Model\Manipulator;
+
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Border;
use Alchemy\Phrasea\Border\Attribute\AttributeInterface;
@@ -17,6 +18,8 @@ use Doctrine\ORM\EntityRepository;
use PHPExiftool\Driver\Metadata\Metadata;
use Symfony\Component\Filesystem\Exception\IOException;
use Symfony\Component\Filesystem\Filesystem;
+
+
class LazaretManipulator
{
/** @var Application */
@@ -31,6 +34,7 @@ class LazaretManipulator
* @var EntityManager
*/
private $entityManager;
+
public function __construct(Application $app, EntityRepository $repository, Filesystem $fileSystem, EntityManager $entityManager)
{
$this->app = $app;
@@ -38,23 +42,29 @@ class LazaretManipulator
$this->fileSystem = $fileSystem;
$this->entityManager = $entityManager;
}
+
public function deny($lazaret_id)
{
$ret = ['success' => false, 'message' => '', 'result' => []];
+
/** @var LazaretFile $lazaretFile */
$lazaretFile = $this->repository->find($lazaret_id);
if (null === $lazaretFile) {
$ret['message'] = $this->app->trans('File is not present in quarantine anymore, please refresh');
+
return $ret;
}
+
try {
$this->denyLazaretFile($lazaretFile);
$ret['success'] = true;
} catch (\Exception $e) {
// No-op
}
+
return $ret;
}
+
/**
* Empty lazaret
*
@@ -74,14 +84,17 @@ class LazaretManipulator
'max' => '',
)
);
+
if( $maxTodo <= 0) {
$maxTodo = -1; // all
}
$ret['result']['max'] = $maxTodo;
+
$ret['result']['tobedone'] = (int) $this->repository->createQueryBuilder('id')
->select('COUNT(id)')
->getQuery()
->getSingleScalarResult();
+
if($maxTodo == -1) {
// all
$lazaretFiles = $this->repository->findAll();
@@ -89,7 +102,9 @@ class LazaretManipulator
// limit maxTodo
$lazaretFiles = $this->repository->findBy(array(), null, $maxTodo);
}
+
$this->entityManager->beginTransaction();
+
try {
foreach ($lazaretFiles as $lazaretFile) {
$this->denyLazaretFile($lazaretFile);
@@ -102,20 +117,28 @@ class LazaretManipulator
$ret['message'] = $this->app->trans('An error occured');
}
$ret['result']['todo'] = $ret['result']['tobedone'] - $ret['result']['done'];
+
return $ret;
}
+
+
public function add($file_id, $keepAttributes=true, Array $attributesToKeep=[])
{
$ret = ['success' => false, 'message' => '', 'result' => []];
+
/* @var LazaretFile $lazaretFile */
$lazaretFile = $this->repository->find($file_id);
+
if (null === $lazaretFile) {
$ret['message'] = $this->app->trans('File is not present in quarantine anymore, please refresh');
+
return $ret;
}
+
$path = $this->app['tmp.lazaret.path'];
$lazaretFileName = $path .'/'.$lazaretFile->getFilename();
$lazaretThumbFileName = $path .'/'.$lazaretFile->getThumbFilename();
+
try {
$borderFile = Border\File::buildFromPathfile(
$lazaretFileName,
@@ -123,12 +146,14 @@ class LazaretManipulator
$this->app,
$lazaretFile->getOriginalName()
);
+
//Post record creation
/** @var \record_adapter $record */
$record = null;
$callBack = function ($element) use (&$record) {
$record = $element;
};
+
//Force creation record
$this->getBorderManager()->process(
$lazaretFile->getSession(),
@@ -136,10 +161,13 @@ class LazaretManipulator
$callBack,
Border\Manager::FORCE_RECORD
);
+
if ($keepAttributes) {
//add attribute
+
$metaFields = new Border\MetaFieldsBag();
$metadataBag = new Border\MetadataBag();
+
foreach ($lazaretFile->getAttributes() as $attr) {
//Check which ones to keep
if (!!count($attributesToKeep)) {
@@ -147,11 +175,13 @@ class LazaretManipulator
continue;
}
}
+
try {
$attribute = Border\Attribute\Factory::getFileAttribute($this->app, $attr->getName(), $attr->getValue());
} catch (\InvalidArgumentException $e) {
continue;
}
+
switch ($attribute->getName()) {
case AttributeInterface::NAME_METADATA:
/** @var Metadata $value */
@@ -164,7 +194,7 @@ class LazaretManipulator
$value->appendChild($record);
break;
case AttributeInterface::NAME_STATUS:
- $record->set_binary_status($attribute->getValue());
+ $record->setStatus($attribute->getValue());
break;
case AttributeInterface::NAME_METAFIELD:
/** @var Border\Attribute\MetaField $attribute */
@@ -172,25 +202,32 @@ class LazaretManipulator
break;
}
}
- $data = $metadataBag->toMetadataArray($record->get_databox()->get_meta_structure());
+
+ $data = $metadataBag->toMetadataArray($record->getDatabox()->get_meta_structure());
$record->set_metadatas($data);
- $fields = $metaFields->toMetadataArray($record->get_databox()->get_meta_structure());
+
+ $fields = $metaFields->toMetadataArray($record->getDatabox()->get_meta_structure());
$record->set_metadatas($fields);
}
+
//Delete lazaret file
$this->entityManager->remove($lazaretFile);
$this->entityManager->flush();
+
$ret['success'] = true;
} catch (\Exception $e) {
$ret['message'] = $this->app->trans('An error occured');
}
+
try {
$this->fileSystem->remove([$lazaretFileName, $lazaretThumbFileName]);
} catch (IOException $e) {
// no-op
}
+
return $ret;
}
+
/**
* @return Border\Manager
*/
@@ -198,19 +235,24 @@ class LazaretManipulator
{
return $this->app['border-manager'];
}
+
protected function denyLazaretFile(LazaretFile $lazaretFile)
{
$path = $this->app['tmp.lazaret.path'];
$lazaretFileName = $path .'/'.$lazaretFile->getFilename();
$lazaretThumbFileName = $path .'/'.$lazaretFile->getThumbFilename();
+
$this->entityManager->remove($lazaretFile);
$this->entityManager->flush();
+
try {
$this->fileSystem->remove([$lazaretFileName, $lazaretThumbFileName]);
} catch (IOException $e) {
// no-op
}
+
return $this;
}
-}
+
+}
diff --git a/lib/Alchemy/Phrasea/Model/Repositories/BasketRepository.php b/lib/Alchemy/Phrasea/Model/Repositories/BasketRepository.php
index 7f02a63ba2..6304f3eaa6 100644
--- a/lib/Alchemy/Phrasea/Model/Repositories/BasketRepository.php
+++ b/lib/Alchemy/Phrasea/Model/Repositories/BasketRepository.php
@@ -196,7 +196,7 @@ class BasketRepository extends EntityRepository
AND b.user = :usr_id';
$params = [
- 'record_id' => $record->get_record_id(),
+ 'record_id' => $record->getRecordId(),
'usr_id' => $user->getId()
];
diff --git a/lib/Alchemy/Phrasea/Model/Repositories/StoryWZRepository.php b/lib/Alchemy/Phrasea/Model/Repositories/StoryWZRepository.php
index 9b6f3f1605..d973d9ccdf 100644
--- a/lib/Alchemy/Phrasea/Model/Repositories/StoryWZRepository.php
+++ b/lib/Alchemy/Phrasea/Model/Repositories/StoryWZRepository.php
@@ -99,8 +99,8 @@ class StoryWZRepository extends EntityRepository
{
$story = $this->findOneBy([
'user' => $user->getId(),
- 'sbas_id' => $Story->get_sbas_id(),
- 'record_id' => $Story->get_record_id(),
+ 'sbas_id' => $Story->getDataboxId(),
+ 'record_id' => $Story->getRecordId(),
]);
if ($story) {
@@ -129,8 +129,8 @@ class StoryWZRepository extends EntityRepository
$query = $this->_em->createQuery($dql);
$query->setParameters([
- 'sbas_id' => $Story->get_sbas_id(),
- 'record_id' => $Story->get_record_id(),
+ 'sbas_id' => $Story->getDataboxId(),
+ 'record_id' => $Story->getRecordId(),
]);
/** @var StoryWZ[] $stories */
diff --git a/lib/Alchemy/Phrasea/Model/Serializer/CaptionSerializer.php b/lib/Alchemy/Phrasea/Model/Serializer/CaptionSerializer.php
index 10af2018cf..3c0618e949 100644
--- a/lib/Alchemy/Phrasea/Model/Serializer/CaptionSerializer.php
+++ b/lib/Alchemy/Phrasea/Model/Serializer/CaptionSerializer.php
@@ -1,9 +1,8 @@
technicalDataService = $technicalDataService;
+ }
+
+ /**
+ * @param \caption_record $caption
+ * @param string $format
+ * @param bool $includeBusinessFields
+ * @return string
+ * @throws \Exception
+ */
public function serialize(\caption_record $caption, $format, $includeBusinessFields = false)
{
switch ($format) {
case self::SERIALIZE_XML:
- return $this->serializeXML($caption, (Boolean) $includeBusinessFields);
- break;
+ return $this->serializeXML($caption, (bool) $includeBusinessFields);
case self::SERIALIZE_YAML:
- return $this->serializeYAML($caption, (Boolean) $includeBusinessFields);
- break;
+ return $this->serializeYAML($caption, (bool) $includeBusinessFields);
case self::SERIALIZE_JSON:
- return $this->serializeJSON($caption, (Boolean) $includeBusinessFields);
- break;
+ return $this->serializeJSON($caption, (bool) $includeBusinessFields);
default:
throw new \Exception(sprintf('Unknown format %s', $format));
- break;
}
}
@@ -47,6 +72,11 @@ class CaptionSerializer extends AbstractSerializer
return \p4string::jsonencode($this->toArray($caption, $includeBusinessFields));
}
+ /**
+ * @param \caption_record $caption
+ * @param bool $includeBusinessFields
+ * @return array
+ */
public function toArray(\caption_record $caption, $includeBusinessFields)
{
$buffer = [];
@@ -77,7 +107,7 @@ class CaptionSerializer extends AbstractSerializer
$dom_doc->standalone = true;
$record = $dom_doc->createElement('record');
- $record->setAttribute('record_id', $caption->get_record()->get_record_id());
+ $record->setAttribute('record_id', $caption->getRecordReference()->getRecordId());
$dom_doc->appendChild($record);
$description = $dom_doc->createElement('description');
$record->appendChild($description);
@@ -96,7 +126,8 @@ class CaptionSerializer extends AbstractSerializer
$doc = $dom_doc->createElement('doc');
- $tc_datas = $caption->get_record()->get_technical_infos()->getValues();
+ $technicalData = $this->getTechnicalDataService()->fetchRecordsTechnicalData([$caption->getRecordReference()]);
+ $tc_datas = $technicalData[0]->getValues();
foreach ($tc_datas as $key => $data) {
$doc->setAttribute($key, $data);
@@ -106,4 +137,27 @@ class CaptionSerializer extends AbstractSerializer
return $dom_doc->saveXML();
}
+
+ /**
+ * @return TechnicalDataService
+ * @throws \UnexpectedValueException
+ */
+ private function getTechnicalDataService()
+ {
+ if (!$this->technicalDataService instanceof TechnicalDataService) {
+ $instance = call_user_func($this->technicalDataService);
+
+ if (!$instance instanceof TechnicalDataService) {
+ throw new \UnexpectedValueException(sprintf(
+ 'Expected a %s instance, got %s.',
+ TechnicalDataService::class,
+ is_object($instance) ? get_class($instance) : gettype($instance)
+ ));
+ }
+
+ $this->technicalDataService = $instance;
+ }
+
+ return $this->technicalDataService;
+ }
}
diff --git a/lib/Alchemy/Phrasea/Model/Serializer/ESRecordSerializer.php b/lib/Alchemy/Phrasea/Model/Serializer/ESRecordSerializer.php
index e3a991c436..8c63c947dd 100644
--- a/lib/Alchemy/Phrasea/Model/Serializer/ESRecordSerializer.php
+++ b/lib/Alchemy/Phrasea/Model/Serializer/ESRecordSerializer.php
@@ -50,7 +50,7 @@ class ESRecordSerializer extends AbstractSerializer
}
$i = 0;
- foreach (preg_split('//', strrev($record->get_status()), -1, PREG_SPLIT_NO_EMPTY) as $val) {
+ foreach (preg_split('//', strrev($record->getStatus()), -1, PREG_SPLIT_NO_EMPTY) as $val) {
$status['status-'.$i] = (int) $val;
$i++;
}
diff --git a/lib/Alchemy/Phrasea/Order/Controller/ApiOrderController.php b/lib/Alchemy/Phrasea/Order/Controller/ApiOrderController.php
new file mode 100644
index 0000000000..2b0e05a618
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Order/Controller/ApiOrderController.php
@@ -0,0 +1,260 @@
+decodeJsonBody($request, 'orders.json#/definitions/order_request');
+
+ $availableRecords = $this->toRequestedRecords($data->data->records);
+ $records = $this->filterOrderableRecords($availableRecords);
+
+ $recordRequest = new RecordsRequest($records, new ArrayCollection($availableRecords), null, RecordsRequest::FLATTEN_YES);
+
+ $filler = new OrderFiller($this->app['repo.collection-references'], $this->app['orm.em']);
+
+ $filler->assertAllRecordsHaveOrderMaster($recordRequest);
+
+ $order = new Order();
+ $order->setUser($this->getAuthenticatedUser());
+ $order->setDeadline(new \DateTime($data->data->deadline, new \DateTimeZone('UTC')));
+ $order->setOrderUsage($data->data->usage);
+
+ $filler->fillOrder($order, $recordRequest);
+
+ $this->dispatch(PhraseaEvents::ORDER_CREATE, new OrderEvent($order));
+
+ $resource = new Item($order, $this->getOrderTransformer());
+
+ return $this->returnResourceResponse($request, ['elements'], $resource);
+ }
+
+ public function indexAction(Request $request)
+ {
+ $page = max((int) $request->get('page', '1'), 1);
+ $perPage = min(max((int)$request->get('per_page', '10'), 1), 100);
+ $fractal = $this->buildFractalManager($request->get('includes', []));
+
+ $routeGenerator = function ($page) use ($perPage) {
+ return $this->app->path('api_v2_orders_index', [
+ 'page' => $page,
+ 'per_page' => $perPage,
+ ]);
+ };
+
+ $builder = $this->app['repo.orders']->createQueryBuilder('o');
+ $builder
+ ->where($builder->expr()->eq('o.user', $this->getAuthenticatedUser()->getId()))
+ ;
+
+ if (in_array('elements', $fractal->getRequestedIncludes(), false)) {
+ $builder
+ ->addSelect('e')
+ ->leftJoin('o.elements', 'e')
+ ;
+ }
+
+ $collection = $this->getViewBuilder()->buildViews(
+ $builder->getQuery()->getResult(),
+ $fractal->getRequestedIncludes()
+ );
+
+ $resource = new Collection($collection, $this->getOrderTransformer());
+
+ $pager = new Pagerfanta(new DoctrineORMAdapter($builder, false));
+ $pager->setCurrentPage($page);
+ $pager->setMaxPerPage($perPage);
+
+ $resource->setPaginator(new PagerfantaPaginatorAdapter($pager, $routeGenerator));
+
+ return $this->returnResourceResponse($request, $fractal, $resource);
+ }
+
+ /**
+ * @param Request $request
+ * @param int $orderId
+ * @return Response
+ */
+ public function showAction(Request $request, $orderId)
+ {
+ $order = $this->findOr404($orderId);
+
+ $fractal = $this->buildFractalManager($request->get('includes', []));
+
+ if ($order->getUser()->getId() !== $this->getAuthenticatedUser()->getId()) {
+ throw new AccessDeniedHttpException(sprintf('Cannot access order "%d"', $order->getId()));
+ }
+
+ $model = $this->getViewBuilder()->buildView($order, $fractal->getRequestedIncludes());
+ $resource = new Item($model, $this->getOrderTransformer());
+
+ return $this->returnResourceResponse($request, $fractal, $resource);
+ }
+
+ public function acceptElementsAction(Request $request, $orderId)
+ {
+ $elementIds = $this->fetchElementIdsFromRequest($request);
+
+ $elements = $this->doAcceptElements($orderId, $elementIds, $this->getAuthenticatedUser());
+
+ $resource = new Collection($elements, function (BasketElement $element) {
+ return [
+ 'id' => $element->getId(),
+ 'created' => $element->getCreated(),
+ 'databox_id' => $element->getSbasId(),
+ 'record_id' => $element->getRecordId(),
+ 'index' => $element->getOrd(),
+ ];
+ });
+
+ return $this->returnResourceResponse($request, [], $resource);
+ }
+
+ public function denyElementsAction(Request $request, $orderId)
+ {
+ $elementIds = $this->fetchElementIdsFromRequest($request);
+
+ $this->doDenyElements($orderId, $elementIds, $this->getAuthenticatedUser());
+
+ return Result::create($request, [])->createResponse();
+ }
+
+ /**
+ * @param array $records
+ * @return \record_adapter[]
+ */
+ private function toRequestedRecords(array $records)
+ {
+ $requestedRecords = [];
+
+ foreach ($records as $item) {
+ $requestedRecords[] = [
+ 'databox_id' => $item->databox_id,
+ 'record_id' => $item->record_id,
+ ];
+ }
+
+ return RecordReferenceCollection::fromArrayOfArray($requestedRecords)->toRecords($this->getApplicationBox());
+ }
+
+ /**
+ * @param \record_adapter[] $records
+ * @return \record_adapter[]
+ */
+ private function filterOrderableRecords(array $records)
+ {
+ $acl = $this->getAclForUser();
+
+ $filtered = [];
+
+ foreach ($records as $index => $record) {
+ if ($acl->has_right_on_base($record->getBaseId(), 'cancmd')) {
+ $filtered[$index] = $record;
+ }
+ }
+
+ return $filtered;
+ }
+
+ /**
+ * @return OrderTransformer
+ */
+ private function getOrderTransformer()
+ {
+ return new OrderTransformer(new OrderElementTransformer($this->app['media_accessor.subdef_url_generator']));
+ }
+
+ /**
+ * @param string|array $includes
+ * @return Manager
+ */
+ private function buildFractalManager($includes)
+ {
+ $fractal = new Manager();
+
+ $fractal->parseIncludes($includes ?: []);
+
+ return $fractal;
+ }
+
+ /**
+ * @param Request $request
+ * @param string|array|Manager $includes
+ * @param ResourceInterface $resource
+ * @return Response
+ */
+ private function returnResourceResponse(Request $request, $includes, ResourceInterface $resource)
+ {
+ $fractal = $includes instanceof Manager ? $includes : $this->buildFractalManager($includes);
+
+ return Result::create($request, $fractal->createData($resource)->toArray())->createResponse();
+ }
+
+ /**
+ * @param Request $request
+ * @return array
+ */
+ private function fetchElementIdsFromRequest(Request $request)
+ {
+ $data = $this->decodeJsonBody($request, 'orders.json#/definitions/order_element_collection');
+
+ $elementIds = [];
+
+ foreach ($data as $elementId) {
+ $elementIds[] = $elementId->id;
+ }
+
+ return $elementIds;
+ }
+
+ private function getViewBuilder()
+ {
+ return new OrderViewBuilder(
+ $this->app,
+ $this->getApplicationBox(),
+ $this->app['service.media_subdef']
+ );
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Order/Controller/BaseOrderController.php b/lib/Alchemy/Phrasea/Order/Controller/BaseOrderController.php
index eaee31a899..14f10cb5da 100644
--- a/lib/Alchemy/Phrasea/Order/Controller/BaseOrderController.php
+++ b/lib/Alchemy/Phrasea/Order/Controller/BaseOrderController.php
@@ -189,10 +189,12 @@ class BaseOrderController extends Controller
$references = new RecordReferenceCollection();
- foreach ($elements as $element) {
- $reference = RecordReference::createFromDataboxIdAndRecordId($element->getSbasId(), $element->getRecordId());
+ $basket->getElements()->forAll(function (BasketElement $element) use ($references) {
+ $references->addRecordReference($element->getSbasId(), $element->getRecordId());
+ });
- $references->addRecordReference($reference);
+ foreach ($elements as $element) {
+ $references->addRecordReference($element->getSbasId(), $element->getRecordId());
}
$groups = $references->groupPerDataboxId();
diff --git a/lib/Alchemy/Phrasea/Order/OrderElementTransformer.php b/lib/Alchemy/Phrasea/Order/OrderElementTransformer.php
new file mode 100644
index 0000000000..2e961dcf93
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Order/OrderElementTransformer.php
@@ -0,0 +1,108 @@
+urlGenerator = $urlGenerator;
+ }
+
+ public function transform(OrderElementView $model)
+ {
+ $element = $model->getElement();
+ $record = $model->getRecordReference();
+
+ $data = [
+ 'id' => $element->getId(),
+ 'record' => [
+ 'databox_id' => $record->getDataboxId(),
+ 'record_id' => $record->getRecordId(),
+ ],
+ ];
+
+ $data['status'] = 'pending';
+
+ if (null !== $element->getOrderMaster()) {
+ $data['validator_id'] = $element->getOrderMaster()->getId();
+ $data['status'] = $element->getDeny() ? 'rejected' : 'accepted';
+ }
+
+ return $data;
+ }
+
+ public function includeResourceLinks(OrderElementView $model, ParamBag $params = null)
+ {
+ $parameterArray = $this->extractParamBagValues($params);
+ $usedParams = array_keys(array_filter($parameterArray));
+
+ if (array_diff($usedParams, $this->validParams)) {
+ throw new \RuntimeException(sprintf(
+ 'Invalid param(s): "%s". Valid param(s): "%s"',
+ implode(', ', $usedParams),
+ implode(', ', $this->validParams)
+ ));
+ }
+
+ list ($ttl) = $parameterArray['ttl'];
+
+ if (null === $ttl) {
+ $ttl = $this->urlGenerator->getDefaultTTL();
+ }
+
+ $subdefs = $model->getOrderableMediaSubdefs();
+ $urls = $this->urlGenerator->generateMany($model->getAuthenticatedUser(), $subdefs, $ttl);
+
+ $data = array_map(null, $subdefs, $urls);
+
+ return $this->collection($data, function (array $data) use ($ttl) {
+ /** @var \media_subdef $subdef */
+ list($subdef, $url) = $data;
+
+ return [
+ 'name' => $subdef->get_name(),
+ 'url' => $url,
+ 'url_ttl' => $ttl,
+ ];
+ });
+ }
+
+ /**
+ * @param ParamBag|null $params
+ * @return array
+ */
+ private function extractParamBagValues(ParamBag $params = null)
+ {
+ $array = array_fill_keys($this->validParams, null);
+
+ if ($params) {
+ array_walk($array, function (&$value, $key) use ($params) {
+ $value = $params[$key];
+ });
+ }
+
+ return $array;
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Order/OrderElementView.php b/lib/Alchemy/Phrasea/Order/OrderElementView.php
new file mode 100644
index 0000000000..a4d2c31135
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Order/OrderElementView.php
@@ -0,0 +1,95 @@
+element = $element;
+ $this->record = $record;
+ $this->user = $user;
+ }
+
+ /**
+ * @return OrderElement
+ */
+ public function getElement()
+ {
+ return $this->element;
+ }
+
+ /**
+ * @return RecordReferenceInterface
+ */
+ public function getRecordReference()
+ {
+ return $this->record;
+ }
+
+ /**
+ * @return User
+ */
+ public function getAuthenticatedUser()
+ {
+ return $this->user;
+ }
+
+ /**
+ * @param \media_subdef[] $subdefs
+ */
+ public function setOrderableMediaSubdefs($subdefs)
+ {
+ Assertion::allIsInstanceOf($subdefs, \media_subdef::class);
+
+ $this->subdefs = $subdefs instanceof \Traversable ? iterator_to_array($subdefs) : $subdefs;
+ }
+
+ /**
+ * @return \media_subdef[]
+ */
+ public function getOrderableMediaSubdefs()
+ {
+ return $this->subdefs;
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Order/OrderTransformer.php b/lib/Alchemy/Phrasea/Order/OrderTransformer.php
new file mode 100644
index 0000000000..9838e9dafa
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Order/OrderTransformer.php
@@ -0,0 +1,56 @@
+elementTransformer = $elementTransformer;
+ }
+
+ public function transform(OrderView $view)
+ {
+ $order = $view->getOrder();
+
+ $data = [
+ 'id' => (int)$order->getId(),
+ 'owner_id' => (int)$order->getUser()->getId(),
+ 'created' => $order->getCreatedOn()->format(DATE_ATOM),
+ 'usage' => $order->getOrderUsage(),
+ 'status' => 0 === $order->getTodo() ? 'finished' : 'pending'
+ ];
+
+ if ($order->getDeadline()) {
+ $data['deadline'] = $order->getDeadline()->format(DATE_ATOM);
+ }
+
+ return $data;
+ }
+
+ public function includeElements(OrderView $order)
+ {
+ $elements = $order->getElements();
+
+ return $this->collection($elements, $this->elementTransformer);
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Order/OrderValidator.php b/lib/Alchemy/Phrasea/Order/OrderValidator.php
index d0e919040f..55339c2697 100644
--- a/lib/Alchemy/Phrasea/Order/OrderValidator.php
+++ b/lib/Alchemy/Phrasea/Order/OrderValidator.php
@@ -137,7 +137,7 @@ class OrderValidator
throw new \RuntimeException('At least one collection was not found.');
}
- $references->addRecordReference(RecordReference::createFromDataboxIdAndRecordId(
+ $references->add(RecordReference::createFromDataboxIdAndRecordId(
$databoxIdMap[$orderElement->getBaseId()],
$orderElement->getRecordId()
));
diff --git a/lib/Alchemy/Phrasea/Order/OrderView.php b/lib/Alchemy/Phrasea/Order/OrderView.php
new file mode 100644
index 0000000000..cd43659ba1
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Order/OrderView.php
@@ -0,0 +1,61 @@
+order = $order;
+ }
+
+ /**
+ * @param OrderElementView[] $viewElements
+ */
+ public function setViewElements($viewElements)
+ {
+ Assertion::allIsInstanceOf($viewElements, OrderElementView::class);
+
+ $this->viewElements = $viewElements instanceof \Traversable ? iterator_to_array($viewElements) : $viewElements;
+ }
+
+ /**
+ * @return Order
+ */
+ public function getOrder()
+ {
+ return $this->order;
+ }
+
+ /**
+ * @return OrderElementView[]
+ */
+ public function getElements()
+ {
+ return $this->viewElements;
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Order/OrderViewBuilder.php b/lib/Alchemy/Phrasea/Order/OrderViewBuilder.php
new file mode 100644
index 0000000000..bd31b48dbf
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Order/OrderViewBuilder.php
@@ -0,0 +1,221 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Alchemy\Phrasea\Order;
+
+use Alchemy\Phrasea\Application;
+use Alchemy\Phrasea\Databox\Subdef\MediaSubdefService;
+use Alchemy\Phrasea\Model\Entities\Order;
+use Alchemy\Phrasea\Model\Entities\OrderElement;
+use Alchemy\Phrasea\Model\RecordReferenceInterface;
+use Alchemy\Phrasea\Record\RecordReference;
+use Alchemy\Phrasea\Record\RecordReferenceCollection;
+use Assert\Assertion;
+
+class OrderViewBuilder
+{
+
+ /**
+ * @var Application
+ */
+ private $application;
+
+ /**
+ * @var \appbox
+ */
+ private $applicationBox;
+
+ /**
+ * @var MediaSubdefService
+ */
+ private $mediaSubdefService;
+
+ /**
+ * @param Application $application
+ * @param \appbox $appbox
+ * @param MediaSubdefService $subdefService
+ */
+ public function __construct(Application $application, \appbox $appbox, MediaSubdefService $subdefService)
+ {
+ $this->application = $application;
+ $this->applicationBox = $appbox;
+ $this->mediaSubdefService = $subdefService;
+ }
+
+ public function buildView(Order $order, array $includes)
+ {
+ $view = new OrderView($order);
+
+ $this->fillViews([$view], $includes);
+
+ return $view;
+ }
+
+ /**
+ * @param Order[] $orders
+ * @param string[] $includes
+ * @return OrderView[]
+ */
+ public function buildViews(array $orders, array $includes)
+ {
+ Assertion::allIsInstanceOf($orders, Order::class);
+
+ $views = array_map(function (Order $order) {
+ return new OrderView($order);
+ }, $orders);
+
+ $this->fillViews($views, $includes);
+
+ return $views;
+ }
+
+ /**
+ * @param OrderView[] $views
+ * @param array $includes
+ * @return void
+ */
+ private function fillViews(array $views, array $includes)
+ {
+ if (!in_array('elements', $includes, true)) {
+ return;
+ }
+
+ $elements = $this->gatherElements($views);
+
+ $allElements = $elements ? call_user_func_array('array_merge', $elements) : [];
+ $allElements = array_combine(
+ array_map(function (OrderElement $element) {
+ return $element->getId();
+ }, $allElements),
+ $allElements
+ );
+
+ if (!$allElements) {
+ return;
+ }
+
+ $collectionToDataboxMap = $this->mapBaseIdToDataboxId($allElements);
+
+ $records = RecordReferenceCollection::fromListExtractor(
+ $allElements,
+ function (OrderElement $element) use ($collectionToDataboxMap) {
+ return isset($collectionToDataboxMap[$element->getBaseId()])
+ ? [$collectionToDataboxMap[$element->getBaseId()], $element->getRecordId()]
+ : null;
+ },
+ function (array $data) {
+ list ($databoxId, $recordId) = $data;
+
+ return RecordReference::createFromDataboxIdAndRecordId($databoxId, $recordId);
+ }
+ );
+
+ $this->createOrderElementViews($views, $elements, $records);
+
+ if (!in_array('elements.resource_links', $includes, true)) {
+ return;
+ }
+
+ // Load all records
+ $records->toRecords($this->applicationBox);
+
+ // Load all subdefs
+ $subdefs = $this->mediaSubdefService->findSubdefsFromRecordReferenceCollection($records);
+ \media_Permalink_Adapter::getMany($this->application, $subdefs);
+
+ $orderableSubdefs = [];
+
+ foreach ($subdefs as $subdef) {
+ $databoxId = $subdef->get_sbas_id();
+ $recordId = $subdef->get_record_id();
+
+ if (!isset($orderableSubdefs[$databoxId][$recordId])) {
+ $orderableSubdefs[$databoxId][$recordId] = [];
+ }
+
+ $orderableSubdefs[$databoxId][$recordId][] = $subdef;
+ }
+
+ foreach ($views as $model) {
+ foreach ($model->getElements() as $element) {
+ $databoxId = $collectionToDataboxMap[$element->getElement()->getBaseId()];
+ $recordId = $element->getElement()->getRecordId();
+
+ if (isset($orderableSubdefs[$databoxId][$recordId])) {
+ $element->setOrderableMediaSubdefs($orderableSubdefs[$databoxId][$recordId]);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * @param OrderView[] $orderViews
+ * @return OrderElement[][]
+ */
+ private function gatherElements(array $orderViews)
+ {
+ Assertion::allIsInstanceOf($orderViews, OrderView::class);
+
+ $elements = [];
+
+ foreach ($orderViews as $index => $orderView) {
+ $elements[$index] = $orderView->getOrder()->getElements()->toArray();
+ }
+
+ return $elements;
+ }
+
+ /**
+ * @param OrderElement[] $elements
+ * @return array
+ */
+ private function mapBaseIdToDataboxId(array $elements)
+ {
+ $baseIds = array_keys(array_reduce($elements, function (array &$baseIds, OrderElement $element) {
+ $baseIds[$element->getBaseId()] = true;
+
+ return $baseIds;
+ }, []));
+
+ $collectionToDataboxMap = [];
+
+ foreach ($this->application['repo.collection-references']->findMany($baseIds) as $collectionReference) {
+ $collectionToDataboxMap[$collectionReference->getBaseId()] = $collectionReference->getDataboxId();
+ }
+
+ return $collectionToDataboxMap;
+ }
+
+ /**
+ * @param OrderView[] $orderViews
+ * @param OrderElement[][] $elements
+ * @param RecordReferenceInterface[]|RecordReferenceCollection $records
+ * @return void
+ */
+ private function createOrderElementViews(array $orderViews, $elements, $records)
+ {
+ $user = $this->application->getAuthenticatedUser();
+
+ foreach ($orderViews as $index => $model) {
+ $models = [];
+
+ /** @var OrderElement $element */
+ foreach ($elements[$index] as $elementIndex => $element) {
+ if (isset($records[$element->getId()])) {
+ $models[$elementIndex] = new OrderElementView($element, $records[$element->getId()], $user);
+ }
+ }
+
+ $model->setViewElements($models);
+ }
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Out/Module/PDF.php b/lib/Alchemy/Phrasea/Out/Module/PDF.php
index 8fe925d8b3..bdbd809655 100644
--- a/lib/Alchemy/Phrasea/Out/Module/PDF.php
+++ b/lib/Alchemy/Phrasea/Out/Module/PDF.php
@@ -166,7 +166,7 @@ class PDF
$fimg = $subdef->getRealPath();
- if (!$this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($rec->get_base_id(), "nowatermark")
+ if (!$this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($rec->getBaseId(), "nowatermark")
&& $subdef->get_type() == \media_subdef::TYPE_IMAGE) {
$fimg = \recordutils_image::watermark($this->app, $subdef);
}
@@ -258,7 +258,7 @@ class PDF
$y = $this->pdf->GetY();
- $t = \phrasea::bas_labels($rec->get_base_id(), $this->app);
+ $t = \phrasea::bas_labels($rec->getBaseId(), $this->app);
$this->pdf->SetFont(PhraseaPDF::FONT, '', 10);
$this->pdf->SetFillColor(220, 220, 220);
$this->pdf->SetLeftMargin($lmargin);
@@ -339,10 +339,10 @@ class PDF
$RIGHT_TEXT = "";
$RIGHT_IMG = NULL;
- $LEFT__IMG = $this->app['root.path'] . "/config/minilogos/logopdf_" . $rec->get_sbas_id() . ".jpg";
+ $LEFT__IMG = $this->app['root.path'] . "/config/minilogos/logopdf_" . $rec->getDataboxId() . ".jpg";
if (!is_file($LEFT__IMG)) {
- $databox = $rec->get_databox();
+ $databox = $rec->getDatabox();
$str = $databox->get_sxml_structure();
$vn = (string) ($str->pdfPrintLogo);
if (($vn * 1) == 1) {
@@ -350,7 +350,7 @@ class PDF
}
}
- $collection = \collection::getByBaseId($this->app, $rec->get_base_id());
+ $collection = \collection::getByBaseId($this->app, $rec->getBaseId());
$vn = "";
if (false !== $str = simplexml_load_string($collection->get_prefs())) {
@@ -358,9 +358,9 @@ class PDF
}
if ($vn == "" || $vn == "1") {
- $RIGHT_TEXT = \phrasea::bas_labels($rec->get_base_id(), $this->app);
+ $RIGHT_TEXT = \phrasea::bas_labels($rec->getBaseId(), $this->app);
} elseif ($vn == "2") {
- $RIGHT_IMG = $this->app['root.path'] . "/config/minilogos/" . $rec->get_base_id();
+ $RIGHT_IMG = $this->app['root.path'] . "/config/minilogos/" . $rec->getBaseId();
}
$xtmp = $this->pdf->GetX();
@@ -438,7 +438,7 @@ class PDF
$f = $subdef->getRealPath();
- if (!$this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($rec->get_base_id(), "nowatermark")
+ if (!$this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($rec->getBaseId(), "nowatermark")
&& $subdef->get_type() == \media_subdef::TYPE_IMAGE)
$f = \recordutils_image::watermark($this->app, $subdef);
diff --git a/lib/Alchemy/Phrasea/Record/RecordReferenceCollection.php b/lib/Alchemy/Phrasea/Record/RecordReferenceCollection.php
index 802d4a9e67..97bb80ceef 100644
--- a/lib/Alchemy/Phrasea/Record/RecordReferenceCollection.php
+++ b/lib/Alchemy/Phrasea/Record/RecordReferenceCollection.php
@@ -1,5 +1,5 @@
$records
@@ -28,7 +28,7 @@ class RecordReferenceCollection implements \IteratorAggregate
foreach ($records as $index => $record) {
if (isset($record['id'])) {
$references[$index] = RecordReference::createFromRecordReference($record['id']);
- } elseif (isset($record['databox_id']) && isset($record['record_id'])) {
+ } elseif (isset($record['databox_id'], $record['record_id'])) {
$references[$index] = RecordReference::createFromDataboxIdAndRecordId($record['databox_id'], $record['record_id']);
}
}
@@ -36,6 +36,43 @@ class RecordReferenceCollection implements \IteratorAggregate
return new self($references);
}
+ /**
+ * Append all RecordReferences extracted via call to extractor on each element
+ *
+ * @param array|\Traversable $list List of elements to process
+ * @param callable $extractor Extracts data from each element or return null if unavailable
+ * @param callable $creator Creates Reference from extracted data. no-op when null
+ * @return RecordReferenceCollection
+ */
+ public static function fromListExtractor($list, callable $extractor, callable $creator = null)
+ {
+ Assertion::isTraversable($list);
+
+ $references = [];
+
+ if (null === $creator) {
+ $creator = function ($data) {
+ return $data;
+ };
+ }
+
+ foreach ($list as $index => $item) {
+ $data = $extractor($item);
+
+ if (null === $data) {
+ continue;
+ }
+
+ $reference = $creator($data);
+
+ if ($reference instanceof RecordReferenceInterface) {
+ $references[$index] = $reference;
+ }
+ }
+
+ return new self($references);
+ }
+
/**
* @var RecordReferenceInterface[]
*/
@@ -53,13 +90,35 @@ class RecordReferenceCollection implements \IteratorAggregate
{
Assertion::allIsInstanceOf($references, RecordReferenceInterface::class);
- $this->references = $references instanceof \Traversable ? iterator_to_array($references) : $references;
+ $this->references = $references instanceof \Traversable ? iterator_to_array($references, true) : $references;
}
- public function addRecordReference(RecordReferenceInterface $reference)
+ /**
+ * @param RecordReferenceInterface $reference
+ * @param null|string|int $index
+ */
+ public function add(RecordReferenceInterface $reference, $index = null)
{
- $this->references[] = $reference;
$this->groups = null;
+
+ if (null === $index) {
+ $this->references[] = $reference;
+
+ return;
+ }
+
+ $this->references[$index] = $reference;
+ }
+
+ /**
+ * @param int $databoxId
+ * @param int $recordId
+ * @param null|string|int $index
+ * @return void
+ */
+ public function addRecordReference($databoxId, $recordId, $index = null)
+ {
+ $this->add(RecordReference::createFromDataboxIdAndRecordId($databoxId, $recordId), $index);
}
public function getIterator()
@@ -115,8 +174,48 @@ class RecordReferenceCollection implements \IteratorAggregate
}
}
- ksort($records);
+ $indexes = array_flip(array_keys($this->references));
- return array_values($records);
+ uksort($records, function ($keyA, $keyB) use ($indexes) {
+ $indexA = $indexes[$keyA];
+ $indexB = $indexes[$keyB];
+
+ if ($indexA < $indexB) {
+ return -1;
+ } elseif ($indexA > $indexB) {
+ return 1;
+ }
+
+ return 0;
+ });
+
+ return $records;
+ }
+
+ public function offsetExists($offset)
+ {
+ return isset($this->references[$offset]);
+ }
+
+ /**
+ * @param mixed $offset
+ * @return RecordReferenceInterface
+ */
+ public function offsetGet($offset)
+ {
+ return $this->references[$offset];
+ }
+
+ public function offsetSet($offset, $value)
+ {
+ Assertion::isInstanceOf($value, RecordReferenceInterface::class);
+
+ $this->add($value, $offset);
+ }
+
+ public function offsetUnset($offset)
+ {
+ unset($this->references[$offset]);
+ $this->groups = null;
}
}
diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php
index 4807f28b81..073325d510 100644
--- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php
+++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php
@@ -268,7 +268,7 @@ class ElasticSearchEngine implements SearchEngineInterface
/**
* {@inheritdoc}
*/
- public function query($string, $offset, $perPage, SearchEngineOptions $options = null)
+ public function query($string, SearchEngineOptions $options = null)
{
$options = $options ?: new SearchEngineOptions();
$context = $this->context_factory->createContext($options);
@@ -282,13 +282,15 @@ class ElasticSearchEngine implements SearchEngineInterface
// ask ES to return field _version (incremental version number of document)
$params['body']['version'] = true;
- $params['body']['from'] = $offset;
- $params['body']['size'] = $perPage;
+ $params['body']['from'] = $options->getFirstResult();
+ $params['body']['size'] = $options->getMaxResults();
if($this->options->getHighlight()) {
$params['body']['highlight'] = $this->buildHighlightRules($context);
}
- if ($aggs = $this->getAggregationQueryParams($options)) {
+ $aggs = $this->getAggregationQueryParams($options);
+
+ if ($aggs) {
$params['body']['aggs'] = $aggs;
}
@@ -314,7 +316,7 @@ class ElasticSearchEngine implements SearchEngineInterface
$results, // ArrayCollection of results
json_encode($query),
$res['took'], // duration
- $offset, // offset start
+ $options->getFirstResult(),
$res['hits']['total'], // available
$res['hits']['total'], // total
null, // error
@@ -369,16 +371,6 @@ class ElasticSearchEngine implements SearchEngineInterface
throw new RuntimeException('Elasticsearch engine currently does not support auto-complete.');
}
- /**
- * {@inheritdoc}
- */
- public function excerpt($query, $fields, \record_adapter $record, SearchEngineOptions $options = null)
- {
- //@todo implements
-
- return array();
- }
-
/**
* {@inheritdoc}
*/
diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticsearchSettingsFormType.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticsearchSettingsFormType.php
index 2bd893309e..7874269643 100644
--- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticsearchSettingsFormType.php
+++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticsearchSettingsFormType.php
@@ -30,6 +30,14 @@ class ElasticsearchSettingsFormType extends AbstractType
'label' => 'ElasticSearch index name',
'constraints' => new NotBlank(),
])
+ ->add('esSettingsDropIndexButton', 'button', [
+ 'label' => "Drop index",
+ 'attr' => ['data-id' => "esSettingsDropIndexButton"]
+ ])
+ ->add('esSettingsCreateIndexButton', 'button', [
+ 'label' => "Create index",
+ 'attr' => ['data-id' => "esSettingsCreateIndexButton"]
+ ])
->add('shards', 'integer', [
'label' => 'Number of shards',
'constraints' => new Range(['min' => 1]),
diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Mapping.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Mapping.php
index 2f44fcc7bd..aad818cc95 100644
--- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Mapping.php
+++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Mapping.php
@@ -36,6 +36,7 @@ class Mapping
const TYPE_LONG = 'long';
const TYPE_SHORT = 'short';
const TYPE_BYTE = 'byte';
+ const TYPE_IP = 'ip';
// Compound types
const TYPE_OBJECT = 'object';
@@ -49,6 +50,7 @@ class Mapping
self::TYPE_LONG,
self::TYPE_SHORT,
self::TYPE_BYTE,
+ self::TYPE_IP,
);
public function add($name, $type)
diff --git a/lib/Alchemy/Phrasea/SearchEngine/SearchEngineInterface.php b/lib/Alchemy/Phrasea/SearchEngine/SearchEngineInterface.php
index 4a388ba2ae..e0f993d70b 100644
--- a/lib/Alchemy/Phrasea/SearchEngine/SearchEngineInterface.php
+++ b/lib/Alchemy/Phrasea/SearchEngine/SearchEngineInterface.php
@@ -76,7 +76,7 @@ interface SearchEngineInterface
/**
*
- * @return an array of self::GEM_TYPE_* indexed types
+ * @return array an array of self::GEM_TYPE_* indexed types
*/
public function getAvailableTypes();
@@ -162,15 +162,12 @@ interface SearchEngineInterface
public function updateFeedEntry(FeedEntry $entry);
/**
- *
* @param string $query
- * @param integer $offset
- * @param integer $perPage
* @param SearchEngineOptions $options
*
* @return SearchEngineResult
*/
- public function query($query, $offset, $perPage, SearchEngineOptions $options = null);
+ public function query($query, SearchEngineOptions $options = null);
/**
* Return an array of suggestions corresponding to the last word of the
@@ -182,17 +179,6 @@ interface SearchEngineInterface
*/
public function autocomplete($query, SearchEngineOptions $options);
- /**
- * Highlight the fields of a record
- *
- * @param type $query
- * @param type $fields
- * @param \record_adapter $record
- *
- * @return array The array of highlighted fields
- */
- public function excerpt($query, $fields, \record_adapter $record, SearchEngineOptions $options = null);
-
/**
* Reset the cache of the SE (if applicable)
*
diff --git a/lib/Alchemy/Phrasea/SearchEngine/SearchEngineOptions.php b/lib/Alchemy/Phrasea/SearchEngine/SearchEngineOptions.php
index 0b1dad1798..ac682970c8 100644
--- a/lib/Alchemy/Phrasea/SearchEngine/SearchEngineOptions.php
+++ b/lib/Alchemy/Phrasea/SearchEngine/SearchEngineOptions.php
@@ -14,6 +14,8 @@ namespace Alchemy\Phrasea\SearchEngine;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Authentication\ACLProvider;
use Alchemy\Phrasea\Authentication\Authenticator;
+use Alchemy\Phrasea\Collection\Reference\CollectionReferenceCollection;
+use Assert\Assertion;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
@@ -47,9 +49,80 @@ class SearchEngineOptions
'stemming',
'sort_by',
'sort_ord',
- 'business_fields'
+ 'business_fields',
+ 'max_results',
+ 'first_result',
];
+ /**
+ * @param Application $app
+ * @return callable[]
+ */
+ private static function getHydrateMethods(Application $app)
+ {
+ $fieldNormalizer = function ($value) use ($app) {
+ return array_map(function ($serialized) use ($app) {
+ $data = explode('_', $serialized, 2);
+
+ return $app->findDataboxById($data[0])->get_meta_structure()->get_element($data[1]);
+ }, $value);
+ };
+
+ $collectionNormalizer = function ($value) use ($app) {
+ $references = new CollectionReferenceCollection($app['repo.collection-references']->findMany($value));
+
+ $collections = [];
+
+ foreach ($references->groupByDataboxIdAndCollectionId() as $databoxId => $indexes) {
+ $repository = $app['repo.collections-registry']->getRepositoryByDatabox($databoxId);
+
+ foreach ($indexes as $collectionId => $index) {
+ $collections[] = $repository->find($collectionId);
+ }
+ }
+
+ return $collections;
+ };
+
+ $optionSetter = function ($setter) {
+ return function ($value, SearchEngineOptions $options) use ($setter) {
+ $options->{$setter}($value);
+ };
+ };
+
+ return [
+ 'record_type' => $optionSetter('setRecordType'),
+ 'search_type' => $optionSetter('setSearchType'),
+ 'status' => $optionSetter('setStatus'),
+ 'date_min' => function ($value, SearchEngineOptions $options) {
+ $options->setMinDate($value ? \DateTime::createFromFormat(DATE_ATOM, $value) : null);
+ },
+ 'date_max' => function ($value, SearchEngineOptions $options) {
+ $options->setMaxDate($value ? \DateTime::createFromFormat(DATE_ATOM, $value) : null);
+ },
+ 'i18n' => function ($value, SearchEngineOptions $options) {
+ if ($value) {
+ $options->setLocale($value);
+ }
+ },
+ 'stemming' => $optionSetter('setStemming'),
+ 'date_fields' => function ($value, SearchEngineOptions $options) use ($fieldNormalizer) {
+ $options->setDateFields($fieldNormalizer($value));
+ },
+ 'fields' => function ($value, SearchEngineOptions $options) use ($fieldNormalizer) {
+ $options->setFields($fieldNormalizer($value));
+ },
+ 'collections' => function ($value, SearchEngineOptions $options) use ($collectionNormalizer) {
+ $options->onCollections($collectionNormalizer($value));
+ },
+ 'business_fields' => function ($value, SearchEngineOptions $options) use ($collectionNormalizer) {
+ $options->allowBusinessFieldsOn($collectionNormalizer($value));
+ },
+ 'first_result' => $optionSetter('setFirstResult'),
+ 'max_results' => $optionSetter('setMaxResults'),
+ ];
+ }
+
/** @var string */
protected $record_type;
@@ -77,6 +150,16 @@ class SearchEngineOptions
protected $sort_ord = self::SORT_MODE_DESC;
protected $business_fields = [];
+ /**
+ * @var int
+ */
+ private $max_results = 10;
+
+ /**
+ * @var int
+ */
+ private $first_result = 0;
+
/**
* Defines locale code to use for query
*
@@ -452,86 +535,30 @@ class SearchEngineOptions
$options = new static();
$options->disallowBusinessFields();
- $sort_by = $sort_ord = null;
+ $methods = self::getHydrateMethods($app);
+
+ $sort_by = null;
+ $methods['sort_by'] = function ($value) use (&$sort_by) {
+ $sort_by = $value;
+ };
+
+ $sort_ord = null;
+ $methods['sort_ord'] = function ($value) use (&$sort_ord) {
+ $sort_ord = $value;
+ };
foreach ($serialized as $key => $value) {
-
- switch (true) {
- case is_null($value):
- $value = null;
- break;
- case in_array($key, ['date_min', 'date_max']):
- $value = \DateTime::createFromFormat(DATE_ATOM, $value);
- break;
- case $value instanceof \stdClass:
- $tmpvalue = (array) $value;
- $value = [];
-
- foreach ($tmpvalue as $k => $data) {
- $k = ctype_digit($k) ? (int) $k : $k;
- $value[$k] = $data;
- }
- break;
- case in_array($key, ['date_fields', 'fields']):
- $value = array_map(function ($serialized) use ($app) {
- $data = explode('_', $serialized);
-
- return $app->findDataboxById($data[0])->get_meta_structure()->get_element($data[1]);
- }, $value);
- break;
- case in_array($key, ['collections', 'business_fields']):
- $value = array_map(function ($base_id) use ($app) {
- return \collection::getByBaseId($app, $base_id);
- }, $value);
- break;
+ if (!isset($methods[$key])) {
+ throw new \RuntimeException(sprintf('Unable to handle key `%s`', $key));
}
- switch ($key) {
- case 'record_type':
- $options->setRecordType($value);
- break;
- case 'search_type':
- $options->setSearchType($value);
- break;
- case 'status':
- $options->setStatus($value);
- break;
- case 'date_min':
- $options->setMinDate($value);
- break;
- case 'date_max':
- $options->setMaxDate($value);
- break;
- case 'i18n':
- if ($value) {
- $options->setLocale($value);
- }
- break;
- case 'stemming':
- $options->setStemming($value);
- break;
- case 'sort_by':
- $sort_by = $value;
- break;
- case 'sort_ord':
- $sort_ord = $value;
- break;
- case 'date_fields':
- $options->setDateFields($value);
- break;
- case 'fields':
- $options->setFields($value);
- break;
- case 'collections':
- $options->onCollections($value);
- break;
- case 'business_fields':
- $options->allowBusinessFieldsOn($value);
- break;
- default:
- throw new \RuntimeException(sprintf('Unable to handle key `%s`', $key));
- break;
+ if ($value instanceof \stdClass) {
+ $value = (array)$value;
}
+
+ $callable = $methods[$key];
+
+ $callable($value, $options);
}
if ($sort_by) {
@@ -682,4 +709,35 @@ class SearchEngineOptions
return $options;
}
+
+ public function setMaxResults($max_results)
+ {
+ Assertion::greaterOrEqualThan($max_results, 0);
+
+ $this->max_results = (int)$max_results;
+ }
+
+ public function getMaxResults()
+ {
+ return $this->max_results;
+ }
+
+ /**
+ * @param int $first_result
+ * @return void
+ */
+ public function setFirstResult($first_result)
+ {
+ Assertion::greaterOrEqualThan($first_result, 0);
+
+ $this->first_result = (int)$first_result;
+ }
+
+ /**
+ * @return int
+ */
+ public function getFirstResult()
+ {
+ return $this->first_result;
+ }
}
diff --git a/lib/Alchemy/Phrasea/TaskManager/Job/ArchiveJob.php b/lib/Alchemy/Phrasea/TaskManager/Job/ArchiveJob.php
index 3f7965ad21..210d00e85e 100644
--- a/lib/Alchemy/Phrasea/TaskManager/Job/ArchiveJob.php
+++ b/lib/Alchemy/Phrasea/TaskManager/Job/ArchiveJob.php
@@ -872,7 +872,7 @@ class ArchiveJob extends AbstractJob
$story = $this->createStory($app, $collection, $path . '/' . $representationFileName, $path . '/' . $captionFileName, $stat0, $stat1);
}
- $rid = $story->get_record_id();
+ $rid = $story->getRecordId();
$this->log('debug', sprintf('story %s created', $rid));
@@ -1011,7 +1011,7 @@ class ArchiveJob extends AbstractJob
$story->set_metadatas($metaFields->toMetadataArray($metadatasStructure), true);
}
- $story->set_binary_status(\databox_status::operation_or($stat0, $stat1));
+ $story->setStatus(\databox_status::operation_or($stat0, $stat1));
$story->rebuild_subdefs();
unset($media);
diff --git a/lib/Alchemy/Phrasea/TaskManager/Job/FtpJob.php b/lib/Alchemy/Phrasea/TaskManager/Job/FtpJob.php
index a5eabfc08f..332e501a86 100644
--- a/lib/Alchemy/Phrasea/TaskManager/Job/FtpJob.php
+++ b/lib/Alchemy/Phrasea/TaskManager/Job/FtpJob.php
@@ -412,7 +412,7 @@ class FtpJob extends AbstractJob
private function logexport(Application $app, \record_adapter $record, $obj, $ftpLog)
{
foreach ($obj as $oneObj) {
- $app['phraseanet.logger']($record->get_databox())
+ $app['phraseanet.logger']($record->getDatabox())
->log($record, \Session_Logger::EVENT_EXPORTFTP, $ftpLog, '');
}
diff --git a/lib/Alchemy/Phrasea/TaskManager/Job/RecordMoverJob.php b/lib/Alchemy/Phrasea/TaskManager/Job/RecordMoverJob.php
index 8ac3f3064a..9e2878cdd0 100644
--- a/lib/Alchemy/Phrasea/TaskManager/Job/RecordMoverJob.php
+++ b/lib/Alchemy/Phrasea/TaskManager/Job/RecordMoverJob.php
@@ -91,14 +91,14 @@ class RecordMoverJob extends AbstractJob
// change sb ?
if (array_key_exists('sb', $row)) {
- $status = str_split($rec->get_status());
+ $status = str_split($rec->getStatus());
foreach (str_split(strrev($row['sb'])) as $bit => $val) {
if ($val == '0' || $val == '1') {
$status[31 - $bit] = $val;
}
}
$status = implode('', $status);
- $rec->set_binary_status($status);
+ $rec->setStatus($status);
if ($logsql) {
$this->log('debug', sprintf("on sbas %s set rid %s status to %s \n", $row['sbas_id'], $row['record_id'], $status));
}
@@ -108,16 +108,16 @@ class RecordMoverJob extends AbstractJob
case 'DELETE':
if ($row['deletechildren'] && $rec->isStory()) {
/** @var record_adapter $child */
- foreach ($rec->get_children() as $child) {
+ foreach ($rec->getChildren() as $child) {
$child->delete();
if ($logsql) {
- $this->log('debug', sprintf("on sbas %s delete (grp child) rid %s \n", $row['sbas_id'], $child->get_record_id()));
+ $this->log('debug', sprintf("on sbas %s delete (grp child) rid %s \n", $row['sbas_id'], $child->getRecordId()));
}
}
}
$rec->delete();
if ($logsql) {
- $this->log('debug', sprintf("on sbas %s delete rid %s \n", $row['sbas_id'], $rec->get_record_id()));
+ $this->log('debug', sprintf("on sbas %s delete rid %s \n", $row['sbas_id'], $rec->getRecordId()));
}
break;
}
diff --git a/lib/Alchemy/Phrasea/Utilities/LazyArrayAccess.php b/lib/Alchemy/Phrasea/Utilities/LazyArrayAccess.php
new file mode 100644
index 0000000000..47418a7ce4
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Utilities/LazyArrayAccess.php
@@ -0,0 +1,54 @@
+locator = $locator;
+ }
+
+ public function offsetExists($offset)
+ {
+ return $this->fetchArrayAccessible()->offsetExists($offset);
+ }
+
+ public function offsetGet($offset)
+ {
+ return $this->fetchArrayAccessible()->offsetGet($offset);
+ }
+
+ public function offsetSet($offset, $value)
+ {
+ $this->fetchArrayAccessible()->offsetSet($offset, $value);
+ }
+
+ public function offsetUnset($offset)
+ {
+ $this->fetchArrayAccessible()->offsetUnset($offset);
+ }
+
+ /**
+ * @return \ArrayAccess
+ */
+ private function fetchArrayAccessible()
+ {
+ $locator = $this->locator;
+
+ return $locator();
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Utilities/NullableDateTime.php b/lib/Alchemy/Phrasea/Utilities/NullableDateTime.php
new file mode 100644
index 0000000000..6f47da81c7
--- /dev/null
+++ b/lib/Alchemy/Phrasea/Utilities/NullableDateTime.php
@@ -0,0 +1,19 @@
+format($format) : $default;
+ }
+}
diff --git a/lib/Alchemy/Phrasea/Vocabulary/ControlProvider/ControlProviderInterface.php b/lib/Alchemy/Phrasea/Vocabulary/ControlProvider/ControlProviderInterface.php
index bbe9153ab2..557f3d2600 100644
--- a/lib/Alchemy/Phrasea/Vocabulary/ControlProvider/ControlProviderInterface.php
+++ b/lib/Alchemy/Phrasea/Vocabulary/ControlProvider/ControlProviderInterface.php
@@ -1,5 +1,4 @@
app['phraseanet.user-query'];
@@ -64,35 +60,28 @@ class UserProvider implements ControlProviderInterface
->limit(0, 50)
->execute()->get_results();
- $results = new ArrayCollection();
-
- foreach ($users as $user) {
- $results->add(
- new Term($user->getDisplayName(), '', $this, $user->getId())
- );
- }
-
- return $results;
+ return array_map(function (User $user) {
+ return new Term($user->getDisplayName(), '', $this, $user->getId());
+ }, $users->toArray());
}
/**
- *
* @param mixed $id
- * @return boolean
+ * @return bool
*/
public function validate($id)
{
- return (Boolean) $this->app['repo.users']->find($id);
+ return (bool)$this->fetchUser($id);
}
/**
- *
- * @param mixed $id
+ * @param mixed $id
* @return string
+ * @throws \Exception
*/
public function getValue($id)
{
- $user = $this->app['repo.users']->find($id);
+ $user = $this->fetchUser($id);
if (null === $user) {
throw new \Exception('User unknown');
@@ -102,11 +91,19 @@ class UserProvider implements ControlProviderInterface
}
/**
- *
* @param mixed $id
* @return string
*/
public function getResource($id)
+ {
+ return $this->fetchUser($id);
+ }
+
+ /**
+ * @param $id
+ * @return null|User
+ */
+ private function fetchUser($id)
{
return $this->app['repo.users']->find($id);
}
diff --git a/lib/Alchemy/Phrasea/Vocabulary/Controller.php b/lib/Alchemy/Phrasea/Vocabulary/Controller.php
deleted file mode 100644
index 83ae884ed4..0000000000
--- a/lib/Alchemy/Phrasea/Vocabulary/Controller.php
+++ /dev/null
@@ -1,51 +0,0 @@
-value = $value;
$this->context = $context;
$this->type = $type;
$this->id = $id;
-
- return $this;
}
/**
@@ -84,7 +74,6 @@ class Term
}
/**
- *
* @return ControlProviderInterface
*/
public function getType()
@@ -93,7 +82,6 @@ class Term
}
/**
- *
* @return mixed
*/
public function getId()
diff --git a/lib/classes/ACL.php b/lib/classes/ACL.php
index 649a781528..f5f62f4cb5 100644
--- a/lib/classes/ACL.php
+++ b/lib/classes/ACL.php
@@ -26,6 +26,7 @@ use Alchemy\Phrasea\Core\Event\Acl\SysadminChangedEvent;
use Alchemy\Phrasea\Model\Entities\User;
use Alchemy\Phrasea\Model\RecordInterface;
use Alchemy\Phrasea\Model\RecordReferenceInterface;
+use Alchemy\Phrasea\Utilities\NullableDateTime;
use Doctrine\DBAL\DBALException;
@@ -1706,10 +1707,10 @@ class ACL implements cache_cacheableInterface
}
$params = [
- ':usr_id' => $this->user->getId()
- , ':base_id' => $base_id
- , 'limited_from' => ($limit_from ? $limit_from->format(DATE_ISO8601) : null)
- , 'limited_to' => ($limit_to ? $limit_to->format(DATE_ISO8601) : null)
+ ':usr_id' => $this->user->getId(),
+ ':base_id' => $base_id,
+ 'limited_from' => NullableDateTime::format($limit_from, DATE_ISO8601),
+ 'limited_to' => NullableDateTime::format($limit_to, DATE_ISO8601),
];
$stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql);
diff --git a/lib/classes/Bridge/Api/Dailymotion.php b/lib/classes/Bridge/Api/Dailymotion.php
index 7edc4ebeab..aefa57cd42 100644
--- a/lib/classes/Bridge/Api/Dailymotion.php
+++ b/lib/classes/Bridge/Api/Dailymotion.php
@@ -466,7 +466,7 @@ class Bridge_Api_Dailymotion extends Bridge_Api_Abstract implements Bridge_Api_I
public function acceptable_records()
{
return function (record_adapter $record) {
- return $record->get_type() === 'video';
+ return $record->getType() === 'video';
};
}
@@ -568,7 +568,7 @@ class Bridge_Api_Dailymotion extends Bridge_Api_Abstract implements Bridge_Api_I
*/
public function upload(record_adapter $record, array $options = [])
{
- switch ($record->get_type()) {
+ switch ($record->getType()) {
case self::ELEMENT_TYPE_VIDEO :
$url_file = $this->_api->sendFile($record->get_hd_file()->getRealPath(), $this->oauth_token);
$options = array_merge(['url' => $url_file], $options);
@@ -793,7 +793,7 @@ class Bridge_Api_Dailymotion extends Bridge_Api_Abstract implements Bridge_Api_I
{
$errors = $this->check_record_constraints($record);
$check = function ($field) use (&$errors, $datas, $record) {
- $key = $record->get_serialize_key();
+ $key = $record->getId();
$required = ! ! $field["required"];
$name = $field["name"];
$length = (int) $field["length"];
@@ -850,7 +850,7 @@ class Bridge_Api_Dailymotion extends Bridge_Api_Abstract implements Bridge_Api_I
*/
public function get_upload_datas(Request $request, record_adapter $record)
{
- $key = $record->get_serialize_key();
+ $key = $record->getId();
$datas = [
'title' => $request->get('title_' . $key),
'description' => $request->get('description_' . $key),
diff --git a/lib/classes/Bridge/Api/Flickr.php b/lib/classes/Bridge/Api/Flickr.php
index d89b7391e8..7d51eba91d 100644
--- a/lib/classes/Bridge/Api/Flickr.php
+++ b/lib/classes/Bridge/Api/Flickr.php
@@ -504,7 +504,7 @@ class Bridge_Api_Flickr extends Bridge_Api_Abstract implements Bridge_Api_Interf
$privacy = $this->get_default_privacy();
$uploader->setPerms($privacy['public'], $privacy['friends'], $privacy['family']);
- $type = $record->get_type() == 'image' ? self::ELEMENT_TYPE_PHOTO : $record->get_type();
+ $type = $record->getType() == 'image' ? self::ELEMENT_TYPE_PHOTO : $record->getType();
switch ($type) {
case self::ELEMENT_TYPE_PHOTO :
return $uploader->upload($record->get_hd_file()->getRealPath(), $options['title'], $options['description'], $options['tags'], true);
@@ -522,7 +522,7 @@ class Bridge_Api_Flickr extends Bridge_Api_Abstract implements Bridge_Api_Interf
public function acceptable_records()
{
return function (record_adapter $record) {
- return in_array($record->get_type(), ['image']);
+ return in_array($record->getType(), ['image']);
};
}
@@ -683,7 +683,7 @@ class Bridge_Api_Flickr extends Bridge_Api_Abstract implements Bridge_Api_Interf
{
$errors = $this->check_record_constraints($record);
$check = function ($field) use (&$errors, $datas, $record) {
- $key = $record->get_serialize_key();
+ $key = $record->getId();
$name = $field['name'];
$length = (int) $field['length'];
$required = ! ! $field['required'];
@@ -751,7 +751,7 @@ class Bridge_Api_Flickr extends Bridge_Api_Abstract implements Bridge_Api_Interf
*/
public function get_upload_datas(Request $request, record_adapter $record)
{
- $key = $record->get_serialize_key();
+ $key = $record->getId();
$datas = [
'title' => $request->get('title_' . $key),
'description' => $request->get('description_' . $key),
diff --git a/lib/classes/Bridge/Api/Youtube.php b/lib/classes/Bridge/Api/Youtube.php
index 98779a273b..75e99a4113 100644
--- a/lib/classes/Bridge/Api/Youtube.php
+++ b/lib/classes/Bridge/Api/Youtube.php
@@ -418,7 +418,7 @@ class Bridge_Api_Youtube extends Bridge_Api_Abstract implements Bridge_Api_Inter
public function acceptable_records()
{
return function (record_adapter $record) {
- return $record->get_type() === 'video';
+ return $record->getType() === 'video';
};
}
@@ -646,7 +646,7 @@ class Bridge_Api_Youtube extends Bridge_Api_Abstract implements Bridge_Api_Inter
*/
public function upload(record_adapter $record, array $options = [])
{
- switch ($record->get_type()) {
+ switch ($record->getType()) {
case 'video':
$video_entry = new Zend_Gdata_YouTube_VideoEntry();
@@ -902,7 +902,7 @@ class Bridge_Api_Youtube extends Bridge_Api_Abstract implements Bridge_Api_Inter
$errors = $this->check_record_constraints($record);
$check = function ($field) use (&$errors, $datas, $record) {
- $key = $record->get_serialize_key();
+ $key = $record->getId();
$name = $field['name'];
$length = (int) $field['length'];
$required = ! ! $field['required'];
@@ -981,7 +981,7 @@ class Bridge_Api_Youtube extends Bridge_Api_Abstract implements Bridge_Api_Inter
*/
public function get_upload_datas(Request $request, record_adapter $record)
{
- $key = $record->get_serialize_key();
+ $key = $record->getId();
$datas = [
'title' => $request->get('title_' . $key),
'description' => $request->get('description_' . $key),
@@ -1012,7 +1012,7 @@ class Bridge_Api_Youtube extends Bridge_Api_Abstract implements Bridge_Api_Inter
private function check_record_constraints(record_adapter $record)
{
$errors = [];
- $key = $record->get_serialize_key();
+ $key = $record->getId();
//Record must rely on real file
if ( ! $record->get_hd_file() instanceof SplFileInfo) {
$errors["file_size_" . $key] = $this->translator->trans("Le record n'a pas de fichier physique");
diff --git a/lib/classes/Bridge/Element.php b/lib/classes/Bridge/Element.php
index 84f0184446..5a81808e55 100644
--- a/lib/classes/Bridge/Element.php
+++ b/lib/classes/Bridge/Element.php
@@ -10,6 +10,7 @@
*/
use Alchemy\Phrasea\Application;
+use Alchemy\Phrasea\Utilities\NullableDateTime;
class Bridge_Element
{
@@ -383,9 +384,9 @@ class Bridge_Element
SET uploaded_on = :uploaded_on, updated_on = :update WHERE id = :id';
$params = [
- ':uploaded_on' => $this->uploaded_on ? $this->uploaded_on->format(DATE_ISO8601) : null
- , ':id' => $this->id
- , ':update' => $this->updated_on->format(DATE_ISO8601)
+ ':uploaded_on' => NullableDateTime::format($this->uploaded_on, DATE_ISO8601),
+ ':id' => $this->id,
+ ':update' => $this->updated_on->format(DATE_ISO8601),
];
$stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql);
@@ -448,13 +449,13 @@ class Bridge_Element
,:datas , :status, NOW(), NOW())';
$params = [
- ':account_id' => $account->get_id()
- , ':sbas_id' => $record->get_sbas_id()
- , ':record_id' => $record->get_record_id()
- , ':status' => $status
- , ':title' => $title
- , ':type' => $type
- , ':datas' => serialize($datas)
+ ':account_id' => $account->get_id(),
+ ':sbas_id' => $record->getDataboxId(),
+ ':record_id' => $record->getRecordId(),
+ ':status' => $status,
+ ':title' => $title,
+ ':type' => $type,
+ ':datas' => serialize($datas),
];
$stmt = $app->getApplicationBox()->get_connection()->prepare($sql);
diff --git a/lib/classes/Session/Logger.php b/lib/classes/Session/Logger.php
index 02f838492a..9ab980b192 100644
--- a/lib/classes/Session/Logger.php
+++ b/lib/classes/Session/Logger.php
@@ -73,11 +73,11 @@ class Session_Logger
$stmt = $this->databox->get_connection()->prepare($sql);
$params = [
- ':log_id' => $this->get_id()
- , ':record_id' => $record->get_record_id()
- , ':action' => $action
- , ':final' => $final
- , ':comm' => $comment
+ ':log_id' => $this->get_id(),
+ ':record_id' => $record->getRecordId(),
+ ':action' => $action,
+ ':final' => $final,
+ ':comm' => $comment,
];
$stmt->execute($params);
diff --git a/lib/classes/cache/databox.php b/lib/classes/cache/databox.php
index 229eb7676c..4e9ed4dd82 100644
--- a/lib/classes/cache/databox.php
+++ b/lib/classes/cache/databox.php
@@ -75,8 +75,6 @@ class cache_databox
$databox->delete_data_from_cache($key);
$key = 'record_' . $sbas_id . '_' . $row['value'] . '_' . \record_adapter::CACHE_SHA256;
$databox->delete_data_from_cache($key);
- $key = 'record_' . $sbas_id . '_' . $row['value'] . '_' . \record_adapter::CACHE_STATUS;
- $databox->delete_data_from_cache($key);
$key = 'record_' . $sbas_id . '_' . $row['value'] . '_' . \record_adapter::CACHE_TECHNICAL_DATA;
$databox->delete_data_from_cache($key);
diff --git a/lib/classes/caption/Field/ThesaurusValue.php b/lib/classes/caption/Field/ThesaurusValue.php
deleted file mode 100644
index 6fbdfb05ee..0000000000
--- a/lib/classes/caption/Field/ThesaurusValue.php
+++ /dev/null
@@ -1,47 +0,0 @@
-value = $value;
- $this->field = $field;
- $this->query = $query;
- }
-
- public function getValue()
- {
- return $this->value;
- }
-
- public function getField()
- {
- return $this->field;
- }
-
- public function getQuery()
- {
- return $this->query;
- }
-
- public function __toString()
- {
- return $this->value;
- }
-}
diff --git a/lib/classes/caption/Field/Value.php b/lib/classes/caption/Field/Value.php
index d216de6f78..b51ef904bf 100644
--- a/lib/classes/caption/Field/Value.php
+++ b/lib/classes/caption/Field/Value.php
@@ -11,30 +11,46 @@
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Utilities\StringHelper;
-use Alchemy\Phrasea\Vocabulary;
+use Alchemy\Phrasea\Vocabulary\ControlProvider\ControlProviderInterface;
class caption_Field_Value implements cache_cacheableInterface
{
const RETRIEVE_VALUES = true;
const DONT_RETRIEVE_VALUES = false;
- /** @var int */
+ /**
+ * @var int
+ */
protected $id;
- /** @var string */
+ /**
+ * @var string
+ */
protected $value;
- /** @var \Alchemy\Phrasea\Vocabulary\ControlProvider\ControlProviderInterface */
- protected $VocabularyType;
+ /**
+ * @var ControlProviderInterface|null
+ */
+ protected $vocabularyType;
- /** @var int */
- protected $VocabularyId;
+ /**
+ * @var mixed
+ */
+ protected $vocabularyId;
- /** @var databox_field */
+ /**
+ * @var databox_field
+ */
protected $databox_field;
- /** @var record_adapter */
+ /**
+ * @var record_adapter
+ */
protected $record;
+
+ /**
+ * @var Application
+ */
protected $app;
/**
@@ -45,21 +61,20 @@ class caption_Field_Value implements cache_cacheableInterface
*/
protected $qjs;
- /*
+ /**
* Tells whether the value is matched against a thesaurus value.
+ * @var bool
*/
protected $isThesaurusValue;
protected static $localCache = [];
/**
- *
- * @param Application $app
- * @param databox_field $databox_field
- * @param record_adapter $record
- * @param mixed $id
- * @param bool $retrieveValues
- * @return \caption_Field_Value
+ * @param Application $app
+ * @param databox_field $databox_field
+ * @param record_adapter $record
+ * @param mixed $id
+ * @param bool $retrieveValues
*/
public function __construct(Application $app, databox_field $databox_field, record_adapter $record, $id, $retrieveValues = self::RETRIEVE_VALUES)
{
@@ -68,107 +83,94 @@ class caption_Field_Value implements cache_cacheableInterface
$this->record = $record;
$this->app = $app;
- if($retrieveValues == self::RETRIEVE_VALUES) {
+ if ($retrieveValues === self::RETRIEVE_VALUES) {
$this->retrieveValues();
}
}
+ /**
+ * @return string
+ */
public function getQjs()
{
return $this->qjs;
}
- public function injectValues($value, $VocabularyType, $VocabularyId)
+ /**
+ * @param string $value
+ * @param string $vocabularyType
+ * @param string $vocabularyId
+ */
+ public function injectValues($value, $vocabularyType, $vocabularyId)
{
$this->value = StringHelper::crlfNormalize($value);
- try {
- $this->VocabularyType = $VocabularyType ? Vocabulary\Controller::get($this->app, $VocabularyType) : null;
- $this->VocabularyId = $VocabularyId;
- } catch (\InvalidArgumentException $e) {
+ $this->fetchVocabulary($vocabularyType, $vocabularyId);
- }
-
- if ($this->VocabularyType) {
- /**
- * Vocabulary Control has been deactivated
- */
- if ( ! $this->databox_field->getVocabularyControl()) {
+ if ($this->vocabularyType) {
+ if (!$this->databox_field->getVocabularyControl()) {
+ // Vocabulary Control has been deactivated
$this->removeVocabulary();
- }
- /**
- * Vocabulary Control has changed
- */
- elseif ($this->databox_field->getVocabularyControl()->getType() !== $this->VocabularyType->getType()) {
+ } elseif ($this->databox_field->getVocabularyControl()->getType() !== $this->vocabularyType->getType()) {
+ // Vocabulary Control has changed
$this->removeVocabulary();
- }
- /**
- * Current Id is not available anymore
- */
- elseif ( ! $this->VocabularyType->validate($this->VocabularyId)) {
+ } elseif (!$this->vocabularyType->validate($this->vocabularyId)) {
+ // Current Id is not available anymore
$this->removeVocabulary();
- }
- /**
- * String equivalence has changed
- */
- elseif ($this->VocabularyType->getValue($this->VocabularyId) !== $this->value) {
- $this->set_value($this->VocabularyType->getValue($this->VocabularyId));
+ } elseif ($this->vocabularyType->getValue($this->vocabularyId) !== $this->value) {
+ // String equivalence has changed
+ $this->set_value($this->vocabularyType->getValue($this->vocabularyId));
}
}
-
- $datas = [
- 'value' => $this->value,
- 'vocabularyId' => $this->VocabularyId,
- 'vocabularyType' => $this->VocabularyType ? $this->VocabularyType->getType() : null,
- ];
-
- $this->set_data_to_cache($datas);
}
protected function retrieveValues()
{
try {
- $datas = $this->get_data_from_cache();
-
- $this->value = $datas['value'];
- $this->VocabularyType = $datas['vocabularyType'] ? Vocabulary\Controller::get($this->app, $datas['vocabularyType']) : null;
- $this->VocabularyId = $datas['vocabularyId'];
-
- return $this;
+ $data = $this->get_data_from_cache();
+ $cacheRefreshNeeded = false;
} catch (\Exception $e) {
+ $data = $this->databox_field->get_databox()->get_connection()
+ ->fetchAssoc(
+ 'SELECT value, VocabularyType as vocabularyType, VocabularyId as vocabularyId FROM metadatas WHERE id = :id',
+ [':id' => $this->id]
+ );
+ if (!is_array($data)) {
+ $data = [
+ 'value' => null,
+ 'vocabularyId' => null,
+ 'vocabularyType' => null,
+ ];
+ }
+
+ $cacheRefreshNeeded = true;
}
- $connbas = $this->databox_field->get_databox()->get_connection();
+ $this->injectValues($data['value'], $data['vocabularyType'], $data['vocabularyId']);
- $sql = 'SELECT record_id, value, VocabularyType, VocabularyId FROM metadatas WHERE id = :id';
-
- $stmt = $connbas->prepare($sql);
- $stmt->execute([':id' => $this->id]);
- $row = $stmt->fetch(PDO::FETCH_ASSOC);
- $stmt->closeCursor();
-
- if($row) {
- $this->injectValues($row['value'], $row['VocabularyType'], $row['VocabularyId']);
- }
- else {
- $this->injectValues(null, null, null);
+ if ($cacheRefreshNeeded) {
+ $this->set_data_to_cache([
+ 'value' => $this->value,
+ 'vocabularyId' => $this->vocabularyId,
+ 'vocabularyType' => $this->vocabularyType ? $this->vocabularyType->getType() : null,
+ ]);
}
return $this;
}
/**
- * @return Vocabulary\ControlProvider\ControlProviderInterface
+ * @return ControlProviderInterface|null
*/
public function getVocabularyType()
{
- return $this->VocabularyType;
+ return $this->vocabularyType;
}
public function getVocabularyId()
{
- return $this->VocabularyId;
+ return $this->vocabularyId;
}
public function getId()
@@ -183,7 +185,7 @@ class caption_Field_Value implements cache_cacheableInterface
public function getResource()
{
- return $this->VocabularyType ? $this->VocabularyType->getResource($this->VocabularyId) : null;
+ return $this->vocabularyType ? $this->vocabularyType->getResource($this->vocabularyId) : null;
}
public function getDatabox_field()
@@ -198,12 +200,7 @@ class caption_Field_Value implements cache_cacheableInterface
public function delete()
{
- $connbas = $this->databox_field->get_connection();
-
- $sql = 'DELETE FROM metadatas WHERE id = :id';
- $stmt = $connbas->prepare($sql);
- $stmt->execute([':id' => $this->id]);
- $stmt->closeCursor();
+ $this->getConnection()->delete('metadatas', ['id' => $this->id]);
$this->delete_data_from_cache();
$this->databox_field->delete_data_from_cache();
@@ -213,144 +210,129 @@ class caption_Field_Value implements cache_cacheableInterface
return $this;
}
+ /**
+ * @return $this
+ * @throws \Doctrine\DBAL\DBALException
+ */
public function removeVocabulary()
{
- $connbas = $this->databox_field->get_connection();
+ $this->getConnection()->executeUpdate(
+ 'UPDATE metadatas SET VocabularyType = NULL, VocabularyId = NULL WHERE id = :meta_id',
+ ['meta_id' => $this->getId()]
+ );
- $params = [
- ':VocabType' => null
- , ':VocabularyId' => null
- , ':meta_id' => $this->getId()
- ];
-
- $sql_up = 'UPDATE metadatas'
- . ' SET VocabularyType = :VocabType, VocabularyId = :VocabularyId'
- . ' WHERE id = :meta_id';
- $stmt_up = $connbas->prepare($sql_up);
- $stmt_up->execute($params);
- $stmt_up->closeCursor();
-
- $this->VocabularyId = $this->VocabularyType = null;
+ $this->vocabularyId = null;
+ $this->vocabularyType = null;
$this->delete_data_from_cache();
return $this;
}
- public function setVocab(Vocabulary\ControlProvider\ControlProviderInterface $vocabulary, $vocab_id)
+ /**
+ * @param ControlProviderInterface $vocabulary
+ * @param mixed $vocab_id
+ * @return $this
+ * @throws \Doctrine\DBAL\DBALException
+ */
+ public function setVocab(ControlProviderInterface $vocabulary, $vocab_id)
{
- $connbas = $this->databox_field->get_connection();
-
- $params = [
- ':VocabType' => $vocabulary->getType()
- , ':VocabularyId' => $vocab_id
- , ':meta_id' => $this->getId()
- ];
-
- $sql_up = 'UPDATE metadatas'
- . ' SET VocabularyType = :VocabType, VocabularyId = :VocabularyId'
- . ' WHERE id = :meta_id';
- $stmt_up = $connbas->prepare($sql_up);
- $stmt_up->execute($params);
- $stmt_up->closeCursor();
+ $this->getConnection()->executeUpdate(
+ 'UPDATE metadatas SET VocabularyType = :VocabType, VocabularyId = :VocabularyId WHERE id = :meta_id',
+ [
+ 'VocabType' => $vocabulary->getType(),
+ 'VocabularyId' => $vocab_id,
+ 'meta_id' => $this->getId(),
+ ]
+ );
$this->set_value($vocabulary->getValue($vocab_id));
return $this;
}
+ /**
+ * @param ControlProviderInterface|null $vocabulary
+ * @param mixed|null $vocabularyId
+ * @return $this
+ * @throws \Doctrine\DBAL\DBALException
+ */
+ public function changeVocabulary(ControlProviderInterface $vocabulary = null, $vocabularyId = null)
+ {
+ if (isset($vocabulary, $vocabularyId)) {
+ return $this->setVocab($vocabulary, $vocabularyId);
+ }
+
+ return $this->removeVocabulary();
+ }
+
+ /**
+ * @param string $value
+ * @return $this
+ * @throws \Doctrine\DBAL\DBALException
+ */
public function set_value($value)
{
$this->value = $value;
- $connbas = $this->databox_field->get_connection();
-
- $params = [
- ':meta_id' => $this->id
- , ':value' => $value
- ];
-
- $sql_up = 'UPDATE metadatas SET value = :value WHERE id = :meta_id';
- $stmt_up = $connbas->prepare($sql_up);
- $stmt_up->execute($params);
- $stmt_up->closeCursor();
+ $this->getConnection()->executeUpdate(
+ 'UPDATE metadatas SET value = :value WHERE id = :meta_id',
+ [
+ 'meta_id' => $this->id,
+ 'value' => $value,
+ ]
+ );
$this->delete_data_from_cache();
- $this->update_cache_value($value);
-
return $this;
}
- /**
- *
- * @param array $value
- * @return caption_field
- */
- public function update_cache_value($value)
+ public static function create(Application $app, databox_field $databox_field, \record_adapter $record, $value, ControlProviderInterface $vocabulary = null, $vocabularyId = null)
{
- $this->record->get_caption()->delete_data_from_cache();
+ $connection = $databox_field->get_connection();
- return $this;
- }
-
- public static function create(Application $app, databox_field $databox_field, \record_adapter $record, $value, Vocabulary\ControlProvider\ControlProviderInterface $vocabulary = null, $vocabularyId = null)
- {
- $connbas = $databox_field->get_connection();
-
- /**
- * Check consistency
- */
- if ( ! $databox_field->is_multi()) {
+ // Check consistency
+ if (!$databox_field->is_multi()) {
try {
$field = $record->get_caption()->get_field($databox_field->get_name());
$values = $field->get_values();
- $caption_field_value = array_pop($values);
- /* @var $value \caption_Field_Value */
+ } catch (Exception $exception) {
+ // Field was not found, so no values found either
+ $values = [];
+ }
+ if (!empty($values)) {
+ /** @var caption_Field_Value $caption_field_value */
+ $caption_field_value = reset($values);
$caption_field_value->set_value($value);
-
- if (! $vocabulary || ! $vocabularyId) {
- $caption_field_value->removeVocabulary();
- } else {
- $caption_field_value->setVocab($vocabulary, $vocabularyId);
- }
+ $caption_field_value->changeVocabulary($vocabulary, $vocabularyId);
return $caption_field_value;
- } catch (\Exception $e) {
-
}
}
- $sql_ins = 'INSERT INTO metadatas (id, record_id, meta_struct_id, value, VocabularyType, VocabularyId)'
- . ' VALUES (null, :record_id, :field, :value, :VocabType, :VocabId)';
-
- $params = [
- ':record_id' => $record->get_record_id(),
- ':field' => $databox_field->get_id(),
- ':value' => $value,
- ':VocabType' => $vocabulary ? $vocabulary->getType() : null,
- ':VocabId' => $vocabulary ? $vocabularyId : null,
+ $data = [
+ 'record_id' => $record->getRecordId(),
+ 'meta_struct_id' => $databox_field->get_id(),
+ 'value' => $value,
+ 'VocabularyType' => $vocabulary ? $vocabulary->getType() : null,
+ 'VocabularyId' => $vocabulary ? $vocabularyId : null,
];
- $stmt_ins = $connbas->prepare($sql_ins);
- $stmt_ins->execute($params);
+ $connection->insert('metadatas', $data);
- $stmt_ins->closeCursor();
- $meta_id = $connbas->lastInsertId();
+ $meta_id = $connection->lastInsertId();
- $caption_field_value = new self($app, $databox_field, $record, $meta_id);
- $caption_field_value->update_cache_value($value);
+ $caption_field_value = new self($app, $databox_field, $record, $meta_id, self::DONT_RETRIEVE_VALUES);
+ $caption_field_value->injectValues($data['value'], $data['VocabularyType'], $data['VocabularyId']);
- $record->get_caption()->delete_data_from_cache();
$databox_field->delete_data_from_cache();
-
$caption_field_value->delete_data_from_cache();
return $caption_field_value;
}
/**
- *
* @return string
*/
public function highlight_thesaurus()
@@ -361,7 +343,7 @@ class caption_Field_Value implements cache_cacheableInterface
$tbranch = $this->databox_field->get_tbranch();
- if (! $tbranch || ! $XPATH_thesaurus) {
+ if (!$tbranch || !$XPATH_thesaurus) {
return $value;
}
@@ -390,8 +372,9 @@ class caption_Field_Value implements cache_cacheableInterface
$note = 0;
$note += ($node->getAttribute("lng") == $this->app['locale']) ? 4 : 0;
$note += ($node->getAttribute("w") == $term_noacc) ? 2 : 0;
- if($context_noacc != "")
+ if ($context_noacc != "") {
$note += ($node->getAttribute("k") == $context_noacc) ? 1 : 0;
+ }
if ($note > $bestnote) {
$bestnode = $node;
}
@@ -401,41 +384,39 @@ class caption_Field_Value implements cache_cacheableInterface
list($term, $context) = $this->splitTermAndContext(str_replace(["[[em]]", "[[/em]]"], ["", ""], $value));
// a value has been found in thesaurus, update value & set the query to bounce to the value
$this->value = $bestnode->getAttribute('v');
- $this->qjs = $term . ($context ? '['.$context.']' : '');
+ $this->qjs = $term . ($context ? '[' . $context . ']' : '');
$this->isThesaurusValue = true;
} else {
$this->isThesaurusValue = false;
}
- return $this;
+ return $this->value;
}
/**
- * @return boolean
+ * @return bool
*/
public function isThesaurusValue()
{
if (null === $this->isThesaurusValue) {
- $this->highlight_thesaurus();
+ throw new LogicException('Value was not checked against thesaurus yet. Call hightlight_thesaurus() first');
}
return $this->isThesaurusValue;
}
/**
- *
* @param string $word
- * @return array
+ * @return string[]
*/
protected function splitTermAndContext($word)
{
$term = trim($word);
- $context = "";
- if (($po = strpos($term, "(")) !== false) {
- if (($pc = strpos($term, ")", $po)) !== false) {
- $context = trim(substr($term, $po + 1, $pc - $po - 1));
- $term = trim(substr($term, 0, $po));
- }
+ $context = '';
+
+ if (($po = strpos($term, '(')) !== false && ($pc = strpos($term, ')', $po)) !== false) {
+ $context = trim(substr($term, $po + 1, $pc - $po - 1));
+ $term = trim(substr($term, 0, $po));
}
return [$term, $context];
@@ -488,14 +469,9 @@ class caption_Field_Value implements cache_cacheableInterface
*/
public function delete_data_from_cache($option = null)
{
- $this->value = $this->VocabularyId = $this->VocabularyType = null;
+ $this->value = $this->vocabularyId = $this->vocabularyType = null;
$this->record->delete_data_from_cache(record_adapter::CACHE_TITLE);
-
- try {
- $this->record->get_caption()->get_field($this->databox_field->get_name())->delete_data_from_cache();
- } catch (\Exception $e) {
-
- }
+ $this->record->get_caption()->delete_data_from_cache();
unset(self::$localCache[$this->get_cache_key($option)]);
}
@@ -509,4 +485,26 @@ class caption_Field_Value implements cache_cacheableInterface
{
self::$localCache = [];
}
+
+ /**
+ * @param string $vocabularyType
+ * @param mixed $vocabularyId
+ */
+ private function fetchVocabulary($vocabularyType, $vocabularyId)
+ {
+ try {
+ $this->vocabularyType = $vocabularyType ? $this->app['vocabularies'][strtolower($vocabularyType)] : null;
+ $this->vocabularyId = $vocabularyId;
+ } catch (\InvalidArgumentException $e) {
+ // Invalid or unknown Vocabulary
+ }
+ }
+
+ /**
+ * @return \Doctrine\DBAL\Connection
+ */
+ private function getConnection()
+ {
+ return $this->databox_field->get_connection();
+ }
}
diff --git a/lib/classes/caption/field.php b/lib/classes/caption/field.php
index ecd4ac9bf2..37b2b8ab5a 100644
--- a/lib/classes/caption/field.php
+++ b/lib/classes/caption/field.php
@@ -40,8 +40,6 @@ class caption_field implements cache_cacheableInterface
* @param databox_field $databox_field
* @param record_adapter $record
* @param bool $retrieveValues
- *
- * @return caption_field
*/
public function __construct(Application $app, databox_field $databox_field, \record_adapter $record, $retrieveValues = self::RETRIEVE_VALUES)
{
@@ -62,8 +60,6 @@ class caption_field implements cache_cacheableInterface
}
}
}
-
- return $this;
}
/**
@@ -147,27 +143,27 @@ class caption_field implements cache_cacheableInterface
}
/**
- * @param array $values
- * @param string $separator
+ * @param caption_Field_Value[] $values
+ * @param string $separator
+ * @param bool $highlight
* @return string
*/
- protected static function serialize_value(Array $values, $separator, $highlight = false)
+ protected function serialize_value(array $values, $separator, $highlight = false)
{
- if (strlen($separator) > 1)
+ if (strlen($separator) > 1) {
$separator = $separator[0];
+ }
- if (trim($separator) === '')
+ if (trim($separator) === '') {
$separator = ' ';
- else
+ } else {
$separator = ' ' . $separator . ' ';
+ }
$array_values = [];
foreach ($values as $value) {
- if ($highlight)
- $array_values[] = $value->highlight_thesaurus();
- else
- $array_values[] = $value->getValue();
+ $array_values[] = $highlight ? $value->highlight_thesaurus() : $value->getValue();
}
return implode($separator, $array_values);
@@ -191,10 +187,10 @@ class caption_field implements cache_cacheableInterface
}
/**
- * @param String $custom_separator
- * @param Boolean $highlightTheso
+ * @param string|bool $custom_separator
+ * @param bool $highlight
*
- * @return mixed
+ * @return string
*/
public function get_serialized_values($custom_separator = false, $highlight = false)
{
@@ -205,12 +201,12 @@ class caption_field implements cache_cacheableInterface
if ($this->is_multi()) {
$separator = $custom_separator !== false ? $custom_separator : $this->databox_field->get_separator();
- return self::serialize_value($this->values, $separator, $highlight);
+ return $this->serialize_value($this->values, $separator, $highlight);
}
+ /** @var caption_Field_Value $value */
$value = current($this->values);
- /* @var $value Caption_Field_Value */
if ($highlight) {
return $value->highlight_thesaurus();
}
@@ -258,7 +254,6 @@ class caption_field implements cache_cacheableInterface
*/
public static function get_multi_values($serialized_value, $separator)
{
- $values = [];
if (strlen($separator) == 1) {
$values = explode($separator, $serialized_value);
} else {
@@ -360,8 +355,7 @@ class caption_field implements cache_cacheableInterface
$caption_field->delete();
$record->set_metadatas([]);
- unset($caption_field);
- unset($record);
+ unset($caption_field, $record);
} catch (\Exception $e) {
}
@@ -381,7 +375,7 @@ class caption_field implements cache_cacheableInterface
*/
public function get_cache_key($option = null)
{
- return 'caption_field_' . $this->databox_field->get_id() . '_' . $this->record->get_serialize_key() . ($option ? '_' . $option : '');
+ return 'caption_field_' . $this->databox_field->get_id() . '_' . $this->record->getId() . ($option ? '_' . $option : '');
}
/**
@@ -389,6 +383,7 @@ class caption_field implements cache_cacheableInterface
*
* @param string $option
* @return mixed
+ * @throws Exception
*/
public function get_data_from_cache($option = null)
{
diff --git a/lib/classes/caption/interface.php b/lib/classes/caption/interface.php
deleted file mode 100644
index 477b24e6ba..0000000000
--- a/lib/classes/caption/interface.php
+++ /dev/null
@@ -1,22 +0,0 @@
-app = $app;
- $this->sbas_id = $record->getDataboxId();
$this->record = $record;
- $this->databox = $databox;
}
public function toArray($includeBusinessFields)
@@ -57,7 +43,10 @@ class caption_record implements caption_interface, cache_cacheableInterface
return $serializer->toArray($this, $includeBusinessFields);
}
- public function get_record()
+ /**
+ * @return RecordReferenceInterface
+ */
+ public function getRecordReference()
{
return $this->record;
}
@@ -72,26 +61,29 @@ class caption_record implements caption_interface, cache_cacheableInterface
return $this->fields;
}
+ $databox = $this->getDatabox();
+
try {
$fields = $this->get_data_from_cache();
} catch (\Exception $e) {
- $sql = "SELECT m.id AS meta_id, s.id AS structure_id, value, VocabularyType, VocabularyId"
- . " FROM metadatas m, metadatas_structure s"
- . " WHERE m.record_id = :record_id AND s.id = m.meta_struct_id"
- . " ORDER BY s.sorter ASC";
- $stmt = $this->databox->get_connection()->prepare($sql);
- $stmt->execute([':record_id' => $this->record->getRecordId()]);
- $fields = $stmt->fetchAll(PDO::FETCH_ASSOC);
- $stmt->closeCursor();
- if ($fields) {
- $this->set_data_to_cache($fields);
- }
+ $sql = <<<'SQL'
+SELECT m.id AS meta_id, s.id AS structure_id, value, VocabularyType, VocabularyId
+FROM metadatas m INNER JOIN metadatas_structure s ON s.id = m.meta_struct_id
+WHERE m.record_id = :record_id
+ORDER BY s.sorter ASC
+SQL;
+ $fields = $databox->get_connection()
+ ->executeQuery($sql, [':record_id' => $this->record->getRecordId()])
+ ->fetchAll(PDO::FETCH_ASSOC);
+
+ $this->set_data_to_cache($fields);
}
$rec_fields = array();
if ($fields) {
- $databox_descriptionStructure = $this->databox->get_meta_structure();
+ $databox_descriptionStructure = $databox->get_meta_structure();
+ $record = $databox->get_record($this->record->getRecordId());
// first group values by field
$caption_fields = [];
@@ -113,7 +105,7 @@ class caption_record implements caption_interface, cache_cacheableInterface
$cfv = new caption_Field_Value(
$this->app,
$caption_fields[$structure_id]['db_field'],
- $this->record,
+ $record,
$row['meta_id'],
caption_Field_Value::DONT_RETRIEVE_VALUES // ask caption_Field_Value "no n+1 sql"
);
@@ -132,7 +124,7 @@ class caption_record implements caption_interface, cache_cacheableInterface
$cf = new caption_field(
$this->app,
$caption_field['db_field'],
- $this->record,
+ $record,
caption_field::DONT_RETRIEVE_VALUES // ask caption_field "no n+1 sql"
);
@@ -159,7 +151,7 @@ class caption_record implements caption_interface, cache_cacheableInterface
$fields = [];
foreach ($this->retrieve_fields() as $meta_struct_id => $field) {
- if ($grep_fields && ! in_array($field->get_name(), $grep_fields)) {
+ if ($grep_fields && ! in_array($field->get_name(), $grep_fields, true)) {
continue;
}
@@ -201,15 +193,29 @@ class caption_record implements caption_interface, cache_cacheableInterface
}
/**
- *
+ * @return caption_field[]
+ */
+ public function getDCFields()
+ {
+ $databoxDcesFieldIds = array_map(function (databox_field $databox_field) {
+ return $databox_field->get_id();
+ }, $this->getDatabox()->get_meta_structure()->getDcesFields());
+
+ return array_intersect_key(
+ $this->retrieve_fields(),
+ array_fill_keys($databoxDcesFieldIds, null)
+ );
+ }
+
+ /**
* @param string $label
- * @return caption_field
+ * @return caption_field|null
*/
public function get_dc_field($label)
{
$fields = $this->retrieve_fields();
- if (null !== $field = $this->databox->get_meta_structure()->get_dces_field($label)) {
+ if (null !== $field = $this->getDatabox()->get_meta_structure()->get_dces_field($label)) {
if (isset($fields[$field->get_id()])) {
return $fields[$field->get_id()];
}
@@ -219,15 +225,12 @@ class caption_record implements caption_interface, cache_cacheableInterface
}
/**
- *
- * @param string $highlight
- * @param array $grep_fields
- * @param SearchEngineInterface $searchEngine
- * @param Boolean $includeBusiness
- *
+ * @param string $highlight
+ * @param array $grep_fields
+ * @param bool $includeBusiness
* @return array
*/
- public function get_highlight_fields($highlight = '', Array $grep_fields = null, SearchEngineInterface $searchEngine = null, $includeBusiness = false, SearchEngineOptions $options = null)
+ public function get_highlight_fields($highlight = '', array $grep_fields = null, $includeBusiness = false)
{
$fields = [];
@@ -236,9 +239,14 @@ class caption_record implements caption_interface, cache_cacheableInterface
foreach ($field->get_values() as $metaId => $v) {
$values[$metaId] = [
'value' => $v->getValue(),
- 'from_thesaurus' => $highlight ? $v->isThesaurusValue() : false,
- 'qjs' => $v->getQjs(),
+ 'from_thesaurus' => false,
+ 'qjs' => null,
];
+ if ($highlight) {
+ $v->highlight_thesaurus();
+ $values[$metaId]['from_thesaurus'] = $v->isThesaurusValue();
+ $values[$metaId]['qjs'] = $v->getQjs();
+ }
}
$fields[$field->get_name()] = [
'values' => $values,
@@ -249,24 +257,6 @@ class caption_record implements caption_interface, cache_cacheableInterface
];
}
- if ($searchEngine instanceof SearchEngineInterface) {
- $ret = $searchEngine->excerpt($highlight, $fields, $this->record, $options);
-
- // sets highlighted value from search engine, highlighted values will now
- // be surrounded by [[em]][[/em]] tags
- if ($ret) {
- foreach ($fields as $key => $value) {
- if (!isset($ret[$key])) {
- continue;
- }
-
- foreach ($ret[$key] as $metaId => $newValue) {
- $fields[$key]['values'][$metaId]['value'] = $newValue;
- }
- }
- }
- }
-
return $fields;
}
@@ -278,7 +268,7 @@ class caption_record implements caption_interface, cache_cacheableInterface
*/
public function get_cache_key($option = null)
{
- return 'caption_' . $this->record->get_serialize_key() . ($option ? '_' . $option : '');
+ return 'caption_' . $this->record->getId() . ($option ? '_' . $option : '');
}
/**
@@ -289,7 +279,7 @@ class caption_record implements caption_interface, cache_cacheableInterface
*/
public function get_data_from_cache($option = null)
{
- return $this->record->getDatabox()->get_data_from_cache($this->get_cache_key($option));
+ return $this->getDatabox()->get_data_from_cache($this->get_cache_key($option));
}
/**
@@ -302,7 +292,7 @@ class caption_record implements caption_interface, cache_cacheableInterface
*/
public function set_data_to_cache($value, $option = null, $duration = 0)
{
- return $this->record->getDatabox()->set_data_to_cache($value, $this->get_cache_key($option), $duration);
+ return $this->getDatabox()->set_data_to_cache($value, $this->get_cache_key($option), $duration);
}
/**
@@ -315,6 +305,14 @@ class caption_record implements caption_interface, cache_cacheableInterface
{
$this->fields = null;
- return $this->record->getDatabox()->delete_data_from_cache($this->get_cache_key($option));
+ return $this->getDatabox()->delete_data_from_cache($this->get_cache_key($option));
+ }
+
+ /**
+ * @return databox
+ */
+ private function getDatabox()
+ {
+ return $this->app->findDataboxById($this->record->getDataboxId());
}
}
diff --git a/lib/classes/databox/descriptionStructure.php b/lib/classes/databox/descriptionStructure.php
index 24c5c4ff74..d772d0e514 100644
--- a/lib/classes/databox/descriptionStructure.php
+++ b/lib/classes/databox/descriptionStructure.php
@@ -1,5 +1,4 @@
|null
*/
- protected $cache_name_id = [];
+ protected $cache_name_id;
/**
* @param databox_field[] $fields
@@ -51,6 +52,10 @@ class databox_descriptionStructure implements IteratorAggregate, Countable
{
$this->elements[$field->get_id()] = $field;
+ if (null !== $this->cache_name_id) {
+ $this->cache_name_id[$field->get_name()] = $field->get_id();
+ }
+
return $this;
}
@@ -60,8 +65,9 @@ class databox_descriptionStructure implements IteratorAggregate, Countable
*/
public function remove_element(databox_field $field)
{
- if (isset($this->elements[$field->get_id()]))
- unset($this->elements[$field->get_id()]);
+ if (isset($this->elements[$field->get_id()])) {
+ unset($this->elements[$field->get_id()], $this->cache_name_id[$field->get_name()]);
+ }
return $this;
}
@@ -75,14 +81,14 @@ class databox_descriptionStructure implements IteratorAggregate, Countable
}
/**
- *
- * @param int $id
+ * @param int $id
* @return databox_field
*/
public function get_element($id)
{
- if ( ! isset($this->elements[$id]))
+ if (!isset($this->elements[$id])) {
throw new Exception_Databox_FieldNotFound ();
+ }
return $this->elements[$id];
}
@@ -93,23 +99,35 @@ class databox_descriptionStructure implements IteratorAggregate, Countable
*/
public function get_element_by_name($name)
{
- $name = databox_field::generateName($name);
+ if (null === $this->cache_name_id) {
+ $this->cache_name_id = [];
- if (isset($this->cache_name_id[$name])) {
- return $this->elements[$this->cache_name_id[$name]];
- }
-
- foreach ($this->elements as $id => $meta) {
- if ($meta->get_name() === $name) {
- $this->cache_name_id[$name] = $id;
-
- return $meta;
+ foreach ($this->elements as $id => $meta) {
+ $this->cache_name_id[$meta->get_name()] = $id;
}
}
- return null;
+ $name = databox_field::generateName($name);
+
+ return isset($this->cache_name_id[$name])
+ ? $this->elements[$this->cache_name_id[$name]]
+ : null;
}
+ /**
+ * @return databox_field[]
+ */
+ public function getDcesFields()
+ {
+ return array_filter($this->elements, function (databox_field $field) {
+ return null !== $field->get_dces_element();
+ });
+ }
+
+ /**
+ * @param string $label
+ * @return databox_field|null
+ */
public function get_dces_field($label)
{
foreach ($this->elements as $field) {
@@ -125,13 +143,16 @@ class databox_descriptionStructure implements IteratorAggregate, Countable
/**
* @param string $id
- * @return boolean
+ * @return bool
*/
public function isset_element($id)
{
return isset($this->elements[$id]);
}
+ /**
+ * @return array
+ */
public function toArray()
{
return array_map(function (databox_field $element) {
diff --git a/lib/classes/databox/field.php b/lib/classes/databox/field.php
index 7fb8299d37..4e4eb70970 100644
--- a/lib/classes/databox/field.php
+++ b/lib/classes/databox/field.php
@@ -1,5 +1,4 @@
'databox_Field_DCES_Type',
];
+ /**
+ * @var databox_Field_DCESAbstract|null
+ */
protected $dces_element;
+
+ /**
+ * @var ControlProviderInterface|null
+ */
protected $Vocabulary;
+
+ /**
+ * @var string|null
+ */
protected $VocabularyType;
+
+ /**
+ * @var bool
+ */
protected $VocabularyRestriction = false;
protected $on_error = false;
protected $original_src;
@@ -504,7 +517,6 @@ class databox_field implements cache_cacheableInterface
}
/**
- *
* @return databox_Field_DCESAbstract
*/
public function get_dces_element()
@@ -514,29 +526,25 @@ class databox_field implements cache_cacheableInterface
public function set_dces_element(databox_Field_DCESAbstract $DCES_element = null)
{
- $connbas = $this->get_connection();
-
+ $connection = $this->get_connection();
if (null !== $DCES_element) {
- $sql = 'UPDATE metadatas_structure
- SET dces_element = null WHERE dces_element = :dces_element';
-
- $stmt = $connbas->prepare($sql);
- $stmt->execute([
- ':dces_element' => $DCES_element->get_label()
- ]);
- $stmt->closeCursor();
+ $connection->executeUpdate(
+ 'UPDATE metadatas_structure SET dces_element = null WHERE dces_element = :dces_element',
+ [
+ 'dces_element' => $DCES_element->get_label(),
+ ]
+ );
}
- $sql = 'UPDATE metadatas_structure
- SET dces_element = :dces_element WHERE id = :id';
+ $connection->executeUpdate(
+ 'UPDATE metadatas_structure SET dces_element = :dces_element WHERE id = :id',
+ [
+ 'dces_element' => $DCES_element ? $DCES_element->get_label() : null,
+ 'id' => $this->id,
+ ]
+ );
- $stmt = $connbas->prepare($sql);
- $stmt->execute([
- ':dces_element' => $DCES_element ? $DCES_element->get_label() : null
- , ':id' => $this->id
- ]);
- $stmt->closeCursor();
$this->dces_element = $DCES_element;
$this->delete_data_from_cache();
@@ -934,12 +942,12 @@ class databox_field implements cache_cacheableInterface
}
/**
- *
* @return array
*/
public function __sleep()
{
$vars = [];
+
foreach ($this as $key => $value) {
if (in_array($key, ['databox', 'app', 'Vocabulary']))
continue;
@@ -997,10 +1005,14 @@ class databox_field implements cache_cacheableInterface
private function loadVocabulary()
{
- try {
- $this->Vocabulary = Vocabulary\Controller::get($this->app, $this->VocabularyType);
- } catch (\InvalidArgumentException $e) {
+ if ($this->VocabularyType === '') {
+ return;
+ }
+ try {
+ $this->Vocabulary = $this->app['vocabularies'][$this->VocabularyType];
+ } catch (\InvalidArgumentException $e) {
+ // Could not find Vocabulary
}
}
diff --git a/lib/classes/media/Permalink/Adapter.php b/lib/classes/media/Permalink/Adapter.php
index d7f0382c8b..38c662b3f2 100644
--- a/lib/classes/media/Permalink/Adapter.php
+++ b/lib/classes/media/Permalink/Adapter.php
@@ -12,6 +12,9 @@
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Exception\RuntimeException;
use Alchemy\Phrasea\Model\Manipulator\TokenManipulator;
+use Alchemy\Phrasea\Utilities\NullableDateTime;
+use Assert\Assertion;
+use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DBALException;
use Guzzle\Http\Url;
@@ -37,17 +40,22 @@ class media_Permalink_Adapter implements cache_cacheableInterface
protected $app;
/**
- * @param Application $app
- * @param databox $databox
- * @param media_subdef $media_subdef
+ * @param Application $app
+ * @param databox $databox
+ * @param media_subdef $media_subdef
+ * @param array $data
*/
- public function __construct(Application $app, databox $databox, media_subdef $media_subdef)
+ public function __construct(Application $app, databox $databox, media_subdef $media_subdef, array $data = null)
{
$this->app = $app;
$this->databox = $databox;
$this->media_subdef = $media_subdef;
- $this->load();
+ if (null === $data) {
+ $this->load();
+ } else {
+ $this->loadFromData($data);
+ }
}
/**
@@ -106,12 +114,12 @@ class media_Permalink_Adapter implements cache_cacheableInterface
$label = $this->get_label() . '.' . pathinfo($this->media_subdef->get_file(), PATHINFO_EXTENSION);
return Url::factory($this->app->url('permalinks_permalink', [
- 'sbas_id' => $this->media_subdef->get_sbas_id(),
+ 'sbas_id' => $this->media_subdef->get_sbas_id(),
'record_id' => $this->media_subdef->get_record_id(),
- 'subdef' => $this->media_subdef->get_name(),
+ 'subdef' => $this->media_subdef->get_name(),
/** @Ignore */
- 'label' => $label,
- 'token' => $this->get_token(),
+ 'label' => $label,
+ 'token' => $this->get_token(),
]));
}
@@ -121,10 +129,10 @@ class media_Permalink_Adapter implements cache_cacheableInterface
public function get_page()
{
return $this->app->url('permalinks_permaview', [
- 'sbas_id' => $this->media_subdef->get_sbas_id(),
+ 'sbas_id' => $this->media_subdef->get_sbas_id(),
'record_id' => $this->media_subdef->get_record_id(),
- 'subdef' => $this->media_subdef->get_name(),
- 'token' => $this->get_token(),
+ 'subdef' => $this->media_subdef->get_name(),
+ 'token' => $this->get_token(),
]);
}
@@ -139,7 +147,7 @@ class media_Permalink_Adapter implements cache_cacheableInterface
$sql = 'UPDATE permalinks SET token = :token, last_modified = NOW()
WHERE id = :id';
$stmt = $this->databox->get_connection()->prepare($sql);
- $stmt->execute([':token' => $this->token, ':id' => $this->get_id()]);
+ $stmt->execute([':token' => $this->token, ':id' => $this->get_id()]);
$stmt->closeCursor();
$this->delete_data_from_cache();
@@ -148,24 +156,17 @@ class media_Permalink_Adapter implements cache_cacheableInterface
}
/**
- * @param string $is_activated
+ * @param bool $is_activated
* @return $this
*/
public function set_is_activated($is_activated)
{
- $this->is_activated = ! ! $is_activated;
+ $this->is_activated = (bool)$is_activated;
- $sql = 'UPDATE permalinks SET activated = :activated, last_modified = NOW()
- WHERE id = :id';
- $stmt = $this->databox->get_connection()->prepare($sql);
-
- $params = [
- ':activated' => $this->is_activated,
- ':id' => $this->get_id()
- ];
-
- $stmt->execute($params);
- $stmt->closeCursor();
+ $this->databox->get_connection()->executeUpdate(
+ 'UPDATE permalinks SET activated = :activated, last_modified = NOW() WHERE id = :id',
+ ['activated' => $this->is_activated, 'id' => $this->get_id()]
+ );
$this->delete_data_from_cache();
@@ -179,81 +180,79 @@ class media_Permalink_Adapter implements cache_cacheableInterface
public function set_label($label)
{
$label = trim($label) ? trim($label) : 'untitled';
- while (strpos($label, ' ') !== false)
+
+ while (strpos($label, ' ') !== false) {
$label = str_replace(' ', ' ', $label);
+ }
$this->label = $this->app['unicode']->remove_nonazAZ09(
str_replace(' ', '-', $label)
);
- $sql = 'UPDATE permalinks SET label = :label, last_modified = NOW()
- WHERE id = :id';
- $stmt = $this->databox->get_connection()->prepare($sql);
- $stmt->execute([':label' => $this->label, ':id' => $this->get_id()]);
- $stmt->closeCursor();
+ $this->databox->get_connection()->executeUpdate(
+ 'UPDATE permalinks SET label = :label, last_modified = NOW() WHERE id = :id',
+ ['label' => $this->label, 'id' => $this->get_id()]
+ );
$this->delete_data_from_cache();
return $this;
}
- /**
- * @return $this
- */
protected function load()
{
try {
- $datas = $this->get_data_from_cache();
- $this->id = $datas['id'];
- $this->token = $datas['token'];
- $this->is_activated = $datas['is_activated'];
- $this->created_on = $datas['created_on'];
- $this->last_modified = $datas['last_modified'];
- $this->label = $datas['label'];
-
- return $this;
+ $data = $this->get_data_from_cache();
} catch (\Exception $e) {
-
+ $data = false;
}
- $sql = '
- SELECT p.id, p.token, p.activated, p.created_on, p.last_modified, p.label
- FROM permalinks p
- WHERE p.subdef_id = :subdef_id';
- $stmt = $this->databox->get_connection()->prepare($sql);
- $stmt->execute([':subdef_id' => $this->media_subdef->get_subdef_id()]);
- $row = $stmt->fetch(PDO::FETCH_ASSOC);
- $stmt->closeCursor();
+ if (is_array($data)) {
+ $this->loadFromData($data);
- if (!$row) {
- throw new Exception_Media_SubdefNotFound ();
+ return;
}
- $this->id = (int) $row['id'];
- $this->token = $row['token'];
- $this->is_activated = ! ! $row['activated'];
- $this->created_on = new DateTime($row['created_on']);
- $this->last_modified = new DateTime($row['last_modified']);
- $this->label = $row['label'];
+ $data = $this->databox->get_connection()->fetchAssoc(
+ self::getSelectSql(),
+ [':subdef_id' => $this->media_subdef->get_subdef_id()]
+ );
+
+ if (!$data) {
+ throw new Exception_Media_SubdefNotFound();
+ }
+
+ $this->loadFromData($data);
+
+ $this->set_data_to_cache($this->toArray());
+ }
+
+ private function loadFromData(array $data)
+ {
+ $this->id = (int)$data['id'];
+ $this->token = $data['token'];
+ $this->is_activated = (bool)$data['is_activated'];
+ $this->created_on = new DateTime($data['created_on']);
+ $this->last_modified = new DateTime($data['last_modified']);
+ $this->label = $data['label'];
+ }
+
+ private function toArray()
+ {
+ return [
+ 'id' => $this->id,
+ 'token' => $this->token,
+ 'is_activated' => $this->is_activated,
+ 'created_on' => NullableDateTime::format($this->created_on),
+ 'last_modified' => NullableDateTime::format($this->last_modified),
+ 'label' => $this->label,
- $datas = [
- 'id' => $this->id,
- 'token' => $this->token,
- 'is_activated' => $this->is_activated,
- 'created_on' => $this->created_on,
- 'last_modified' => $this->last_modified,
- /** @Ignore */
- 'label' => $this->label,
];
-
- $this->set_data_to_cache($datas);
-
- return $this;
}
/**
- * @param Application $app
- * @param databox $databox
+ * @param Application $app
+ * @param databox $databox
* @param media_subdef $media_subdef
* @return $this
*/
@@ -262,57 +261,220 @@ class media_Permalink_Adapter implements cache_cacheableInterface
try {
return new self($app, $databox, $media_subdef);
} catch (\Exception $e) {
-
+ // Could not load, try to create
}
return self::create($app, $databox, $media_subdef);
}
/**
- * @param Application $app
- * @param databox $databox
+ * @param Application $app
+ * @param media_subdef[] $subdefs
+ * @return media_Permalink_Adapter[]
+ */
+ public static function getMany(Application $app, $subdefs)
+ {
+ Assertion::allIsInstanceOf($subdefs, media_subdef::class);
+
+ $permalinks = [];
+ $subdefPerDatabox = [];
+
+ foreach ($subdefs as $index => $subdef) {
+ if (!isset($subdefPerDatabox[$subdef->get_sbas_id()])) {
+ $subdefPerDatabox[$subdef->get_sbas_id()] = [];
+ }
+ $subdefPerDatabox[$subdef->get_sbas_id()][$index] = $subdef;
+
+ $permalinks[$index] = null;
+ }
+
+ foreach ($subdefPerDatabox as $databoxId => $media_subdefs) {
+ $databox = $app->findDataboxById($databoxId);
+
+ $subdefIds = array_map(function (media_subdef $media_subdef) {
+ return $media_subdef->get_subdef_id();
+ }, $media_subdefs);
+
+ $data = self::fetchData($databox, $subdefIds);
+
+ $missing = array_diff_key($media_subdefs, $data);
+
+ if ($missing) {
+ self::createMany($app, $databox, $missing);
+ $data = array_replace($data, self::fetchData($databox, array_diff_key($subdefIds, $data)));
+ }
+
+ foreach ($media_subdefs as $index => $subdef) {
+ if (!isset($data[$index])) {
+ throw new \RuntimeException('Could not fetch some data. Should never happen');
+ }
+
+ $permalinks[$index] = new self($app, $databox, $subdef, $data[$index]);
+ }
+ }
+
+ return $permalinks;
+ }
+
+ /**
+ * Returns present data in storage with same indexes but different order
+ *
+ * @param databox $databox
+ * @param int[] $subdefIds
+ * @return array
+ */
+ private static function fetchData(databox $databox, array $subdefIds)
+ {
+ $found = [];
+ $missing = [];
+
+ foreach ($subdefIds as $index => $subdefId) {
+ try {
+ $data = self::doGetDataFromCache($databox, $subdefId);
+ } catch (Exception $exception) {
+ $data = false;
+ }
+
+ if (is_array($data)) {
+ $found[$index] = $data;
+
+ continue;
+ }
+
+ $missing[$index] = $subdefId;
+ }
+
+ if (!$missing) {
+ return $found;
+ }
+
+ $dbalData = $databox->get_connection()->fetchAll(
+ self::getSelectSql(),
+ ['subdef_id' => array_values($missing)],
+ ['subdef_id' => Connection::PARAM_INT_ARRAY]
+ );
+
+ foreach ($dbalData as $item) {
+ $itemSubdefId = $item['subdef_id'];
+
+ $databox->set_data_to_cache($item, self::generateCacheKey($itemSubdefId));
+
+ $foundIndexes = array_keys(array_intersect($missing, [$itemSubdefId]));
+
+ foreach ($foundIndexes as $foundIndex) {
+ $found[$foundIndex] = $item;
+ unset($missing[$foundIndex]);
+ }
+ }
+
+ return $found;
+ }
+
+ /**
+ * @param Application $app
+ * @param databox $databox
+ * @param media_subdef[] $subdefs
+ * @throws DBALException
+ * @throws \InvalidArgumentException
+ */
+ public static function createMany(Application $app, databox $databox, $subdefs)
+ {
+ $databoxId = $databox->get_sbas_id();
+ $recordIds = [];
+
+ foreach ($subdefs as $media_subdef) {
+ if ($media_subdef->get_sbas_id() !== $databoxId) {
+ throw new InvalidArgumentException(sprintf(
+ 'All subdefs should be from databox %d, got %d',
+ $databoxId,
+ $media_subdef->get_sbas_id()
+ ));
+ }
+
+ $recordIds[] = $media_subdef->get_record_id();
+ }
+
+ $databoxRecords = $databox->getRecordRepository()->findByRecordIds($recordIds);
+
+ /** @var record_adapter[] $records */
+ $records = array_combine(
+ array_map(function (record_adapter $record) {
+ return $record->getRecordId();
+ }, $databoxRecords),
+ $databoxRecords
+ );
+
+ if (count(array_unique($recordIds)) !== count($records)) {
+ throw new \RuntimeException('Some records are missing');
+ }
+
+ $generator = $app['random.medium'];
+
+ $data = [];
+
+ foreach ($subdefs as $media_subdef) {
+ $data[] = [
+ 'subdef_id' => $media_subdef->get_subdef_id(),
+ 'token' => $generator->generateString(64, TokenManipulator::LETTERS_AND_NUMBERS),
+ 'label' => $records[$media_subdef->get_record_id()]->get_title(false, null, true),
+ ];
+ }
+
+ try {
+ $databox->get_connection()->transactional(function (Connection $connection) use ($data) {
+ $sql = <<<'SQL'
+INSERT INTO permalinks (subdef_id, token, activated, created_on, last_modified, label)
+VALUES (:subdef_id, :token, 1, NOW(), NOW(), :label)
+SQL;
+
+ $statement = $connection->prepare($sql);
+
+ foreach ($data as $params) {
+ $statement->execute($params);
+ }
+ });
+ } catch (Exception $e) {
+ throw new RuntimeException('Permalink already exists', $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * @param Application $app
+ * @param databox $databox
* @param media_subdef $media_subdef
* @return $this
*/
public static function create(Application $app, databox $databox, media_subdef $media_subdef)
{
- $sql = 'INSERT INTO permalinks
- (id, subdef_id, token, activated, created_on, last_modified, label)
- VALUES (null, :subdef_id, :token, :activated, NOW(), NOW(), "")';
+ self::createMany($app, $databox, [$media_subdef]);
- $params = [
- ':subdef_id' => $media_subdef->get_subdef_id()
- , ':token' => $app['random.medium']->generateString(64, TokenManipulator::LETTERS_AND_NUMBERS)
- , ':activated' => '1'
- ];
+ return self::getPermalink($app, $databox, $media_subdef);
+ }
- $error = null;
- $stmt = $databox->get_connection()->prepare($sql);
- try {
- $stmt->execute($params);
- } catch (DBALException $e) {
- $error = $e;
- }
- $stmt->closeCursor();
-
- if ($error) {
- throw new RuntimeException('Permalink already exists', $e->getCode(), $e);
- }
-
- $permalink = self::getPermalink($app, $databox, $media_subdef);
- $permalink->set_label(strip_tags($media_subdef->get_record()->get_title(false, null, true)));
-
- return $permalink;
+ private static function generateCacheKey($id, $option = null)
+ {
+ return 'permalink_' . $id . ($option ? '_' . $option : '');
}
public function get_cache_key($option = null)
{
- return 'permalink_' . $this->media_subdef->get_subdef_id() . ($option ? '_' . $option : '');
+ return self::generateCacheKey($this->media_subdef->get_subdef_id(), $option);
+ }
+
+ /**
+ * @param databox $databox
+ * @param int $subdefId
+ * @param null $option
+ * @return string
+ */
+ private static function doGetDataFromCache(databox $databox, $subdefId, $option = null)
+ {
+ return $databox->get_data_from_cache(self::generateCacheKey($subdefId, $option));
}
public function get_data_from_cache($option = null)
{
- return $this->databox->get_data_from_cache($this->get_cache_key($option));
+ return self::doGetDataFromCache($this->databox, $this->media_subdef->get_subdef_id(), $option);
}
public function set_data_to_cache($value, $option = null, $duration = 0)
@@ -324,4 +486,16 @@ class media_Permalink_Adapter implements cache_cacheableInterface
{
$this->databox->delete_data_from_cache($this->get_cache_key($option));
}
+
+ /**
+ * @return string
+ */
+ protected static function getSelectSql()
+ {
+ return <<<'SQL'
+SELECT p.id, p.subdef_id, p.token, p.activated AS is_activated, p.created_on, p.last_modified, p.label
+FROM permalinks p
+WHERE p.subdef_id IN (:subdef_id)
+SQL;
+ }
}
diff --git a/lib/classes/media/subdef.php b/lib/classes/media/subdef.php
index bf8711d1e4..7150a3c989 100644
--- a/lib/classes/media/subdef.php
+++ b/lib/classes/media/subdef.php
@@ -10,7 +10,11 @@
*/
use Alchemy\Phrasea\Application;
+use Alchemy\Phrasea\Databox\Subdef\MediaSubdefRepository;
use Alchemy\Phrasea\Http\StaticFile\Symlink\SymLinker;
+use Alchemy\Phrasea\Model\RecordReferenceInterface;
+use Alchemy\Phrasea\Utilities\NullableDateTime;
+use Assert\Assertion;
use Guzzle\Http\Url;
use MediaAlchemyst\Alchemyst;
use MediaVorus\Media\MediaInterface;
@@ -18,6 +22,16 @@ use MediaVorus\MediaVorus;
class media_subdef extends media_abstract implements cache_cacheableInterface
{
+ /**
+ * @param Application $app
+ * @param int $databoxId
+ * @return MediaSubdefRepository
+ */
+ private static function getMediaSubdefRepository(Application $app, $databoxId)
+ {
+ return $app['provider.repo.media_subdef']->getRepositoryForDatabox($databoxId);
+ }
+
/** @var Application */
protected $app;
@@ -103,114 +117,149 @@ class media_subdef extends media_abstract implements cache_cacheableInterface
const TC_DATA_LIGHTVALUE = 'LightValue';
/**
- * @param Application $app
- * @param record_adapter $record
- * @param string $name
- * @param bool $substitute
+ * @param Application $app
+ * @param RecordReferenceInterface $record
+ * @param string $name
+ * @param bool $substitute
+ * @param array|null $data
*/
- public function __construct(Application $app, record_adapter $record, $name, $substitute = false)
+ public function __construct(Application $app, RecordReferenceInterface $record, $name, $substitute = false, array $data = null)
{
$this->app = $app;
$this->name = $name;
- $this->record = $record;
- $this->load($substitute);
+ $this->record = $record instanceof record_adapter
+ ? $record
+ : $app->findDataboxById($record->getDataboxId())->get_record($record->getRecordId());
- $this->generate_url();
+ if (null !== $data) {
+ $this->loadFromArray($data);
+ } else {
+ $this->load($substitute);
+ }
- parent::__construct($this->width, $this->height, $this->url);
+ parent::__construct($this->width, $this->height, $this->generateUrl());
}
/**
* @param bool $substitute
- * @return $this
+ * @return void
*/
protected function load($substitute)
{
try {
- $datas = $this->get_data_from_cache();
- if (!is_array($datas)) {
- throw new \Exception('Could not retrieve data');
- }
- $this->mime = $datas['mime'];
- $this->width = $datas['width'];
- $this->height = $datas['height'];
- $this->size = $datas['size'];
- $this->etag = $datas['etag'];
- $this->path = $datas['path'];
- $this->url = $datas['url'];
- $this->file = $datas['file'];
- $this->is_physically_present = $datas['physically_present'];
- $this->is_substituted = $datas['is_substituted'];
- $this->subdef_id = $datas['subdef_id'];
- $this->modification_date = $datas['modification_date'];
- $this->creation_date = $datas['creation_date'];
-
- return $this;
- } catch (\Exception $e) {
-
+ $data = $this->get_data_from_cache();
+ } catch (Exception $e) {
+ $data = false;
}
- $connbas = $this->record->getDatabox()->get_connection();
+ if (is_array($data)) {
+ $this->loadFromArray($data);
- $sql = "SELECT subdef_id, name, file, width, height, mime,"
- . " path, size, substit, created_on, updated_on, etag"
- . " FROM subdef"
- . " WHERE name = :name AND record_id = :record_id";
+ return;
+ }
- $params = [
- ':record_id' => $this->record->getRecordId(),
- ':name' => $this->name
- ];
+ $sql = <<<'SQL'
+SELECT subdef_id, name, file, width, height, mime, path, size, substit, created_on, updated_on, etag
+FROM subdef
+WHERE name = :name AND record_id = :record_id
+SQL;
- $stmt = $connbas->prepare($sql);
- $stmt->execute($params);
- $row = $stmt->fetch(PDO::FETCH_ASSOC);
- $stmt->closeCursor();
+ $row = $this->getDataboxConnection()->fetchAssoc($sql, [
+ 'record_id' => $this->record->getRecordId(),
+ 'name' => $this->name
+ ]);
if ($row) {
- $this->width = (int) $row['width'];
- $this->size = (int) $row['size'];
- $this->height = (int) $row['height'];
- $this->mime = $row['mime'];
- $this->file = $row['file'];
- $this->path = p4string::addEndSlash($row['path']);
- $this->is_physically_present = file_exists($this->getRealPath());
- $this->etag = $row['etag'];
- $this->is_substituted = ! ! $row['substit'];
- $this->subdef_id = (int) $row['subdef_id'];
-
- if ($row['updated_on'])
- $this->modification_date = new DateTime($row['updated_on']);
- if ($row['created_on'])
- $this->creation_date = new DateTime($row['created_on']);
-
+ $this->loadFromArray([
+ 'width' => (int)$row['width'],
+ 'size' => (int)$row['size'],
+ 'height' => (int)$row['height'],
+ 'mime' => $row['mime'],
+ 'file' => $row['file'],
+ 'path' => p4string::addEndSlash($row['path']),
+ 'physically_present' => true,
+ 'is_substituted' => (bool)$row['substit'],
+ 'subdef_id' => (int)$row['subdef_id'],
+ 'updated_on' => $row['updated_on'],
+ 'created_on' => $row['created_on'],
+ 'etag' => $row['etag'] ?: null,
+ ]);
} elseif ($substitute === false) {
throw new Exception_Media_SubdefNotFound($this->name . ' not found');
}
- if (! $row) {
- $this->find_substitute_file();
+ if (!$row) {
+ $this->markPhysicallyUnavailable();
}
- $datas = [
- 'mime' => $this->mime,
- 'width' => $this->width,
- 'size' => $this->size,
- 'height' => $this->height,
- 'etag' => $this->etag,
- 'path' => $this->path,
- 'url' => $this->url,
- 'file' => $this->file,
+ $this->set_data_to_cache($this->toArray());
+ }
+
+ private function loadFromArray(array $data)
+ {
+ if (!$data) {
+ $data = [
+ 'mime' => 'unknown',
+ 'width' => 0,
+ 'height' => 0,
+ 'size' => 0,
+ 'path' => '',
+ 'file' => '',
+ 'physically_present' => false,
+ 'is_substituted' => false,
+ 'subdef_id' => null,
+ 'updated_on' => null,
+ 'created_on' => null,
+ 'url' => null,
+ ];
+ }
+
+ $normalizer = function ($field, callable $then, callable $else = null) use ($data) {
+ if (isset($data[$field]) || array_key_exists($field, $data)) {
+ return $then($data[$field]);
+ }
+
+ return $else ? $else() : null;
+ };
+
+ $this->mime = $data['mime'];
+ $this->width = (int)$data['width'];
+ $this->height = (int)$data['height'];
+ $this->size = (int)$data['size'];
+ $this->etag = $normalizer('etag', 'strval');
+ $this->path = p4string::addEndSlash($data['path']);
+ $this->file = $data['file'];
+ $this->is_physically_present = (bool)$data['physically_present'];
+ $this->is_substituted = (bool)$data['is_substituted'];
+ $this->subdef_id = $normalizer('subdef_id', 'intval');
+ $this->modification_date = $normalizer('updated_on', 'date_create');
+ $this->creation_date = $normalizer('created_on', 'date_create');
+ $this->url = $normalizer('url', [Url::class, 'factory'], [$this, 'generateUrl']);
+
+ if (!$this->isStillAccessible()) {
+ $this->markPhysicallyUnavailable();
+ }
+ }
+
+ private function toArray()
+ {
+ return [
+ 'record_id' => $this->get_record_id(),
+ 'name' => $this->get_name(),
+ 'width' => $this->width,
+ 'size' => $this->size,
+ 'height' => $this->height,
+ 'mime' => $this->mime,
+ 'file' => $this->file,
+ 'path' => $this->path,
'physically_present' => $this->is_physically_present,
- 'is_substituted' => $this->is_substituted,
- 'subdef_id' => $this->subdef_id,
- 'modification_date' => $this->modification_date,
- 'creation_date' => $this->creation_date,
+ 'is_substituted' => $this->is_substituted,
+ 'subdef_id' => $this->subdef_id,
+ 'updated_on' => NullableDateTime::format($this->modification_date),
+ 'created_on' => NullableDateTime::format($this->creation_date),
+ 'etag' => $this->etag,
+ 'url' => (string)$this->url,
];
-
- $this->set_data_to_cache($datas);
-
- return $this;
}
/**
@@ -225,11 +274,13 @@ class media_subdef extends media_abstract implements cache_cacheableInterface
$this->delete_data_from_cache();
- if ($this->get_permalink() instanceof media_Permalink_Adapter) {
- $this->get_permalink()->delete_data_from_cache();
+ $permalink = $this->get_permalink();
+
+ if ($permalink instanceof media_Permalink_Adapter) {
+ $permalink->delete_data_from_cache();
}
- $this->find_substitute_file();
+ $this->markPhysicallyUnavailable();
}
return $this;
@@ -245,57 +296,55 @@ class media_subdef extends media_abstract implements cache_cacheableInterface
$subdef_id = $this->subdef_id;
$this->remove_file();
- $connbas = $this->record->getDatabox()->get_connection();
+ $connection = $this->getDataboxConnection();
- $sql = "DELETE FROM subdef WHERE subdef_id = :subdef_id";
- $stmt = $connbas->prepare($sql);
- $stmt->execute(['subdef_id'=>$subdef_id]);
- $stmt->closeCursor();
+ $connection->executeUpdate(
+ 'DELETE FROM subdef WHERE subdef_id = :subdef_id',
+ ['subdef_id' => $subdef_id]
+ );
- $sql = "DELETE FROM permalinks WHERE subdef_id = :subdef_id";
- $stmt = $connbas->prepare($sql);
- $stmt->execute(['subdef_id'=>$subdef_id]);
- $stmt->closeCursor();
+ $connection->executeUpdate(
+ 'DELETE FROM permalinks WHERE subdef_id = :subdef_id',
+ ['subdef_id'=>$subdef_id]
+ );
$this->delete_data_from_cache();
$this->record->delete_data_from_cache(record_adapter::CACHE_SUBDEFS);
}
- /**
- * Find a substitution file for a subdef
- *
- * @return \media_subdef
- */
- protected function find_substitute_file()
+ private function getSubstituteFilename()
{
if ($this->record->isStory()) {
- $this->mime = 'image/png';
- $this->width = 256;
- $this->height = 256;
- $this->path = $this->app['root.path'] . '/www/assets/common/images/icons/substitution/';
- $this->file = 'regroup_thumb.png';
- $this->url = Url::factory('/assets/common/images/icons/substitution/regroup_thumb.png');
- } else {
- $mime = $this->record->getMimeType();
- $mime = trim($mime) != '' ? str_replace('/', '_', $mime) : 'application_octet-stream';
-
- $this->mime = 'image/png';
- $this->width = 256;
- $this->height = 256;
- $this->path = $this->app['root.path'] . '/www/assets/common/images/icons/substitution/';
- $this->file = str_replace('+', '%20', $mime) . '.png';
- $this->url = Url::factory('/assets/common/images/icons/substitution/' . $this->file);
+ return 'regroup_thumb.png';
}
+ $mime = $this->record->getMimeType();
+ $mime = trim($mime) != '' ? str_replace('/', '_', $mime) : 'application_octet-stream';
+
+ return str_replace('+', '%20', $mime) . '.png';
+ }
+
+ /**
+ * Find a substitution file for a subdef
+ * @return void
+ */
+ protected function markPhysicallyUnavailable()
+ {
$this->is_physically_present = false;
- if ( ! file_exists($this->path . $this->file)) {
+ $this->mime = 'image/png';
+ $this->width = 256;
+ $this->height = 256;
+ $this->file = $this->getSubstituteFilename();
+
+ $this->path = $this->app['root.path'] . '/www/assets/common/images/icons/substitution/';
+ $this->url = Url::factory('/assets/common/images/icons/substitution/' . $this->file);
+
+ if (!file_exists($this->getRealPath())) {
$this->path = $this->app['root.path'] . '/www/assets/common/images/icons/';
$this->file = 'substitution.png';
$this->url = Url::factory('/assets/common/images/icons/' . $this->file);
}
-
- return $this;
}
/**
@@ -319,8 +368,9 @@ class media_subdef extends media_abstract implements cache_cacheableInterface
*/
public function get_permalink()
{
- if ( ! $this->permalink && $this->is_physically_present())
+ if (null === $this->permalink && $this->is_physically_present()) {
$this->permalink = media_Permalink_Adapter::getPermalink($this->app, $this->record->getDatabox(), $this);
+ }
return $this->permalink;
}
@@ -337,37 +387,44 @@ class media_subdef extends media_abstract implements cache_cacheableInterface
{
if (!$this->etag && $this->is_physically_present()) {
$file = new SplFileInfo($this->getRealPath());
+
if ($file->isFile()) {
- $this->setEtag(md5($file->getMTime()));
+ $this->setEtag(md5($file->getRealPath() . $file->getMTime()));
}
}
return $this->etag;
}
+ /**
+ * @param string|null $etag
+ */
public function setEtag($etag)
{
$this->etag = $etag;
- $sql = "UPDATE subdef SET etag = :etag WHERE subdef_id = :subdef_id";
- $stmt = $this->record->getDatabox()->get_connection()->prepare($sql);
- $stmt->execute([':subdef_id' => $this->subdef_id, ':etag' => $etag]);
- $stmt->closeCursor();
+ $this->getDataboxConnection()->executeUpdate(
+ 'UPDATE subdef SET etag = :etag WHERE subdef_id = :subdef_id',
+ [':subdef_id' => $this->subdef_id, ':etag' => $etag]
+ );
return $this;
}
+ /**
+ * @param boolean $substit
+ */
public function set_substituted($substit)
{
$this->is_substituted = !!$substit;
- $sql = "UPDATE subdef SET substit = :substit, updated_on=NOW() WHERE subdef_id = :subdef_id";
- $stmt = $this->record->getDatabox()->get_connection()->prepare($sql);
- $stmt->execute(array(
- ':subdef_id' => $this->subdef_id,
- ':substit' => $this->is_substituted
- ));
- $stmt->closeCursor();
+ $this->getDataboxConnection()->executeUpdate(
+ 'UPDATE subdef SET substit = :substit, updated_on=NOW() WHERE subdef_id = :subdef_id',
+ [
+ ':subdef_id' => $this->subdef_id,
+ ':substit' => $this->is_substituted
+ ]
+ );
$this->delete_data_from_cache();
@@ -387,31 +444,22 @@ class media_subdef extends media_abstract implements cache_cacheableInterface
*/
public function get_type()
{
- switch ($this->mime) {
- case 'video/mp4':
- $type = self::TYPE_VIDEO_MP4;
- break;
- case 'video/x-flv':
- $type = self::TYPE_VIDEO_FLV;
- break;
- case 'application/x-shockwave-flash':
- $type = self::TYPE_FLEXPAPER;
- break;
- case 'audio/mpeg':
- case 'audio/mp3':
- $type = self::TYPE_AUDIO_MP3;
- break;
- case 'image/jpeg':
- case 'image/png':
- case 'image/gif':
- $type = self::TYPE_IMAGE;
- break;
- default:
- $type = self::TYPE_NO_PLAYER;
- break;
+ static $types = [
+ 'application/x-shockwave-flash' => self::TYPE_FLEXPAPER,
+ 'audio/mp3' => self::TYPE_AUDIO_MP3,
+ 'audio/mpeg' => self::TYPE_AUDIO_MP3,
+ 'image/gif' => self::TYPE_IMAGE,
+ 'image/jpeg' => self::TYPE_IMAGE,
+ 'image/png' => self::TYPE_IMAGE,
+ 'video/mp4' => self::TYPE_VIDEO_MP4,
+ 'video/x-flv' => self::TYPE_VIDEO_FLV,
+ ];
+
+ if (isset($types[$this->mime])) {
+ return $types[$this->mime];
}
- return $type;
+ return self::TYPE_NO_PLAYER;
}
/**
@@ -496,11 +544,11 @@ class media_subdef extends media_abstract implements cache_cacheableInterface
}
/**
- * @return string
+ * @return Url
*/
public function renew_url()
{
- $this->generate_url();
+ $this->url = $this->generateUrl();
return $this->get_url();
}
@@ -520,7 +568,7 @@ class media_subdef extends media_abstract implements cache_cacheableInterface
public function getDevices()
{
- if ($this->get_name() == 'document') {
+ if ($this->get_name() === 'document') {
return [\databox_subdef::DEVICE_ALL];
}
@@ -544,7 +592,7 @@ class media_subdef extends media_abstract implements cache_cacheableInterface
*/
public function rotate($angle, Alchemyst $alchemyst, MediaVorus $mediavorus)
{
- if ( ! $this->is_physically_present()) {
+ if (!$this->is_physically_present()) {
throw new \Alchemy\Phrasea\Exception\RuntimeException('You can not rotate a substitution');
}
@@ -559,27 +607,26 @@ class media_subdef extends media_abstract implements cache_cacheableInterface
$media = $mediavorus->guess($this->getRealPath());
- $sql = "UPDATE subdef SET height = :height , width = :width, updated_on = NOW()"
- . " WHERE record_id = :record_id AND name = :name";
+ $sql = <<<'SQL'
+UPDATE subdef SET height = :height , width = :width, updated_on = NOW()
+WHERE record_id = :record_id AND name = :name
+SQL;
- $params = [
- ':width' => $media->getWidth(),
- ':height' => $media->getHeight(),
- ':record_id' => $this->get_record_id(),
- ':name' => $this->get_name(),
- ];
-
- $stmt = $this->record->getDatabox()->get_connection()->prepare($sql);
- $stmt->execute($params);
- $stmt->closeCursor();
+ $this->getDataboxConnection()->executeUpdate(
+ $sql,
+ [
+ ':width' => $media->getWidth(),
+ ':height' => $media->getHeight(),
+ ':record_id' => $this->get_record_id(),
+ ':name' => $this->get_name(),
+ ]
+ );
$this->width = $media->getWidth();
$this->height = $media->getHeight();
$this->delete_data_from_cache();
- unset($media);
-
return $this;
}
@@ -591,7 +638,7 @@ class media_subdef extends media_abstract implements cache_cacheableInterface
*/
public function readTechnicalDatas(MediaVorus $mediavorus)
{
- if ( ! $this->is_physically_present()) {
+ if (!$this->is_physically_present()) {
return [];
}
@@ -643,50 +690,47 @@ class media_subdef extends media_abstract implements cache_cacheableInterface
return $datas;
}
- public static function create(Application $app, \record_adapter $record, $name, MediaInterface $media)
+ public static function create(Application $app, RecordReferenceInterface $record, $name, MediaInterface $media)
{
- $databox = $record->getDatabox();
- $connbas = $databox->get_connection();
-
$path = $media->getFile()->getPath();
$newname = $media->getFile()->getFilename();
$params = [
- ':record_id' => $record->getRecordId(),
- ':name' => $name,
- ':path' => $path,
- ':file' => $newname,
- ':width' => 0,
- ':height' => 0,
- ':mime' => $media->getFile()->getMimeType(),
- ':size' => $media->getFile()->getSize(),
- ':dispatched' => 1,
+ 'record_id' => $record->getRecordId(),
+ 'name' => $name,
+ 'path' => $path,
+ 'file' => $newname,
+ 'width' => 0,
+ 'height' => 0,
+ 'mime' => $media->getFile()->getMimeType(),
+ 'size' => $media->getFile()->getSize(),
+ 'physically_present' => true,
+ 'is_substituted' => false,
];
if (method_exists($media, 'getWidth') && null !== $media->getWidth()) {
- $params[':width'] = $media->getWidth();
+ $params['width'] = $media->getWidth();
}
if (method_exists($media, 'getHeight') && null !== $media->getHeight()) {
- $params[':height'] = $media->getHeight();
+ $params['height'] = $media->getHeight();
}
- $sql = "INSERT INTO subdef"
- . " (record_id, name, path, file, width, height, mime, size, dispatched, created_on, updated_on)"
- . " VALUES (:record_id, :name, :path, :file, :width, :height, :mime, :size, :dispatched, NOW(), NOW())"
- . " ON DUPLICATE KEY UPDATE"
- . " path = VALUES(path), file = VALUES(file),"
- . " width = VALUES(width) , height = VALUES(height), mime = VALUES(mime),"
- . " size = VALUES(size), dispatched = VALUES(dispatched), updated_on = NOW()";
+ $factoryProvider = $app['provider.factory.media_subdef'];
+ $factory = $factoryProvider($record->getDataboxId());
- $stmt = $connbas->prepare($sql);
- $stmt->execute($params);
- $stmt->closeCursor();
+ $subdef = $factory($params);
+ Assertion::isInstanceOf($subdef, \media_subdef::class);
- $subdef = new self($app, $record, $name);
- $subdef->delete_data_from_cache();
+ $repository = self::getMediaSubdefRepository($app, $record->getDataboxId());
+ $repository->save($subdef);
- if ($subdef->get_permalink() instanceof media_Permalink_Adapter) {
- $subdef->get_permalink()->delete_data_from_cache();
+ // Refresh from Database.
+ $subdef = $repository->findOneByRecordIdAndName($record->getRecordId(), $name);
+
+ $permalink = $subdef->get_permalink();
+
+ if ($permalink instanceof media_Permalink_Adapter) {
+ $permalink->delete_data_from_cache();
}
if ($name === 'thumbnail') {
@@ -695,48 +739,44 @@ class media_subdef extends media_abstract implements cache_cacheableInterface
$symlinker->symlink($subdef->getRealPath());
}
- unset($media);
-
return $subdef;
}
- protected function generate_url()
+ /**
+ * @return Url
+ */
+ protected function generateUrl()
{
if (!$this->is_physically_present()) {
- return;
+ $this->markPhysicallyUnavailable();
+
+ return $this->url;
}
- // serve thumbnails using static file service
- if ($this->get_name() === 'thumbnail') {
- if (null !== $url = $this->app['phraseanet.static-file']->getUrl($this->getRealPath())) {
- $url->getQuery()->offsetSet('etag', $this->getEtag());
- $this->url = $url;
+ $generators = [
+ [$this, 'tryGetThumbnailUrl'],
+ [$this, 'tryGetVideoUrl'],
+ ];
- return;
- }
- }
-
- if ($this->app['phraseanet.h264-factory']->isH264Enabled() && in_array($this->mime, ['video/mp4'])) {
- if (null !== $url = $this->app['phraseanet.h264']->getUrl($this->getRealPath())) {
- $this->url = $url;
+ foreach ($generators as $generator) {
+ $url = $generator();
- return;
+ if ($url instanceof Url) {
+ return $url;
}
}
- $this->url = Url::factory($this->app->path('datafile', [
+ return Url::factory($this->app->path('datafile', [
'sbas_id' => $this->record->getDataboxId(),
'record_id' => $this->record->getRecordId(),
'subdef' => $this->get_name(),
'etag' => $this->getEtag(),
]));
-
- return;
}
public function get_cache_key($option = null)
{
- return 'subdef_' . $this->get_record()->get_serialize_key()
+ return 'subdef_' . $this->get_record()->getId()
. '_' . $this->name . ($option ? '_' . $option : '');
}
@@ -785,4 +825,52 @@ class media_subdef extends media_abstract implements cache_cacheableInterface
{
return $this->path . 'stamp_' . $this->file;
}
+
+ /**
+ * @return \Doctrine\DBAL\Connection
+ */
+ private function getDataboxConnection()
+ {
+ return $this->record->getDatabox()->get_connection();
+ }
+
+ /**
+ * @return bool
+ */
+ private function isStillAccessible()
+ {
+ return $this->is_physically_present && file_exists($this->getRealPath());
+ }
+
+ /**
+ * @return Url|null
+ */
+ protected function tryGetThumbnailUrl()
+ {
+ if ('thumbnail' !== $this->get_name()) {
+ return null;
+ }
+
+ $url = $this->app['phraseanet.static-file']->getUrl($this->getRealPath());
+
+ if (null === $url) {
+ return null;
+ }
+
+ $url->getQuery()->offsetSet('etag', $this->getEtag());
+
+ return $url;
+ }
+
+ /**
+ * @return Url|null
+ */
+ protected function tryGetVideoUrl()
+ {
+ if ($this->mime !== 'video/mp4' || !$this->app['phraseanet.h264-factory']->isH264Enabled()) {
+ return null;
+ }
+
+ return $this->app['phraseanet.h264']->getUrl($this->getRealPath());
+ }
}
diff --git a/lib/classes/module/console/systemExport.php b/lib/classes/module/console/systemExport.php
index 272124fb75..f6763d52b5 100644
--- a/lib/classes/module/console/systemExport.php
+++ b/lib/classes/module/console/systemExport.php
@@ -252,9 +252,9 @@ class module_console_systemExport extends Command
$dest_file = new \SplFileInfo($outfile);
touch(
- $dest_file->getPathname()
- , $record->get_creation_date()->format('U')
- , $record->get_modification_date()->format('U')
+ $dest_file->getPathname(),
+ $record->getCreated()->format('U'),
+ $record->getUpdated()->format('U')
);
switch (strtolower($caption)) {
diff --git a/lib/classes/module/report/nav.php b/lib/classes/module/report/nav.php
index 25e42f3eed..09ad769ff9 100644
--- a/lib/classes/module/report/nav.php
+++ b/lib/classes/module/report/nav.php
@@ -516,7 +516,7 @@ class module_report_nav extends module_report
'photo' =>
"
"
- , 'record_id' => $record->get_record_id()
+ , 'record_id' => $record->getRecordId()
, 'date' => $this->app['date-formatter']->getPrettyString($document->get_creation_date())
, 'type' => $document->get_mime()
, 'titre' => $record->get_title()
diff --git a/lib/classes/patch/320alpha4b.php b/lib/classes/patch/320alpha4b.php
index a0e649bb87..fa1bd4184f 100644
--- a/lib/classes/patch/320alpha4b.php
+++ b/lib/classes/patch/320alpha4b.php
@@ -133,8 +133,8 @@ class patch_320alpha4b extends patchAbstract
$item = new FeedItem();
$item->setEntry($entry);
$entry->addItem($item);
- $item->setRecordId($record->get_record_id());
- $item->setSbasId($record->get_sbas_id());
+ $item->setRecordId($record->getRecordId());
+ $item->setSbasId($record->getDataboxId());
$app['orm.em']->persist($item);
} catch (NotFoundHttpException $e) {
diff --git a/lib/classes/record/adapter.php b/lib/classes/record/adapter.php
index a827125487..b765eee819 100644
--- a/lib/classes/record/adapter.php
+++ b/lib/classes/record/adapter.php
@@ -1,5 +1,5 @@
app = $app;
$this->reference = RecordReference::createFromDataboxIdAndRecordId($sbas_id, $record_id);
- $this->number = (int) $number;
+ $this->number = (int)$number;
if ($load) {
$this->load();
@@ -141,6 +140,7 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
$this->created = $record->getCreated();
$this->base_id = $record->getBaseId();
$this->collection_id = $record->getCollectionId();
+ $this->status = $record->getStatus();
}
/**
@@ -201,7 +201,7 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
*/
public function setNumber($number)
{
- $this->number = (int) $number;
+ $this->number = (int)$number;
return $this;
}
@@ -370,8 +370,19 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
* Return record collection
*
* @return \collection
+ * @deprecated use {@link self::getCollection} instead.
*/
public function get_collection()
+ {
+ return $this->getCollection();
+ }
+
+ /**
+ * Return collection to which the record belongs to.
+ *
+ * @return \collection
+ */
+ public function getCollection()
{
return \collection::getByCollectionId($this->app, $this->getDatabox(), $this->collection_id);
}
@@ -460,7 +471,7 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
*/
public function move_to_collection(collection $collection, appbox $appbox)
{
- if ($this->get_collection()->get_base_id() === $collection->get_base_id()) {
+ if ($this->getCollection()->get_base_id() === $collection->get_base_id()) {
return $this;
}
@@ -517,54 +528,9 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
return $this->sha256;
}
- /**
- * @return string
- */
- public function get_status()
- {
- if (!$this->status) {
- $this->status = $this->retrieve_status();
- }
-
- return $this->status;
- }
-
- /**
- * @return string
- * @throws Exception
- * @throws \Doctrine\DBAL\DBALException
- */
- protected function retrieve_status()
- {
- try {
- $data = $this->get_data_from_cache(self::CACHE_STATUS);
- } catch (Exception $e) {
- $data = false;
- }
-
- if (false !== $data) {
- return $data;
- }
-
- $status = $this->getDataboxConnection()->fetchColumn(
- 'SELECT BIN(status) as status FROM record WHERE record_id = :record_id',
- [':record_id' => $this->getRecordId()]
- );
-
- if (false === $status) {
- throw new Exception('status not found');
- }
-
- $status = str_pad($status, 32, '0', STR_PAD_LEFT);
-
- $this->set_data_to_cache($status, self::CACHE_STATUS);
-
- return $status;
- }
-
public function has_subdef($name)
{
- return in_array($name, $this->get_available_subdefs());
+ return in_array($name, $this->get_available_subdefs(), false);
}
/**
@@ -579,17 +545,13 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
return $this->subdefs[$name];
}
- if (!in_array($name, $this->get_available_subdefs())) {
+ if (!in_array($name, $this->get_available_subdefs(), false)) {
throw new Exception_Media_SubdefNotFound(sprintf("subdef `%s` not found", $name));
}
- if (!$this->subdefs) {
- $this->subdefs = [];
- }
+ $subdefs = $this->getMediaSubdefRepository()->findOneByRecordIdAndName($this->getRecordId(), $name);
- $substitute = ($name !== 'document');
-
- return $this->subdefs[$name] = new media_subdef($this->app, $this, $name, $substitute);
+ return $subdefs ?: new media_subdef($this->app, $this, $name, ($name !== 'document'));
}
/**
@@ -607,15 +569,15 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
if (isset($availableSubdefs['document'])) {
- $mime_ok = !$mimes || in_array($availableSubdefs['document']->get_mime(), (array) $mimes);
- $devices_ok = !$devices || array_intersect($availableSubdefs['document']->getDevices(), (array) $devices);
+ $mime_ok = !$mimes || in_array($availableSubdefs['document']->get_mime(), (array)$mimes, false);
+ $devices_ok = !$devices || array_intersect($availableSubdefs['document']->getDevices(), (array)$devices);
if ($mime_ok && $devices_ok) {
$subdefs['document'] = $availableSubdefs['document'];
}
}
- $searchDevices = array_merge((array) $devices, (array) databox_subdef::DEVICE_ALL);
+ $searchDevices = array_merge((array)$devices, (array)databox_subdef::DEVICE_ALL);
$type = $this->isStory() ? 'image' : $this->getType();
@@ -641,7 +603,7 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
continue;
}
- if ($mimes && !in_array($subdef->get_mime(), (array) $mimes)) {
+ if ($mimes && !in_array($subdef->get_mime(), (array)$mimes)) {
continue;
}
@@ -656,13 +618,20 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
*/
public function get_subdefs()
{
- if (!$this->subdefs) {
- $this->subdefs = [];
+ if (null !== $this->subdefs) {
+ return $this->subdefs;
}
- $subdefs = $this->get_available_subdefs();
- foreach ($subdefs as $name) {
- $this->get_subdef($name);
+ $this->subdefs = [];
+
+ foreach ($this->getMediaSubdefRepository()->findByRecordIdsAndNames([$this->getRecordId()]) as $subdef) {
+ $this->subdefs[$subdef->get_name()] = $subdef;
+ }
+
+ foreach (['preview', 'thumbnail'] as $name) {
+ if (!isset($this->subdefs[$name])) {
+ $this->subdefs[$name] = new media_subdef($this->app, $this, $name, true, []);
+ }
}
return $this->subdefs;
@@ -673,6 +642,10 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
*/
protected function get_available_subdefs()
{
+ if (null !== $this->subdefs) {
+ return array_keys($this->subdefs);
+ }
+
try {
$data = $this->get_data_from_cache(self::CACHE_SUBDEFS);
} catch (\Exception $e) {
@@ -683,18 +656,8 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
return $data;
}
- $rs = $this->getDataboxConnection()->fetchAll(
- 'SELECT name FROM subdef WHERE record_id = :record_id',
- ['record_id' => $this->getRecordId()]
- );
+ $subdefs = array_keys($this->get_subdefs());
- $subdefs = ['preview', 'thumbnail'];
-
- foreach ($rs as $row) {
- $subdefs[] = $row['name'];
- }
-
- $subdefs = array_unique($subdefs);
$this->set_data_to_cache($subdefs, self::CACHE_SUBDEFS);
return $subdefs;
@@ -716,13 +679,10 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
*/
public function get_technical_infos($data = '')
{
- if (!$this->technical_data && !$this->mapTechnicalDataFromCache()) {
- $this->technical_data = [];
- $rs = $this->fetchTechnicalDataFromDb();
+ if (null === $this->technical_data) {
+ $sets = $this->app['service.technical_data']->fetchRecordsTechnicalData([$this]);
- $this->mapTechnicalDataFromDb($rs);
-
- $this->set_data_to_cache($this->technical_data, self::CACHE_TECHNICAL_DATA);
+ $this->setTechnicalDataSet(reset($sets));
}
if ($data) {
@@ -736,12 +696,21 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
return $this->technical_data;
}
+ /**
+ * @param TechnicalDataSet $dataSet
+ * @internal
+ */
+ public function setTechnicalDataSet(TechnicalDataSet $dataSet)
+ {
+ $this->technical_data = $dataSet;
+ }
+
/**
* @return caption_record
*/
public function get_caption()
{
- return new caption_record($this->app, $this, $this->getDatabox());
+ return new caption_record($this->app, $this);
}
public function getCaption(array $fields = null)
@@ -758,7 +727,7 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
$collection = [];
foreach ($fields as $field) {
- $values = array_map(function(caption_Field_Value $fieldValue) {
+ $values = array_map(function (caption_Field_Value $fieldValue) {
return $fieldValue->getValue();
}, $field->get_values());
@@ -857,7 +826,7 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
}
if (count($fields_to_retrieve) > 0) {
- $retrieved_fields = $this->get_caption()->get_highlight_fields($highlight, $fields_to_retrieve, $searchEngine);
+ $retrieved_fields = $this->get_caption()->get_highlight_fields($highlight, $fields_to_retrieve);
$titles = [];
foreach ($retrieved_fields as $value) {
foreach ($value['values'] as $v) {
@@ -904,6 +873,7 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
/**
* @return string
+ * @deprecated use {@link self::getId} instead.
*/
public function get_serialize_key()
{
@@ -1066,16 +1036,16 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
}
$record = $this;
- $wanted_subdefs = array_map(function(databox_subdef $subDef) {
+ $wanted_subdefs = array_map(function (databox_subdef $subDef) {
return $subDef->get_name();
- }, array_filter($subDefDefinitions, function(databox_subdef $subDef) use ($record) {
+ }, array_filter(iterator_to_array($subDefDefinitions), function (databox_subdef $subDef) use ($record) {
return !$record->has_subdef($subDef->get_name());
}));
- $missing_subdefs = array_map(function(media_subdef $subDef) {
+ $missing_subdefs = array_map(function (media_subdef $subDef) {
return $subDef->get_name();
- }, array_filter($this->get_subdefs(), function(media_subdef $subdef) {
+ }, array_filter($this->get_subdefs(), function (media_subdef $subdef) {
return !$subdef->is_physically_present();
}));
@@ -1096,26 +1066,6 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
return $this;
}
- /**
- * @param string $status
- * @return record_adapter
- */
- public function set_binary_status($status)
- {
- $connection = $this->getDataboxConnection();
-
- $connection->executeUpdate(
- 'UPDATE record SET moddate = NOW(), status = :status WHERE record_id= :record_id',
- ['status' => bindec($status), 'record_id' => $this->getRecordId()]
- );
-
- $this->delete_data_from_cache(self::CACHE_STATUS);
-
- $this->dispatch(RecordEvents::STATUS_CHANGED, new StatusChangedEvent($this));
-
- return $this;
- }
-
private function dispatch($eventName, RecordEvent $event)
{
$this->app['dispatcher']->dispatch($eventName, $event);
@@ -1255,12 +1205,12 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
}
$connection = $this->getDataboxConnection();
- $sql = 'DELETE FROM technical_datas WHERE record_id = :record_id';
- $stmt = $connection->prepare($sql);
- $stmt->execute([':record_id' => $this->getRecordId()]);
- $stmt->closeCursor();
+ $connection->executeUpdate('DELETE FROM technical_datas WHERE record_id = :record_id', [
+ ':record_id' => $this->getRecordId(),
+ ]);
$sqlValues = [];
+
foreach ($document->readTechnicalDatas($mediavorus) as $name => $value) {
if (is_null($value)) {
continue;
@@ -1271,21 +1221,15 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
$value = 0;
}
}
- $sqlValues[] = join(',', array(
- 'null',
- $connection->quote($this->getRecordId()),
- $connection->quote($name),
- $connection->quote($value),
- ));
+ $sqlValues[] = [$this->getRecordId(), $name, $value];
}
- $sql = "INSERT INTO technical_datas (id, record_id, name, value)"
- . " VALUES (" . join('),(', $sqlValues) . ")";
- ;
- $stmt = $connection->prepare($sql);
- $stmt->execute();
-
- $stmt->closeCursor();
+ if ($sqlValues) {
+ $connection->transactional(function (Connection $connection) use ($sqlValues) {
+ $statement = $connection->prepare('INSERT INTO technical_datas (record_id, name, value) VALUES (?, ?, ?)');
+ array_walk($sqlValues, [$statement, 'execute']);
+ });
+ }
$this->delete_data_from_cache(self::CACHE_TECHNICAL_DATA);
@@ -1357,8 +1301,9 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
$ftodel = [];
foreach ($this->get_subdefs() as $subdef) {
- if (!$subdef->is_physically_present())
+ if (!$subdef->is_physically_present()) {
continue;
+ }
if ($subdef->get_name() === 'thumbnail') {
$this->app['phraseanet.thumb-symlinker']->unlink($subdef->getRealPath());
@@ -1366,11 +1311,13 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
$ftodel[] = $subdef->getRealPath();
$watermark = $subdef->getWatermarkRealPath();
- if (file_exists($watermark))
+ if (file_exists($watermark)) {
$ftodel[] = $watermark;
+ }
$stamp = $subdef->getStampRealPath();
- if (file_exists($stamp))
+ if (file_exists($stamp)) {
$ftodel[] = $stamp;
+ }
}
$origcoll = $this->collection_id;
@@ -1500,16 +1447,13 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
public function delete_data_from_cache($option = null)
{
- switch ($option) {
- case self::CACHE_STATUS:
- $this->status = null;
- break;
+ switch ($option)
+ {
case self::CACHE_SUBDEFS:
$this->subdefs = null;
break;
- default:
- break;
}
+
$databox = $this->getDatabox();
$databox->delete_data_from_cache($this->get_cache_key($option));
@@ -1540,7 +1484,7 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
/**
* @todo de meme avec stories
- * @return Array
+ * @return \Alchemy\Phrasea\Model\Entities\Basket[]
*/
public function get_container_baskets(EntityManager $em, User $user)
{
@@ -1560,8 +1504,8 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
*/
public static function get_records_by_originalname(databox $databox, $original_name, $caseSensitive = false, $offset_start = 0, $how_many = 10)
{
- $offset_start = (int) ($offset_start < 0 ? 0 : $offset_start);
- $how_many = (int) (($how_many > 20 || $how_many < 1) ? 10 : $how_many);
+ $offset_start = (int)($offset_start < 0 ? 0 : $offset_start);
+ $how_many = (int)(($how_many > 20 || $how_many < 1) ? 10 : $how_many);
$sql = sprintf(
'SELECT record_id FROM record WHERE originalname = :original_name COLLATE %s LIMIT %d, %d',
@@ -1694,7 +1638,7 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
public function hasChild(\record_adapter $record)
{
- return $this->get_children()->offsetExists($record->get_serialize_key());
+ return $this->getChildren()->offsetExists($record->getId());
}
public function appendChild(\record_adapter $record)
@@ -1786,17 +1730,36 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
return $this->reference->getId();
}
+ /**
+ * @param string $status
+ * @return void
+ */
public function setStatus($status)
{
- $this->set_binary_status($status);
+ $this->getDataboxConnection()->executeUpdate(
+ 'UPDATE record SET moddate = NOW(), status = :status WHERE record_id=:record_id',
+ ['status' => bindec($status), 'record_id' => $this->getRecordId()]
+ );
- $this->delete_data_from_cache(self::CACHE_STATUS);
+ $this->status = str_pad($status, 32, '0', STR_PAD_LEFT);
+ // modification date is now unknown, delete from cache to reload on another record
+ $this->delete_data_from_cache();
+
+ $this->dispatch(RecordEvents::STATUS_CHANGED, new StatusChangedEvent($this));
+ }
+
+ /**
+ * @return string
+ */
+ public function getStatus()
+ {
+ return $this->status;
}
/** {@inheritdoc} */
public function getStatusBitField()
{
- return bindec($this->get_status());
+ return bindec($this->getStatus());
}
/** {@inheritdoc} */
@@ -1823,6 +1786,7 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
'created' => $this->created->format(DATE_ISO8601),
'base_id' => $this->base_id,
'collection_id' => $this->collection_id,
+ 'status' => $this->status,
];
$this->set_data_to_cache($data);
@@ -1848,64 +1812,13 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
$this->original_name = $row['originalName'];
$this->sha256 = $row['sha256'];
$this->mime = $row['mime'];
- }
-
- /**
- * @return bool
- */
- private function mapTechnicalDataFromCache()
- {
- try {
- $technical_data = $this->get_data_from_cache(self::CACHE_TECHNICAL_DATA);
- } catch (Exception $e) {
- $technical_data = false;
- }
-
- if (false === $technical_data) {
- return false;
- }
-
- $this->technical_data = $technical_data;
-
- return true;
- }
-
- /**
- * @return false|array
- */
- private function fetchTechnicalDataFromDb()
- {
- $sql = 'SELECT name, value FROM technical_datas WHERE record_id = :record_id';
-
- return $this->getDataboxConnection()
- ->fetchAll($sql, ['record_id' => $this->getRecordId()]);
- }
-
- /**
- * @param array $rows
- */
- private function mapTechnicalDataFromDb(array $rows)
- {
- $this->technical_data = new ArrayTechnicalDataSet();
-
- foreach ($rows as $row) {
- switch (true) {
- case ctype_digit($row['value']):
- $this->technical_data[] = new IntegerTechnicalData($row['name'], $row['value']);
- break;
- case preg_match('/[0-9]?\.[0-9]+/', $row['value']):
- $this->technical_data[] = new FloatTechnicalData($row['name'], $row['value']);
- break;
- default:
- $this->technical_data[] = new StringTechnicalData($row['name'], $row['value']);
- }
- }
+ $this->status = str_pad($row['status'], 32, '0', STR_PAD_LEFT);
}
/**
* @return Connection
*/
- private function getDataboxConnection()
+ protected function getDataboxConnection()
{
if (null === $this->connection) {
$this->connection = $this->getDatabox()->get_connection();
@@ -1913,4 +1826,12 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
return $this->connection;
}
+
+ /**
+ * @return MediaSubdefRepository
+ */
+ private function getMediaSubdefRepository()
+ {
+ return $this->app['provider.repo.media_subdef']->getRepositoryForDatabox($this->getDataboxId());
+ }
}
diff --git a/lib/classes/record/exportElement.php b/lib/classes/record/exportElement.php
index fe225f145d..737ad5a1ad 100644
--- a/lib/classes/record/exportElement.php
+++ b/lib/classes/record/exportElement.php
@@ -83,14 +83,13 @@ class record_exportElement extends record_adapter
$sd = $this->get_subdefs();
- $sbas_id = phrasea::sbasFromBas($this->app, $this->get_base_id());
-
- $subdefgroups = $this->app->findDataboxById($sbas_id)->get_subdef_structure();
+ $sbas_id = phrasea::sbasFromBas($this->app, $this->getBaseId());
+ /** @var databox_subdef[] $subdefs */
$subdefs = [];
- foreach ($subdefgroups as $subdef_type => $subdefs_obj) {
- if ($subdef_type == $this->get_type()) {
+ foreach ($this->app->findDataboxById($sbas_id)->get_subdef_structure() as $subdef_type => $subdefs_obj) {
+ if ($subdef_type == $this->getType()) {
$subdefs = $subdefs_obj;
break;
}
@@ -102,10 +101,10 @@ class record_exportElement extends record_adapter
'thumbnail' => true
];
- if ($this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($this->get_base_id(), 'candwnldhd')) {
+ if ($this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($this->getBaseId(), 'candwnldhd')) {
$go_dl['document'] = true;
}
- if ($this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($this->get_base_id(), 'candwnldpreview')) {
+ if ($this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($this->getBaseId(), 'candwnldpreview')) {
$go_dl['preview'] = true;
}
if ($this->app->getAclForUser($this->app->getAuthenticatedUser())->has_hd_grant($this)) {
@@ -118,18 +117,18 @@ class record_exportElement extends record_adapter
$query = $this->app['phraseanet.user-query'];
- $masters = $query->on_base_ids([$this->get_base_id()])
+ $masters = $query->on_base_ids([$this->getBaseId()])
->who_have_right(['order_master'])
->execute()->get_results();
- $go_cmd = (count($masters) > 0 && $this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($this->get_base_id(), 'cancmd'));
+ $go_cmd = (count($masters) > 0 && $this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($this->getBaseId(), 'cancmd'));
$orderable['document'] = false;
$downloadable['document'] = false;
if (isset($sd['document']) && is_file($sd['document']->getRealPath())) {
if ($go_dl['document'] === true) {
- if ($this->app->getAclForUser($this->app->getAuthenticatedUser())->is_restricted_download($this->get_base_id())) {
+ if ($this->app->getAclForUser($this->app->getAuthenticatedUser())->is_restricted_download($this->getBaseId())) {
$this->remain_hd --;
if ($this->remain_hd >= 0) {
$localizedLabel = $this->app->trans('document original');
@@ -183,7 +182,7 @@ class record_exportElement extends record_adapter
if (isset($sd[$name]) && $sd[$name]->is_physically_present()) {
if ($class == 'document') {
- if ($this->app->getAclForUser($this->app->getAuthenticatedUser())->is_restricted_download($this->get_base_id())) {
+ if ($this->app->getAclForUser($this->app->getAuthenticatedUser())->is_restricted_download($this->getBaseId())) {
$this->remain_hd --;
if ($this->remain_hd >= 0)
$downloadable[$name] = [
diff --git a/lib/classes/record/preview.php b/lib/classes/record/preview.php
index 805b9ba120..4c84db903e 100644
--- a/lib/classes/record/preview.php
+++ b/lib/classes/record/preview.php
@@ -10,8 +10,7 @@
*/
use Alchemy\Phrasea\Application;
-use Alchemy\Phrasea\Model\Entities\Basket;
-use Alchemy\Phrasea\Model\Entities\BasketElement;
+use Alchemy\Phrasea\Model\Entities\FeedEntry;
use Alchemy\Phrasea\SearchEngine\SearchEngineInterface;
use Alchemy\Phrasea\SearchEngine\SearchEngineOptions;
use Guzzle\Http\Url;
@@ -19,69 +18,59 @@ use Guzzle\Http\Url;
class record_preview extends record_adapter
{
/**
- *
* @var string
*/
protected $env;
/**
- *
* @var int
*/
protected $total;
/**
- *
* @var string
*/
protected $name;
/**
- *
* @var mixed content
*/
protected $container;
/**
- *
* @var mixed content
*/
protected $train;
/**
- *
* @var string
*/
protected $title;
/**
- *
- * @var Array
+ * @var array
*/
protected $short_history;
/**
- *
- * @var media
+ * @var media_adapter
*/
protected $view_popularity;
/**
- *
- * @var media
+ * @var media_adapter
*/
protected $refferer_popularity;
/**
- *
- * @var media
+ * @var media_adapter
*/
protected $download_popularity;
protected $original_item;
protected $pos;
- protected$search_engine;
+ protected $searchEngine;
protected $query;
protected $options;
@@ -100,8 +89,13 @@ class record_preview extends record_adapter
if (null === $search_engine) {
throw new \LogicException('Search Engine should be provided');
}
+ if (!$options) {
+ $options = new SearchEngineOptions();
+ }
+ $options->setFirstResult($pos);
+ $options->setMaxResults(1);
- $results = $search_engine->query($query, (int) ($pos), 1, $options);
+ $results = $search_engine->query($query, $options);
if ($results->getResults()->isEmpty()) {
throw new Exception('Record introuvable');
@@ -124,11 +118,11 @@ class record_preview extends record_adapter
if ($pos == 0) {
$number = 0;
} else {
- $children = $this->container->get_children();
+ $children = $this->container->getChildren();
foreach ($children as $child) {
- $sbas_id = $child->get_sbas_id();
+ $sbas_id = $child->getDataboxId();
$this->original_item = $child;
- $record_id = $child->get_record_id();
+ $record_id = $child->getRecordId();
if ($child->getNumber() == $pos)
break;
}
@@ -141,34 +135,25 @@ class record_preview extends record_adapter
$Basket = $app['converter.basket']->convert($contId);
$app['acl.basket']->hasAccess($Basket, $app->getAuthenticatedUser());
- /* @var $Basket Basket */
$this->container = $Basket;
$this->total = $Basket->getElements()->count();
$i = 0;
$first = true;
foreach ($Basket->getElements() as $element) {
- /* @var $element BasketElement */
$i ++;
- if ($first) {
+ if ($element->getOrd() == $pos || $first) {
$this->original_item = $element;
- $sbas_id = $element->getRecord($this->app)->get_sbas_id();
- $record_id = $element->getRecord($this->app)->get_record_id();
- $this->name = $Basket->getName();
- $number = $element->getOrd();
- }
- $first = false;
-
- if ($element->getOrd() == $pos) {
- $this->original_item = $element;
- $sbas_id = $element->getRecord($this->app)->get_sbas_id();
- $record_id = $element->getRecord($this->app)->get_record_id();
+ $sbas_id = $element->getSbasId();
+ $record_id = $element->getRecordId();
$this->name = $Basket->getName();
$number = $element->getOrd();
+ $first = false;
}
}
break;
case "FEED":
+ /** @var FeedEntry $entry */
$entry = $app['repo.feed-entries']->find($contId);
$this->container = $entry;
@@ -178,25 +163,24 @@ class record_preview extends record_adapter
foreach ($entry->getItems() as $element) {
$i ++;
- if ($first) {
- $sbas_id = $element->getRecord($this->app)->get_sbas_id();
- $record_id = $element->getRecord($this->app)->get_record_id();
- $this->name = $entry->getTitle();
- $this->original_item = $element;
- $number = $element->getOrd();
- }
- $first = false;
-
- if ($element->getOrd() == $pos) {
- $sbas_id = $element->getRecord($this->app)->get_sbas_id();
- $record_id = $element->getRecord($this->app)->get_record_id();
+ if ($element->getOrd() == $pos || $first) {
+ $sbas_id = $element->getSbasId();
+ $record_id = $element->getRecordId();
$this->name = $entry->getTitle();
$this->original_item = $element;
$number = $element->getOrd();
+ $first = false;
}
}
break;
+ default:
+ throw new InvalidArgumentException(sprintf('Expects env argument to one of (RESULT, REG, BASK, FEED) got %s', $env));
}
+
+ if (!(isset($sbas_id) && isset($record_id))) {
+ throw new Exception('No record could be found');
+ }
+
parent::__construct($app, $sbas_id, $record_id, $number);
}
@@ -208,9 +192,11 @@ class record_preview extends record_adapter
switch ($this->env) {
case 'RESULT':
- $perPage = 56;
- $index = ($this->pos - 3) < 0 ? 0 : ($this->pos - 3);
- $results = $this->searchEngine->query($this->query, $index, $perPage, $this->options);
+ $options = $this->options ?: new SearchEngineOptions();
+ $options->setFirstResult(($this->pos - 3) < 0 ? 0 : ($this->pos - 3));
+ $options->setMaxResults(56);
+
+ $results = $this->searchEngine->query($this->query, $options);
$this->train = $results->getResults()->toArray();
break;
@@ -226,22 +212,23 @@ class record_preview extends record_adapter
}
/**
- *
- * @return boolean
+ * @return bool
*/
public function is_from_result()
{
return $this->env == 'RESULT';
}
+ /**
+ * @return bool
+ */
public function is_from_feed()
{
return $this->env == 'FEED';
}
/**
- *
- * @return boolean
+ * @return bool
*/
public function is_from_basket()
{
@@ -249,8 +236,7 @@ class record_preview extends record_adapter
}
/**
- *
- * @return boolean
+ * @return bool
*/
public function is_from_reg()
{
@@ -272,7 +258,7 @@ class record_preview extends record_adapter
return $this->title;
}
- $this->title = collection::getLogo($this->get_base_id(), $this->app) . ' ';
+ $this->title = collection::getLogo($this->getBaseId(), $this->app) . ' ';
switch ($this->env) {
@@ -303,7 +289,6 @@ class record_preview extends record_adapter
}
/**
- *
* @return mixed content
*/
public function get_container()
@@ -312,8 +297,7 @@ class record_preview extends record_adapter
}
/**
- *
- * @return Array
+ * @return array
*/
public function get_short_history()
{
@@ -323,16 +307,13 @@ class record_preview extends record_adapter
$tab = [];
- $report = $this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($this->get_base_id(), 'canreport');
-
- $databox = $this->app->findDataboxById($this->get_sbas_id());
- $connsbas = $databox->get_connection();
+ $report = $this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($this->getBaseId(), 'canreport');
$sql = 'SELECT d . * , l.user, l.usrid as usr_id, l.site
FROM log_docs d, log l
WHERE d.log_id = l.id
AND d.record_id = :record_id ';
- $params = [':record_id' => $this->get_record_id()];
+ $params = [':record_id' => $this->getRecordId()];
if (! $report) {
$sql .= ' AND ((l.usrid = :usr_id AND l.site= :site) OR action="add")';
@@ -342,12 +323,7 @@ class record_preview extends record_adapter
$sql .= 'ORDER BY d.date, usrid DESC';
- $stmt = $connsbas->prepare($sql);
- $stmt->execute($params);
- $rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
- $stmt->closeCursor();
-
- foreach ($rs as $row) {
+ foreach ($this->getDataboxConnection()->executeQuery($sql, $params)->fetchAll(PDO::FETCH_ASSOC) as $row) {
$hour = $this->app['date-formatter']->getPrettyString(new DateTime($row['date']));
if ( ! isset($tab[$hour]))
@@ -374,7 +350,7 @@ class record_preview extends record_adapter
if ( ! in_array($row['final'], $tab[$hour][$site][$action][$row['usr_id']]['final'])) {
if ($action == 'collection') {
- $tab[$hour][$site][$action][$row['usr_id']]['final'][] = phrasea::baseFromColl($this->get_sbas_id(), $row['final'], $this->app);
+ $tab[$hour][$site][$action][$row['usr_id']]['final'][] = phrasea::baseFromColl($this->getDataboxId(), $row['final'], $this->app);
} else {
$tab[$hour][$site][$action][$row['usr_id']]['final'][] = $row['final'];
}
@@ -390,8 +366,7 @@ class record_preview extends record_adapter
}
/**
- *
- * @return media_image
+ * @return media_adapter
*/
public function get_view_popularity()
{
@@ -400,7 +375,7 @@ class record_preview extends record_adapter
}
$report = $this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base(
- $this->get_base_id(), 'canreport');
+ $this->getBaseId(), 'canreport');
if ( ! $report && ! $this->app['conf']->get(['registry', 'webservices', 'google-charts-enabled'])) {
$this->view_popularity = false;
@@ -429,19 +404,14 @@ class record_preview extends record_adapter
AND site_id = :site
GROUP BY datee ORDER BY datee ASC';
- $databox = $this->app->findDataboxById($this->get_sbas_id());
- $connsbas = $databox->get_connection();
- $stmt = $connsbas->prepare($sql);
- $stmt->execute(
- [
- ':record_id' => $this->get_record_id(),
- ':site' => $this->app['conf']->get(['main', 'key'])
- ]
- );
- $rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
- $stmt->closeCursor();
+ $result = $this->getDataboxConnection()
+ ->executeQuery($sql, [
+ ':record_id' => $this->getRecordId(),
+ ':site' => $this->app['conf']->get(['main', 'key'])
+ ])
+ ->fetchAll(PDO::FETCH_ASSOC);
- foreach ($rs as $row) {
+ foreach ($result as $row) {
if (isset($views[$row['datee']])) {
$views[$row['datee']] = (int) $row['views'];
$top = max((int) $row['views'], $top);
@@ -480,8 +450,7 @@ class record_preview extends record_adapter
}
/**
- *
- * @return media
+ * @return media_adapter
*/
public function get_refferer_popularity()
{
@@ -490,7 +459,7 @@ class record_preview extends record_adapter
}
$report = $this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base(
- $this->get_base_id(), 'canreport');
+ $this->getBaseId(), 'canreport');
if ( ! $report && ! $this->app['conf']->get(['registry', 'webservices', 'google-charts-enabled'])) {
$this->refferer_popularity = false;
@@ -498,23 +467,19 @@ class record_preview extends record_adapter
return $this->refferer_popularity;
}
- $databox = $this->app->findDataboxById($this->get_sbas_id());
- $connsbas = $databox->get_connection();
-
$sql = 'SELECT count( id ) AS views, referrer
FROM `log_view`
WHERE record_id = :record_id
AND date > ( NOW( ) - INTERVAL 1 MONTH )
GROUP BY referrer ORDER BY referrer ASC';
- $stmt = $connsbas->prepare($sql);
- $stmt->execute([':record_id' => $this->get_record_id()]);
- $rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
- $stmt->closeCursor();
+ $result = $this->getDataboxConnection()
+ ->executeQuery($sql, [':record_id' => $this->getRecordId()])
+ ->fetchAll(PDO::FETCH_ASSOC);
$referrers = [];
- foreach ($rs as $row) {
+ foreach ($result as $row) {
if ($row['referrer'] == 'NO REFERRER')
$row['referrer'] = $this->app->trans('report::acces direct');
if ($row['referrer'] == $this->app['conf']->get('servername') . 'prod/')
@@ -553,8 +518,7 @@ class record_preview extends record_adapter
}
/**
- *
- * @return media
+ * @return media_adapter
*/
public function get_download_popularity()
{
@@ -562,7 +526,7 @@ class record_preview extends record_adapter
return $this->download_popularity;
}
- $report = $this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($this->get_base_id(), 'canreport');
+ $report = $this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($this->getBaseId(), 'canreport');
$ret = false;
if ( ! $report && ! $this->app['conf']->get(['registry', 'webservices', 'google-charts-enabled'])) {
@@ -592,21 +556,16 @@ class record_preview extends record_adapter
AND site= :site
GROUP BY datee ORDER BY datee ASC';
- $databox = $this->app->findDataboxById($this->get_sbas_id());
- $connsbas = $databox->get_connection();
- $stmt = $connsbas->prepare($sql);
- $stmt->execute(
- [
- ':record_id' => $this->get_record_id(),
+ $result = $this->getDataboxConnection()
+ ->executeQuery($sql, [
+ ':record_id' => $this->getRecordId(),
':site' => $this->app['conf']->get(['main', 'key'])
- ]
- );
- $rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
- $stmt->closeCursor();
+ ])
+ ->fetchAll(PDO::FETCH_ASSOC);
$top = 10;
- foreach ($rs as $row) {
+ foreach ($result as $row) {
if (isset($dwnls[$row['datee']])) {
$dwnls[$row['datee']] = (int) $row['dwnl'];
$top = max(((int) $row['dwnl'] + 10), $top);
diff --git a/lib/classes/recordutils/image.php b/lib/classes/recordutils/image.php
index 1c0fa411e9..a7fee96aeb 100644
--- a/lib/classes/recordutils/image.php
+++ b/lib/classes/recordutils/image.php
@@ -49,7 +49,7 @@ class recordutils_image
}
};
- $base_id = $subdef->get_record()->get_base_id();
+ $base_id = $subdef->get_record()->getBaseId();
if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) {
return $subdef->getRealPath();
@@ -71,7 +71,7 @@ class recordutils_image
$domprefs = new DOMDocument();
- if (false === $domprefs->loadXML($subdef->get_record()->get_collection()->get_prefs())) {
+ if (false === $domprefs->loadXML($subdef->get_record()->getCollection()->get_prefs())) {
return $subdef->getRealPath();
}
@@ -172,7 +172,7 @@ class recordutils_image
@unlink($pathOut); // no cache possible when date changes
break;
case 'RECORD_ID':
- $varval = $subdef->get_record()->get_record_id();
+ $varval = $subdef->get_record()->getRecordId();
break;
}
$n->parentNode->replaceChild($domprefs->createTextNode($varval), $n);
@@ -381,7 +381,7 @@ class recordutils_image
$palette = new RGB();
}
- $base_id = $subdef->get_record()->get_base_id();
+ $base_id = $subdef->get_record()->getBaseId();
if ($subdef->get_name() !== 'preview') {
return $subdef->getRealPath();
@@ -429,7 +429,7 @@ class recordutils_image
$in_image->paste($wm_image, new Point(($in_w - $wm_size->getWidth()) >> 1, ($in_h - $wm_size->getHeight()) >> 1))->save($pathOut);
} else {
- $collname = $subdef->get_record()->get_collection()->get_name();
+ $collname = $subdef->get_record()->getCollection()->get_name();
$draw = $in_image->draw();
$black = $palette->color("000000");
$white = $palette->color("FFFFFF");
diff --git a/lib/classes/set/abstract.php b/lib/classes/set/abstract.php
index d724199676..499332df36 100644
--- a/lib/classes/set/abstract.php
+++ b/lib/classes/set/abstract.php
@@ -121,7 +121,7 @@ abstract class set_abstract implements IteratorAggregate
*/
public function add_element(\record_adapter $record)
{
- $this->elements[$record->get_serialize_key()] = $record;
+ $this->elements[$record->getId()] = $record;
return $this;
}
@@ -132,7 +132,7 @@ abstract class set_abstract implements IteratorAggregate
*/
public function remove_element(\record_adapter $record)
{
- $key = $record->get_serialize_key();
+ $key = $record->getId();
if (isset($this->elements[$key]))
unset($this->elements[$key]);
@@ -146,7 +146,7 @@ abstract class set_abstract implements IteratorAggregate
{
$basrec = [];
foreach ($this->elements as $record) {
- $basrec[] = $record->get_serialize_key();
+ $basrec[] = $record->getId();
}
return implode(';', $basrec);
diff --git a/lib/classes/unicode.php b/lib/classes/unicode.php
index 4372f89fca..cb360240df 100644
--- a/lib/classes/unicode.php
+++ b/lib/classes/unicode.php
@@ -1541,17 +1541,7 @@ class unicode
]
];
- protected $endCharacters_utf8 = "\t\r\n !\"#\$%&'()+,-./:;<=>@[\]^_`{|}~£§¨°";
-
- public function get_indexer_bad_chars()
- {
- return $this->endCharacters_utf8;
- }
-
- public function has_indexer_bad_char($string)
- {
- return mb_strpos($this->endCharacters_utf8, $string);
- }
+ protected $endCharacters_utf8 = "\t\r\n !\"#\$%&'()+,-./:;<=>@[\\]^_`{|}~£§¨°";
/**
* Converts a string
diff --git a/lib/conf.d/json_schema/orders.json b/lib/conf.d/json_schema/orders.json
new file mode 100644
index 0000000000..9e10d09909
--- /dev/null
+++ b/lib/conf.d/json_schema/orders.json
@@ -0,0 +1,119 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "definitions": {
+ "order_request": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "object",
+ "properties": {
+ "usage": {
+ "type": "string"
+ },
+ "deadline": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "records": {
+ "type": "array",
+ "items": {
+ "$ref": "records.json#/definitions/record"
+ }
+ }
+ },
+ "required": [
+ "usage",
+ "records"
+ ]
+ }
+ },
+ "required": ["data"]
+ },
+ "order": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer"
+ },
+ "owner_id": {
+ "type": "integer"
+ },
+ "created": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "usage": {
+ "type": "string"
+ },
+ "deadline": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "elements": {
+ "type": "array",
+ "items": {
+ "$ref": "records.json#/definitions/record"
+ }
+ },
+ "basket_id": {
+ "$ref": "records.json#/definitions/record"
+ }
+ },
+ "required": [
+ "id",
+ "owner_id",
+ "created",
+ "usage",
+ "elements"
+ ]
+ },
+ "order_element": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer"
+ },
+ "record_id": {
+ "$ref": "records.json#/definitions/record"
+ },
+ "order_master_id": {
+ "type": "integer"
+ },
+ "status": {
+ "enum": ["accepted", "rejected"]
+ }
+ },
+ "required": [
+ "id",
+ "record_id"
+ ]
+ },
+ "order_element_id": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer"
+ }
+ },
+ "required": [
+ "id"
+ ]
+ },
+ "order_element_collection": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/order_element_id"
+ }
+ }
+ },
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/order"
+ }
+ }
+ },
+ "required": ["data"]
+}
diff --git a/templates/web/admin/search-engine/elastic-search.html.twig b/templates/web/admin/search-engine/elastic-search.html.twig
index 3f347614d4..d4fd99361f 100644
--- a/templates/web/admin/search-engine/elastic-search.html.twig
+++ b/templates/web/admin/search-engine/elastic-search.html.twig
@@ -1,3 +1,22 @@
{{ 'ElasticSearch configuration' | trans }}
{{ form(form) }}
+
+
+
+
+Really drop index ?
+
+{% block javascript %}
+
+
+{% endblock %}
diff --git a/templates/web/admin/search-engine/phrasea.html.twig b/templates/web/admin/search-engine/phrasea.html.twig
deleted file mode 100644
index 88871479d2..0000000000
--- a/templates/web/admin/search-engine/phrasea.html.twig
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
diff --git a/templates/web/admin/search-engine/sphinx-search.html.twig b/templates/web/admin/search-engine/sphinx-search.html.twig
deleted file mode 100644
index 5ae9b85257..0000000000
--- a/templates/web/admin/search-engine/sphinx-search.html.twig
+++ /dev/null
@@ -1,26 +0,0 @@
-{{ 'SphinxSearch search-engine configuration' | trans }}
-
-
-
-
\ No newline at end of file
diff --git a/templates/web/common/macros.html.twig b/templates/web/common/macros.html.twig
index cb5824f8f3..b3388b8e6c 100644
--- a/templates/web/common/macros.html.twig
+++ b/templates/web/common/macros.html.twig
@@ -103,7 +103,7 @@
{% endmacro %}
{% macro format_caption(record, highlight, search_engine, include_business, bounceable, technical_data) %}
- {% for field in record.get_caption().get_highlight_fields(highlight, null, search_engine, include_business) %}
+ {% for field in record.get_caption().get_highlight_fields(highlight, null, include_business) %}
{% set extra_classes = ['pair'] %}
{% if loop.index is odd %}
{% set extra_classes = ['impair'] %}
diff --git a/tests/Alchemy/Tests/Phrasea/Application/OverviewTest.php b/tests/Alchemy/Tests/Phrasea/Application/OverviewTest.php
index cbae2afcff..5e2d3ca11a 100644
--- a/tests/Alchemy/Tests/Phrasea/Application/OverviewTest.php
+++ b/tests/Alchemy/Tests/Phrasea/Application/OverviewTest.php
@@ -34,21 +34,23 @@ class OverviewTest extends \PhraseanetAuthenticatedWebTestCase
->method('get')
->will($this->returnValue($acl));
- self::$DI['app']['acl'] = $aclProvider;
+ $app = $this->getApplication();
+ $app['acl'] = $aclProvider;
- $path = self::$DI['app']['url_generator']->generate('datafile', [
- 'sbas_id' => self::$DI['record_1']->get_sbas_id(),
- 'record_id' => self::$DI['record_1']->get_record_id(),
+ $record1 = $this->getRecord1();
+
+ $path = $app['url_generator']->generate('datafile', [
+ 'sbas_id' => $record1->getDataboxId(),
+ 'record_id' => $record1->getRecordId(),
'subdef' => $subdef,
]);
- self::$DI['client']->request('GET', $path);
- $response = self::$DI['client']->getResponse();
+ $response = $this->request('GET', $path);
$this->assertEquals(200, $response->getStatusCode());
$this->assertEquals('inline', explode(';', $response->headers->get('content-disposition'))[0]);
- $this->assertEquals(self::$DI['record_1']->get_preview()->get_mime(), $response->headers->get('content-type'));
- $this->assertEquals(self::$DI['record_1']->get_preview()->get_size(), $response->headers->get('content-length'));
+ $this->assertEquals($record1->get_preview()->get_mime(), $response->headers->get('content-type'));
+ $this->assertEquals($record1->get_preview()->get_size(), $response->headers->get('content-length'));
}
public function testDatafilesNonExistentSubdef()
@@ -255,8 +257,8 @@ class OverviewTest extends \PhraseanetAuthenticatedWebTestCase
self::$DI['app']['subdef.substituer']->substitute($story, $name, $media);
$path = self::$DI['app']['url_generator']->generate('datafile', [
- 'sbas_id' => $story->get_sbas_id(),
- 'record_id' => $story->get_record_id(),
+ 'sbas_id' => $story->getDataboxId(),
+ 'record_id' => $story->getRecordId(),
'subdef' => $name,
]);
@@ -334,13 +336,13 @@ class OverviewTest extends \PhraseanetAuthenticatedWebTestCase
// Ensure permalink is created
\media_Permalink_Adapter::getPermalink(
self::$DI['app'],
- $record->get_databox(),
+ $record->getDatabox(),
$record->get_subdef('preview')
);
$path = self::$DI['app']['url_generator']->generate('permalinks_permaview', [
- 'sbas_id' => $record->get_sbas_id(),
- 'record_id' => $record->get_record_id(),
+ 'sbas_id' => $record->getDataboxId(),
+ 'record_id' => $record->getRecordId(),
'subdef' => 'preview',
]);
diff --git a/tests/Alchemy/Tests/Phrasea/Authentication/Provider/LinkedinTest.php b/tests/Alchemy/Tests/Phrasea/Authentication/Provider/LinkedinTest.php
index 3cdf7b9417..920e80ffbf 100644
--- a/tests/Alchemy/Tests/Phrasea/Authentication/Provider/LinkedinTest.php
+++ b/tests/Alchemy/Tests/Phrasea/Authentication/Provider/LinkedinTest.php
@@ -16,12 +16,24 @@ class LinkedinTest extends ProviderTestCase
{
$state = md5(mt_rand());
+ // test cases
+ $data = [];
+
+ $data[] = [$this->getProvider(), $this->getRequestMock()];
+
+ // Second test
$request = $this->getRequestMock();
$this->addQueryParameter($request, ['state' => $state]);
- $provider1 = $this->getProvider();
- $provider1->setGuzzleClient($this->getGuzzleMock(401));
- $provider1->getSession()->set('linkedin.provider.state', $state);
+ $provider = $this->getProvider();
+ $provider->setGuzzleClient($this->getGuzzleMock(401));
+ $provider->getSession()->set('linkedin.provider.state', $state);
+
+ $data[] = [$provider, $request];
+
+ // Third test
+ $request = $this->getRequestMock();
+ $this->addQueryParameter($request, ['state' => $state]);
$mock = $this->getMock('Guzzle\Http\ClientInterface');
@@ -67,15 +79,13 @@ class LinkedinTest extends ProviderTestCase
->method('post')
->will($this->returnValue($requestPost));
- $provider2 = $this->getProvider();
- $provider2->setGuzzleClient($mock);
- $provider2->getSession()->set('linkedin.provider.state', $state);
+ $provider = $this->getProvider();
+ $provider->setGuzzleClient($mock);
+ $provider->getSession()->set('linkedin.provider.state', $state);
- return [
- [$this->getProvider(), $this->getRequestMock()],
- [$provider1, $request],
- [$provider2, $request],
- ];
+ $data[] = [$provider, $request];
+
+ return $data;
}
public function getProviderForLogout()
diff --git a/tests/Alchemy/Tests/Phrasea/Border/ManagerTest.php b/tests/Alchemy/Tests/Phrasea/Border/ManagerTest.php
index e893004740..5dedd2bc7a 100644
--- a/tests/Alchemy/Tests/Phrasea/Border/ManagerTest.php
+++ b/tests/Alchemy/Tests/Phrasea/Border/ManagerTest.php
@@ -13,6 +13,7 @@ use Alchemy\Phrasea\Border\Attribute\MetaField;
use Alchemy\Phrasea\Border\Attribute\Metadata;
use Alchemy\Phrasea\Border\Attribute\Status;
use Alchemy\Phrasea\Border\Attribute\Story;
+use Alchemy\Phrasea\Model\Entities\LazaretFile;
/**
* @group functional
@@ -144,13 +145,15 @@ class ManagerTest extends \PhraseanetAuthenticatedWebTestCase
$records = [];
$postProcessRecord = function ($record) use (&$records) {
- $records[] = $record;
- };
+ $records[] = $record;
+ };
- $file = File::buildFromPathfile(self::$file1, self::$DI['collection'], self::$DI['app']);
+ $app = $this->getApplication();
+ $collection = $this->getCollection();
+ $file = File::buildFromPathfile(self::$file1, $collection, $app);
$first = $odd = false;
$tofetch = [];
- foreach (self::$DI['collection']->get_databox()->get_meta_structure() as $databox_field) {
+ foreach ($collection->get_databox()->get_meta_structure() as $databox_field) {
if ($databox_field->is_readonly()) {
continue;
}
@@ -196,7 +199,7 @@ class ManagerTest extends \PhraseanetAuthenticatedWebTestCase
$odd = !$odd;
}
- $story = \record_adapter::createStory(self::$DI['app'], self::$DI['collection']);
+ $story = \record_adapter::createStory($app, $collection);
$file->addAttribute(new Story($story));
$status = '';
@@ -208,17 +211,19 @@ class ManagerTest extends \PhraseanetAuthenticatedWebTestCase
}
}
- $file->addAttribute(new Status(self::$DI['app'], strrev($status)));
+ $file->addAttribute(new Status($app, strrev($status)));
- self::$DI['app']['phraseanet.SE'] = $this->createSearchEngineMock();
+ $app['phraseanet.SE'] = $this->createSearchEngineMock();
$this->assertEquals(Manager::RECORD_CREATED, $this->object->process($this->session, $file, $postProcessRecord, Manager::FORCE_RECORD));
+ /** @var \record_adapter $record */
$record = current($records);
+ $this->assertInstanceOf(\record_adapter::class, $record);
$found = false;
foreach ($record->get_grouping_parents()->get_elements() as $parent_story) {
- if ($parent_story->get_serialize_key() === $story->get_serialize_key()) {
+ if ($parent_story->getId() === $story->getId()) {
$found = true;
}
}
@@ -227,18 +232,19 @@ class ManagerTest extends \PhraseanetAuthenticatedWebTestCase
$this->fail('Unable to find story in parents');
}
- $status = strrev($record->get_status());
+ $status = strrev($record->getStatus());
$this->assertEquals(32, strlen($status));
$this->assertEquals('1', substr($status, 4, 1));
$this->assertEquals('1', substr($status, 8, 1));
foreach ($tofetch as $name => $values) {
-
$found = [];
+
foreach ($record->get_caption()->get_field($name)->get_values() as $value) {
$found[] = $value->getValue();
}
+
$this->assertEquals($values, $found);
}
@@ -261,10 +267,12 @@ class ManagerTest extends \PhraseanetAuthenticatedWebTestCase
$lazaret = $element;
};
- $file = File::buildFromPathfile(self::$file1, self::$DI['collection'], self::$DI['app']);
+ $app = $this->getApplication();
+ $collection = $this->getCollection();
+ $file = File::buildFromPathfile(self::$file1, $collection, $app);
$odd = false;
$tofetchMeta = $tofetchField = [];
- foreach (self::$DI['collection']->get_databox()->get_meta_structure() as $databox_field) {
+ foreach ($collection->get_databox()->get_meta_structure() as $databox_field) {
if ($databox_field->is_readonly()) {
continue;
}
@@ -300,14 +308,16 @@ class ManagerTest extends \PhraseanetAuthenticatedWebTestCase
$odd = !$odd;
}
- $file->addAttribute(new Story(self::$DI['record_story_1']));
+ $story = $this->getRecordStory1();
+ $file->addAttribute(new Story($story));
$status = '1';
+
foreach (range(1, 31) as $i) {
$status .= '0';
}
- $file->addAttribute(new Status(self::$DI['app'], $status));
+ $file->addAttribute(new Status($app, $status));
$this->assertEquals(Manager::LAZARET_CREATED, $this->object->process($this->session, $file, $postProcessRecord, Manager::FORCE_LAZARET));
@@ -315,12 +325,13 @@ class ManagerTest extends \PhraseanetAuthenticatedWebTestCase
$foundMeta = $foundField = [];
- /* @var $lazaret \Alchemy\Phrasea\Model\Entities\LazaretFile */
+ /** @var LazaretFile $lazaret */
foreach ($lazaret->getAttributes() as $attr) {
- $attribute = Factory::getFileAttribute(self::$DI['app'], $attr->getName(), $attr->getValue());
+ $attribute = Factory::getFileAttribute($app, $attr->getName(), $attr->getValue());
if ($attribute->getName() == AttributeInterface::NAME_STORY) {
- if ($attribute->getValue()->get_serialize_key() == self::$DI['record_story_1']->get_serialize_key()) {
+ /** @var Story $attribute */
+ if ($attribute->getValue()->getId() == $story->getId()) {
$story_found = true;
}
} elseif ($attribute->getName() == AttributeInterface::NAME_METADATA) {
diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Admin/FieldsTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Admin/FieldsTest.php
index 78b4cbcf39..8e10b1842c 100644
--- a/tests/Alchemy/Tests/Phrasea/Controller/Admin/FieldsTest.php
+++ b/tests/Alchemy/Tests/Phrasea/Controller/Admin/FieldsTest.php
@@ -3,8 +3,6 @@
namespace Alchemy\Tests\Phrasea\Controller\Admin;
use PHPExiftool\Driver\Tag\IPTC\ObjectName;
-use Alchemy\Phrasea\Vocabulary\Controller as VocabularyController;
-use Symfony\Component\HttpKernel\Client;
/**
* @group functional
@@ -16,18 +14,17 @@ class FieldsTest extends \PhraseanetAuthenticatedWebTestCase
{
public function testRoot()
{
- $databoxes = self::$DI['app']->getDataboxes();
+ $databoxes = $this->getApplication()->getDataboxes();
$databox = array_shift($databoxes);
- self::$DI['client']->request("GET", "/admin/fields/" . $databox->get_sbas_id());
+ $response = $this->request("GET", "/admin/fields/" . $databox->get_sbas_id());
- $this->assertTrue(self::$DI['client']->getResponse()->isOk());
+ $this->assertTrue($response->isOk());
}
public function testLanguage()
{
- self::$DI['client']->request("GET", "/admin/fields/language.json");
- $response = self::$DI['client']->getResponse();
+ $response = $this->request("GET", "/admin/fields/language.json");
$this->assertTrue($response->isOk());
$this->assertEquals("application/json", $response->headers->get("content-type"));
@@ -37,9 +34,7 @@ class FieldsTest extends \PhraseanetAuthenticatedWebTestCase
{
$tag = new ObjectName();
- self::$DI['client']->request("GET", "/admin/fields/tags/".$tag->getTagname());
-
- $response = self::$DI['client']->getResponse();
+ $response = $this->request("GET", "/admin/fields/tags/".$tag->getTagname());
$this->assertEquals("application/json", $response->headers->get("content-type"));
$data = json_decode($response->getContent(), true);
@@ -52,13 +47,11 @@ class FieldsTest extends \PhraseanetAuthenticatedWebTestCase
public function testListDcFields()
{
- self::$DI['client']->request("GET", "/admin/fields/dc-fields");
+ $response = $this->request("GET", "/admin/fields/dc-fields");
- $response = self::$DI['client']->getResponse()->getContent();
+ $this->assertEquals("application/json", $response->headers->get("content-type"));
- $this->assertEquals("application/json", self::$DI['client']->getResponse()->headers->get("content-type"));
-
- $data = json_decode($response, true);
+ $data = json_decode($response->getContent(), true);
$this->assertInternalType('array', $data);
foreach ($data as $dc) {
@@ -72,49 +65,40 @@ class FieldsTest extends \PhraseanetAuthenticatedWebTestCase
public function testListVocabularies()
{
- self::$DI['client']->request("GET", "/admin/fields/vocabularies");
+ $response = $this->request("GET", "/admin/fields/vocabularies");
- $response = self::$DI['client']->getResponse()->getContent();
- $this->assertEquals("application/json", self::$DI['client']->getResponse()->headers->get("content-type"));
+ $this->assertEquals("application/json", $response->headers->get("content-type"));
- $data = json_decode($response, true);
+ $data = json_decode($response->getContent(), true);
$this->assertInternalType('array', $data);
foreach ($data as $vocabulary) {
$this->assertArrayHasKey('type', $vocabulary);
$this->assertArrayHasKey('name', $vocabulary);
-
- $voc = VocabularyController::get(self::$DI['app'], $vocabulary['type']);
- $this->assertInstanceOf('Alchemy\Phrasea\Vocabulary\ControlProvider\ControlProviderInterface', $voc);
}
}
public function testGetVocabulary()
{
- self::$DI['client']->request("GET", "/admin/fields/vocabularies/user");
+ $response = $this->request("GET", "/admin/fields/vocabularies/user");
- $response = self::$DI['client']->getResponse()->getContent();
- $this->assertEquals("application/json", self::$DI['client']->getResponse()->headers->get("content-type"));
+ $this->assertEquals("application/json", $response->headers->get("content-type"));
- $data = json_decode($response, true);
+ $data = json_decode($response->getContent(), true);
$this->assertArrayHasKey('type', $data);
$this->assertEquals('User', $data['type']);
$this->assertArrayHasKey('name', $data);
-
- $voc = VocabularyController::get(self::$DI['app'], $data['type']);
- $this->assertInstanceOf('Alchemy\Phrasea\Vocabulary\ControlProvider\UserProvider', $voc);
}
public function testSearchTag()
{
- self::$DI['client']->request("GET", "/admin/fields/tags/search?term=xmp-exif");
+ $response = $this->request("GET", "/admin/fields/tags/search?term=xmp-exif");
- $response = self::$DI['client']->getResponse()->getContent();
- $this->assertEquals("application/json", self::$DI['client']->getResponse()->headers->get("content-type"));
+ $this->assertEquals("application/json", $response->headers->get("content-type"));
- $data = json_decode($response, true);
+ $data = json_decode($response->getContent(), true);
$this->assertGreaterThan(90, count($data));
@@ -128,7 +112,7 @@ class FieldsTest extends \PhraseanetAuthenticatedWebTestCase
public function testUpdateFields()
{
- $databoxes = self::$DI['app']->getDataboxes();
+ $databoxes = $this->getApplication()->getDataboxes();
$databox = array_shift($databoxes);
$fieldObjects = [];
// create two fields
@@ -170,7 +154,7 @@ class FieldsTest extends \PhraseanetAuthenticatedWebTestCase
]];
foreach ($fields as $fieldData) {
- $field = \databox_field::create(self::$DI['app'], $databox, $fieldData['name'], $fieldData['multi']);
+ $field = \databox_field::create($this->getApplication(), $databox, $fieldData['name'], $fieldData['multi']);
$field
->set_thumbtitle($fieldData['thumbtitle'])
->set_tag(\databox_field::loadClassFromTagName($fieldData['tag']))
@@ -197,13 +181,11 @@ class FieldsTest extends \PhraseanetAuthenticatedWebTestCase
$body[count($body) - 1]['readonly'] = true;
$body[count($body) - 1]['required'] = false;
- self::$DI['client']->request("PUT", sprintf("/admin/fields/%d/fields", $databox->get_sbas_id()), [], [], [], json_encode($body));
+ $response = $this->request("PUT", sprintf("/admin/fields/%d/fields", $databox->get_sbas_id()), [], [], json_encode($body));
- $response = self::$DI['client']->getResponse()->getContent();
+ $this->assertEquals("application/json", $response->headers->get("content-type"));
- $this->assertEquals("application/json", self::$DI['client']->getResponse()->headers->get("content-type"));
-
- $data = json_decode($response, true);
+ $data = json_decode($response->getContent(), true);
$this->assertTrue(is_array($data));
@@ -248,14 +230,11 @@ class FieldsTest extends \PhraseanetAuthenticatedWebTestCase
'vocabulary-restricted' => true,
]);
- /** @var Client $client */
- $client = self::$DI['client'];
- $client->request("POST", sprintf("/admin/fields/%d/fields", $databox->get_sbas_id()), [], [], [], $body);
+ $response = $this->request("POST", sprintf("/admin/fields/%d/fields", $databox->get_sbas_id()), [], [], $body);
- $response = $client->getResponse()->getContent();
- $this->assertEquals("application/json", $client->getResponse()->headers->get("content-type"));
+ $this->assertEquals("application/json", $response->headers->get("content-type"));
- $data = json_decode($response, true);
+ $data = json_decode($response->getContent(), true);
$this->assertTrue(is_array($data));
@@ -271,15 +250,14 @@ class FieldsTest extends \PhraseanetAuthenticatedWebTestCase
public function testListField()
{
- $databoxes = self::$DI['app']->getDataboxes();
+ $databoxes = $this->getApplication()->getDataboxes();
$databox = array_shift($databoxes);
- self::$DI['client']->request("GET", sprintf("/admin/fields/%d/fields", $databox->get_sbas_id()));
+ $response = $this->request("GET", sprintf("/admin/fields/%d/fields", $databox->get_sbas_id()));
- $response = self::$DI['client']->getResponse()->getContent();
- $this->assertEquals("application/json", self::$DI['client']->getResponse()->headers->get("content-type"));
+ $this->assertEquals("application/json", $response->headers->get("content-type"));
- $data = json_decode($response, true);
+ $data = json_decode($response->getContent(), true);
$this->assertInternalType('array', $data);
@@ -297,13 +275,11 @@ class FieldsTest extends \PhraseanetAuthenticatedWebTestCase
$data = $field->toArray();
- $client = $this->getClient();
- $client->request("GET", sprintf("/admin/fields/%d/fields/%d", $databox->get_sbas_id(), $field->get_id()));
+ $response = $this->request("GET", sprintf("/admin/fields/%d/fields/%d", $databox->get_sbas_id(), $field->get_id()));
- $response = $client->getResponse()->getContent();
- $this->assertEquals("application/json", $client->getResponse()->headers->get("content-type"));
+ $this->assertEquals("application/json", $response->headers->get("content-type"));
- $this->assertEquals($data, json_decode($response, true));
+ $this->assertEquals($data, json_decode($response->getContent(), true));
$field->delete();
}
@@ -320,11 +296,9 @@ class FieldsTest extends \PhraseanetAuthenticatedWebTestCase
$data['business'] = true;
$data['vocabulary-type'] = 'User';
- $client = $this->getClient();
- $client->request("PUT", sprintf("/admin/fields/%d/fields/%d", $databox->get_sbas_id(), $field->get_id()), [], [], [], json_encode($data));
+ $response = $this->request("PUT", sprintf("/admin/fields/%d/fields/%d", $databox->get_sbas_id(), $field->get_id()), [], [], json_encode($data));
- $response = $client->getResponse()->getContent();
- $this->assertEquals($data, json_decode($response, true));
+ $this->assertEquals($data, json_decode($response->getContent(), true));
$field->delete();
}
@@ -342,13 +316,10 @@ class FieldsTest extends \PhraseanetAuthenticatedWebTestCase
$data['business'] = true;
$data['vocabulary-type'] = 'User';
- /** @var Client $client */
- $client = self::$DI['client'];
- $client->request("DELETE", sprintf("/admin/fields/%d/fields/%d", $databox->get_sbas_id(), $field->get_id()), [], [], [], json_encode($data));
+ $response = $this->request("DELETE", sprintf("/admin/fields/%d/fields/%d", $databox->get_sbas_id(), $field->get_id()), [], [], json_encode($data));
- $response = $client->getResponse()->getContent();
- $this->assertEquals('', $response);
- $this->assertEquals(204, $client->getResponse()->getStatusCode());
+ $this->assertEquals('', $response->getContent());
+ $this->assertEquals(204, $response->getStatusCode());
try {
$databox->get_meta_structure()->get_element($fieldId);
diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Api/ApiJsonTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Api/ApiJsonTest.php
index f3ca34b2e2..6945e4c151 100644
--- a/tests/Alchemy/Tests/Phrasea/Controller/Api/ApiJsonTest.php
+++ b/tests/Alchemy/Tests/Phrasea/Controller/Api/ApiJsonTest.php
@@ -60,8 +60,8 @@ class ApiJsonTest extends ApiTestCase
$record = \record_adapter::createFromFile($file, $app);
$story['story_records'] = array(array(
- 'databox_id' => $record->get_sbas_id(),
- 'record_id' => $record->get_record_id()
+ 'databox_id' => $record->getDataboxId(),
+ 'record_id' => $record->getRecordId()
));
$client = $this->getClient();
@@ -96,7 +96,7 @@ class ApiJsonTest extends ApiTestCase
$this->setToken($this->userAccessToken);
$story = \record_adapter::createStory(self::$DI['app'], self::$DI['collection']);
- $route = sprintf('/api/v1/stories/%s/%s/addrecords', $story->get_sbas_id(), $story->get_record_id());
+ $route = sprintf('/api/v1/stories/%s/%s/addrecords', $story->getDataboxId(), $story->getRecordId());
$file = new File(
self::$DI['app'],
@@ -106,8 +106,8 @@ class ApiJsonTest extends ApiTestCase
$record = \record_adapter::createFromFile($file, self::$DI['app']);
$records = array(
- 'databox_id' => $record->get_sbas_id(),
- 'record_id' => $record->get_record_id()
+ 'databox_id' => $record->getDataboxId(),
+ 'record_id' => $record->getRecordId()
);
self::$DI['client']->request(
@@ -549,7 +549,7 @@ class ApiJsonTest extends ApiTestCase
$record_1 = $this->getRecord1();
$client = $this->getClient();
- $route = '/api/v1/records/' . $record_1->get_sbas_id() . '/' . $record_1->get_record_id() . '/';
+ $route = '/api/v1/records/' . $record_1->getDataboxId() . '/' . $record_1->getRecordId() . '/';
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
$client->request('GET', $route, $this->getParameters(), [], ['HTTP_Accept' => $this->getAcceptMimeType()]);
$content = $this->unserialize($client->getResponse()->getContent());
@@ -903,11 +903,14 @@ class ApiJsonTest extends ApiTestCase
->method('getSuggestions')
->will($this->returnValue(new ArrayCollection()));
- self::$DI['app']['phraseanet.SE'] = $this->getMock('Alchemy\Phrasea\SearchEngine\SearchEngineInterface');
+ $app = $this->getApplication();
+ $mock = $this->getMock('Alchemy\Phrasea\SearchEngine\SearchEngineInterface');
+ $app['phraseanet.SE'] = $mock;
- self::$DI['app']['phraseanet.SE']->expects($this->once())
+ $mock
+ ->expects($this->once())
->method('query')
- ->with('koala', 0, 10)
+ ->withAnyParameters()
->will($this->returnValue(
$this->getMockBuilder('Alchemy\Phrasea\SearchEngine\SearchEngineResult')
->disableOriginalConstructor()
@@ -1012,7 +1015,7 @@ class ApiJsonTest extends ApiTestCase
/** @var \record_adapter $record_1 */
$record_1 = self::$DI['record_1'];
- $route = '/api/v1/records/' . $record_1->get_sbas_id() . '/' . $record_1->get_record_id() . '/embed/';
+ $route = '/api/v1/records/' . $record_1->getDataboxId() . '/' . $record_1->getRecordId() . '/embed/';
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
/** @var Client $client */
@@ -1099,7 +1102,7 @@ class ApiJsonTest extends ApiTestCase
/** @var \record_adapter $story */
$story = self::$DI['record_story_1'];
- $route = '/api/v1/stories/' . $story->get_sbas_id() . '/' . $story->get_record_id() . '/embed/';
+ $route = '/api/v1/stories/' . $story->getDataboxId() . '/' . $story->getRecordId() . '/embed/';
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
/** @var Client $client */
@@ -1234,13 +1237,15 @@ class ApiJsonTest extends ApiTestCase
public function testRecordsSetStatus()
{
- self::$DI['app']['phraseanet.SE'] = $this->createSearchEngineMock();
+ $app = $this->getApplication();
+ $app['phraseanet.SE'] = $this->createSearchEngineMock();
$this->setToken($this->userAccessToken);
- $route = '/api/v1/records/' . self::$DI['record_1']->get_sbas_id() . '/' . self::$DI['record_1']->get_record_id() . '/setstatus/';
+ $record1 = $this->getRecord1();
+ $route = '/api/v1/records/' . $record1->getDataboxId() . '/' . $record1->getRecordId() . '/setstatus/';
- $record_status = strrev(self::$DI['record_1']->get_status());
- $statusStructure = self::$DI['record_1']->getStatusStructure();
+ $record_status = strrev($record1->getStatus());
+ $statusStructure = $record1->getStatusStructure();
$tochange = [];
foreach ($statusStructure as $n => $datas) {
@@ -1248,20 +1253,18 @@ class ApiJsonTest extends ApiTestCase
}
$this->evaluateMethodNotAllowedRoute($route, ['GET', 'PUT', 'DELETE']);
- self::$DI['client']->request('POST', $route, $this->getParameters(['status' => $tochange]), [], ['HTTP_Accept' => $this->getAcceptMimeType()]);
- $content = $this->unserialize(self::$DI['client']->getResponse()->getContent());
+ $response = $this->request('POST', $route, $this->getParameters(['status' => $tochange]), ['HTTP_Accept' => $this->getAcceptMimeType()]);
+ $content = $this->unserialize($response->getContent());
- /**
- * Get fresh record_1
- */
- $testRecord = new \record_adapter(self::$DI['app'], self::$DI['record_1']->get_sbas_id(), self::$DI['record_1']->get_record_id());
+ // Get fresh record_1
+ $testRecord = new \record_adapter($app, $record1->getDataboxId(), $record1->getRecordId());
- $this->evaluateResponse200(self::$DI['client']->getResponse());
+ $this->evaluateResponse200($response);
$this->evaluateMeta200($content);
$this->evaluateRecordsStatusResponse($testRecord, $content);
- $record_status = strrev($testRecord->get_status());
+ $record_status = strrev($testRecord->getStatus());
foreach ($statusStructure as $n => $datas) {
$this->assertEquals(substr($record_status, ($n), 1), $tochange[$n]);
}
@@ -1270,25 +1273,23 @@ class ApiJsonTest extends ApiTestCase
$tochange[$n] = $value == '0' ? '1' : '0';
}
- self::$DI['client']->request('POST', $route, $this->getParameters(['status' => $tochange]), [], ['HTTP_Accept' => $this->getAcceptMimeType()]);
- $content = $this->unserialize(self::$DI['client']->getResponse()->getContent());
+ $response = $this->request('POST', $route, $this->getParameters(['status' => $tochange]), ['HTTP_Accept' => $this->getAcceptMimeType()]);
+ $content = $this->unserialize($response->getContent());
- /**
- * Get fresh record_1
- */
- $testRecord = new \record_adapter(self::$DI['app'], $testRecord->get_sbas_id(), $testRecord->get_record_id());
+ // Get fresh record_1
+ $testRecord = new \record_adapter($app, $testRecord->getDataboxId(), $testRecord->getRecordId());
- $this->evaluateResponse200(self::$DI['client']->getResponse());
+ $this->evaluateResponse200($response);
$this->evaluateMeta200($content);
$this->evaluateRecordsStatusResponse($testRecord, $content);
- $record_status = strrev($testRecord->get_status());
+ $record_status = strrev($testRecord->getStatus());
foreach ($statusStructure as $n => $datas) {
$this->assertEquals(substr($record_status, ($n), 1), $tochange[$n]);
}
- self::$DI['record_1']->set_binary_status(str_repeat('0', 32));
+ $record1->setStatus(str_repeat('0', 32));
}
public function testMoveRecordToCollection()
@@ -1299,11 +1300,11 @@ class ApiJsonTest extends ApiTestCase
$this->setToken($this->userAccessToken);
- $route = '/api/v1/records/' . $record->get_sbas_id() . '/' . $record->get_record_id() . '/setcollection/';
+ $route = '/api/v1/records/' . $record->getDataboxId() . '/' . $record->getRecordId() . '/setcollection/';
$base_id = false;
- foreach ($record->get_databox()->get_collections() as $collection) {
- if ($collection->get_base_id() != $record->get_base_id()) {
+ foreach ($record->getDatabox()->get_collections() as $collection) {
+ if ($collection->get_base_id() != $record->getBaseId()) {
$base_id = $collection->get_base_id();
break;
}
diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Api/ApiTestCase.php b/tests/Alchemy/Tests/Phrasea/Controller/Api/ApiTestCase.php
index ea90eefb66..054f779076 100644
--- a/tests/Alchemy/Tests/Phrasea/Controller/Api/ApiTestCase.php
+++ b/tests/Alchemy/Tests/Phrasea/Controller/Api/ApiTestCase.php
@@ -694,9 +694,9 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
protected function evaluateRecordsStatusResponse(\record_adapter $record, $content)
{
- $statusStructure = $record->get_databox()->getStatusStructure();
+ $statusStructure = $record->getDatabox()->getStatusStructure();
- $r_status = strrev($record->get_status());
+ $r_status = strrev($record->getStatus());
$this->assertArrayHasKey('status', $content['response']);
$this->assertEquals(count((array) $content['response']['status']), count($statusStructure->toArray()));
foreach ($content['response']['status'] as $status) {
@@ -714,7 +714,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
protected function injectMetadatas(\record_adapter $record)
{
- foreach ($record->get_databox()->get_meta_structure()->get_elements() as $field) {
+ foreach ($record->getDatabox()->get_meta_structure()->get_elements() as $field) {
try {
$values = $record->get_caption()->get_field($field->get_name())->get_values();
$value = array_pop($values);
diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Prod/DownloadTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Prod/DownloadTest.php
index 670e0d9a3d..a3909c95e9 100644
--- a/tests/Alchemy/Tests/Phrasea/Controller/Prod/DownloadTest.php
+++ b/tests/Alchemy/Tests/Phrasea/Controller/Prod/DownloadTest.php
@@ -57,7 +57,7 @@ class DownloadTest extends \PhraseanetAuthenticatedWebTestCase
//has_right_on_base return true
$stubbedACL->expects($this->any())
- ->method('has_right_on_bas')
+ ->method('has_right_on_base')
->will($this->returnValue(false));
//has_access_to_subdef return true
diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Prod/ExportTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Prod/ExportTest.php
index b7a42e6448..da278639c2 100644
--- a/tests/Alchemy/Tests/Phrasea/Controller/Prod/ExportTest.php
+++ b/tests/Alchemy/Tests/Phrasea/Controller/Prod/ExportTest.php
@@ -142,7 +142,7 @@ class ExportTest extends \PhraseanetAuthenticatedWebTestCase
//inserted rows from this function are deleted in tearDownAfterClass
$this->getClient()->request('POST', '/prod/export/ftp/', [
- 'lst' => $this->getRecord1()->get_serialize_key(),
+ 'lst' => $this->getRecord1()->getId(),
'user_dest' => $user->getId(),
'address' => 'local.phrasea.test',
'login' => $user->getEmail(),
@@ -168,7 +168,7 @@ class ExportTest extends \PhraseanetAuthenticatedWebTestCase
$this->mockNotificationDeliverer('Alchemy\Phrasea\Notification\Mail\MailRecordsExport');
$this->getClient()->request('POST', '/prod/export/mail/', [
- 'lst' => $this->getRecord1()->get_serialize_key(),
+ 'lst' => $this->getRecord1()->getId(),
'destmail' => 'user@example.com',
'obj' => ['preview'],
]);
diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Prod/LazaretTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Prod/LazaretTest.php
index 38d0d6f05f..82c916e197 100644
--- a/tests/Alchemy/Tests/Phrasea/Controller/Prod/LazaretTest.php
+++ b/tests/Alchemy/Tests/Phrasea/Controller/Prod/LazaretTest.php
@@ -142,7 +142,7 @@ class LazaretTest extends \PhraseanetAuthenticatedWebTestCase
//Provide some valid test values
$lazaretAttribute->expects($this->exactly(4))
->method('getValue')
- ->will($this->onConsecutiveCalls('metadataValue', $story->get_serialize_key(), '00001111', 'metafieldValue'));
+ ->will($this->onConsecutiveCalls('metadataValue', $story->getId(), '00001111', 'metafieldValue'));
//Add the 5 attribute
$lazaretFile->addAttribute($lazaretAttribute);
diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Prod/OrderTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Prod/OrderTest.php
index 19c49119c3..558b599b88 100644
--- a/tests/Alchemy/Tests/Phrasea/Controller/Prod/OrderTest.php
+++ b/tests/Alchemy/Tests/Phrasea/Controller/Prod/OrderTest.php
@@ -29,7 +29,7 @@ class OrderTest extends \PhraseanetAuthenticatedWebTestCase
});
$client = $this->getClient();
$client->request('POST', '/prod/order/', [
- 'lst' => $this->getRecord1()->get_serialize_key(),
+ 'lst' => $this->getRecord1()->getId(),
'deadline' => '+10 minutes'
]);
@@ -54,7 +54,7 @@ class OrderTest extends \PhraseanetAuthenticatedWebTestCase
});
$response = $this->XMLHTTPRequest('POST', '/prod/order/', [
- 'lst' => $this->getRecord1()->get_serialize_key(),
+ 'lst' => $this->getRecord1()->getId(),
'deadline' => '+10 minutes'
]);
@@ -71,7 +71,7 @@ class OrderTest extends \PhraseanetAuthenticatedWebTestCase
public function testDisplayOrders()
{
$this->XMLHTTPRequest('POST', '/prod/order/', [
- 'lst' => $this->getRecord1()->get_serialize_key(),
+ 'lst' => $this->getRecord1()->getId(),
'deadline' => '+10 minutes'
]);
$response = $this->request('GET', '/prod/order/', [
diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Prod/PropertyTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Prod/PropertyTest.php
index c0d2088b82..2389da527e 100644
--- a/tests/Alchemy/Tests/Phrasea/Controller/Prod/PropertyTest.php
+++ b/tests/Alchemy/Tests/Phrasea/Controller/Prod/PropertyTest.php
@@ -102,12 +102,12 @@ class PropertyTest extends \PhraseanetAuthenticatedWebTestCase
self::$DI['app']['acl'] = $aclProvider;
self::$DI['client']->request('POST', '/prod/records/property/status/', [
- 'apply_to_children' => [$story->get_sbas_id() => true],
+ 'apply_to_children' => [$story->getDataboxId() => true],
'status' => [
- $record->get_sbas_id() => [6 => true, 8 => true, 11 => true]
+ $record->getDataboxId() => [6 => true, 8 => true, 11 => true]
],
'lst' => implode(';', [
- $record->get_serialize_key(),$story->get_serialize_key()
+ $record->getId(),$story->getId()
])
]);
$response = self::$DI['client']->getResponse();
@@ -116,11 +116,11 @@ class PropertyTest extends \PhraseanetAuthenticatedWebTestCase
$this->assertTrue($datas['success']);
$this->assertArrayHasKey('updated', $datas);
- $record = new \record_adapter(self::$DI['app'], $record->get_sbas_id(), $record->get_record_id());
- $story = new \record_adapter(self::$DI['app'], $story->get_sbas_id(), $story->get_record_id());
+ $record = new \record_adapter(self::$DI['app'], $record->getDataboxId(), $record->getRecordId());
+ $story = new \record_adapter(self::$DI['app'], $story->getDataboxId(), $story->getRecordId());
- $recordStatus = strrev($record->get_status());
- $storyStatus = strrev($story->get_status());
+ $recordStatus = strrev($record->getStatus());
+ $storyStatus = strrev($story->getStatus());
$this->assertEquals(1, substr($recordStatus, 6, 1));
$this->assertEquals(1, substr($recordStatus, 8, 1));
@@ -130,8 +130,8 @@ class PropertyTest extends \PhraseanetAuthenticatedWebTestCase
$this->assertEquals(1, substr($storyStatus, 8, 1));
$this->assertEquals(1, substr($storyStatus, 11, 1));
- foreach ($story->get_children() as $child) {
- $childStatus = strrev($child->get_status());
+ foreach ($story->getChildren() as $child) {
+ $childStatus = strrev($child->getStatus());
$this->assertEquals(1, substr($childStatus, 6, 1));
$this->assertEquals(1, substr($childStatus, 8, 1));
$this->assertEquals(1, substr($childStatus, 11, 1));
@@ -155,11 +155,11 @@ class PropertyTest extends \PhraseanetAuthenticatedWebTestCase
self::$DI['client']->request('POST', '/prod/records/property/type/', [
'lst' => implode(';', [
- $record->get_serialize_key(), $record2->get_serialize_key()
+ $record->getId(), $record2->getId()
]),
'types' => [
- $record->get_serialize_key() => 'document',
- $record2->get_serialize_key() => 'flash',
+ $record->getId() => 'document',
+ $record2->getId() => 'flash',
]
]);
$response = self::$DI['client']->getResponse();
@@ -168,11 +168,11 @@ class PropertyTest extends \PhraseanetAuthenticatedWebTestCase
$this->assertTrue($datas['success']);
$this->assertArrayHasKey('updated', $datas);
- $record = new \record_adapter(self::$DI['app'], $record->get_sbas_id(), $record->get_record_id());
- $record2 = new \record_adapter(self::$DI['app'], $record2->get_sbas_id(), $record2->get_record_id());
+ $record = new \record_adapter(self::$DI['app'], $record->getDataboxId(), $record->getRecordId());
+ $record2 = new \record_adapter(self::$DI['app'], $record2->getDataboxId(), $record2->getRecordId());
- $this->assertEquals('document', $record->get_type());
- $this->assertEquals('flash', $record2->get_type());
+ $this->assertEquals('document', $record->getType());
+ $this->assertEquals('flash', $record2->getType());
$record->delete();
$record2->delete();
diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Prod/QueryTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Prod/QueryTest.php
index a89a2a2877..3cc103a18b 100644
--- a/tests/Alchemy/Tests/Phrasea/Controller/Prod/QueryTest.php
+++ b/tests/Alchemy/Tests/Phrasea/Controller/Prod/QueryTest.php
@@ -13,10 +13,6 @@ use Prophecy\Argument;
*/
class QueryTest extends \PhraseanetAuthenticatedWebTestCase
{
-
- /**
- * @covers Alchemy\Phrasea\Controller\Prod\Query::query
- */
public function testQuery()
{
$route = '/prod/query/';
@@ -46,9 +42,6 @@ class QueryTest extends \PhraseanetAuthenticatedWebTestCase
$this->assertInternalType('array', $data);
}
- /**
- * @covers Alchemy\Phrasea\Controller\Prod\Query::queryAnswerTrain
- */
public function testQueryAnswerTrain()
{
$app = $this->mockElasticsearchResult(self::$DI['record_2']);
@@ -58,13 +51,11 @@ class QueryTest extends \PhraseanetAuthenticatedWebTestCase
$options->onCollections($app->getAclForUser($app->getAuthenticatedUser())->get_granted_base());
$serializedOptions = $options->serialize();
- $client = $this->getClient();
- $client->request('POST', '/prod/query/answer-train/', [
+ $response = $this->request('POST', '/prod/query/answer-train/', [
'options_serial' => $serializedOptions,
'pos' => 0,
'query' => ''
]);
- $response = $client->getResponse();
$this->assertTrue($response->isOk());
$datas = (array) json_decode($response->getContent());
$this->assertArrayHasKey('current', $datas);
diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Prod/RecordsTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Prod/RecordsTest.php
index e8bfa58d8f..2a94180c1f 100644
--- a/tests/Alchemy/Tests/Phrasea/Controller/Prod/RecordsTest.php
+++ b/tests/Alchemy/Tests/Phrasea/Controller/Prod/RecordsTest.php
@@ -18,9 +18,6 @@ class RecordsTest extends \PhraseanetAuthenticatedWebTestCase
{
protected $client;
- /**
- * @covers Alchemy\Phrasea\Controller\Prod\Records::whatCanIDelete
- */
public function testWhatCanIDelete()
{
self::$DI['client']->request('POST', '/prod/records/delete/what/', ['lst' => self::$DI['record_1']->get_serialize_key()]);
@@ -29,40 +26,31 @@ class RecordsTest extends \PhraseanetAuthenticatedWebTestCase
unset($response);
}
- /**
- * @covers Alchemy\Phrasea\Controller\Prod\Records::doDeleteRecords
- */
public function testDoDeleteRecords()
{
$file = new File(self::$DI['app'], self::$DI['app']['mediavorus']->guess(__DIR__ . '/../../../../../files/cestlafete.jpg'), self::$DI['collection']);
$record = \record_adapter::createFromFile($file, self::$DI['app']);
- $response = $this->XMLHTTPRequest('POST', '/prod/records/delete/', ['lst' => $record->get_serialize_key()]);
+ $response = $this->XMLHTTPRequest('POST', '/prod/records/delete/', ['lst' => $record->getId()]);
$datas = (array) json_decode($response->getContent());
- $this->assertContains($record->get_serialize_key(), $datas);
+ $this->assertContains($record->getId(), $datas);
try {
- new \record_adapter(self::$DI['app'], $record->get_sbas_id(), $record->get_record_id());
+ new \record_adapter(self::$DI['app'], $record->getDataboxId(), $record->getRecordId());
$this->fail('Record not deleted');
} catch (\Exception $e) {
}
}
- /**
- * @covers Alchemy\Phrasea\Controller\Prod\Records::renewUrl
- */
public function testRenewUrl()
{
$file = new File(self::$DI['app'], self::$DI['app']['mediavorus']->guess(__DIR__ . '/../../../../../files/cestlafete.jpg'), self::$DI['collection']);
$record = \record_adapter::createFromFile($file, self::$DI['app']);
- $response = $this->XMLHTTPRequest('POST', '/prod/records/renew-url/', ['lst' => $record->get_serialize_key()]);
+ $response = $this->XMLHTTPRequest('POST', '/prod/records/renew-url/', ['lst' => $record->getId()]);
$datas = (array) json_decode($response->getContent());
$this->assertTrue(count($datas) > 0);
$record->delete();
}
- /**
- * @covers Alchemy\Phrasea\Controller\Prod\Records::getRecord
- */
public function testGetRecordDetailNotAjax()
{
self::$DI['client']->request('POST', '/prod/records/');
@@ -108,9 +96,6 @@ class RecordsTest extends \PhraseanetAuthenticatedWebTestCase
$this->assertArrayHasKey('title', $data);
}
- /**
- * @covers Alchemy\Phrasea\Controller\Prod\Records::getRecord
- */
public function testGetRecordDetailResult()
{
$app = $this->mockElasticsearchResult(self::$DI['record_1']);
@@ -141,9 +126,6 @@ class RecordsTest extends \PhraseanetAuthenticatedWebTestCase
$this->assertArrayHasKey('title', $data);
}
- /**
- * @covers Alchemy\Phrasea\Controller\Prod\Records::getRecord
- */
public function testGetRecordDetailREG()
{
$this->authenticate(self::$DI['app']);
@@ -168,9 +150,6 @@ class RecordsTest extends \PhraseanetAuthenticatedWebTestCase
$this->assertObjectHasAttribute('title', $data);
}
- /**
- * @covers Alchemy\Phrasea\Controller\Prod\Records::getRecord
- */
public function testGetRecordDetailBasket()
{
$this->authenticate(self::$DI['app']);
@@ -198,9 +177,6 @@ class RecordsTest extends \PhraseanetAuthenticatedWebTestCase
unset($response, $data);
}
- /**
- * @covers Alchemy\Phrasea\Controller\Prod\Records::getRecord
- */
public function testGetRecordDetailFeed()
{
$this->authenticate(self::$DI['app']);
diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Prod/RootTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Prod/RootTest.php
index 95c1d4a675..2083ed043c 100644
--- a/tests/Alchemy/Tests/Phrasea/Controller/Prod/RootTest.php
+++ b/tests/Alchemy/Tests/Phrasea/Controller/Prod/RootTest.php
@@ -16,9 +16,8 @@ class RootTest extends \PhraseanetAuthenticatedWebTestCase
public function testRouteSlash()
{
self::$DI['app']['phraseanet.SE'] = $this->createSearchEngineMock();
- self::$DI['client']->request('GET', '/prod/');
+ $response = $this->request('GET', '/prod/');
- $response = self::$DI['client']->getResponse();
$this->assertTrue($response->isOk());
$this->assertEquals('UTF-8', $response->getCharset());
}
diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Prod/StoryTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Prod/StoryTest.php
index 182cffc9a5..f6a4a1a92d 100644
--- a/tests/Alchemy/Tests/Phrasea/Controller/Prod/StoryTest.php
+++ b/tests/Alchemy/Tests/Phrasea/Controller/Prod/StoryTest.php
@@ -100,7 +100,7 @@ class StoryTest extends \PhraseanetAuthenticatedWebTestCase
{
$story = \record_adapter::createStory(self::$DI['app'], self::$DI['collection']);
- $route = sprintf("/prod/story/%s/%s/addElements/", $story->get_sbas_id(), $story->get_record_id());
+ $route = sprintf("/prod/story/%s/%s/addElements/", $story->getDataboxId(), $story->getRecordId());
$records = [
self::$DI['record_1']->get_serialize_key(),
@@ -115,7 +115,7 @@ class StoryTest extends \PhraseanetAuthenticatedWebTestCase
$this->assertEquals(302, $response->getStatusCode());
- $this->assertEquals(2, $story->get_children()->get_count());
+ $this->assertEquals(2, $story->getChildren()->get_count());
$story->delete();
}
@@ -123,7 +123,7 @@ class StoryTest extends \PhraseanetAuthenticatedWebTestCase
{
$story = \record_adapter::createStory(self::$DI['app'], self::$DI['collection']);
- $route = sprintf("/prod/story/%s/%s/addElements/", $story->get_sbas_id(), $story->get_record_id());
+ $route = sprintf("/prod/story/%s/%s/addElements/", $story->getDataboxId(), $story->getRecordId());
$records = [
self::$DI['record_1']->get_serialize_key(),
@@ -140,7 +140,7 @@ class StoryTest extends \PhraseanetAuthenticatedWebTestCase
$this->assertEquals(200, $response->getStatusCode());
- $this->assertEquals(2, $story->get_children()->get_count());
+ $this->assertEquals(2, $story->getChildren()->get_count());
$story->delete();
}
@@ -157,16 +157,16 @@ class StoryTest extends \PhraseanetAuthenticatedWebTestCase
$story->appendChild($record);
}
- $totalRecords = $story->get_children()->get_count();
+ $totalRecords = $story->getChildren()->get_count();
$n = 0;
foreach ($records as $record) {
/* @var $record \record_adapter */
$route = sprintf(
- "/prod/story/%s/%s/delete/%s/%s/"
- , $story->get_sbas_id()
- , $story->get_record_id()
- , $record->get_sbas_id()
- , $record->get_record_id()
+ "/prod/story/%s/%s/delete/%s/%s/",
+ $story->getDataboxId(),
+ $story->getRecordId(),
+ $record->getDataboxId(),
+ $record->getRecordId()
);
if (($n % 2) === 0) {
@@ -188,7 +188,7 @@ class StoryTest extends \PhraseanetAuthenticatedWebTestCase
$this->assertTrue($data['success']);
}
$n ++;
- $this->assertEquals($totalRecords - $n, $story->get_children()->get_count());
+ $this->assertEquals($totalRecords - $n, $story->getChildren()->get_count());
}
$story->delete();
}
diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Prod/UploadTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Prod/UploadTest.php
index 97bc731f56..65832cf4dc 100644
--- a/tests/Alchemy/Tests/Phrasea/Controller/Prod/UploadTest.php
+++ b/tests/Alchemy/Tests/Phrasea/Controller/Prod/UploadTest.php
@@ -377,7 +377,7 @@ class UploadTest extends \PhraseanetAuthenticatedWebTestCase
$id = explode('_', $datas['id']);
$record = new \record_adapter(self::$DI['app'], $id[0], $id[1]);
$this->assertFalse($record->isStory());
- $this->assertEquals(1, substr(strrev($record->get_status()), 4, 1));
+ $this->assertEquals(1, substr(strrev($record->getStatus()), 4, 1));
$this->assertEquals([], $datas['reasons']);
}
diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Report/InformationsTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Report/InformationsTest.php
index 73bc5a7701..4f6456d31e 100644
--- a/tests/Alchemy/Tests/Phrasea/Controller/Report/InformationsTest.php
+++ b/tests/Alchemy/Tests/Phrasea/Controller/Report/InformationsTest.php
@@ -269,8 +269,8 @@ class InformationsTest extends \PhraseanetAuthenticatedWebTestCase
'dmax' => $this->dmax->format('Y-m-d H:i:s'),
'sbasid' => $this->getCollection()->get_sbas_id(),
'collection' => $this->getCollection()->get_coll_id(),
- 'sbasid' => $this->getRecord1()->get_sbas_id(),
- 'rid' => $this->getRecord1()->get_record_id(),
+ 'sbasid' => $this->getRecord1()->getDataboxId(),
+ 'rid' => $this->getRecord1()->getRecordId(),
]);
$response = $this->client->getResponse();
@@ -285,8 +285,8 @@ class InformationsTest extends \PhraseanetAuthenticatedWebTestCase
'dmax' => $this->dmax->format('Y-m-d H:i:s'),
'sbasid' => $this->getCollection()->get_sbas_id(),
'collection' => $this->getCollection()->get_coll_id(),
- 'sbasid' => $this->getRecord1()->get_sbas_id(),
- 'rid' => $this->getRecord1()->get_record_id(),
+ 'sbasid' => $this->getRecord1()->getDataboxId(),
+ 'rid' => $this->getRecord1()->getRecordId(),
'from' => 'TOOL'
]);
@@ -302,8 +302,8 @@ class InformationsTest extends \PhraseanetAuthenticatedWebTestCase
'dmax' => $this->dmax->format('Y-m-d H:i:s'),
'sbasid' => $this->getCollection()->get_sbas_id(),
'collection' => $this->getCollection()->get_coll_id(),
- 'sbasid' => $this->getRecord1()->get_sbas_id(),
- 'rid' => $this->getRecord1()->get_record_id(),
+ 'sbasid' => $this->getRecord1()->getDataboxId(),
+ 'rid' => $this->getRecord1()->getRecordId(),
'from' => 'DASH'
]);
@@ -319,8 +319,8 @@ class InformationsTest extends \PhraseanetAuthenticatedWebTestCase
'dmax' => $this->dmax->format('Y-m-d H:i:s'),
'sbasid' => $this->getCollection()->get_sbas_id(),
'collection' => $this->getCollection()->get_coll_id(),
- 'sbasid' => $this->getRecord1()->get_sbas_id(),
- 'rid' => $this->getRecord1()->get_record_id(),
+ 'sbasid' => $this->getRecord1()->getDataboxId(),
+ 'rid' => $this->getRecord1()->getRecordId(),
'user' => $this->getUser()->getId()
]);
diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Root/RSSFeedTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Root/RSSFeedTest.php
index c1d78612c2..9ae0c68a2a 100644
--- a/tests/Alchemy/Tests/Phrasea/Controller/Root/RSSFeedTest.php
+++ b/tests/Alchemy/Tests/Phrasea/Controller/Root/RSSFeedTest.php
@@ -388,7 +388,7 @@ class RSSFeedTest extends \PhraseanetWebTestCase
$this->assertEquals($ressource->get_mime(), $value);
break;
case "medium":
- $this->assertEquals(strtolower($record->get_type()), $value);
+ $this->assertEquals(strtolower($record->getType()), $value);
break;
case "isDefault":
!$is_thumbnail ? $this->assertEquals("true", $value) : $this->assertEquals("false", $value);
diff --git a/tests/Alchemy/Tests/Phrasea/Core/Configuration/Fixtures/configuration-setup.yml b/tests/Alchemy/Tests/Phrasea/Core/Configuration/Fixtures/configuration-setup.yml
index 371b7b1d02..3a312ed3bb 100644
--- a/tests/Alchemy/Tests/Phrasea/Core/Configuration/Fixtures/configuration-setup.yml
+++ b/tests/Alchemy/Tests/Phrasea/Core/Configuration/Fixtures/configuration-setup.yml
@@ -196,3 +196,18 @@ crossdomain:
-
domain: '*.cooliris.com'
secure: 'false'
+embed_bundle:
+ video:
+ player: videojs
+ autoplay: false
+ coverSubdef: thumbnail
+ available-speeds:
+ - 1
+ - 1.5
+ - 3
+ audio:
+ player: videojs
+ autoplay: false
+ document:
+ player: flexpaper
+ enable-pdfjs: true
diff --git a/tests/Alchemy/Tests/Phrasea/Core/Configuration/Fixtures/configuration.yml b/tests/Alchemy/Tests/Phrasea/Core/Configuration/Fixtures/configuration.yml
index 371b7b1d02..3a312ed3bb 100644
--- a/tests/Alchemy/Tests/Phrasea/Core/Configuration/Fixtures/configuration.yml
+++ b/tests/Alchemy/Tests/Phrasea/Core/Configuration/Fixtures/configuration.yml
@@ -196,3 +196,18 @@ crossdomain:
-
domain: '*.cooliris.com'
secure: 'false'
+embed_bundle:
+ video:
+ player: videojs
+ autoplay: false
+ coverSubdef: thumbnail
+ available-speeds:
+ - 1
+ - 1.5
+ - 3
+ audio:
+ player: videojs
+ autoplay: false
+ document:
+ player: flexpaper
+ enable-pdfjs: true
diff --git a/tests/Alchemy/Tests/Phrasea/Databox/DataboxBoundRepositoryProviderTest.php b/tests/Alchemy/Tests/Phrasea/Databox/DataboxBoundRepositoryProviderTest.php
new file mode 100644
index 0000000000..99859f2f08
--- /dev/null
+++ b/tests/Alchemy/Tests/Phrasea/Databox/DataboxBoundRepositoryProviderTest.php
@@ -0,0 +1,57 @@
+prophesize(DataboxBoundRepositoryFactory::class);
+
+ $factory
+ ->createRepositoryFor(Argument::type('integer'))
+ ->will(function ($args) {
+ return (object)['databoxId' => $args[0]];
+ });
+
+ $this->sut = new DataboxBoundRepositoryProvider($factory->reveal());
+ }
+
+ public function testItCreatesRepositoriesIfUnknown()
+ {
+ $repository = $this->sut->getRepositoryForDatabox(42);
+
+ $this->assertNotNull($repository, 'Failed to create a repository');
+ $this->assertSame($repository, $this->sut->getRepositoryForDatabox(42));
+ }
+
+ public function testItShouldNotCreateTwoRepositoriesPerDatabox()
+ {
+ $repository1 = $this->sut->getRepositoryForDatabox(1);
+ $repository2 = $this->sut->getRepositoryForDatabox(2);
+
+ $this->assertNotNull($repository1, 'Failed to create first repository');
+ $this->assertNotNull($repository2, 'Failed to create second repository');
+ $this->assertNotSame($repository1, $repository2, 'Different Databoxes should have different repositories');
+
+ $this->assertSame($repository2, $this->sut->getRepositoryForDatabox(2), 'Second Repository should be returned');
+ $this->assertSame($repository1, $this->sut->getRepositoryForDatabox(1), 'First Repository should be returned');
+ }
+}
diff --git a/tests/Alchemy/Tests/Phrasea/Hydration/IdentityMapTest.php b/tests/Alchemy/Tests/Phrasea/Hydration/IdentityMapTest.php
new file mode 100644
index 0000000000..ceeb43eea4
--- /dev/null
+++ b/tests/Alchemy/Tests/Phrasea/Hydration/IdentityMapTest.php
@@ -0,0 +1,114 @@
+prophesize(Hydrator::class);
+
+ $hydrator->extract(Argument::type(\stdClass::class))
+ ->will(function ($args) {
+ return (array)$args[0];
+ });
+
+ $hydrator->hydrate(Argument::type(\stdClass::class), Argument::type('array'))
+ ->will(function ($args) {
+
+ foreach ($args[1] as $property => $value) {
+ $args[0]->{$property} = $value;
+ }
+ });
+
+ $this->sut = new IdentityMap($hydrator->reveal(), (object)['foo' => null, 'bar' => null]);
+ }
+
+ public function testItShouldBeArrayAccessibleTraversableAndCountable()
+ {
+ $this->assertInstanceOf(\Traversable::class, $this->sut);
+ $this->assertInstanceOf(\ArrayAccess::class, $this->sut);
+ $this->assertInstanceOf(\Countable::class, $this->sut);
+ }
+
+ public function testItShouldHydrateAnInstanceWhenNotYetInMap()
+ {
+ $expected = (object)['foo' => 'foo', 'bar' => 'bar'];
+
+ $instance = $this->sut->hydrate(42, ['foo' => 'foo', 'bar' => 'bar']);
+
+ $this->assertEquals($expected, $instance, 'Invalid instance generated');
+
+ $this->assertSame($instance, $this->sut[42], 'Accessing by offset should succeed');
+ }
+
+ public function testItShouldReHydrateAnInstance()
+ {
+ $instance = $this->sut->hydrate(42, ['foo' => 'Foo', 'bar' => 'Bar']);
+
+ $this->assertAttributeSame('Foo', 'foo', $instance);
+ $this->assertAttributeSame('Bar', 'bar', $instance);
+
+ $instance2 = $this->sut->hydrate(42, ['foo' => 'new foo value', 'bar' => null]);
+
+ $this->assertAttributeSame('new foo value', 'foo', $instance);
+ $this->assertAttributeSame(null, 'bar', $instance);
+
+ $this->assertSame($instance, $instance2, 'Same instance was not rehydrated');
+
+ $this->assertCount(1, $this->sut);
+ }
+
+ public function testItsOffsetCanBeUnset()
+ {
+ $this->sut[42] = ['foo' => 'Foo', 'bar' => 'Bar'];
+
+ $this->assertTrue(isset($this->sut[42]), 'Offset should exists');
+
+ unset($this->sut[42]);
+
+ $this->assertFalse(isset($this->sut[42]), 'Offset should not exists after unset');
+ }
+
+ public function testItHydratesAllEntities()
+ {
+ $data = [
+ ['foo' => 'Foo1', 'bar' => 'Bar1'],
+ ['foo' => 'Foo2', 'bar' => 'Bar2'],
+ ];
+
+ $this->sut->hydrateAll($data);
+
+ $entities = [];
+
+ foreach ($this->sut as $key => $value) {
+ $entities[$key] = $value;
+ }
+
+ foreach ($data as $key => $value) {
+ $this->assertArrayHasKey($key, $entities, 'An entity is missing');
+ $this->assertEquals((object)$value, $entities[$key], 'Unexpected entity value');
+ }
+
+ $this->assertCount(2, $this->sut);
+ $this->sut->clear();
+ $this->assertCount(0, $this->sut, 'Map was not cleared');
+ }
+}
diff --git a/tests/Alchemy/Tests/Phrasea/Hydration/ReflectionHydratorTest.php b/tests/Alchemy/Tests/Phrasea/Hydration/ReflectionHydratorTest.php
new file mode 100644
index 0000000000..a956414f94
--- /dev/null
+++ b/tests/Alchemy/Tests/Phrasea/Hydration/ReflectionHydratorTest.php
@@ -0,0 +1,73 @@
+sut = new ReflectionHydrator(ToHydrate::class, ['foo', 'bar']);
+ }
+
+ public function testItThrowsExceptionOnUnknownProperty()
+ {
+ $this->setExpectedException(\ReflectionException::class);
+
+ $sut = new ReflectionHydrator(ToHydrate::class, ['baz']);
+ $sut->extract(new ToHydrate());
+ }
+
+ public function testItShouldImplementHydrator()
+ {
+ $this->assertInstanceOf(Hydrator::class, $this->sut);
+ }
+
+ public function testItShouldProperlyHydrateInstance()
+ {
+ $stub = new ToHydrate();
+
+ $this->sut->hydrate($stub, ['foo' => 'foo modified', 'bar' => 'bar changed']);
+
+ $this->assertEquals('foo modified', $stub->getFoo(), 'Property foo was not hydrated');
+ $this->assertEquals('bar changed', $stub->getBar(), 'Property bar was not hydrated');
+ }
+
+ public function testItShouldProperlyExtractData()
+ {
+ $data = $this->sut->extract(new ToHydrate());
+
+ $this->assertSame(['foo' => 'foo', 'bar' => 'bar'], $data, 'Improper extraction of properties');
+ }
+}
+
+class ToHydrate
+{
+ private $foo = 'foo';
+ private $bar = 'bar';
+
+ public function getFoo()
+ {
+ return $this->foo;
+ }
+
+ public function getBar()
+ {
+ return $this->bar;
+ }
+}
diff --git a/tests/Alchemy/Tests/Phrasea/SearchEngine/ElasticSearchEngineTest.php b/tests/Alchemy/Tests/Phrasea/SearchEngine/ElasticSearchEngineTest.php
deleted file mode 100644
index 1848ef38ef..0000000000
--- a/tests/Alchemy/Tests/Phrasea/SearchEngine/ElasticSearchEngineTest.php
+++ /dev/null
@@ -1,54 +0,0 @@
-markTestSkipped();
- if (false === @file_get_contents('http://localhost:9200')) {
- $this->markTestSkipped('Unable to connect to elasticsearch.');
- }
-
- parent::setUp();
-
- /** @var Indexer $indexer */
- $indexer = self::$DI['app']['elasticsearch.indexer'];
-
- // Re-index everything
- ob_start();
- $indexer->deleteIndex();
- $indexer->createIndex();
- $indexer->populateIndex();
- ob_end_clean();
- }
-
- public function initialize()
- {
- // Change the index name
- self::$DI['app']['conf']->set(['main', 'search-engine', 'options', 'index'], 'test');
-
- self::$searchEngine = $es = new ElasticSearchEngine(
- self::$DI['app'],
- self::$DI['app']['elasticsearch.client'],
- self::$DI['app']['elasticsearch.options']['index']
- );
-
- self::$searchEngineClass = 'Alchemy\Phrasea\SearchEngine\Elastic\ElasticSearchEngine';
- }
-
- public function testAutocomplete()
- {
- $this->markTestSkipped("Not implemented yet.");
- }
-
- protected function updateIndex(array $stemms = [])
- {
- $client = self::$searchEngine->getClient();
- $client->indices()->refresh();
- }
-}
diff --git a/tests/Alchemy/Tests/Phrasea/SearchEngine/SearchEngineAbstractTest.php b/tests/Alchemy/Tests/Phrasea/SearchEngine/SearchEngineAbstractTest.php
deleted file mode 100644
index e5f24b7aa2..0000000000
--- a/tests/Alchemy/Tests/Phrasea/SearchEngine/SearchEngineAbstractTest.php
+++ /dev/null
@@ -1,773 +0,0 @@
-get_databox()->get_meta_structure()->get_elements() as $field) {
- if (!$field->isBusiness()) {
- continue;
- }
- $found = true;
- }
-
- if (!$found) {
- $field = \databox_field::create(self::$DI['app'], self::$DI['record_2']->get_databox(), 'testBusiness' . mt_rand(), false);
- $field->set_business(true);
- $field->save();
- }
-
- foreach (self::$DI['app']->getDataboxes() as $databox) {
- break;
- }
- }
-
- $this->initialize();
-
- if (!self::$searchEngine instanceof SearchEngineInterface) {
- $this->markTestSkipped('Unable to initialize search Engine');
- }
-
- $options = new SearchEngineOptions();
- $options->onCollections($databox->get_collections());
-
- $this->options = $options;
- }
-
- public static function tearDownAfterClass()
- {
- self::$searchEngine = self::$searchEngineClass = self::$initialized = null;
- parent::tearDownAfterClass();
- }
-
- /**
- * @return SearchEngineOptions
- */
- private function getOptions()
- {
- return $this->options;
- }
-
- public function testQueryRecordId()
- {
- $record = self::$DI['record_2'];
- $query_string = 'recordid=' . $record->get_record_id();
-
- self::$searchEngine->addRecord($record);
- $this->updateIndex();
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $this->options);
- $this->assertEquals(1, $results->getTotal());
-
- $result = $results->getResults()->first();
-
- $this->assertEquals($record->get_record_id(), $result->get_record_id());
- $this->assertEquals($record->get_sbas_id(), $result->get_sbas_id());
- }
-
- public function testQueryStoryId()
- {
- $record = self::$DI['record_2'];
- $query_string = 'storyid=' . $record->get_record_id();
-
- self::$searchEngine->addRecord($record);
- $this->updateIndex();
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $this->options);
- $this->assertEquals(1, $results->getTotal());
-
- $result = $results->getResults()->first();
-
- $this->assertEquals($record->get_record_id(), $result->get_record_id());
- $this->assertEquals($record->get_sbas_id(), $result->get_sbas_id());
- }
-
- public function testQueryByDateMin()
- {
- $record = self::$DI['record_2'];
- $query_string = 'boomboklot' . $record->get_record_id() . 'dateMin';
-
- $this->editRecord($query_string, $record);
-
- $date_field = $this->editDateRecord('2012-12-21 12:12:00', $record);
-
- if (!$date_field) {
- $this->markTestSkipped('unable to add a date to record');
- }
-
- self::$searchEngine->addRecord($record);
- $this->updateIndex();
-
- $options = $this->getOptions();
- $options->setDateFields([$date_field]);
- $options->setMinDate(\DateTime::createFromFormat('Y-m-d H:i:s', '2012-12-23 01:01:00'));
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $options);
- $this->assertEquals(0, $results->getTotal());
-
- $options->setMinDate(\DateTime::createFromFormat('Y-m-d H:i:s', '2012-12-20 01:01:00'));
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $options);
- $this->assertEquals(1, $results->getTotal());
- }
-
- private function editDateRecord($date, \record_adapter $record)
- {
- $date_field = null;
-
- foreach ($record->get_databox()->get_meta_structure() as $databox_field) {
- if ($databox_field->get_type() != \databox_field::TYPE_DATE) {
- continue;
- }
-
- $date_field = $databox_field;
-
- break;
- }
-
- if ($date_field) {
-
- $toupdate = [];
-
- try {
- $values = $record->get_caption()->get_field($databox_field->get_name())->get_values();
- $value = array_pop($values);
- $meta_id = $value->getId();
- } catch (\Exception $e) {
- $meta_id = null;
- }
-
- $toupdate[$databox_field->get_id()] = [
- 'meta_id' => $meta_id
- , 'meta_struct_id' => $databox_field->get_id()
- , 'value' => $date
- ];
-
- $record->set_metadatas($toupdate);
- }
-
- return $date_field;
- }
-
- public function testQueryByDateMax()
- {
- $record = self::$DI['record_2'];
- $query_string = 'boomboklot' . $record->get_record_id() . 'dateMax';
-
- $this->editRecord($query_string, $record);
-
- $date_field = $this->editDateRecord('2012-12-21 12:12:00', $record);
-
- if (!$date_field) {
- $this->markTestSkipped('unable to add a date to record');
- }
-
- self::$searchEngine->addRecord($record);
- $this->updateIndex();
-
- $options = $this->getOptions();
- $options->setDateFields([$date_field]);
- $options->setMaxDate(\DateTime::createFromFormat('Y-m-d H:i:s', '2012-12-20 01:01:00'));
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $options);
- $this->assertEquals(0, $results->getTotal());
-
- $options->setMaxDate(\DateTime::createFromFormat('Y-m-d H:i:s', '2012-12-23 01:01:00'));
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $options);
- $this->assertEquals(1, $results->getTotal());
- }
-
- public function testQueryByDateRange()
- {
- $record = self::$DI['record_2'];
- $query_string = 'boomboklot' . $record->get_record_id() . 'dateRange';
-
- $this->editRecord($query_string, $record);
-
- $date_field = $this->editDateRecord('2012-12-21 12:12:00', $record);
-
- if (!$date_field) {
- $this->markTestSkipped('unable to add a date to record');
- }
-
- self::$searchEngine->addRecord($record);
- $this->updateIndex();
-
- $options = $this->getOptions();
- $options->setDateFields([$date_field]);
- $options->setMinDate(\DateTime::createFromFormat('Y-m-d H:i:s', '2012-12-18 01:01:00'));
- $options->setMaxDate(\DateTime::createFromFormat('Y-m-d H:i:s', '2012-12-20 01:01:00'));
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $options);
- $this->assertEquals(0, $results->getTotal());
-
- $options->setMaxDate(\DateTime::createFromFormat('Y-m-d H:i:s', '2012-12-22 01:01:00'));
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $options);
- $this->assertEquals(1, $results->getTotal());
- }
-
- protected function editRecord($string2add, \record_adapter &$record, $indexable = true, $business = false)
- {
- $toupdate = [];
- $field = null;
-
- foreach ($record->get_databox()->get_meta_structure()->get_elements() as $field) {
-
- if ($indexable !== $field->is_indexable() || $field->isBusiness() !== $business) {
- continue;
- }
-
- try {
- $values = $record->get_caption()->get_field($field->get_name())->get_values();
- $value = array_pop($values);
- $meta_id = $value->getId();
- } catch (\Exception $e) {
- $meta_id = null;
- }
-
- $toupdate[$field->get_id()] = [
- 'meta_id' => $meta_id
- , 'meta_struct_id' => $field->get_id()
- , 'value' => $string2add
- ];
- break;
- }
-
- $record->set_metadatas($toupdate);
-
- return $field;
- }
-
- public function testRecordNotIndexed()
- {
- $record = self::$DI['record_2'];
- $query_string = 'boomboklot' . $record->get_record_id() . 'defaultNotIndexed';
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $this->options);
- $this->assertEquals(0, $results->getTotal());
-
- $this->editRecord($query_string, $record);
-
- self::$searchEngine->resetCache();
- $this->updateIndex();
- $results = self::$searchEngine->query($query_string, 0, 1, $this->options);
- $this->assertEquals(1, $results->getTotal());
- }
-
- public function testAddRecord()
- {
- $record = self::$DI['record_2'];
- $query_string = 'boomboklot' . $record->get_record_id() . 'defaultAdd';
-
- $this->editRecord($query_string, $record);
-
- self::$searchEngine->addRecord($record);
- $this->updateIndex();
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $this->options);
- $this->assertEquals(1, $results->getTotal());
- }
-
- public function testUpdateRecord()
- {
- $record = self::$DI['record_2'];
-
- self::$searchEngine->addRecord($record);
- $this->updateIndex();
-
- $query_string = 'boomboklot' . $record->get_record_id() . 'updateRecord';
-
- $this->editRecord($query_string, $record);
-
- self::$searchEngine->updateRecord($record);
- $this->updateIndex();
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $this->options);
- $this->assertEquals(1, $results->getTotal());
- }
-
- protected function getDefaultOptions()
- {
- $appbox = self::$DI['app']['phraseanet.appbox'];
- foreach ($appbox->get_databoxes() as $databox) {
- break;
- }
- $options = new SearchEngineOptions();
- $options->onCollections($databox->get_collections());
-
- return $options;
- }
-
- /**
- * @dataProvider provideStemmData
- */
- public function testUpdateRecordWithStemm($language, $word, $stemm)
- {
- if (!self::$searchEngine->hasStemming()) {
- $this->markTestSkipped(sprintf(
- '%s does not support stemm, passing stemmatization for language %s',
- get_class(self::$searchEngine),
- $language
- ));
- }
-
- $options = $this->getDefaultOptions();
- $options->setStemming(true);
- $options->setLocale($language);
-
- $record = self::$DI['record_2'];
- $index_string = sprintf(
- 'boomboklot%dstemmed%s %s',
- $record->get_record_id(),
- $language,
- $word
- );
- $query_string = sprintf(
- 'boomboklot%dstemmed%s %s',
- $record->get_record_id(),
- $language,
- $stemm
- );
-
- $this->editRecord($index_string, $record);
-
- self::$searchEngine->addRecord($record);
- $this->updateIndex([$language]);
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $options);
- $this->assertEquals(1, $results->getTotal());
- }
-
- public function provideStemmData()
- {
- $stemms = [];
-
- $examples = [
- 'fr' => ['word' => 'chevaux', 'stemm' => 'cheval'],
- 'en' => ['word' => 'consistency', 'stemm' => 'consistent'],
- 'de' => ['word' => 'aufeinanderfolgender', 'stemm' => 'aufeinanderfolg'],
- 'nl' => ['word' => 'lichamelijk', 'stemm' => 'licham'],
- ];
-
- foreach (Application::getAvailableLanguages() as $languageCode => $name) {
- $data = explode('_', $languageCode);
- $code = $data[0];
-
- if (!isset($examples[$code])) {
- $this->fail(sprintf('Missing stemm examples for language %s', $code));
- }
-
- $stemms[] = [
- $code,
- $examples[$code]['word'],
- $examples[$code]['stemm'],
- ];
- }
-
- return $stemms;
- }
-
- public function testUpdateQueryOnField()
- {
- $options = $this->getDefaultOptions();
- $record = self::$DI['record_2'];
-
- $query_string = 'boomboklot' . $record->get_record_id() . 'onfield';
-
- $field = $this->editRecord($query_string, $record);
- $options->setFields([$field]);
-
- self::$searchEngine->addRecord($record);
- $this->updateIndex();
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $options);
- $this->assertEquals(1, $results->getTotal());
- }
-
- public function testBusinessFieldAvailable()
- {
- $options = $this->getDefaultOptions();
- $record = self::$DI['record_2'];
-
- $query_string = 'boomboklot' . $record->get_record_id() . 'businessAvailable';
-
- $this->editRecord($query_string, $record, true, true);
- $options->allowBusinessFieldsOn([$record->get_collection()]);
-
- self::$searchEngine->addRecord($record);
- $this->updateIndex();
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $options);
- $this->assertEquals(1, $results->getTotal());
- }
-
- public function testBusinessFieldNotAvailable()
- {
- $record = self::$DI['record_2'];
- $query_string = 'boomboklot' . $record->get_record_id() . 'businessNotAvailable';
-
- $this->editRecord($query_string, $record, true, true);
-
- self::$searchEngine->addRecord($record);
- $this->updateIndex();
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $this->options);
- $this->assertEquals(0, $results->getTotal());
- }
-
- public function testUpdateQueryOnEmptyField()
- {
- $options = $this->getDefaultOptions();
-
- $record = self::$DI['record_2'];
- $query_string = 'boomboklot' . $record->get_record_id() . 'anotherfield';
-
- $selectedField = $this->editRecord($query_string, $record);
-
- foreach ($record->get_databox()->get_meta_structure()->get_elements() as $field) {
- if ($selectedField->get_id() != $field->get_id()) {
- $options->setFields([$field]);
-
- break;
- }
- }
-
- self::$searchEngine->addRecord($record);
- $this->updateIndex();
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $options);
- $this->assertEquals(0, $results->getTotal());
- }
-
- public function testUpdateNonIndexableRecord()
- {
- $record = self::$DI['record_2'];
- $query_string = 'boomboklot_no_index_' . $record->get_record_id() . '_';
-
- $field = $this->editRecord($query_string, $record, false);
- if (!$field) {
- $this->markTestSkipped('No non-indexable field found');
- }
-
- self::$searchEngine->addRecord($record);
- $this->updateIndex();
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $this->options);
- $this->assertEquals(0, $results->getTotal());
- }
-
- public function testDeleteRecord()
- {
- $record = self::$DI['record_2'];
- $query_string = 'boomboklot' . $record->get_record_id() . 'deleteRecord';
-
- $field = $this->editRecord($query_string, $record);
-
- self::$searchEngine->addRecord($record);
- $this->updateIndex();
- self::$searchEngine->removeRecord($record);
- $this->updateIndex();
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $this->options);
- $this->assertEquals(0, $results->getTotal());
-
- $options = $this->getDefaultOptions();
- $options->setFields([$field]);
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $options);
- $this->assertEquals(0, $results->getTotal());
- }
-
- /**
- * @dataProvider provideStemmData
- */
- public function testDeleteRecordWithinStemmContext($language, $word, $stemm)
- {
- $record = self::$DI['record_2'];
- $index_string = 'boomboklot' . $record->get_record_id() . 'deleteRecordInStemmContext '.$word;
- $query_string = 'boomboklot' . $record->get_record_id() . 'deleteRecordInStemmContext '.$stemm;
-
- $options = $this->getDefaultOptions();
- $options->setStemming(true);
- $options->setLocale($language);
-
- $field = $this->editRecord($index_string, $record);
-
- self::$searchEngine->addRecord($record);
- $this->updateIndex();
- self::$searchEngine->removeRecord($record);
- $this->updateIndex();
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $options);
- $this->assertEquals(0, $results->getTotal());
-
- $options->setFields([$field]);
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $options);
- $this->assertEquals(0, $results->getTotal());
- }
-
- public function testAvailableTypes()
- {
- $this->assertTrue(is_array(self::$searchEngine->getAvailableTypes()));
- foreach (self::$searchEngine->getAvailableTypes() as $type) {
- $this->assertTrue(in_array($type, [SearchEngineInterface::GEM_TYPE_ENTRY, SearchEngineInterface::GEM_TYPE_RECORD, SearchEngineInterface::GEM_TYPE_STORY]));
- }
- }
-
- public function testStatus()
- {
- foreach (self::$searchEngine->getStatus() as $StatusKeyValue) {
- $this->assertTrue(is_array($StatusKeyValue));
- $this->assertTrue(is_scalar($StatusKeyValue[0]));
- $this->assertTrue(is_scalar($StatusKeyValue[1]));
- }
- }
-
- public function testAddStory()
- {
- $story = self::$DI['record_story_1'];
- $query_string = 'story' . $story->get_record_id() . 'addStory';
-
- $options = $this->getDefaultOptions();
- $options->setSearchType(SearchEngineOptions::RECORD_GROUPING);
-
- $this->editRecord($query_string, $story);
-
- self::$searchEngine->addStory($story);
- $this->updateIndex();
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $options);
- $this->assertEquals(1, $results->getTotal());
- }
-
- public function testUpdateStory()
- {
- $story = self::$DI['record_story_1'];
-
- $options = $this->getDefaultOptions();
- $options->setSearchType(SearchEngineOptions::RECORD_GROUPING);
-
- self::$searchEngine->addStory($story);
- $this->updateIndex();
-
- $query_string = 'story' . $story->get_record_id() . 'updateStory';
- $this->editRecord($query_string, $story);
-
- self::$searchEngine->updateStory($story);
- $this->updateIndex();
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $options);
- $this->assertEquals(1, $results->getTotal());
- }
-
- public function testStatusQueryOnOverOff()
- {
- $options = $this->getDefaultOptions();
- $record = self::$DI['record_2'];
- $record->set_binary_status('00000');
-
- $query_string = 'boomboklot' . $record->get_record_id() . 'statusQueryOff';
- $this->editRecord($query_string, $record);
-
- self::$searchEngine->addRecord($record);
- $this->updateIndex();
-
- $options->setStatus([4 => ['on' => [$record->get_databox()->get_sbas_id()]]]);
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $options);
- $this->assertEquals(0, $results->getTotal());
- }
-
- public function testStatusQueryOnOverOn()
- {
- $options = $this->getDefaultOptions();
-
- $record = self::$DI['record_2'];
- $record->set_binary_status('10000');
-
- $options->setStatus([4 => ['on' => [$record->get_databox()->get_sbas_id()]]]);
-
- $query_string = 'boomboklot' . $record->get_record_id() . 'statusQueryOnOverOn';
- $this->editRecord($query_string, $record);
-
- self::$searchEngine->addRecord($record);
- $this->updateIndex();
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $options);
- $this->assertEquals(1, $results->getTotal());
- }
-
- public function testStatusQueryOffOverOn()
- {
- $options = $this->getDefaultOptions();
-
- $record = self::$DI['record_2'];
- $record->set_binary_status('10000');
-
- $options->setStatus([4 => ['off' => [$record->get_databox()->get_sbas_id()]]]);
-
- $query_string = 'boomboklot' . $record->get_record_id() . 'statusQueryOff';
- $this->editRecord($query_string, $record);
-
- self::$searchEngine->addRecord($record);
- $this->updateIndex();
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $options);
- $this->assertEquals(0, $results->getTotal());
- }
-
- public function testStatusQueryOffOverOff()
- {
- $options = $this->getDefaultOptions();
-
- $record = self::$DI['record_2'];
- $record->set_binary_status('00000');
-
- $options->setStatus([4 => ['off' => [$record->get_databox()->get_sbas_id()]]]);
-
- $query_string = 'boomboklot' . $record->get_record_id() . 'statusQueryOff';
- $this->editRecord($query_string, $record);
-
- self::$searchEngine->addRecord($record);
- $this->updateIndex();
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $options);
- $this->assertEquals(1, $results->getTotal());
- }
-
- public function testStatusQueryUpdate()
- {
- $options = $this->getDefaultOptions();
- $record = self::$DI['record_2'];
- $record->set_binary_status('00000');
-
- $query_string = 'boomboklot' . $record->get_record_id() . 'statusQueryUpdate';
- $this->editRecord($query_string, $record);
-
- self::$searchEngine->addRecord($record);
- $this->updateIndex();
-
- $options->setStatus([4 => ['on' => [$record->get_databox()->get_sbas_id()]]]);
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $options);
- $this->assertEquals(0, $results->getTotal());
-
- $record->set_binary_status('10000');
-
- self::$searchEngine->updateRecord($record);
- $this->updateIndex();
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $this->options);
- $this->assertEquals(1, $results->getTotal());
- }
-
- public function testExcerptFromSimpleQuery()
- {
- $record = self::$DI['record_2'];
- $query_string = 'boomboklot' . $record->get_record_id() . 'excerptSimpleQuery';
-
- $this->editRecord($query_string, $record);
-
- self::$searchEngine->addRecord($record);
- $this->updateIndex();
-
- self::$searchEngine->resetCache();
- $results = self::$searchEngine->query($query_string, 0, 1, $this->options);
- $fields = [];
- $foundRecord = $results->getResults()->first();
-
- $this->assertInstanceOf('\record_adapter', $foundRecord);
-
- foreach ($foundRecord->get_caption()->get_fields() as $field) {
- foreach ($field->get_values() as $metaId => $v) {
- $values[$metaId] = [
- 'value' => $v->getValue(),
- 'from_thesaurus' => false,
- 'qjs' => null,
- ];
- }
-
- $fields[$field->get_name()] = [
- 'values' => $values,
- 'separator' => ';',
- ];
- }
-
- $found = false;
- $highlightedValues = self::$searchEngine->excerpt($query_string, $fields, $foundRecord);
- foreach ($highlightedValues as $fieldValues) {
- foreach ($fieldValues as $metaId => $field) {
- if (strpos($field, '[[em]]') !== false && strpos($field, '[[/em]]') !== false) {
- $found = true;
- break 2;
- }
- }
- }
-
- if (!$found && count($highlightedValues) > 0) {
- $this->fail('Unable to build the excerpt');
- }
- }
-
- public function testCreateSubscriber()
- {
- $classname = self::$searchEngineClass;
- //$this->assertInstanceOf('Symfony\Component\EventDispatcher\EventSubscriberInterface', $classname::createSubscriber(self::$DI['app']));
- }
-
- abstract public function initialize();
-
- abstract public function testAutocomplete();
-
- abstract protected function updateIndex(array $stemms = []);
-}
diff --git a/tests/Alchemy/Tests/Phrasea/SearchEngine/SearchEngineOptionsTest.php b/tests/Alchemy/Tests/Phrasea/SearchEngine/SearchEngineOptionsTest.php
index 3276d1ed99..ef9e66cf31 100644
--- a/tests/Alchemy/Tests/Phrasea/SearchEngine/SearchEngineOptionsTest.php
+++ b/tests/Alchemy/Tests/Phrasea/SearchEngine/SearchEngineOptionsTest.php
@@ -38,6 +38,8 @@ class SearchEngineOptionsTest extends \PhraseanetTestCase
$options->setMinDate(\DateTime::createFromFormat(DATE_ATOM, $min_date->format(DATE_ATOM)));
$options->setMaxDate(\DateTime::createFromFormat(DATE_ATOM, $max_date->format(DATE_ATOM)));
+ $options->setFirstResult(3);
+ $options->setMaxResults(42);
$serialized = $options->serialize();
diff --git a/tests/Alchemy/Tests/Phrasea/Vocabulary/ControlProvider/UserProviderTest.php b/tests/Alchemy/Tests/Phrasea/Vocabulary/ControlProvider/UserProviderTest.php
index 6dd28f28c8..0940636d44 100644
--- a/tests/Alchemy/Tests/Phrasea/Vocabulary/ControlProvider/UserProviderTest.php
+++ b/tests/Alchemy/Tests/Phrasea/Vocabulary/ControlProvider/UserProviderTest.php
@@ -3,7 +3,6 @@
namespace Alchemy\Tests\Phrasea\Vocabulary\ControlProvider;
use Alchemy\Phrasea\Vocabulary\ControlProvider\UserProvider;
-use Doctrine\ORM\EntityManager;
/**
* @group functional
@@ -63,22 +62,22 @@ class UserProviderTest extends \PhraseanetTestCase
$results = $this->object->find('BABE', $user, self::$DI['collection']->get_databox());
- $this->assertInstanceOf('\\Doctrine\\Common\\Collections\\ArrayCollection', $results);
+ $this->assertInternalType('array', $results);
$results = $this->object->find($user->getEmail(), $user, self::$DI['collection']->get_databox());
- $this->assertInstanceOf('\\Doctrine\\Common\\Collections\\ArrayCollection', $results);
- $this->assertTrue($results->count() > 0);
+ $this->assertInternalType('array', $results);
+ $this->assertGreaterThan(0, count($results), 'There should be more users matching');
$results = $this->object->find($user->getFirstName(), $user, self::$DI['collection']->get_databox());
- $this->assertInstanceOf('\\Doctrine\\Common\\Collections\\ArrayCollection', $results);
- $this->assertTrue($results->count() > 0);
+ $this->assertInternalType('array', $results);
+ $this->assertGreaterThan(0, count($results), 'There should be more users matching');
$results = $this->object->find($user->getLastName(), $user, self::$DI['collection']->get_databox());
- $this->assertInstanceOf('\\Doctrine\\Common\\Collections\\ArrayCollection', $results);
- $this->assertTrue($results->count() > 0);
+ $this->assertInternalType('array', $results);
+ $this->assertGreaterThan(0, count($results), 'There should be more users matching');
self::$DI['app']['manipulator.user']->delete($user);
}
diff --git a/tests/Alchemy/Tests/Phrasea/Vocabulary/ControllerTest.php b/tests/Alchemy/Tests/Phrasea/Vocabulary/ControllerTest.php
deleted file mode 100644
index 83c0bc16c0..0000000000
--- a/tests/Alchemy/Tests/Phrasea/Vocabulary/ControllerTest.php
+++ /dev/null
@@ -1,38 +0,0 @@
-assertInstanceOf('\\Alchemy\\Phrasea\\Vocabulary\\ControlProvider\\UserProvider', $provider);
-
- try {
- $provider = Controller::get(self::$DI['app'], 'Zebulon');
- $this->fail('Should raise an exception');
- } catch (\Exception $e) {
-
- }
- }
-
- public function testGetAvailable()
- {
- $available = Controller::getAvailable(self::$DI['app']);
-
- $this->assertTrue(is_array($available));
-
- foreach ($available as $controller) {
- $this->assertInstanceOf('\\Alchemy\\Phrasea\\Vocabulary\\ControlProvider\\ControlProviderInterface', $controller);
- }
- }
-}
diff --git a/tests/classes/ACLTest.php b/tests/classes/ACLTest.php
index e259569347..11ee12c1eb 100644
--- a/tests/classes/ACLTest.php
+++ b/tests/classes/ACLTest.php
@@ -29,22 +29,30 @@ class ACLTest extends \PhraseanetTestCase
$this->assertTrue($this->object->has_status_access_to_record(self::$DI['record_1']));
}
- public function testHasAccesToRecordStatus()
+ public function testHasAccessToRecordStatus()
{
- self::$DI['record_1']->set_binary_status(str_repeat('0', 32));
- $this->object->set_masks_on_base(self::$DI['record_1']->get_base_id(), '10000', '10000', '0', '0');
- self::$DI['record_1']->set_binary_status('10000');
- $this->assertFalse($this->object->has_status_access_to_record(self::$DI['record_1']));
- self::$DI['record_1']->set_binary_status('00000');
- $this->assertTrue($this->object->has_status_access_to_record(self::$DI['record_1']));
- $this->object->set_masks_on_base(self::$DI['record_1']->get_base_id(), '10000', '10000', '10000', '10000');
- $this->assertFalse($this->object->has_status_access_to_record(self::$DI['record_1']));
- self::$DI['record_1']->set_binary_status('10000');
- $this->assertTrue($this->object->has_status_access_to_record(self::$DI['record_1']));
- $this->object->set_masks_on_base(self::$DI['record_1']->get_base_id(), '0', '0', '0', '0');
- $this->assertTrue($this->object->has_status_access_to_record(self::$DI['record_1']));
- self::$DI['record_1']->set_binary_status(str_repeat('0', 32));
- $this->assertTrue($this->object->has_status_access_to_record(self::$DI['record_1']));
+ $record1 = $this->getRecord1();
+
+ $record1->setStatus(str_repeat('0', 32));
+ $this->object->set_masks_on_base($record1->getBaseId(), '10000', '10000', '0', '0');
+
+ $record1->setStatus('10000');
+ $this->assertFalse($this->object->has_status_access_to_record($record1));
+
+ $record1->setStatus('00000');
+ $this->assertTrue($this->object->has_status_access_to_record($record1));
+
+ $this->object->set_masks_on_base($record1->getBaseId(), '10000', '10000', '10000', '10000');
+ $this->assertFalse($this->object->has_status_access_to_record($record1));
+
+ $record1->setStatus('10000');
+ $this->assertTrue($this->object->has_status_access_to_record($record1));
+
+ $this->object->set_masks_on_base($record1->getBaseId(), '0', '0', '0', '0');
+ $this->assertTrue($this->object->has_status_access_to_record($record1));
+
+ $record1->setStatus(str_repeat('0', 32));
+ $this->assertTrue($this->object->has_status_access_to_record($record1));
}
public function testHasAccesToRecordFailsOnBase()
diff --git a/tests/classes/Bridge/ElementTest.php b/tests/classes/Bridge/ElementTest.php
index 84644a8143..bb8fef2032 100644
--- a/tests/classes/Bridge/ElementTest.php
+++ b/tests/classes/Bridge/ElementTest.php
@@ -70,8 +70,8 @@ class Bridge_ElementTest extends \PhraseanetTestCase
public function testGet_record()
{
$this->assertInstanceOf('record_adapter', $this->object->get_record());
- $this->assertEquals(self::$DI['record_1']->get_sbas_id(), $this->object->get_record()->get_sbas_id());
- $this->assertEquals(self::$DI['record_1']->get_record_id(), $this->object->get_record()->get_record_id());
+ $this->assertEquals(self::$DI['record_1']->get_sbas_id(), $this->object->get_record()->getDataboxId());
+ $this->assertEquals(self::$DI['record_1']->get_record_id(), $this->object->get_record()->getRecordId());
}
public function testGet_dist_id()
diff --git a/tests/classes/PhraseanetAuthenticatedWebTestCase.php b/tests/classes/PhraseanetAuthenticatedWebTestCase.php
index ed839881ba..e5d002f164 100644
--- a/tests/classes/PhraseanetAuthenticatedWebTestCase.php
+++ b/tests/classes/PhraseanetAuthenticatedWebTestCase.php
@@ -66,7 +66,7 @@ abstract class PhraseanetAuthenticatedWebTestCase extends \PhraseanetAuthenticat
'is_admin' => $returnBool,
'give_access_to_sbas' => $returnSelf,
'update_rights_to_sbas' => $returnSelf,
- 'update_rights_to_bas' => $returnSelf,
+ 'update_rights_to_base' => $returnSelf,
'has_right_on_base' => $returnBool,
'has_right_on_sbas' => $returnBool,
'has_access_to_sbas' => $returnBool,
@@ -202,8 +202,8 @@ abstract class PhraseanetAuthenticatedWebTestCase extends \PhraseanetAuthenticat
$app = $this->getApplication();
$elasticsearchRecord = new ElasticsearchRecord();
- $elasticsearchRecord->setDataboxId($record->get_sbas_id());
- $elasticsearchRecord->setRecordId($record->get_record_id());
+ $elasticsearchRecord->setDataboxId($record->getDataboxId());
+ $elasticsearchRecord->setRecordId($record->getRecordId());
$result = new SearchEngineResult(
new SearchEngineOptions(),
@@ -221,10 +221,8 @@ abstract class PhraseanetAuthenticatedWebTestCase extends \PhraseanetAuthenticat
);
$searchEngine = $this->prophesize(SearchEngineInterface::class);
- $searchEngine->query('', 0, Argument::any(), Argument::any())
+ $searchEngine->query('', Argument::any())
->willReturn($result);
- $searchEngine->excerpt(Argument::any(), Argument::any(), Argument::any(), Argument::any())
- ->willReturn([]);
$app['search_engine'] = $searchEngine->reveal();
return $app;
diff --git a/tests/classes/PhraseanetTestCase.php b/tests/classes/PhraseanetTestCase.php
index 32440a1549..8ae9183b8e 100644
--- a/tests/classes/PhraseanetTestCase.php
+++ b/tests/classes/PhraseanetTestCase.php
@@ -234,7 +234,7 @@ abstract class PhraseanetTestCase extends WebTestCase
$file = new File(self::$DI['app'], self::$DI['app']['mediavorus']->guess(__DIR__ . '/../files/cestlafete.jpg'), self::$DI['collection_no_access']);
$record = record_adapter::createFromFile($file, self::$DI['app']);
self::$DI['app']['subdef.generator']->generateSubdefs($record);
- self::$fixtureIds['records'][$id] = $record->get_record_id();
+ self::$fixtureIds['records'][$id] = $record->getRecordId();
return self::$fixtureIds['records'][$id];
});
@@ -250,7 +250,7 @@ abstract class PhraseanetTestCase extends WebTestCase
$file = new File(self::$DI['app'], self::$DI['app']['mediavorus']->guess(__DIR__ . '/../files/cestlafete.jpg'), self::$DI['collection_no_access_by_status']);
$record = record_adapter::createFromFile($file, self::$DI['app']);
self::$DI['app']['subdef.generator']->generateSubdefs($record);
- self::$fixtureIds['records'][$id] = $record->get_record_id();
+ self::$fixtureIds['records'][$id] = $record->getRecordId();
return self::$fixtureIds['records'][$id];
});
@@ -790,9 +790,6 @@ abstract class PhraseanetTestCase extends WebTestCase
protected function createSearchEngineMock()
{
$mock = $this->getMock(SearchEngineInterface::class);
- $mock->expects($this->any())
- ->method('createSubscriber')
- ->will($this->returnValue($this->getMock('Symfony\Component\EventDispatcher\EventSubscriberInterface')));
$mock->expects($this->any())
->method('getStatus')
->will($this->returnValue([]));
diff --git a/tests/classes/media/subdefTest.php b/tests/classes/media/subdefTest.php
index c489f103a8..f097da6a7b 100644
--- a/tests/classes/media/subdefTest.php
+++ b/tests/classes/media/subdefTest.php
@@ -28,13 +28,14 @@ class media_subdefTest extends \PhraseanetTestCase
parent::setUp();
if (null === self::$recordonbleu) {
- $file = new File(self::$DI['app'], self::$DI['app']['mediavorus']->guess(__DIR__ . "/../../files/iphone_pic.jpg"), self::$DI['collection']);
+ $app = $this->getApplication();
+ $file = new File($app, $app['mediavorus']->guess(__DIR__ . "/../../files/iphone_pic.jpg"), self::$DI['collection']);
- self::$recordonbleu = record_adapter::createFromFile($file, self::$DI['app']);
- self::$DI['app']['subdef.generator']->generateSubdefs(self::$recordonbleu);
+ self::$recordonbleu = record_adapter::createFromFile($file, $app);
+ $app['subdef.generator']->generateSubdefs(self::$recordonbleu);
foreach (self::$recordonbleu->get_subdefs() as $subdef) {
- if ($subdef->get_name() == 'document') {
+ if (!in_array($subdef->get_name(), ['thumbnail', 'preview'], true)) {
continue;
}
@@ -80,10 +81,10 @@ class media_subdefTest extends \PhraseanetTestCase
*/
public function testGet_record()
{
- $this->assertEquals(self::$recordonbleu->get_record_id(), self::$objectNotPresent->get_record()->get_record_id());
- $this->assertEquals(self::$recordonbleu->get_record_id(), self::$objectPresent->get_record()->get_record_id());
- $this->assertEquals(self::$recordonbleu->get_sbas_id(), self::$objectNotPresent->get_record()->get_sbas_id());
- $this->assertEquals(self::$recordonbleu->get_sbas_id(), self::$objectPresent->get_record()->get_sbas_id());
+ $this->assertEquals(self::$recordonbleu->getRecordId(), self::$objectNotPresent->get_record()->getRecordId());
+ $this->assertEquals(self::$recordonbleu->getRecordId(), self::$objectPresent->get_record()->getRecordId());
+ $this->assertEquals(self::$recordonbleu->getDataboxId(), self::$objectNotPresent->get_record()->getDataboxId());
+ $this->assertEquals(self::$recordonbleu->getDataboxId(), self::$objectPresent->get_record()->getDataboxId());
}
/**
@@ -111,8 +112,8 @@ class media_subdefTest extends \PhraseanetTestCase
*/
public function testGet_record_id()
{
- $this->assertEquals(self::$recordonbleu->get_record_id(), self::$objectNotPresent->get_record()->get_record_id());
- $this->assertEquals(self::$recordonbleu->get_record_id(), self::$objectPresent->get_record()->get_record_id());
+ $this->assertEquals(self::$recordonbleu->getRecordId(), self::$objectNotPresent->get_record()->getRecordId());
+ $this->assertEquals(self::$recordonbleu->getRecordId(), self::$objectPresent->get_record()->getRecordId());
}
/**
@@ -140,8 +141,8 @@ class media_subdefTest extends \PhraseanetTestCase
*/
public function testGet_sbas_id()
{
- $this->assertEquals(self::$recordonbleu->get_sbas_id(), self::$objectNotPresent->get_record()->get_sbas_id());
- $this->assertEquals(self::$recordonbleu->get_sbas_id(), self::$objectPresent->get_record()->get_sbas_id());
+ $this->assertEquals(self::$recordonbleu->getDataboxId(), self::$objectNotPresent->get_record()->getDataboxId());
+ $this->assertEquals(self::$recordonbleu->getDataboxId(), self::$objectPresent->get_record()->getDataboxId());
}
/**
diff --git a/tests/classes/record/adapterTest.php b/tests/classes/record/adapterTest.php
index 9728cb7da0..c0eafba115 100644
--- a/tests/classes/record/adapterTest.php
+++ b/tests/classes/record/adapterTest.php
@@ -21,7 +21,7 @@ class record_adapterTest extends \PhraseanetAuthenticatedTestCase
// Reset thumbtitle in order to have consistent tests (testGet_title)
if (!self::$thumbtitled) {
- foreach ($this->getRecord1()->get_databox()->get_meta_structure() as $databox_field) {
+ foreach ($this->getRecord1()->getDatabox()->get_meta_structure() as $databox_field) {
$databox_field->set_thumbtitle(false)->save();
}
self::$thumbtitled = true;
@@ -86,7 +86,7 @@ class record_adapterTest extends \PhraseanetAuthenticatedTestCase
$this->getClient()->request(
'POST', $app['url_generator']->generate('prod_order_new'), [
- 'lst' => $this->getRecord1()->get_serialize_key(),
+ 'lst' => $this->getRecord1()->getId(),
'deadline' => '+10 minutes'
]);
@@ -137,16 +137,16 @@ class record_adapterTest extends \PhraseanetAuthenticatedTestCase
{
$record_1 = $this->getRecord1();
try {
- $record_1->set_type('jambon');
+ $record_1->setType('jambon');
$this->fail();
} catch (Exception $e) {
}
- $old_type = $record_1->get_type();
- $record_1->set_type('video');
- $this->assertEquals('video', $record_1->get_type());
- $record_1->set_type($old_type);
- $this->assertEquals($old_type, $record_1->get_type());
+ $old_type = $record_1->getType();
+ $record_1->setType('video');
+ $this->assertEquals('video', $record_1->getType());
+ $record_1->setType($old_type);
+ $this->assertEquals($old_type, $record_1->getType());
}
public function testIs_grouping()
@@ -158,17 +158,17 @@ class record_adapterTest extends \PhraseanetAuthenticatedTestCase
public function testGet_base_id()
{
$record_1 = $this->getRecord1();
- $this->assertTrue(is_int($record_1->get_base_id()));
- $this->assertEquals($this->getCollection()->get_base_id(), $record_1->get_base_id());
+ $this->assertTrue(is_int($record_1->getBaseId()));
+ $this->assertEquals($this->getCollection()->get_base_id(), $record_1->getBaseId());
$record_story_1 = $this->getRecordStory1();
- $this->assertTrue(is_int($record_story_1->get_base_id()));
- $this->assertEquals($this->getCollection()->get_base_id(), $record_story_1->get_base_id());
+ $this->assertTrue(is_int($record_story_1->getBaseId()));
+ $this->assertEquals($this->getCollection()->get_base_id(), $record_story_1->getBaseId());
}
public function testGet_record_id()
{
- $this->assertTrue(is_int($this->getRecord1()->get_record_id()));
- $this->assertTrue(is_int($this->getRecordStory1()->get_record_id()));
+ $this->assertTrue(is_int($this->getRecord1()->getRecordId()));
+ $this->assertTrue(is_int($this->getRecordStory1()->getRecordId()));
}
public function testGet_thumbnail()
@@ -187,7 +187,7 @@ class record_adapterTest extends \PhraseanetAuthenticatedTestCase
public function testGet_type()
{
- $this->assertTrue(in_array($this->getRecord1()->get_type(), ['video', 'audio', 'image', 'document', 'flash', 'unknown']));
+ $this->assertTrue(in_array($this->getRecord1()->getType(), ['video', 'audio', 'image', 'document', 'flash', 'unknown']));
}
public function testGet_formatted_duration()
@@ -208,31 +208,31 @@ class record_adapterTest extends \PhraseanetAuthenticatedTestCase
public function testGet_sha256()
{
$record_1 = $this->getRecord1();
- $this->assertNotNull($record_1->get_sha256());
- $this->assertRegExp('/[a-zA-Z0-9]{32}/', $record_1->get_sha256());
- $this->assertNull($this->getRecordStory1()->get_sha256());
+ $this->assertNotNull($record_1->getSha256());
+ $this->assertRegExp('/[a-zA-Z0-9]{32}/', $record_1->getSha256());
+ $this->assertNull($this->getRecordStory1()->getSha256());
}
public function testGet_mime()
{
- $this->assertRegExp('/image\/\w+/', $this->getRecord1()->get_mime());
+ $this->assertRegExp('/image\/\w+/', $this->getRecord1()->getMimeType());
}
public function testSetMimeType()
{
$record_1 = $this->getRecord1();
- $oldMime = $record_1->get_mime();
- $record_1->set_mime('foo/bar');
- $this->assertEquals('foo/bar', $record_1->get_mime());
+ $oldMime = $record_1->getMimeType();
+ $record_1->setMimeType('foo/bar');
+ $this->assertEquals('foo/bar', $record_1->getMimeType());
- $record_1->set_mime($oldMime);
- $this->assertEquals($oldMime, $record_1->get_mime());
+ $record_1->setMimeType($oldMime);
+ $this->assertEquals($oldMime, $record_1->getMimeType());
}
public function testGet_status()
{
- $this->assertRegExp('/[01]{32}/', $this->getRecord1()->get_status());
+ $this->assertRegExp('/[01]{32}/', $this->getRecord1()->getStatus());
}
public function testGet_subdef()
@@ -307,12 +307,12 @@ class record_adapterTest extends \PhraseanetAuthenticatedTestCase
public function testGet_serialize_key()
{
$record_1 = $this->getRecord1();
- $this->assertTrue($record_1->get_serialize_key() == $record_1->get_sbas_id() . '_' . $record_1->get_record_id());
+ $this->assertTrue($record_1->getId() == $record_1->getDataboxId() . '_' . $record_1->getRecordId());
}
public function testGet_sbas_id()
{
- $this->assertTrue(is_int($this->getRecord1()->get_sbas_id()));
+ $this->assertTrue(is_int($this->getRecord1()->getDataboxId()));
}
public function testSet_metadatas()
@@ -431,15 +431,15 @@ class record_adapterTest extends \PhraseanetAuthenticatedTestCase
FROM record
WHERE jeton & ' . JETON_MAKE_SUBDEF . ' > 0
AND record_id = :record_id';
- $stmt = $record_1->get_databox()->get_connection()->prepare($sql);
+ $stmt = $record_1->getDatabox()->get_connection()->prepare($sql);
- $stmt->execute([':record_id' => $record_1->get_record_id()]);
+ $stmt->execute([':record_id' => $record_1->getRecordId()]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if ( ! $row)
$this->fail();
- if ($row['record_id'] != $record_1->get_record_id())
+ if ($row['record_id'] != $record_1->getRecordId())
$this->fail();
}
@@ -450,15 +450,15 @@ class record_adapterTest extends \PhraseanetAuthenticatedTestCase
$sql = 'SELECT record_id, coll_id, jeton
FROM record WHERE (jeton & ' . JETON_WRITE_META . ' > 0)
AND record_id = :record_id';
- $stmt = $record_1->get_databox()->get_connection()->prepare($sql);
+ $stmt = $record_1->getDatabox()->get_connection()->prepare($sql);
- $stmt->execute([':record_id' => $record_1->get_record_id()]);
+ $stmt->execute([':record_id' => $record_1->getRecordId()]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if ( ! $row)
$this->fail();
- if ($row['record_id'] != $record_1->get_record_id())
+ if ($row['record_id'] != $record_1->getRecordId())
$this->fail();
}
@@ -474,34 +474,34 @@ class record_adapterTest extends \PhraseanetAuthenticatedTestCase
}
$record_1 = $this->getRecord1();
- $record_1->set_binary_status($status);
+ $record_1->setStatus($status);
- $this->assertEquals($status, $record_1->get_status());
+ $this->assertEquals($status, $record_1->getStatus());
}
public function testGet_record_by_sha()
{
$record_1 = $this->getRecord1();
- $tmp_records = record_adapter::get_record_by_sha($record_1->getDatabox(), $record_1->get_sha256());
+ $tmp_records = record_adapter::get_record_by_sha($record_1->getDatabox(), $record_1->getSha256());
$this->assertTrue(is_array($tmp_records));
foreach ($tmp_records as $tmp_record) {
$this->assertInstanceOf('record_adapter', $tmp_record);
- $this->assertEquals($record_1->get_sha256(), $tmp_record->get_sha256());
+ $this->assertEquals($record_1->getSha256(), $tmp_record->getSha256());
}
$tmp_records = record_adapter::get_record_by_sha(
$record_1->getDatabox(),
- $record_1->get_sha256(),
- $record_1->get_record_id()
+ $record_1->getSha256(),
+ $record_1->getRecordId()
);
$this->assertTrue(is_array($tmp_records));
$this->assertTrue(count($tmp_records) === 1);
foreach ($tmp_records as $tmp_record) {
$this->assertInstanceOf('record_adapter', $tmp_record);
- $this->assertEquals($record_1->get_sha256(), $tmp_record->get_sha256());
- $this->assertEquals($record_1->get_record_id(), $tmp_record->get_record_id());
+ $this->assertEquals($record_1->getSha256(), $tmp_record->getSha256());
+ $this->assertEquals($record_1->getRecordId(), $tmp_record->getRecordId());
}
}
@@ -518,8 +518,8 @@ class record_adapterTest extends \PhraseanetAuthenticatedTestCase
$found = $sselcont_id = false;
$record_1 = $this->getRecord1();
- $sbas_id = $record_1->get_sbas_id();
- $record_id = $record_1->get_record_id();
+ $sbas_id = $record_1->getDataboxId();
+ $record_id = $record_1->getRecordId();
foreach ($record_1->get_container_baskets($app['orm.em'], self::$DI['user']) as $c_basket) {
if ($c_basket->getId() == $basket->getId()) {
@@ -538,8 +538,8 @@ class record_adapterTest extends \PhraseanetAuthenticatedTestCase
public function testSetStatus()
{
$record_1 = $this->getRecord1();
- $record = new \record_adapter($this->getApplication(), $record_1->get_sbas_id(), $record_1->get_record_id());
- $record->set_binary_status('1001001001010101');
- $this->assertSame('00000000000000001001001001010101', $record->get_status());
+ $record = new \record_adapter($this->getApplication(), $record_1->getDataboxId(), $record_1->getRecordId());
+ $record->setStatus('1001001001010101');
+ $this->assertSame('00000000000000001001001001010101', $record->getStatus());
}
}
diff --git a/tests/classes/recordutils/imageTest.php b/tests/classes/recordutils/imageTest.php
index 2ab653e927..e27503f3a0 100644
--- a/tests/classes/recordutils/imageTest.php
+++ b/tests/classes/recordutils/imageTest.php
@@ -17,7 +17,7 @@ class recordutils_imageTest extends \PhraseanetTestCase
$app->getApplicationBox()->write_collection_pic(
$app['media-alchemyst'],
$app['filesystem'],
- $record_1->get_collection(),
+ $record_1->getCollection(),
null,
\collection::PIC_WM
);
@@ -36,7 +36,7 @@ class recordutils_imageTest extends \PhraseanetTestCase
$app->getApplicationBox()->write_collection_pic(
$app['media-alchemyst'],
$app['filesystem'],
- $record_1->get_collection(),
+ $record_1->getCollection(),
new SymfoFile(__DIR__ . '/../../files/logocoll.gif'),
\collection::PIC_WM
);
@@ -82,13 +82,13 @@ class recordutils_imageTest extends \PhraseanetTestCase
{
/** @var record_adapter $record_1 */
$record_1 = self::$DI['record_1'];
- $this->addStampConf($record_1->get_collection());
+ $this->addStampConf($record_1->getCollection());
$app = $this->getApplication();
$app->getApplicationBox()->write_collection_pic(
$app['media-alchemyst'],
$app['filesystem'],
- $record_1->get_collection(),
+ $record_1->getCollection(),
null,
\collection::PIC_STAMP
);
@@ -103,13 +103,13 @@ class recordutils_imageTest extends \PhraseanetTestCase
{
/** @var record_adapter $record_1 */
$record_1 = self::$DI['record_1'];
- $this->addStampConf($record_1->get_collection());
+ $this->addStampConf($record_1->getCollection());
$app = $this->getApplication();
$app->getApplicationBox()->write_collection_pic(
$app['media-alchemyst'],
$app['filesystem'],
- $record_1->get_collection(),
+ $record_1->getCollection(),
new SymfoFile(__DIR__ . '/../../files/logocoll.gif'),
\collection::PIC_STAMP
);
diff --git a/www/scripts/apps/admin/main/views/rightPanel.js b/www/scripts/apps/admin/main/views/rightPanel.js
index 89b15fc828..84f70b95d0 100644
--- a/www/scripts/apps/admin/main/views/rightPanel.js
+++ b/www/scripts/apps/admin/main/views/rightPanel.js
@@ -73,11 +73,11 @@ define([
event.preventDefault();
var $this = this;
var link = $(event.currentTarget);
- var url = link.attr('action') || 'GET';
+ var url = link.attr('action');
if(url) {
$.ajax({
- type: link.attr('method'),
+ type: link.attr('method') || 'GET',
url: url,
data: link.serializeArray(),
success: function (data) {
diff --git a/www/scripts/apps/admin/search-engine/views/es_config.js b/www/scripts/apps/admin/search-engine/views/es_config.js
new file mode 100644
index 0000000000..23ba10f4ee
--- /dev/null
+++ b/www/scripts/apps/admin/search-engine/views/es_config.js
@@ -0,0 +1,39 @@
+function searchEngineConfigurationFormInit(indexExists) {
+ $("#dropIndexConfirmDialog").dialog({
+ autoOpen: false,
+ modal: true,
+ title: "Drop index",
+ buttons: [
+ {
+ text: "Ok",
+ click: function () {
+ $("#ElasticSearchDropIndexForm").submit();
+ $("#dropIndexConfirmDialog").dialog("close");
+ }
+ },
+ {
+ text: "Cancel",
+ click: function () {
+ $("#dropIndexConfirmDialog").dialog("close");
+ }
+ }
+ ]
+ });
+
+ if(indexExists) {
+ $("BUTTON[data-id=esSettingsCreateIndexButton]").hide();
+ $("BUTTON[data-id=esSettingsDropIndexButton]").show().bind("click", function (event) {
+ event.preventDefault();
+ $("#dropIndexConfirmDialog").dialog("open");
+ return false;
+ });
+ }
+ else {
+ $("BUTTON[data-id=esSettingsDropIndexButton]").hide();
+ $("BUTTON[data-id=esSettingsCreateIndexButton]").show().bind("click", function (event) {
+ event.preventDefault();
+ $("#ElasticSearchCreateIndexForm").submit();
+ return false;
+ });
+ }
+}