mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-18 15:33:15 +00:00
Add Caption Service and Repositories
This commit is contained in:
@@ -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\Caption\CaptionServiceProvider;
|
||||
use Alchemy\Phrasea\Databox\Subdef\MediaSubdefServiceProvider;
|
||||
use Alchemy\Phrasea\Exception\InvalidArgumentException;
|
||||
use Alchemy\Phrasea\Filesystem\FilesystemServiceProvider;
|
||||
@@ -194,6 +195,7 @@ class Application extends SilexApplication
|
||||
$this->register(new ManipulatorServiceProvider());
|
||||
$this->register(new TechnicalDataServiceProvider());
|
||||
$this->register(new MediaSubdefServiceProvider());
|
||||
$this->register(new CaptionServiceProvider());
|
||||
$this->register(new InstallerServiceProvider());
|
||||
$this->register(new PhraseaVersionServiceProvider());
|
||||
|
||||
|
@@ -1159,6 +1159,7 @@ class V1Controller extends Controller
|
||||
);
|
||||
|
||||
$technicalDatasets = $this->app['service.technical_data']->fetchRecordsTechnicalData($references);
|
||||
|
||||
if (array_intersect($includes, ['results.metadata', 'results.caption'])) {
|
||||
}
|
||||
|
||||
@@ -1280,8 +1281,8 @@ class V1Controller extends Controller
|
||||
|
||||
return [
|
||||
'results.subdefs',
|
||||
//'results.metadata',
|
||||
//'results.caption',
|
||||
'results.metadata',
|
||||
'results.caption',
|
||||
'results.status',
|
||||
];
|
||||
}
|
||||
|
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2016 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Databox\Caption;
|
||||
|
||||
use Alchemy\Phrasea\Cache\MultiAdapter;
|
||||
use Doctrine\Common\Cache\Cache;
|
||||
use Doctrine\Common\Cache\MultiGetCache;
|
||||
use Doctrine\Common\Cache\MultiPutCache;
|
||||
|
||||
class CachedCaptionDataRepository implements CaptionDataRepository
|
||||
{
|
||||
/**
|
||||
* @var CaptionDataRepository
|
||||
*/
|
||||
private $decorated;
|
||||
/**
|
||||
* @var Cache|MultiGetCache|MultiPutCache
|
||||
*/
|
||||
private $cache;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $baseKey;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $lifeTime = 0;
|
||||
|
||||
/**
|
||||
* CachedCaptionDataRepository constructor.
|
||||
* @param CaptionDataRepository $decorated
|
||||
* @param Cache $cache
|
||||
* @param string $baseKey
|
||||
*/
|
||||
public function __construct(CaptionDataRepository $decorated, Cache $cache, $baseKey)
|
||||
{
|
||||
$this->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 array $recordIds
|
||||
* @return \array[]
|
||||
*/
|
||||
public function findByRecordIds(array $recordIds)
|
||||
{
|
||||
$keys = $this->computeKeys($recordIds);
|
||||
|
||||
$data = $this->cache->fetchMultiple($keys);
|
||||
|
||||
if (count($data) === count($keys)) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
$data = $this->decorated->findByRecordIds($recordIds);
|
||||
|
||||
$this->cache->saveMultiple(array_combine(array_values($keys), array_values($data)));
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int[] $recordIds
|
||||
* @return string[]
|
||||
*/
|
||||
private function computeKeys(array $recordIds)
|
||||
{
|
||||
return array_map(function ($recordId) {
|
||||
return $this->baseKey . 'caption' . json_encode([(int)$recordId]);
|
||||
}, $recordIds);
|
||||
}
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2016 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Databox\Caption;
|
||||
|
||||
interface CaptionDataRepository
|
||||
{
|
||||
/**
|
||||
* @param int[] $recordIds
|
||||
* @return array[]
|
||||
*/
|
||||
public function findByRecordIds(array $recordIds);
|
||||
}
|
74
lib/Alchemy/Phrasea/Databox/Caption/CaptionRepository.php
Normal file
74
lib/Alchemy/Phrasea/Databox/Caption/CaptionRepository.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2016 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Databox\Caption;
|
||||
|
||||
use Assert\Assertion;
|
||||
|
||||
class CaptionRepository
|
||||
{
|
||||
/**
|
||||
* @var \caption_record[]
|
||||
*/
|
||||
private $idMap = [];
|
||||
|
||||
/**
|
||||
* @var CaptionDataRepository
|
||||
*/
|
||||
private $dataRepository;
|
||||
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
private $captionFactory;
|
||||
|
||||
public function __construct(CaptionDataRepository $dataRepository, callable $captionFactory)
|
||||
{
|
||||
$this->dataRepository = $dataRepository;
|
||||
$this->captionFactory = $captionFactory;
|
||||
}
|
||||
|
||||
public function findByRecordIds(array $recordIds)
|
||||
{
|
||||
$this->fetchMissing($recordIds);
|
||||
|
||||
$instances = [];
|
||||
|
||||
foreach ($recordIds as $index => $recordId) {
|
||||
$instances[$index] = $this->idMap[$recordId];
|
||||
}
|
||||
|
||||
return $instances;
|
||||
}
|
||||
|
||||
public function clear()
|
||||
{
|
||||
$this->idMap = [];
|
||||
}
|
||||
|
||||
private function fetchMissing(array $recordIds)
|
||||
{
|
||||
$missing = array_diff($recordIds, array_keys($this->idMap));
|
||||
|
||||
if (!$missing) {
|
||||
return;
|
||||
}
|
||||
|
||||
$data = $this->dataRepository->findByRecordIds($missing);
|
||||
|
||||
$factory = $this->captionFactory;
|
||||
|
||||
foreach ($data as $item) {
|
||||
Assertion::keyIsset($item, 'record_id');
|
||||
|
||||
$this->idMap[(int)$item['record_id']] = $factory($item);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2016 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Databox\Caption;
|
||||
|
||||
use Alchemy\Phrasea\Databox\DataboxBoundRepositoryFactory;
|
||||
use Alchemy\Phrasea\Databox\DataboxConnectionProvider;
|
||||
use Doctrine\Common\Cache\Cache;
|
||||
|
||||
class CaptionRepositoryFactory implements DataboxBoundRepositoryFactory
|
||||
{
|
||||
/**
|
||||
* @var DataboxConnectionProvider
|
||||
*/
|
||||
private $connectionProvider;
|
||||
|
||||
/**
|
||||
* @var Cache
|
||||
*/
|
||||
private $cache;
|
||||
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
private $captionFactoryProvider;
|
||||
|
||||
public function __construct(DataboxConnectionProvider $connectionProvider, Cache $cache, callable $captionFactoryProvider)
|
||||
{
|
||||
$this->connectionProvider = $connectionProvider;
|
||||
$this->cache = $cache;
|
||||
$this->captionFactoryProvider = $captionFactoryProvider;
|
||||
}
|
||||
|
||||
public function createRepositoryFor($databoxId)
|
||||
{
|
||||
$connection = $this->connectionProvider->getConnection($databoxId);
|
||||
|
||||
$dbalRepository = new DbalCaptionDataRepository($connection);
|
||||
$dataRepository = new CachedCaptionDataRepository($dbalRepository, $this->cache, sprintf('databox%d:', $databoxId));
|
||||
|
||||
$provider = $this->captionFactoryProvider;
|
||||
$factory = $provider($databoxId);
|
||||
|
||||
if (!is_callable($factory)) {
|
||||
throw new \UnexpectedValueException(sprintf(
|
||||
'Caption factory is expected to be callable, got %s',
|
||||
is_object($factory) ? get_class($factory) : gettype($factory)
|
||||
));
|
||||
}
|
||||
|
||||
return new CaptionRepository($dataRepository, $factory);
|
||||
}
|
||||
}
|
67
lib/Alchemy/Phrasea/Databox/Caption/CaptionService.php
Normal file
67
lib/Alchemy/Phrasea/Databox/Caption/CaptionService.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2016 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Databox\Caption;
|
||||
|
||||
use Alchemy\Phrasea\Databox\DataboxBoundRepositoryProvider;
|
||||
use Alchemy\Phrasea\Model\RecordReferenceInterface;
|
||||
use Alchemy\Phrasea\Record\RecordReferenceCollection;
|
||||
|
||||
class CaptionService
|
||||
{
|
||||
/**
|
||||
* @var DataboxBoundRepositoryProvider
|
||||
*/
|
||||
private $repositoryProvider;
|
||||
|
||||
public function __construct(DataboxBoundRepositoryProvider $repositoryProvider)
|
||||
{
|
||||
$this->repositoryProvider = $repositoryProvider;
|
||||
}
|
||||
|
||||
public function findByReferenceCollection($references)
|
||||
{
|
||||
$references = $this->normalizeReferenceCollection($references);
|
||||
|
||||
$groups = [];
|
||||
|
||||
foreach ($references->groupPerDataboxId() as $databoxId => $indexes) {
|
||||
$this->getRepositoryForDatabox($databoxId)->findByRecordIds(array_keys($indexes));
|
||||
}
|
||||
|
||||
if ($groups) {
|
||||
return call_user_func_array('array_merge', $groups);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RecordReferenceInterface[]|RecordReferenceCollection $references
|
||||
* @return RecordReferenceCollection
|
||||
*/
|
||||
public function normalizeReferenceCollection($references)
|
||||
{
|
||||
if ($references instanceof RecordReferenceCollection) {
|
||||
return $references;
|
||||
}
|
||||
|
||||
return new RecordReferenceCollection($references);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $databoxId
|
||||
* @return CaptionRepository
|
||||
*/
|
||||
private function getRepositoryForDatabox($databoxId)
|
||||
{
|
||||
return $this->repositoryProvider->getRepositoryForDatabox($databoxId);
|
||||
}
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2016 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Databox\Caption;
|
||||
|
||||
use Alchemy\Phrasea\Databox\DataboxBoundRepositoryProvider;
|
||||
use Alchemy\Phrasea\Databox\DataboxConnectionProvider;
|
||||
use Alchemy\Phrasea\Record\RecordReference;
|
||||
use Silex\Application;
|
||||
use Silex\ServiceProviderInterface;
|
||||
|
||||
class CaptionServiceProvider implements ServiceProviderInterface
|
||||
{
|
||||
public function register(Application $app)
|
||||
{
|
||||
$app['provider.factory.caption'] = $app->protect(function ($databoxId) use ($app) {
|
||||
return function (array $data) use ($app, $databoxId) {
|
||||
$recordReference = RecordReference::createFromDataboxIdAndRecordId($databoxId, $data['record_id']);
|
||||
|
||||
return new \caption_record($app, $recordReference, $data);
|
||||
};
|
||||
});
|
||||
|
||||
$app['provider.repo.caption'] = $app->share(function (Application $app) {
|
||||
$connectionProvider = new DataboxConnectionProvider($app['phraseanet.appbox']);
|
||||
$factoryProvider = $app['provider.factory.caption'];
|
||||
|
||||
$repositoryFactory = new CaptionRepositoryFactory($connectionProvider, $app['cache'], $factoryProvider);
|
||||
|
||||
return new DataboxBoundRepositoryProvider($repositoryFactory);
|
||||
});
|
||||
|
||||
$app['service.caption'] = $app->share(function (Application $app) {
|
||||
return new CaptionService($app['provider.repo.caption']);
|
||||
});
|
||||
}
|
||||
|
||||
public function boot(Application $app)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
}
|
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2016 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Databox\Caption;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
|
||||
class DbalCaptionDataRepository implements CaptionDataRepository
|
||||
{
|
||||
/**
|
||||
* @var Connection
|
||||
*/
|
||||
private $connection;
|
||||
|
||||
public function __construct(Connection $connection)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
public function findByRecordIds(array $recordIds)
|
||||
{
|
||||
if (!$recordIds) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$sql = <<<'SQL'
|
||||
SELECT m.record_id, 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 IN (:recordIds)
|
||||
ORDER BY m.record_id ASC, s.sorter ASC
|
||||
SQL;
|
||||
|
||||
$data = $this->connection->fetchAll(
|
||||
$sql, ['recordIds' => $recordIds], ['recordIds' => Connection::PARAM_INT_ARRAY]
|
||||
);
|
||||
|
||||
return $this->mapByRecordId($data, $recordIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param int[] $recordIds
|
||||
* @return array[]
|
||||
*/
|
||||
private function mapByRecordId(array $data, array $recordIds)
|
||||
{
|
||||
$groups = array_fill_keys($recordIds, []);
|
||||
|
||||
foreach ($data as $item) {
|
||||
$recordId = $item['record_id'];
|
||||
|
||||
$groups[$recordId][] = $item;
|
||||
}
|
||||
|
||||
return $groups;
|
||||
}
|
||||
}
|
@@ -31,7 +31,7 @@ class TechnicalDataService
|
||||
*/
|
||||
public function fetchRecordsTechnicalData($references)
|
||||
{
|
||||
if (!$references instanceof RecordReferenceCollection) {
|
||||
if (!$references instanceof RecordReferenceCollection) {
|
||||
$references = new RecordReferenceCollection($references);
|
||||
}
|
||||
|
||||
|
@@ -29,10 +29,16 @@ class caption_record implements cache_cacheableInterface
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
public function __construct(Application $app, RecordReferenceInterface $record)
|
||||
/**
|
||||
* @param Application $app
|
||||
* @param RecordReferenceInterface $record
|
||||
* @param array[]|null $fieldsData
|
||||
*/
|
||||
public function __construct(Application $app, RecordReferenceInterface $record, array $fieldsData = null)
|
||||
{
|
||||
$this->app = $app;
|
||||
$this->record = $record;
|
||||
$this->fields = null === $fieldsData ? null : $this->mapFieldsFromData($fieldsData);
|
||||
}
|
||||
|
||||
public function toArray($includeBusinessFields)
|
||||
@@ -61,8 +67,6 @@ class caption_record implements cache_cacheableInterface
|
||||
return $this->fields;
|
||||
}
|
||||
|
||||
$databox = $this->getDatabox();
|
||||
|
||||
try {
|
||||
$fields = $this->get_data_from_cache();
|
||||
} catch (\Exception $e) {
|
||||
@@ -72,70 +76,14 @@ 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()
|
||||
$fields = $this->getDatabox()->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 = $databox->get_meta_structure();
|
||||
$record = $databox->get_record($this->record->getRecordId());
|
||||
|
||||
// first group values by field
|
||||
$caption_fields = [];
|
||||
foreach ($fields as $row) {
|
||||
$structure_id = $row['structure_id'];
|
||||
if(!array_key_exists($structure_id, $caption_fields)) {
|
||||
$caption_fields[$structure_id] = [
|
||||
'db_field' => $databox_descriptionStructure->get_element($structure_id),
|
||||
'values' => []
|
||||
];
|
||||
}
|
||||
|
||||
if (count($caption_fields[$structure_id]['values']) > 0 && !$caption_fields[$structure_id]['db_field']->is_multi()) {
|
||||
// Inconsistent, should not happen
|
||||
continue;
|
||||
}
|
||||
|
||||
// build an EMPTY caption_Field_Value
|
||||
$cfv = new caption_Field_Value(
|
||||
$this->app,
|
||||
$caption_fields[$structure_id]['db_field'],
|
||||
$record,
|
||||
$row['meta_id'],
|
||||
caption_Field_Value::DONT_RETRIEVE_VALUES // ask caption_Field_Value "no n+1 sql"
|
||||
);
|
||||
|
||||
// inject the value we already know
|
||||
$cfv->injectValues($row['value'], $row['VocabularyType'], $row['VocabularyId']);
|
||||
|
||||
// add the value to the field
|
||||
$caption_fields[$structure_id]['values'][] = $cfv;
|
||||
}
|
||||
|
||||
// now build a "caption_field" with already known "caption_Field_Value"s
|
||||
foreach($caption_fields as $structure_id => $caption_field) {
|
||||
|
||||
// build an EMPTY caption_field
|
||||
$cf = new caption_field(
|
||||
$this->app,
|
||||
$caption_field['db_field'],
|
||||
$record,
|
||||
caption_field::DONT_RETRIEVE_VALUES // ask caption_field "no n+1 sql"
|
||||
);
|
||||
|
||||
// inject the value we already know
|
||||
$cf->injectValues($caption_field['values']);
|
||||
|
||||
// add the field to the fields
|
||||
$rec_fields[$structure_id] = $cf;
|
||||
}
|
||||
}
|
||||
$this->fields = $rec_fields;
|
||||
$this->fields = $this->mapFieldsFromData($fields);
|
||||
|
||||
return $this->fields;
|
||||
}
|
||||
@@ -315,4 +263,73 @@ SQL;
|
||||
{
|
||||
return $this->app->findDataboxById($this->record->getDataboxId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return caption_field[]
|
||||
*/
|
||||
protected function mapFieldsFromData($data)
|
||||
{
|
||||
if (!$data) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$rec_fields = array();
|
||||
|
||||
$databox = $this->getDatabox();
|
||||
$databox_descriptionStructure = $databox->get_meta_structure();
|
||||
$record = $databox->get_record($this->record->getRecordId());
|
||||
|
||||
// first group values by field
|
||||
$caption_fields = [];
|
||||
foreach ($data as $row) {
|
||||
$structure_id = $row['structure_id'];
|
||||
if (!array_key_exists($structure_id, $caption_fields)) {
|
||||
$caption_fields[$structure_id] = [
|
||||
'db_field' => $databox_descriptionStructure->get_element($structure_id),
|
||||
'values' => []
|
||||
];
|
||||
}
|
||||
|
||||
if (count($caption_fields[$structure_id]['values']) > 0 && !$caption_fields[$structure_id]['db_field']->is_multi()) {
|
||||
// Inconsistent, should not happen
|
||||
continue;
|
||||
}
|
||||
|
||||
// build an EMPTY caption_Field_Value
|
||||
$cfv = new caption_Field_Value(
|
||||
$this->app,
|
||||
$caption_fields[$structure_id]['db_field'],
|
||||
$record,
|
||||
$row['meta_id'],
|
||||
caption_Field_Value::DONT_RETRIEVE_VALUES // ask caption_Field_Value "no n+1 sql"
|
||||
);
|
||||
|
||||
// inject the value we already know
|
||||
$cfv->injectValues($row['value'], $row['VocabularyType'], $row['VocabularyId']);
|
||||
|
||||
// add the value to the field
|
||||
$caption_fields[$structure_id]['values'][] = $cfv;
|
||||
}
|
||||
|
||||
// now build a "caption_field" with already known "caption_Field_Value"s
|
||||
foreach ($caption_fields as $structure_id => $caption_field) {
|
||||
|
||||
// build an EMPTY caption_field
|
||||
$cf = new caption_field(
|
||||
$this->app,
|
||||
$caption_field['db_field'],
|
||||
$record,
|
||||
caption_field::DONT_RETRIEVE_VALUES // ask caption_field "no n+1 sql"
|
||||
);
|
||||
|
||||
// inject the value we already know
|
||||
$cf->injectValues($caption_field['values']);
|
||||
|
||||
// add the field to the fields
|
||||
$rec_fields[$structure_id] = $cf;
|
||||
}
|
||||
|
||||
return $rec_fields;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user