diff --git a/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php b/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php index 1632fe1571..9f1cae2919 100644 --- a/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php +++ b/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php @@ -2813,7 +2813,7 @@ class V1Controller extends Controller { $ret = [ "meta_fields" => $this->listUserAuthorizedMetadataFields($this->getAuthenticatedUser()), - "aggregable_fields" => $this->buildUserFieldList(ElasticsearchOptions::getAggregableTechnicalFields($this->app['translator']), ['choices']), + "aggregable_fields" => $this->buildUserFieldList(ElasticsearchOptions::getAggregableTechnicalFields(), ['choices']), "technical_fields" => $this->buildUserFieldList(media_subdef::getTechnicalFieldsList()), ]; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/QueryController.php b/lib/Alchemy/Phrasea/Controller/Prod/QueryController.php index d055206d18..4ca7c3bf0f 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/QueryController.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/QueryController.php @@ -76,8 +76,7 @@ class QueryController extends Controller $this->app['elasticsearch.client'], $query_context_factory, $this->app['elasticsearch.facets_response.factory'], - $this->app['elasticsearch.options'], - $this->app['translator'] + $this->app['elasticsearch.options'] ); $autocomplete = $engine->autocomplete($word, $options); @@ -352,7 +351,7 @@ class QueryController extends Controller // add technical fields $fieldsInfosByName = []; - foreach(ElasticsearchOptions::getAggregableTechnicalFields($this->app['translator']) as $k => $f) { + foreach(ElasticsearchOptions::getAggregableTechnicalFields() as $k => $f) { $fieldsInfosByName[$k] = $f; $fieldsInfosByName[$k]['trans_label'] = $this->app->trans( /** @ignore */ $f['label']); $fieldsInfosByName[$k]['labels'] = []; diff --git a/lib/Alchemy/Phrasea/Core/Provider/SearchEngineServiceProvider.php b/lib/Alchemy/Phrasea/Core/Provider/SearchEngineServiceProvider.php index 71159f028e..bab1a62f28 100644 --- a/lib/Alchemy/Phrasea/Core/Provider/SearchEngineServiceProvider.php +++ b/lib/Alchemy/Phrasea/Core/Provider/SearchEngineServiceProvider.php @@ -96,8 +96,7 @@ class SearchEngineServiceProvider implements ServiceProviderInterface $app['elasticsearch.client'], $app['query_context.factory'], $app['elasticsearch.facets_response.factory'], - $app['elasticsearch.options'], - $app['translator'] + $app['elasticsearch.options'] ); }); diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php index 5eab435c70..43dc650c27 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php +++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php @@ -33,7 +33,6 @@ use Closure; use databox_field; use Doctrine\Common\Collections\ArrayCollection; use Elasticsearch\Client; -use Symfony\Component\Translation\TranslatorInterface; class ElasticSearchEngine implements SearchEngineInterface { @@ -60,8 +59,6 @@ class ElasticSearchEngine implements SearchEngineInterface */ private $context_factory; - private $translator; - /** * @param Application $app * @param GlobalStructure $structure @@ -69,9 +66,8 @@ class ElasticSearchEngine implements SearchEngineInterface * @param QueryContextFactory $context_factory * @param Closure $facetsResponseFactory * @param ElasticsearchOptions $options - * @param TranslatorInterface $translator */ - public function __construct(Application $app, GlobalStructure $structure, Client $client, QueryContextFactory $context_factory, Closure $facetsResponseFactory, ElasticsearchOptions $options, TranslatorInterface $translator) + public function __construct(Application $app, GlobalStructure $structure, Client $client, QueryContextFactory $context_factory, Closure $facetsResponseFactory, ElasticsearchOptions $options) { $this->app = $app; $this->structure = $structure; @@ -79,7 +75,6 @@ class ElasticSearchEngine implements SearchEngineInterface $this->context_factory = $context_factory; $this->facetsResponseFactory = $facetsResponseFactory; $this->options = $options; - $this->translator = $translator; $this->indexName = $options->getIndexName(); } @@ -785,7 +780,7 @@ class ElasticSearchEngine implements SearchEngineInterface { $aggs = []; // technical aggregates (enable + optional limit) - foreach (ElasticsearchOptions::getAggregableTechnicalFields($this->translator) as $k => $f) { + foreach (ElasticsearchOptions::getAggregableTechnicalFields() as $k => $f) { $size = $this->options->getAggregableFieldLimit($k); if ($size !== databox_field::FACET_DISABLED) { if ($size === databox_field::FACET_NO_LIMIT) { @@ -798,13 +793,6 @@ class ElasticSearchEngine implements SearchEngineInterface ] ]; $aggs[$k] = $agg; - if($options->getIncludeUnsetFieldFacet() === true) { - $aggs[$k . '#empty'] = [ - 'missing' => [ - 'field' => $f['esfield'], - ] - ]; - } } } // fields aggregates diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticsearchOptions.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticsearchOptions.php index 581bd42982..4f7de4c7af 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticsearchOptions.php +++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticsearchOptions.php @@ -11,7 +11,6 @@ namespace Alchemy\Phrasea\SearchEngine\Elastic; use databox_field; use igorw; -use Symfony\Component\Translation\TranslatorInterface; class ElasticsearchOptions @@ -313,7 +312,7 @@ class ElasticsearchOptions $this->_customValues = igorw\assoc_in($this->_customValues, $keys, $value); } - public static function getAggregableTechnicalFields(TranslatorInterface $translator) + public static function getAggregableTechnicalFields() { return [ '_base' => [ @@ -339,21 +338,21 @@ class ElasticsearchOptions ], '_camera_model' => [ 'type' => 'string', - 'label' => 'prod::facet:CameraModel_label', + 'label' => 'Camera Model', 'field' => "meta.CameraModel", 'esfield' => 'metadata_tags.CameraModel', - 'query' => 'meta.CameraModel=%s', + 'query' => 'meta.CameraModel:%s', ], '_iso' => [ 'type' => 'number', - 'label' => 'prod::facet:ISO_label', + 'label' => 'ISO', 'field' => "meta.ISO", 'esfield' => 'metadata_tags.ISO', 'query' => 'meta.ISO=%s', ], '_aperture' => [ 'type' => 'number', - 'label' => 'prod::facet:Aperture_label', + 'label' => 'Aperture', 'field' => "meta.Aperture", 'esfield' => 'metadata_tags.Aperture', 'query' => 'meta.Aperture=%s', @@ -363,7 +362,7 @@ class ElasticsearchOptions ], '_shutterspeed' => [ 'type' => 'number', - 'label' => 'prod::facet:ShutterSpeed_label', + 'label' => 'Shutter speed', 'field' => "meta.ShutterSpeed", 'esfield' => 'metadata_tags.ShutterSpeed', 'query' => 'meta.ShutterSpeed=%s', @@ -376,86 +375,63 @@ class ElasticsearchOptions ], '_flashfired' => [ 'type' => 'boolean', - 'label' => 'prod::facet:FlashFired_label', + 'label' => 'FlashFired', 'field' => "meta.FlashFired", 'esfield' => 'metadata_tags.FlashFired', 'query' => 'meta.FlashFired=%s', 'choices' => [ "aggregated (2 values: fired = 0 or 1)" => -1, ], - 'output_formatter' => function($value) use($translator) { - $map = [ - "false" => $translator->trans("facet.flashfired:no"), - "true" => $translator->trans("facet.flashfired:yes"), - '0' => $translator->trans("facet.flashfired:no"), - '1' => $translator->trans("facet.flashfired:yes") - ]; + 'output_formatter' => function($value) { + static $map = ["false"=>"No flash", "true"=>"Flash", '0'=>"No flash", '1'=>"Flash"]; return array_key_exists($value, $map) ? $map[$value] : $value; }, ], '_framerate' => [ 'type' => 'number', - 'label' => 'prod::facet:FrameRate_label', + 'label' => 'FrameRate', 'field' => "meta.FrameRate", 'esfield' => 'metadata_tags.FrameRate', 'query' => 'meta.FrameRate=%s', ], '_audiosamplerate' => [ 'type' => 'number', - 'label' => 'prod::facet:AudioSamplerate_label', + 'label' => 'Audio Samplerate', 'field' => "meta.AudioSamplerate", 'esfield' => 'metadata_tags.AudioSamplerate', 'query' => 'meta.AudioSamplerate=%s', ], '_videocodec' => [ 'type' => 'string', - 'label' => 'prod::facet:VideoCodec_label', + 'label' => 'Video codec', 'field' => "meta.VideoCodec", 'esfield' => 'metadata_tags.VideoCodec', 'query' => 'meta.VideoCodec:%s', ], '_audiocodec' => [ 'type' => 'string', - 'label' => 'prod::facet:AudioCodec_label', + 'label' => 'Audio codec', 'field' => "meta.AudioCodec", 'esfield' => 'metadata_tags.AudioCodec', 'query' => 'meta.AudioCodec:%s', ], '_orientation' => [ 'type' => 'string', - 'label' => 'prod::facet.Orientation_label', + 'label' => 'Orientation', 'field' => "meta.Orientation", 'esfield' => 'metadata_tags.Orientation', 'query' => 'meta.Orientation=%s', ], - '_thumbnail_orientation' => [ - 'type' => 'string', - 'label' => 'prod::facet.ThumbnailOrientation_label', - 'field' => "meta.ThumbnailOrientation", - 'esfield' => 'metadata_tags.ThumbnailOrientation', - 'query' => 'meta.ThumbnailOrientation=%s', - 'choices' => [ - "aggregated (4 values: '', 'S', 'L', 'P')" => -1, - ], - 'output_formatter' => function($value) use($translator) { - $map = [ - "L" => $translator->trans("facet.ThumbnailOrientation:Landscape"), - "P" => $translator->trans("facet.ThumbnailOrientation:Portrait"), - 'S' => $translator->trans("facet.ThumbnailOrientation:Square") - ]; - return array_key_exists($value, $map) ? $map[$value] : $value; - }, - ], '_colorspace' => [ 'type' => 'string', - 'label' => 'prod::facet:Colorspace_label', + 'label' => 'Colorspace', 'field' => "meta.ColorSpace", 'esfield' => 'metadata_tags.ColorSpace', 'query' => 'meta.ColorSpace:%s', ], '_mimetype' => [ 'type' => 'string', - 'label' => 'prod::facet:MimeType_label', + 'label' => 'MimeType', 'field' => "meta.MimeType", 'esfield' => 'metadata_tags.MimeType', 'query' => 'meta.MimeType:%s', diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticsearchSettingsFormType.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticsearchSettingsFormType.php index 3115055a34..0b7a3ce9e6 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticsearchSettingsFormType.php +++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticsearchSettingsFormType.php @@ -137,7 +137,7 @@ class ElasticsearchSettingsFormType extends AbstractType } // add or replace hardcoded tech fields - foreach(ElasticsearchOptions::getAggregableTechnicalFields($this->translator) as $k => $f) { + foreach(ElasticsearchOptions::getAggregableTechnicalFields() as $k => $f) { $choices = array_key_exists('choices', $f) ? $f['choices'] : null; // a tech-field can publish it's own choices $help = null; $label = '#' . $k; diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Indexer/Record/Hydrator/SubDefinitionHydrator.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Indexer/Record/Hydrator/SubDefinitionHydrator.php index 32a06e3781..a7da16e834 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Indexer/Record/Hydrator/SubDefinitionHydrator.php +++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Indexer/Record/Hydrator/SubDefinitionHydrator.php @@ -18,18 +18,7 @@ use media_Permalink_Adapter; class SubDefinitionHydrator implements HydratorInterface { - const ORIENTATION_SQUARE = 'S'; - const ORIENTATION_LANDSCAPE = 'L'; - const ORIENTATION_PORTRAIT = 'P'; - const ORIENTATION_UNKNOW = ''; - -// const ORIENTATION_SQUARE = 1; -// const ORIENTATION_LANDSCAPE = 2; -// const ORIENTATION_PORTRAIT = 3; -// const ORIENTATION_UNKNOW = 0; - - - /** @var Application */ + /** @var Application */ private $app; /** @var databox */ @@ -49,50 +38,45 @@ class SubDefinitionHydrator implements HydratorInterface { if ($this->populatePermalinks) { $this->hydrateRecordsWithPermalinks($records); - } - else { + } else { $this->hydrateRecordsWithoutPermalinks($records); } } private function hydrateRecordsWithPermalinks(&$records) { - foreach (array_keys($records) as $rid) { - - $record = &$records[$rid]; - + foreach(array_keys($records) as $rid) { try { $subdefs = $this->databox->getRecordRepository()->find($rid)->get_subdefs(); $pls = array_map( /** media_Permalink_Adapter|null $plink */ - function ($plink) { - return $plink ? ((string)$plink->get_url()) : null; + function($plink) { + return $plink ? ((string) $plink->get_url()) : null; }, media_Permalink_Adapter::getMany($this->app, $subdefs, false) // false: don't create missing plinks ); - foreach ($subdefs as $subdef) { + foreach($subdefs as $subdef) { $name = $subdef->get_name(); - if (substr(($path = $subdef->get_path()), -1) !== '/') { + if(substr(($path = $subdef->get_path()), -1) !== '/') { $path .= '/'; } - $record['subdefs'][$name] = [ - 'path' => $path . $subdef->get_file(), - 'width' => $subdef->get_width(), - 'height' => $subdef->get_height(), - 'size' => $subdef->get_size(), - 'mime' => $subdef->get_mime(), + $records[$rid]['subdefs'][$name] = array( + 'path' => $path . $subdef->get_file(), + 'width' => $subdef->get_width(), + 'height' => $subdef->get_height(), + 'size' => $subdef->get_size(), + 'mime' => $subdef->get_mime(), 'permalink' => array_key_exists($name, $pls) ? $pls[$name] : null - ]; - if ($name == "thumbnail") { - $this->setOrientation($record, $subdef->get_width(), $subdef->get_height()); - } + ); + } } catch (\Exception $e) { // cant get record ? ignore } + } } @@ -112,42 +96,22 @@ class SubDefinitionHydrator implements HydratorInterface ORDER BY s.record_id SQL; $statement = $this->databox->get_connection()->executeQuery($sql, - [array_keys($records)], - [Connection::PARAM_INT_ARRAY] + array(array_keys($records)), + array(Connection::PARAM_INT_ARRAY) ); $current_rid = null; $record = null; while ($subdef = $statement->fetch()) { - $rid = $subdef['record_id']; - $record = &$records[$rid]; $name = $subdef['name']; - $record['subdefs'][$name] = [ - 'path' => $subdef['path'], - 'width' => $subdef['width'], - 'height' => $subdef['height'], - 'size' => $subdef['size'], - 'mime' => $subdef['mime'], + $records[$subdef['record_id']]['subdefs'][$name] = array( + 'path' => $subdef['path'], + 'width' => $subdef['width'], + 'height' => $subdef['height'], + 'size' => $subdef['size'], + 'mime' => $subdef['mime'], 'permalink' => null - ]; - if ($name == "thumbnail") { - $this->setOrientation($record, $subdef['width'], $subdef['height']); - } + ); } } - - private function setOrientation(&$record, $w, $h) - { - $o = self::ORIENTATION_UNKNOW; - if ($w !== '' && $h !== '' && !is_null($w) && !is_null($h)) { - $w = (int)$w; - $h = (int)$h; - $o = $w == $h ? self::ORIENTATION_SQUARE : ($w > $h ? self::ORIENTATION_LANDSCAPE : self::ORIENTATION_PORTRAIT); - } - if(!array_key_exists('metadata_tags', $record)) { - $record['metadata_tags'] = []; - } - $record['metadata_tags']['ThumbnailOrientation'] = $o; - } } - diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Mapping/MetadataTagToFieldMappingConverter.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Mapping/MetadataTagToFieldMappingConverter.php index ceb7a0a6d9..07d186b4e3 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Mapping/MetadataTagToFieldMappingConverter.php +++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Mapping/MetadataTagToFieldMappingConverter.php @@ -18,25 +18,6 @@ class MetadataTagToFieldMappingConverter { public function convertTag(Tag $tag) - { - if ($tag->getType() === FieldMapping::TYPE_STRING) { - - $fieldMapping = new StringFieldMapping($tag->getName()); - $fieldMapping->addChild((new StringFieldMapping('raw'))->enableRawIndexing()); - if ($tag->isAnalyzable()) { - $fieldMapping->enableAnalysis(); - } - else { - $fieldMapping->disableAnalysis(); - } - - return $fieldMapping; - } - - return new FieldMapping($tag->getName(), $tag->getType()); - } - - public function dead_convertTag(Tag $tag) { if ($tag->getType() === FieldMapping::TYPE_STRING) { $fieldMapping = new StringFieldMapping($tag->getName()); diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/FacetsResponse.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/FacetsResponse.php index 6f7d0b4655..4849ff4693 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/FacetsResponse.php +++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/FacetsResponse.php @@ -24,7 +24,7 @@ class FacetsResponse return; } - $atf = ElasticsearchOptions::getAggregableTechnicalFields($this->translator); + $atf = ElasticsearchOptions::getAggregableTechnicalFields(); // sort facets respecting the order defined in options foreach($options->getAggregableFields() as $name=>$foptions) { @@ -35,11 +35,9 @@ class FacetsResponse $tf = null; $valueFormatter = function($v){ return $v; }; // default equality formatter - $label = $name; if(array_key_exists($name, $atf)) { $tf = $atf[$name]; - $label = $tf['label']; if(array_key_exists('output_formatter', $tf)) { $valueFormatter = $tf['output_formatter']; } @@ -58,8 +56,7 @@ class FacetsResponse if($response['aggregations'][$name . '#empty']['doc_count'] > 0) { // don't add a facet for 0 results $aggregation['buckets'][] = [ 'key' => '_unset_', - 'value' => $this->translator->trans('prod:workzone:facetstab:unset_field_facet_label_(%fieldname%)', ['%fieldname%' =>$label]), // special homemade prop to display a human value instead of the key - // 'value' => 'unset '.$name, // special homemade prop to display a human value instead of the key + 'value' => $this->translator->trans('prod:workzone:facetstab:unset_field_facet_label_(%fieldname%)', ['%fieldname%' =>$name]), // special homemade prop to display a human value instead of the key 'doc_count' => $response['aggregations'][$name . '#empty']['doc_count'] ]; } @@ -73,15 +70,8 @@ class FacetsResponse $key = array_key_exists('key_as_string', $bucket) ? $bucket['key_as_string'] : $bucket['key']; if($tf) { // the field is one of the hardcoded tech fields - if($key == '_unset_' && array_key_exists('value', $bucket)) { - // don't use the valueformatter since 'value' if already translated - $v = $bucket['value']; - } - else { - $v = $valueFormatter($key); - } $value = [ - 'value' => $v, + 'value' => $valueFormatter($key), 'raw_value' => $key, 'count' => $bucket['doc_count'], 'query' => sprintf($tf['query'], $this->escaper->escapeWord($key)) diff --git a/lib/classes/media/subdef.php b/lib/classes/media/subdef.php index 544f838504..8893523fe0 100644 --- a/lib/classes/media/subdef.php +++ b/lib/classes/media/subdef.php @@ -109,7 +109,6 @@ class media_subdef extends media_abstract implements cache_cacheableInterface const TC_DATA_COLORSPACE = 'ColorSpace'; const TC_DATA_CHANNELS = 'Channels'; const TC_DATA_ORIENTATION = 'Orientation'; - const TC_DATA_THUMBNAILORIENTATION = 'ThumbnailOrientation'; const TC_DATA_COLORDEPTH = 'ColorDepth'; const TC_DATA_DURATION = 'Duration'; const TC_DATA_AUDIOCODEC = 'AudioCodec'; @@ -865,7 +864,6 @@ class media_subdef extends media_abstract implements cache_cacheableInterface self::TC_DATA_VIDEOCODEC => ['method' => 'getVideoCodec', 'type' => 'string', 'analyzable' => false], self::TC_DATA_AUDIOCODEC => ['method' => 'getAudioCodec', 'type' => 'string', 'analyzable' => false], self::TC_DATA_ORIENTATION => ['method' => 'getOrientation', 'type' => 'integer', 'analyzable' => false], - self::TC_DATA_THUMBNAILORIENTATION => ['type' => 'string', 'analyzable' => false], self::TC_DATA_LONGITUDE => ['method' => 'getLongitude', 'type' => 'float', 'analyzable' => false], self::TC_DATA_LONGITUDE_REF => ['method' => 'getLongitudeRef'], self::TC_DATA_LATITUDE => ['method' => 'getLatitude', 'type' => 'float', 'analyzable' => false],