Merge branch 'master' into PHRAS-2741-worker-service-part1

This commit is contained in:
Nicolas Maillat
2020-02-19 20:49:31 +01:00
committed by GitHub
82 changed files with 4722 additions and 2955 deletions

View File

@@ -15,6 +15,7 @@ use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Command\Command;
use Alchemy\Phrasea\Exception\RuntimeException;
use Alchemy\Phrasea\Model\Entities\User;
use Alchemy\Phrasea\Plugin\Plugin;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\HttpKernel\Client;
@@ -30,6 +31,15 @@ class JsFixtures extends Command
protected function doExecute(InputInterface $input, OutputInterface $output)
{
/** @var Plugin $plugin */
$msg = [];
foreach($this->container['plugins.manager']->listPlugins() as $plugin) {
$msg[] = sprintf(" bin/setup plugins:remove \"%s\"", $plugin->getName());
}
if(count($msg) !== 0) {
throw new RuntimeException("You must remove plugins first:\n" . join("\n", $msg));
}
if (!file_exists($this->container['db.fixture.info']['path'])) {
throw new RuntimeException('You must generate sqlite db first, run "bin/developer phraseanet:regenerate-sqlite" command.');
}
@@ -104,6 +114,7 @@ class JsFixtures extends Command
private function writeResponse(OutputInterface $output, $method, $path, $to, $authenticateUser = false)
{
$environment = Application::ENV_TEST;
/** @var Application $app */
$app = require __DIR__ . '/../../Application/Root.php';
$app['orm.em'] = $app->extend('orm.em', function($em, $app) {
return $app['orm.ems'][$app['db.fixture.hash.key']];

View File

@@ -13,9 +13,11 @@ namespace Alchemy\Phrasea\Controller\Admin;
use Alchemy\Phrasea\Controller\Controller;
use Alchemy\Phrasea\SearchEngine\Elastic\ElasticsearchSettingsFormType;
use Alchemy\Phrasea\SearchEngine\Elastic\ElasticsearchOptions;
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\GlobalStructure;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use databox_descriptionStructure;
class SearchEngineController extends Controller
{
@@ -31,7 +33,19 @@ class SearchEngineController extends Controller
$form->handleRequest($request);
if ($form->isValid()) {
$this->saveElasticSearchOptions($form->getData());
/** @var ElasticsearchOptions $data */
$data = $form->getData();
// $q = $request->request->get('elasticsearch_settings');
$facetNames = []; // rebuild the data "_customValues/facets" list following the form order
foreach($request->request->get('elasticsearch_settings') as $name=>$value) {
$matches = null;
if(preg_match('/^facets:(.+):limit$/', $name, $matches) === 1) {
$facetNames[] = $matches[1];
}
}
$data->reorderAggregableFields($facetNames);
$this->saveElasticSearchOptions($data);
return $this->app->redirectPath('admin_searchengine_form');
}
@@ -76,6 +90,16 @@ class SearchEngineController extends Controller
*/
private function saveElasticSearchOptions(ElasticsearchOptions $configuration)
{
// save to databoxes fields for backward compatibility (useless ?)
foreach($configuration->getAggregableFields() as $fname=>$aggregableField) {
foreach ($this->app->getDataboxes() as $databox) {
if(!is_null($f = $databox->get_meta_structure()->get_element_by_name($fname, databox_descriptionStructure::STRICT_COMPARE))) {
$f->set_aggregable($aggregableField['limit'])->save();
}
}
}
// save to conf
$this->getConf()->set(['main', 'search-engine', 'options'], $configuration->toArray());
}
@@ -85,7 +109,10 @@ class SearchEngineController extends Controller
*/
private function getConfigurationForm(ElasticsearchOptions $options)
{
return $this->app->form(new ElasticsearchSettingsFormType(), $options, [
/** @var GlobalStructure $g */
$g = $this->app['search_engine.structure'];
return $this->app->form(new ElasticsearchSettingsFormType($g, $options), $options, [
'action' => $this->app->url('admin_searchengine_form'),
]);
}

View File

@@ -19,8 +19,10 @@ use Alchemy\Phrasea\Core\PhraseaEvents;
use Alchemy\Phrasea\Feed\Aggregate;
use Alchemy\Phrasea\Feed\Link\AggregateLinkGenerator;
use Alchemy\Phrasea\Feed\Link\FeedLinkGenerator;
use Alchemy\Phrasea\Model\Entities\Feed;
use Alchemy\Phrasea\Model\Entities\FeedEntry;
use Alchemy\Phrasea\Model\Entities\FeedItem;
use Alchemy\Phrasea\Model\Entities\FeedPublisher;
use Alchemy\Phrasea\Model\Repositories\FeedEntryRepository;
use Alchemy\Phrasea\Model\Repositories\FeedItemRepository;
use Alchemy\Phrasea\Model\Repositories\FeedPublisherRepository;
@@ -46,6 +48,7 @@ class FeedController extends Controller
}
public function createFeedEntryAction(Request $request) {
/** @var Feed $feed */
$feed = $this->getFeedRepository()->find($request->request->get('feed_id'));
if (null === $feed) {
@@ -53,6 +56,8 @@ class FeedController extends Controller
}
$user = $this->getAuthenticatedUser();
/** @var FeedPublisher $publisher */
$publisher = $this->getFeedPublisherRepository()->findOneBy([
'feed' => $feed,
'user' => $user,

View File

@@ -136,6 +136,7 @@ class LanguageController
'or' => $translator->trans('or'),
'Suppr' => $translator->trans('Suppr'),
'Add new range' => $translator->trans('Add new range'),
'Save as VTT' => $translator->trans('Save as VTT'),
'Export ranges' => $translator->trans('Export ranges'),
'Start Range' => $translator->trans('Start Range'),
'End Range' => $translator->trans('End Range'),

View File

@@ -12,7 +12,7 @@ namespace Alchemy\Phrasea\Controller\Prod;
use Alchemy\Phrasea\Application\Helper\DataboxLoggerAware;
use Alchemy\Phrasea\Controller\Controller;
use Alchemy\Phrasea\Helper\Record as RecordHelper;
use Alchemy\Phrasea\Out\Module\PDF as PDFExport;
use Alchemy\Phrasea\Out\Module\PDFRecords;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -24,19 +24,27 @@ class PrinterController extends Controller
{
$printer = new RecordHelper\Printer($this->app, $request);
return $this->render('prod/actions/printer_default.html.twig', ['printer' => $printer, 'message' => '']);
$basketFeedbackId = null;
if($printer->is_basket() && ($basket = $printer->get_original_basket()) && ($validation = $basket->getValidation())) {
if($validation->getInitiator()->getId() === $this->app->getAuthenticatedUser()->getId()) {
$basketFeedbackId = $basket->getId();
}
}
return $this->render('prod/actions/printer_default.html.twig', ['printer' => $printer, 'message' => '', 'basketFeedbackId' => $basketFeedbackId]);
}
public function printAction(Request $request)
{
$printer = new RecordHelper\Printer($this->app, $request);
$b = $printer->get_original_basket();
$layout = $request->request->get('lay');
foreach ($printer->get_elements() as $record) {
$this->getDataboxLogger($record->getDatabox())->log($record, \Session_Logger::EVENT_PRINT, $layout, '');
}
$PDF = new PDFExport($this->app, $printer->get_elements(), $layout);
$PDF = new PDFRecords($this->app, $printer, $layout);
$response = new Response($PDF->render(), 200, array('Content-Type' => 'application/pdf'));
$response->headers->set('Pragma', 'public', true);
@@ -44,4 +52,5 @@ class PrinterController extends Controller
return $response;
}
}

View File

@@ -433,24 +433,15 @@ class QueryController extends Controller
// populates facets (aggregates)
$facets = [];
// $facetClauses = [];
foreach ($result->getFacets() as $facet) {
$facetName = $facet['name'];
if(array_key_exists($facetName, $fieldsInfosByName)) {
$f = $fieldsInfosByName[$facetName];
$facet['label'] = $f['trans_label'];
$facet['labels'] = $f['labels'];
$facet['type'] = strtoupper($f['type']) . "-AGGREGATE";
$facets[] = $facet;
// $facetClauses[] = [
// 'type' => strtoupper($f['type']) . "-AGGREGATE",
// 'field' => $f['field'],
// 'facet' => $facet
// ];
}
}

View File

@@ -458,9 +458,9 @@ class AccountController extends Controller
->setZipCode($request->request->get("form_zip"))
->setPhone($request->request->get("form_phone"))
->setFax($request->request->get("form_fax"))
->setJob($request->request->get("form_activity"))
->setJob($request->request->get("form_function"))
->setCompany($request->request->get("form_company"))
->setPosition($request->request->get("form_function"))
->setPosition($request->request->get("form_activity"))
->setNotifications((Boolean) $request->request->get("mail_notifications"));
$service->updateAccount($command);

View File

@@ -13,7 +13,9 @@ namespace Alchemy\Phrasea\Core\Event\Subscriber;
use Alchemy\Phrasea\Core\Event\FeedEntryEvent;
use Alchemy\Phrasea\Core\PhraseaEvents;
use Alchemy\Phrasea\Model\Entities\User;
use Alchemy\Phrasea\Model\Entities\WebhookEvent;
use Alchemy\Phrasea\Model\Manipulator\TokenManipulator;
use Alchemy\Phrasea\Notification\Receiver;
use Alchemy\Phrasea\Notification\Mail\MailInfoNewPublication;
@@ -53,36 +55,43 @@ class FeedEntrySubscriber extends AbstractNotificationSubscriber
do {
$results = $Query->limit($start, $perLoop)->execute()->get_results();
foreach ($results as $user_to_notif) {
$mailed = false;
$users_emailed = []; // for all users
$users_to_email = []; // list only users who must be emailed (=create tokens)
if ($params['notify_email'] && $this->shouldSendNotificationFor($user_to_notif, 'eventsmanager_notify_feed')) {
$readyToSend = false;
try {
$token = $this->app['manipulator.token']->createFeedEntryToken($user_to_notif, $entry);
$url = $this->app->url('lightbox', ['LOG' => $token->getValue()]);
$receiver = Receiver::fromUser($user_to_notif);
$readyToSend = true;
} catch (\Exception $e) {
}
if ($readyToSend) {
$mail = MailInfoNewPublication::create($this->app, $receiver);
$mail->setButtonUrl($url);
$mail->setAuthor($entry->getAuthorName());
$mail->setTitle($entry->getTitle());
$this->deliver($mail);
$mailed = true;
}
/** @var User $user */
foreach ($results as $user) {
$users_emailed[$user->getId()] = false;
if ($params['notify_email'] && $this->shouldSendNotificationFor($user, 'eventsmanager_notify_feed')) {
$users_to_email[$user->getId()] = $user;
}
$this->app['events-manager']->notify($user_to_notif->getId(), 'eventsmanager_notify_feed', $datas, $mailed);
}
// get many tokens in one shot
$tokens = $this->getTokenManipulator()->createFeedEntryTokens($users_to_email, $entry);
foreach($tokens as $token) {
try {
$url = $this->app->url('lightbox', ['LOG' => $token->getValue()]);
$receiver = Receiver::fromUser($token->getUser());
$mail = MailInfoNewPublication::create($this->app, $receiver);
$mail->setButtonUrl($url);
$mail->setAuthor($entry->getAuthorName());
$mail->setTitle($entry->getTitle());
$this->deliver($mail);
$users_emailed[$token->getUser()->getId()] = true;
}
catch (\Exception $e) {
// no-op
}
}
foreach($users_emailed as $id => $emailed) {
$this->app['events-manager']->notify($id, 'eventsmanager_notify_feed', $datas, $emailed);
}
$start += $perLoop;
} while (count($results) > 0);
}
while (count($results) > 0);
}
public static function getSubscribedEvents()
@@ -91,4 +100,12 @@ class FeedEntrySubscriber extends AbstractNotificationSubscriber
PhraseaEvents::FEED_ENTRY_CREATE => 'onCreate',
];
}
/**
* @return TokenManipulator
*/
private function getTokenManipulator()
{
return $this->app['manipulator.token'];
}
}

View File

@@ -97,7 +97,7 @@ class SearchEngineServiceProvider implements ServiceProviderInterface
});
$app['elasticsearch.facets_response.factory'] = $app->protect(function (array $response) use ($app) {
return new FacetsResponse(new Escaper(), $response, $app['search_engine.structure']);
return new FacetsResponse($app['elasticsearch.options'], new Escaper(), $response, $app['search_engine.structure']);
});
return $app;
@@ -228,7 +228,8 @@ class SearchEngineServiceProvider implements ServiceProviderInterface
});
$app['elasticsearch.options'] = $app->share(function ($app) {
$options = ElasticsearchOptions::fromArray($app['conf']->get(['main', 'search-engine', 'options'], []));
$conf = $app['conf']->get(['main', 'search-engine', 'options'], []);
$options = ElasticsearchOptions::fromArray($conf);
if (empty($options->getIndexName())) {
$options->setIndexName(strtolower(sprintf('phraseanet_%s', str_replace(

View File

@@ -16,7 +16,7 @@ class Version
/**
* @var string
*/
private $number = '4.1.0-alpha.19a';
private $number = '4.1.0-alpha.22a';
/**
* @var string

View File

@@ -657,8 +657,8 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper
->setEmail($parm['email'])
->setAddress($parm['address'])
->setZipCode($parm['zip'])
->setActivity($parm['function'])
->setJob($parm['activite'])
->setActivity($parm['activite'])
->setJob($parm['function'])
->setCompany($parm['company'])
->setPhone($parm['telephone'])
->setFax($parm['fax']);

View File

@@ -456,17 +456,27 @@ class Basket
}
public function hasRecord(Application $app, \record_adapter $record)
{
return !is_null($this->getElementByRecord($app, $record));
}
/**
* @param Application $app
* @param \record_adapter $record
* @return BasketElement
*/
public function getElementByRecord(Application $app, \record_adapter $record)
{
foreach ($this->getElements() as $basket_element) {
$bask_record = $basket_element->getRecord($app);
if ($bask_record->getRecordId() == $record->getRecordId()
&& $bask_record->getDataboxId() == $record->getDataboxId()) {
return true;
return $basket_element;
}
}
return false;
return null;
}
public function getSize(Application $app)

View File

@@ -15,7 +15,14 @@ use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* @ORM\Table(name="Tokens")
* @ORM\Table(name="Tokens",
* indexes={
* @ORM\index(name="type", columns={"type"}),
* @ORM\index(name="created", columns={"created"}),
* @ORM\index(name="updated", columns={"updated"}),
* @ORM\index(name="expiration", columns={"expiration"})
* }
* )
* @ORM\Entity(repositoryClass="Alchemy\Phrasea\Model\Repositories\TokenRepository")
*/
class Token

View File

@@ -30,7 +30,7 @@ class WebhookEventPayload
private $id;
/**
* @ORM\OneToOne(targetEntity="WebhookEventDelivery")
* @ORM\OneToOne(targetEntity="WebhookEventDelivery", inversedBy="payload")
* @ORM\JoinColumn(name="delivery_id", referencedColumnName="id")
*/
private $delivery;

View File

@@ -22,7 +22,6 @@ use RandomLib\Generator;
class TokenManipulator implements ManipulatorInterface
{
const LETTERS_AND_NUMBERS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const TYPE_FEED_ENTRY = 'FEED_ENTRY';
const TYPE_PASSWORD = 'password';
const TYPE_ACCOUNT_UNLOCK = 'account-unlock';
@@ -126,6 +125,38 @@ class TokenManipulator implements ManipulatorInterface
return $this->create($user, self::TYPE_FEED_ENTRY, null, $entry->getId());
}
/**
* Create feedEntryTokens for many users in one shot
*
* @param User[] $users
* @param FeedEntry $entry
* @return Token[]
* @throws \Doctrine\DBAL\DBALException
*/
public function createFeedEntryTokens($users, FeedEntry $entry)
{
// $this->removeExpiredTokens();
$tokens = [];
foreach ($users as $user) {
$value = $this->random->generateString(32, self::LETTERS_AND_NUMBERS) . $user->getId();
$token = new Token();
$token->setUser($user)
->setType(self::TYPE_FEED_ENTRY)
->setValue($value)
->setExpiration(null)
->setData($entry->getId());
$tokens[] = $token;
$this->om->persist($token);
}
$this->om->flush();
$this->om->clear();
return $tokens;
}
/**
* @param User $user
* @param $data

View File

@@ -368,7 +368,7 @@ class UserManipulator implements ManipulatorInterface
throw new InvalidArgumentException(sprintf('Email %s is not legal.', $email));
}
if (null !== $this->repository->findByEmail($email)) {
if (($email !== null) && (null !== $this->repository->findByEmail($email))) {
throw new RuntimeException(sprintf('User with email %s already exists.', $email));
}

View File

@@ -72,4 +72,9 @@ class TokenRepository extends EntityRepository
return $query->getResult();
}
public function getEntityManager()
{
return parent::getEntityManager();
}
}

View File

@@ -20,6 +20,8 @@ class PDF
protected $records;
protected $pdf;
const LAYOUT_FEEDBACK = 'feedback';
const LAYOUT_FEEDBACKONLY = 'feedbackOnly';
const LAYOUT_PREVIEW = 'preview';
const LAYOUT_PREVIEWCAPTION = 'previewCaption';
const LAYOUT_PREVIEWCAPTIONTDM = 'previewCaptionTdm';
@@ -27,64 +29,10 @@ class PDF
const LAYOUT_THUMBNAILGRID = 'thumbnailGrid';
const LAYOUT_CAPTION = 'caption';
public function __construct(Application $app, array $records, $layout)
public function __construct(Application $app)
{
$this->app = $app;
$list = [];
foreach ($records as $record) {
switch ($layout) {
default:
throw new \Exception('Unknown layout');
break;
case self::LAYOUT_PREVIEW:
case self::LAYOUT_PREVIEWCAPTION:
case self::LAYOUT_PREVIEWCAPTIONTDM:
try {
$subdef = $record->get_subdef('preview');
// fallback to thumbnail ( video, sound, doc ) ..
if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) {
$subdef = $record->get_thumbnail();
}
if (!$subdef->is_physically_present()) {
continue 2;
}
if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) {
continue 2;
}
} catch (\Exception $e) {
continue 2;
}
break;
case self::LAYOUT_THUMBNAILLIST:
case self::LAYOUT_THUMBNAILGRID:
try {
$subdef = $record->get_thumbnail();
if (!$subdef->is_physically_present()) {
continue 2;
}
if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) {
continue 2;
}
} catch (\Exception $e) {
continue 2;
}
break;
case self::LAYOUT_CAPTION:
break;
}
$record->setNumber(count($list) + 1);
$list[] = $record;
}
$this->records = $list;
$pdf = new PhraseaPDF("P", "mm", "A4", true, 'UTF-8', false);
$pdf->SetAuthor("Phraseanet");
@@ -92,29 +40,6 @@ class PDF
$pdf->SetDisplayMode("fullpage", "single");
$this->pdf = $pdf;
switch ($layout) {
case self::LAYOUT_PREVIEW:
$this->print_preview(false, false);
break;
case self::LAYOUT_PREVIEWCAPTION:
$this->print_preview(false, true);
break;
case self::LAYOUT_PREVIEWCAPTIONTDM:
$this->print_preview(true, true);
break;
case self::LAYOUT_THUMBNAILLIST:
$this->print_thumbnailList();
break;
case self::LAYOUT_THUMBNAILGRID:
$this->print_thumbnailGrid();
break;
case self::LAYOUT_CAPTION:
$this->print_caption();
break;
}
return $this;
}
public function render()
@@ -123,447 +48,4 @@ class PDF
return $this->pdf->Output('', 'S');
}
protected function print_thumbnailGrid($links = false)
{
$NDiapoW = 3;
$NDiapoH = 4;
$this->pdf->AddPage();
$oldMargins = $this->pdf->getMargins();
$tmargin = $oldMargins['top'];
$lmargin = $oldMargins['left'];
$bmargin = $oldMargins['bottom'];
$rmargin = $oldMargins['right'];
$this->pdf->SetLeftMargin($lmargin + 55);
$clientW = $this->pdf->getPageWidth() - $lmargin - $rmargin;
$clientH = $this->pdf->getPageHeight() - $tmargin - $bmargin;
$DiapoW = floor($clientW / $NDiapoW);
$DiapoH = floor($clientH / $NDiapoH);
$TitleH = 5;
$ImgSize = min($DiapoW, ($DiapoH - $TitleH)) - 5;
$npages = ceil(count($this->records) / ($NDiapoW * $NDiapoH));
$irow = $ipage = 0;
$icol = -1;
foreach ($this->records as $rec) {
/* @var \record_adapter $rec */
if (++$icol >= $NDiapoW) {
$icol = 0;
if (++$irow >= $NDiapoH) {
$irow = 0;
$ipage++;
$this->pdf->AddPage();
}
}
$fimg = null;
$himg = 0;
$subdef = $rec->get_subdef('preview');
if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) {
$subdef = $rec->get_thumbnail();
}
$fimg = $subdef->getRealPath();
if (!$this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($rec->getBaseId(), \ACL::NOWATERMARK)
&& $subdef->get_type() == \media_subdef::TYPE_IMAGE) {
$fimg = \recordutils_image::watermark($this->app, $subdef);
}
$wimg = $himg = $ImgSize;
if ($subdef->get_height() > 0 && $subdef->get_width() > 0) {
if ($subdef->get_width() > $subdef->get_height())
$himg = $wimg * $subdef->get_height() / $subdef->get_width();
else
$wimg = $himg * $subdef->get_width() / $subdef->get_height();
}
if ($fimg) {
$x = $lmargin + ($icol * $DiapoW);
$y = $tmargin + ($irow * $DiapoH);
$this->pdf->SetDrawColor(0);
$this->pdf->Rect($x, $y, $DiapoW, $DiapoH, "D");
$this->pdf->SetXY($x, $y + 1);
$this->pdf->SetFont(PhraseaPDF::FONT, '', 10);
$t = $irow . '-' . $x;
$t = $rec->get_title();
if ($links) {
$lk = $this->pdf->AddLink();
$this->pdf->SetLink($lk, 0, $npages + $rec->getNumber());
$this->pdf->Image(
$fimg
, $x + (($DiapoW - $wimg) / 2)
, $TitleH + $y + (($DiapoH - $TitleH - $himg) / 2)
, $wimg, $himg
, null, $lk
);
} else {
$this->pdf->Image($fimg
, $x + (($DiapoW - $wimg) / 2)
, $TitleH + $y + (($DiapoH - $TitleH - $himg) / 2)
, $wimg, $himg
);
}
$this->pdf->MultiCell($DiapoW, $TitleH, $t, '0', 'C', false);
}
}
$this->pdf->SetLeftMargin($oldMargins['left']);
}
protected function print_thumbnailList()
{
$this->pdf->AddPage();
$oldMargins = $this->pdf->getMargins();
$lmargin = $oldMargins['left'];
$rmargin = $oldMargins['right'];
$this->pdf->SetLeftMargin($lmargin + 55);
$ndoc = 0;
foreach ($this->records as $rec) {
/* @var \record_adapter $rec */
$subdef = $rec->get_subdef('thumbnail');
$fimg = $subdef->getRealPath();
$wimg = $himg = 50;
// 1px = 3.77952 mm
$finalWidth = round($subdef->get_width() / 3.779528, 2);
$finalHeight = round($subdef->get_height() / 3.779528, 2);
$aspectH = $finalWidth/$finalHeight;
$aspectW = $finalHeight/$finalWidth;
if ($finalWidth > 0 && $finalHeight > 0) {
if ($finalWidth > $finalHeight && $finalWidth > $wimg) {
$finalWidth = $wimg;
$finalHeight = $wimg * $aspectW;
} else if ($finalHeight > $finalWidth && $finalHeight > $himg) {
$finalHeight = $himg;
$finalWidth = $himg * $aspectH;
} else if ($finalHeight == $finalWidth & $finalWidth > $wimg) {
$finalHeight = $wimg;
$finalWidth = $himg;
}
}
if ($this->pdf->GetY() > $this->pdf->getPageHeight() - (6 + $finalHeight + 20))
$this->pdf->AddPage();
$title = "record : " . $rec->get_title();
$y = $this->pdf->GetY();
$t = \phrasea::bas_labels($rec->getBaseId(), $this->app);
$this->pdf->SetFont(PhraseaPDF::FONT, '', 10);
$this->pdf->SetFillColor(220, 220, 220);
$this->pdf->SetLeftMargin($lmargin);
$this->pdf->SetRightMargin($rmargin);
$this->pdf->SetX($lmargin);
$this->pdf->SetY($y);
$this->pdf->out = false;
$this->pdf->MultiCell(140, 4, $title, "LTR", "L", 1);
$y2 = $this->pdf->GetY();
$h = $y2 - $y;
$this->pdf->out = true;
$this->pdf->SetX($lmargin);
$this->pdf->SetY($y);
$this->pdf->Cell(0, $h, "", "LTR", 1, "R", 1);
$this->pdf->SetX($lmargin);
$this->pdf->SetY($y);
$this->pdf->Cell(0, 4, $t, "", 1, "R");
$this->pdf->SetX($lmargin);
$this->pdf->SetY($y);
$this->pdf->MultiCell(140, 4, $title, "", "L");
$this->pdf->SetX($lmargin);
$this->pdf->SetY($y = $y2);
$this->pdf->SetLeftMargin($lmargin + 55);
$this->pdf->SetY($y + 2);
if ($fimg) {
$y = $this->pdf->GetY();
$this->pdf->Image($fimg, $lmargin, $y, $finalWidth, $finalHeight);
$this->pdf->SetY($y + 3);
}
$nf = 0;
$this->pdf->SetX($lmargin + 55);
$p0 = $this->pdf->PageNo();
$y0 = $this->pdf->GetY();
foreach ($rec->get_caption()->get_fields() as $field) {
/* @var $field caption_field */
$this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
$this->pdf->Write(5, $field->get_name() . " : ");
$this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
$this->pdf->Write(5, $field->get_serialized_values());
$this->pdf->Write(6, "\n");
$nf++;
}
if ($this->pdf->PageNo() == $p0 && ($this->pdf->GetY() - $y0) < $finalHeight)
$this->pdf->SetY($y0 + $finalHeight);
$ndoc++;
}
$this->pdf->SetLeftMargin($lmargin);
}
protected function print_caption()
{
$this->pdf->AddPage();
$oldMargins = $this->pdf->getMargins();
$lmargin = $oldMargins['left'];
$rmargin = $oldMargins['right'];
foreach ($this->records as $rec) {
$title = "record : " . $rec->get_title();
$y = $this->pdf->GetY();
if($this->pdf->getPageHeight() - $y < 20){ // height of the footer is 15
$this->pdf->AddPage();
$y = $oldMargins['top'];
}
$t = \phrasea::bas_labels($rec->getBaseId(), $this->app);
$this->pdf->SetFont(PhraseaPDF::FONT, '', 10);
$this->pdf->SetFillColor(220, 220, 220);
$this->pdf->SetLeftMargin($lmargin);
$this->pdf->SetRightMargin($rmargin);
$this->pdf->SetX($lmargin);
$this->pdf->SetY($y);
$this->pdf->out = false;
$this->pdf->MultiCell(140, 4, $title, "LTR", "L", 1);
$y2 = $this->pdf->GetY();
$h = $y2 - $y;
$this->pdf->out = true;
$this->pdf->SetX($lmargin);
$this->pdf->SetY($y);
$this->pdf->Cell(0, $h, "", "LTR", 1, "R", 1);
$this->pdf->SetX($lmargin);
$this->pdf->SetY($y);
$this->pdf->Cell(0, 4, $t, "", 1, "R");
$this->pdf->SetX($lmargin);
$this->pdf->SetY($y);
$this->pdf->MultiCell(140, 4, $title, "", "L");
$this->pdf->SetX($lmargin);
$this->pdf->SetY($y = $y2);
$this->pdf->SetY($y + 2);
foreach ($rec->get_caption()->get_fields() as $field) {
$this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
$this->pdf->Write(5, $field->get_name() . " : ");
$this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
$t = str_replace(
["&lt;", "&gt;", "&amp;"]
, ["<", ">", "&"]
, strip_tags($field->get_serialized_values())
);
$this->pdf->Write(5, $t);
$this->pdf->Write(6, "\n");
}
$this->pdf->SetY($this->pdf->GetY() + 10);
}
}
protected function print_preview($withtdm, $write_caption)
{
if ($withtdm === true) {
$this->print_thumbnailGrid($this->pdf, $this->records, true);
}
foreach ($this->records as $krec => $rec) {
/* @var \record_adapter $rec */
$this->pdf->AddPage();
if ($withtdm === "CALCPAGES") {
$rec->setNumber($this->pdf->PageNo());
}
$lmargin = $this->pdf->GetX();
$himg = 0;
$y = 0;
$miniConv = NULL;
$LEFT__TEXT = "";
$LEFT__IMG = NULL;
$RIGHT_TEXT = "";
$RIGHT_IMG = NULL;
$LEFT__IMG = $this->app['root.path'] . "/config/minilogos/logopdf_" . $rec->getDataboxId() . ".jpg";
if (!is_file($LEFT__IMG)) {
$databox = $rec->getDatabox();
$str = $databox->get_sxml_structure();
$vn = (string) ($str->pdfPrintLogo);
if (($vn * 1) == 1) {
$LEFT__TEXT = $databox->get_label($this->app['locale']);
}
}
$collection = \collection::getByBaseId($this->app, $rec->getBaseId());
$vn = "";
if (false !== $str = simplexml_load_string($collection->get_prefs())) {
$vn = (string) ($str->pdfPrintappear);
}
if ($vn == "" || $vn == "1") {
$RIGHT_TEXT = \phrasea::bas_labels($rec->getBaseId(), $this->app);
} elseif ($vn == "2") {
$RIGHT_IMG = $this->app['root.path'] . "/config/minilogos/" . $rec->getBaseId();
}
$xtmp = $this->pdf->GetX();
$ytmp = $this->pdf->GetY();
$this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
$this->pdf->SetFillColor(220, 220, 220);
$y = $this->pdf->GetY();
$this->pdf->MultiCell(95, 7, $LEFT__TEXT, "LTB", "L", 1);
$y2 = $this->pdf->GetY();
$h = $y2 - $y;
$this->pdf->SetY($y);
$this->pdf->SetX(105);
$this->pdf->Cell(95, $h, $RIGHT_TEXT, "TBR", 1, "R", 1);
if ($LEFT__TEXT == "" && is_file($LEFT__IMG)) {
if ($size = @getimagesize($LEFT__IMG)) {
$wmm = (int) $size[0] * 25.4 / 72;
$hmm = (int) $size[1] * 25.4 / 72;
if ($hmm > 6) {
$coeff = $hmm / 6;
$wmm = (int) $wmm / $coeff;
$hmm = (int) $hmm / $coeff;
}
$this->pdf->Image($LEFT__IMG, $xtmp + 0.5, $ytmp + 0.5, $wmm, $hmm);
}
}
if ($RIGHT_IMG != NULL && is_file($RIGHT_IMG)) {
if ($size = @getimagesize($RIGHT_IMG)) {
if ($size[2] == '1') {
if (!isset($miniConv[$RIGHT_IMG])) {
$tmp_filename = tempnam('minilogos/', 'gif4fpdf');
$img = imagecreatefromgif($RIGHT_IMG);
imageinterlace($img, 0);
imagepng($img, $tmp_filename);
rename($tmp_filename, $tmp_filename . '.png');
$miniConv[$RIGHT_IMG] = $tmp_filename . '.png';
$RIGHT_IMG = $tmp_filename . '.png';
} else
$RIGHT_IMG = $miniConv[$RIGHT_IMG];
$wmm = (int) $size[0] * 25.4 / 72;
$hmm = (int) $size[1] * 25.4 / 72;
if ($hmm > 6) {
$coeff = $hmm / 6;
$wmm = (int) $wmm / $coeff;
$hmm = (int) $hmm / $coeff;
}
$tt = 0;
if ($hmm < 6)
$tt = (6 - $hmm) / 2;
$this->pdf->Image($RIGHT_IMG, 200 - 0.5 - $wmm, $ytmp + 0.5 + $tt);
} else {
$wmm = (int) $size[0] * 25.4 / 72;
$hmm = (int) $size[1] * 25.4 / 72;
if ($hmm > 6) {
$coeff = $hmm / 6;
$wmm = (int) $wmm / $coeff;
$hmm = (int) $hmm / $coeff;
}
$this->pdf->Image($RIGHT_IMG, 200 - 0.5 - $wmm, $ytmp + 0.5);
}
}
}
$y = $this->pdf->GetY() + 5;
$subdef = $rec->get_subdef('preview');
if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) {
$subdef = $rec->get_thumbnail();
}
$f = $subdef->getRealPath();
if (!$this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($rec->getBaseId(), \ACL::NOWATERMARK)
&& $subdef->get_type() == \media_subdef::TYPE_IMAGE)
$f = \recordutils_image::watermark($this->app, $subdef);
// original height / original width x new width = new height
$wimg = $himg = 150; // preview dans un carre de 150 mm
// 1px = 3.77952 mm
$finalWidth = round($subdef->get_width() / 3.779528, 2);
$finalHeight = round($subdef->get_height() / 3.779528, 2);
$aspectH = $finalWidth/$finalHeight;
$aspectW = $finalHeight/$finalWidth;
if ($finalWidth > 0 && $finalHeight > 0) {
if ($finalWidth > $finalHeight && $finalWidth > $wimg) {
$finalWidth = $wimg;
$finalHeight = $wimg * $aspectW;
} else if ($finalHeight > $finalWidth && $finalHeight > $himg) {
$finalHeight = $himg;
$finalWidth = $himg * $aspectH;
} else if ($finalHeight == $finalWidth & $finalWidth > $wimg) {
$finalHeight = $wimg;
$finalWidth = $himg;
}
}
$this->pdf->Image($f, (210 - $finalWidth) / 2, $y, $finalWidth, $finalHeight);
if ($miniConv != NULL) {
foreach ($miniConv as $oneF)
unlink($oneF);
}
$this->pdf->SetXY($lmargin, $y += ( $finalHeight + 5));
$nf = 0;
if ($write_caption) {
foreach ($rec->get_caption()->get_fields() as $field) {
/* @var $field caption_field */
if ($nf > 0) {
$this->pdf->Write(6, "\n");
}
$this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
$this->pdf->Write(5, $field->get_name() . " : ");
$this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
$t = str_replace(
["&lt;", "&gt;", "&amp;"]
, ["<", ">", "&"]
, strip_tags($field->get_serialized_values())
);
$this->pdf->Write(5, $t);
$nf++;
}
}
}
return;
}
}

View File

@@ -0,0 +1,789 @@
<?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\Out\Module;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Out\Tool\PhraseaPDF;
use Alchemy\Phrasea\Helper\Record\Printer;
use Alchemy\Phrasea\Model\Entities\ValidationParticipant;
use \IntlDateFormatter as DateFormatter;
class PDFRecords extends PDF
{
/** @var Printer */
private $printer;
public function __construct(Application $app, Printer $printer, $layout)
{
parent::__construct($app);
$this->printer = $printer;
$records = $printer->get_elements();
$list = [];
foreach ($records as $record) {
switch ($layout) {
default:
throw new \Exception('Unknown layout');
break;
case self::LAYOUT_FEEDBACK:
case self::LAYOUT_FEEDBACKONLY:
case self::LAYOUT_PREVIEW:
case self::LAYOUT_PREVIEWCAPTION:
case self::LAYOUT_PREVIEWCAPTIONTDM:
try {
$subdef = $record->get_subdef('preview');
// fallback to thumbnail ( video, sound, doc ) ..
if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) {
$subdef = $record->get_thumbnail();
}
if (!$subdef->is_physically_present()) {
continue 2;
}
if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) {
continue 2;
}
} catch (\Exception $e) {
continue 2;
}
break;
case self::LAYOUT_THUMBNAILLIST:
case self::LAYOUT_THUMBNAILGRID:
try {
$subdef = $record->get_thumbnail();
if (!$subdef->is_physically_present()) {
continue 2;
}
if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) {
continue 2;
}
} catch (\Exception $e) {
continue 2;
}
break;
case self::LAYOUT_CAPTION:
break;
}
$record->setNumber(count($list) + 1);
$list[] = $record;
}
$this->records = $list;
switch ($layout) {
case self::LAYOUT_FEEDBACK:
$this->print_preview(false, true, true);
break;
case self::LAYOUT_FEEDBACKONLY:
$this->print_preview(false, false, true);
break;
case self::LAYOUT_PREVIEW:
$this->print_preview(false, false, false);
break;
case self::LAYOUT_PREVIEWCAPTION:
$this->print_preview(false, true, false);
break;
case self::LAYOUT_PREVIEWCAPTIONTDM:
$this->print_preview(true, true, false);
break;
case self::LAYOUT_THUMBNAILLIST:
$this->print_thumbnailList();
break;
case self::LAYOUT_THUMBNAILGRID:
$this->print_thumbnailGrid();
break;
case self::LAYOUT_CAPTION:
$this->print_caption();
break;
}
}
protected function print_thumbnailGrid($links = false)
{
$NDiapoW = 3;
$NDiapoH = 4;
$this->pdf->AddPage();
$oldMargins = $this->pdf->getMargins();
$tmargin = $oldMargins['top'];
$lmargin = $oldMargins['left'];
$bmargin = $oldMargins['bottom'];
$rmargin = $oldMargins['right'];
$this->pdf->SetLeftMargin($lmargin + 55);
$clientW = $this->pdf->getPageWidth() - $lmargin - $rmargin;
$clientH = $this->pdf->getPageHeight() - $tmargin - $bmargin;
$DiapoW = floor($clientW / $NDiapoW);
$DiapoH = floor($clientH / $NDiapoH);
$TitleH = 5;
$ImgSize = min($DiapoW, ($DiapoH - $TitleH)) - 5;
$npages = ceil(count($this->records) / ($NDiapoW * $NDiapoH));
$irow = $ipage = 0;
$icol = -1;
foreach ($this->records as $rec) {
/* @var \record_adapter $rec */
if (++$icol >= $NDiapoW) {
$icol = 0;
if (++$irow >= $NDiapoH) {
$irow = 0;
$ipage++;
$this->pdf->AddPage();
}
}
$fimg = null;
$himg = 0;
$subdef = $rec->get_subdef('preview');
if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) {
$subdef = $rec->get_thumbnail();
}
$fimg = $subdef->getRealPath();
if (!$this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($rec->getBaseId(), \ACL::NOWATERMARK)
&& $subdef->get_type() == \media_subdef::TYPE_IMAGE) {
$fimg = \recordutils_image::watermark($this->app, $subdef);
}
$wimg = $himg = $ImgSize;
if ($subdef->get_height() > 0 && $subdef->get_width() > 0) {
if ($subdef->get_width() > $subdef->get_height())
$himg = $wimg * $subdef->get_height() / $subdef->get_width();
else
$wimg = $himg * $subdef->get_width() / $subdef->get_height();
}
if ($fimg) {
$x = $lmargin + ($icol * $DiapoW);
$y = $tmargin + ($irow * $DiapoH);
$this->pdf->SetDrawColor(0);
$this->pdf->Rect($x, $y, $DiapoW, $DiapoH, "D");
$this->pdf->SetXY($x, $y + 1);
$this->pdf->SetFont(PhraseaPDF::FONT, '', 10);
$t = $irow . '-' . $x;
$t = $rec->get_title();
if ($links) {
$lk = $this->pdf->AddLink();
$this->pdf->SetLink($lk, 0, $npages + $rec->getNumber());
$this->pdf->Image(
$fimg
, $x + (($DiapoW - $wimg) / 2)
, $TitleH + $y + (($DiapoH - $TitleH - $himg) / 2)
, $wimg, $himg
, null, $lk
);
} else {
$this->pdf->Image($fimg
, $x + (($DiapoW - $wimg) / 2)
, $TitleH + $y + (($DiapoH - $TitleH - $himg) / 2)
, $wimg, $himg
);
}
$this->pdf->MultiCell($DiapoW, $TitleH, $t, '0', 'C', false);
}
}
$this->pdf->SetLeftMargin($oldMargins['left']);
}
protected function print_thumbnailList()
{
$this->pdf->AddPage();
$oldMargins = $this->pdf->getMargins();
$lmargin = $oldMargins['left'];
$rmargin = $oldMargins['right'];
$this->pdf->SetLeftMargin($lmargin + 55);
$ndoc = 0;
foreach ($this->records as $rec) {
/* @var \record_adapter $rec */
$subdef = $rec->get_subdef('thumbnail');
$fimg = $subdef->getRealPath();
$wimg = $himg = 50;
// 1px = 3.77952 mm
$finalWidth = round($subdef->get_width() / 3.779528, 2);
$finalHeight = round($subdef->get_height() / 3.779528, 2);
$aspectH = $finalWidth/$finalHeight;
$aspectW = $finalHeight/$finalWidth;
if ($finalWidth > 0 && $finalHeight > 0) {
if ($finalWidth > $finalHeight && $finalWidth > $wimg) {
$finalWidth = $wimg;
$finalHeight = $wimg * $aspectW;
} else if ($finalHeight > $finalWidth && $finalHeight > $himg) {
$finalHeight = $himg;
$finalWidth = $himg * $aspectH;
} else if ($finalHeight == $finalWidth & $finalWidth > $wimg) {
$finalHeight = $wimg;
$finalWidth = $himg;
}
}
if ($this->pdf->GetY() > $this->pdf->getPageHeight() - (6 + $finalHeight + 20))
$this->pdf->AddPage();
$title = "record : " . $rec->get_title();
$y = $this->pdf->GetY();
$t = \phrasea::bas_labels($rec->getBaseId(), $this->app);
$this->pdf->SetFont(PhraseaPDF::FONT, '', 10);
$this->pdf->SetFillColor(220, 220, 220);
$this->pdf->SetLeftMargin($lmargin);
$this->pdf->SetRightMargin($rmargin);
$this->pdf->SetX($lmargin);
$this->pdf->SetY($y);
$this->pdf->out = false;
$this->pdf->MultiCell(140, 4, $title, "LTR", "L", 1);
$y2 = $this->pdf->GetY();
$h = $y2 - $y;
$this->pdf->out = true;
$this->pdf->SetX($lmargin);
$this->pdf->SetY($y);
$this->pdf->Cell(0, $h, "", "LTR", 1, "R", 1);
$this->pdf->SetX($lmargin);
$this->pdf->SetY($y);
$this->pdf->Cell(0, 4, $t, "", 1, "R");
$this->pdf->SetX($lmargin);
$this->pdf->SetY($y);
$this->pdf->MultiCell(140, 4, $title, "", "L");
$this->pdf->SetX($lmargin);
$this->pdf->SetY($y = $y2);
$this->pdf->SetLeftMargin($lmargin + 55);
$this->pdf->SetY($y + 2);
if ($fimg) {
$y = $this->pdf->GetY();
$this->pdf->Image($fimg, $lmargin, $y, $finalWidth, $finalHeight);
$this->pdf->SetY($y + 3);
}
$nf = 0;
$this->pdf->SetX($lmargin + 55);
$p0 = $this->pdf->PageNo();
$y0 = $this->pdf->GetY();
foreach ($rec->get_caption()->get_fields() as $field) {
/* @var $field caption_field */
$this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
$this->pdf->Write(5, $field->get_name() . " : ");
$this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
$this->pdf->Write(5, $field->get_serialized_values());
$this->pdf->Write(6, "\n");
$nf++;
}
if ($this->pdf->PageNo() == $p0 && ($this->pdf->GetY() - $y0) < $finalHeight)
$this->pdf->SetY($y0 + $finalHeight);
$ndoc++;
}
$this->pdf->SetLeftMargin($lmargin);
}
protected function print_caption()
{
$this->pdf->AddPage();
$oldMargins = $this->pdf->getMargins();
$lmargin = $oldMargins['left'];
$rmargin = $oldMargins['right'];
foreach ($this->records as $rec) {
$title = "record : " . $rec->get_title();
$y = $this->pdf->GetY();
if($this->pdf->getPageHeight() - $y < 20){ // height of the footer is 15
$this->pdf->AddPage();
$y = $oldMargins['top'];
}
$t = \phrasea::bas_labels($rec->getBaseId(), $this->app);
$this->pdf->SetFont(PhraseaPDF::FONT, '', 10);
$this->pdf->SetFillColor(220, 220, 220);
$this->pdf->SetLeftMargin($lmargin);
$this->pdf->SetRightMargin($rmargin);
$this->pdf->SetX($lmargin);
$this->pdf->SetY($y);
$this->pdf->out = false;
$this->pdf->MultiCell(140, 4, $title, "LTR", "L", 1);
$y2 = $this->pdf->GetY();
$h = $y2 - $y;
$this->pdf->out = true;
$this->pdf->SetX($lmargin);
$this->pdf->SetY($y);
$this->pdf->Cell(0, $h, "", "LTR", 1, "R", 1);
$this->pdf->SetX($lmargin);
$this->pdf->SetY($y);
$this->pdf->Cell(0, 4, $t, "", 1, "R");
$this->pdf->SetX($lmargin);
$this->pdf->SetY($y);
$this->pdf->MultiCell(140, 4, $title, "", "L");
$this->pdf->SetX($lmargin);
$this->pdf->SetY($y = $y2);
$this->pdf->SetY($y + 2);
foreach ($rec->get_caption()->get_fields() as $field) {
if ($field->get_databox_field()->get_gui_visible()) {
$this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
$this->pdf->Write(5, $field->get_name() . " : ");
$this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
$t = str_replace(
["&lt;", "&gt;", "&amp;"]
, ["<", ">", "&"]
, strip_tags($field->get_serialized_values())
);
$this->pdf->Write(5, $t);
$this->pdf->Write(6, "\n");
}
}
$this->pdf->SetY($this->pdf->GetY() + 10);
}
}
protected function print_preview($withtdm, $write_caption, $withfeedback)
{
$basket = $validation = null;
if($this->printer->is_basket()) {
$basket = $this->printer->get_original_basket();
if($withfeedback) {
// first page : validation informations
$validation = $basket->getValidation();
$this->pdf->AddPage();
$this->pdf->SetY(20);
$this->pdf->SetFont(PhraseaPDF::FONT, 'B', 14);
$this->pdf->Cell(0, 0,
$this->app->trans("print_feedback:: Feedback on basket %name%", ['%name%'=>$basket->getName()]),
'', 1, 'C', false);
$this->pdf->SetY($this->pdf->GetY()+10);
$this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
$this->pdf->Write(5, $this->app->trans("print_feedback:: Document generated on : ") . " ");
$this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
$this->pdf->Write(5, $this->formatDate(new \DateTime('now')));
$this->pdf->Write(12, "\n");
$this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
$this->pdf->Write(5, $this->app->trans("print_feedback:: Feedback initiated by : ") . " ");
$this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
$this->pdf->Write(5, $this->getDisplayName($validation->getInitiator()));
$this->pdf->Write(6, "\n");
$this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
$this->pdf->Write(5, $this->app->trans("print_feedback:: Feedback initiated on : ") . " ");
$this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
$this->pdf->Write(5, $this->formatDate($validation->getCreated()));
$this->pdf->Write(6, "\n");
$this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
$this->pdf->Write(5, $this->app->trans("print_feedback:: Feedback expiring on : ") . " ");
$this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
$this->pdf->Write(5, $this->formatDate($validation->getExpires()));
$this->pdf->Write(12, "\n");
$this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
$validation->isFinished() ? $this->pdf->Write(5, $this->app->trans("print_feedback:: Feedback expired")) : $this->pdf->Write(5, $this->app->trans("print_feedback:: Feedback active"));
$this->pdf->Write(12, "\n");
$this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
$this->pdf->Write(5, $this->app->trans("print_feedback:: Participants : "));
$this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
foreach ($validation->getParticipants() as $participant) {
$this->pdf->Write(5, "\n - " . $this->getDisplayName($participant->getUser()));
}
}
}
if ($withtdm === true) {
$this->print_thumbnailGrid($this->pdf, $this->records, true);
}
foreach ($this->records as $krec => $rec) {
/* @var \record_adapter $rec */
$this->pdf->AddPage();
if ($withtdm === "CALCPAGES") {
$rec->setNumber($this->pdf->PageNo());
}
$lmargin = $this->pdf->GetX();
$himg = 0;
$y = 0;
$miniConv = NULL;
$LEFT__TEXT = "";
$LEFT__IMG = NULL;
$RIGHT_TEXT = "";
$RIGHT_IMG = NULL;
$LEFT__IMG = $this->app['root.path'] . "/config/minilogos/logopdf_" . $rec->getDataboxId() . ".jpg";
if (!is_file($LEFT__IMG)) {
$databox = $rec->getDatabox();
$str = $databox->get_sxml_structure();
$vn = (string) ($str->pdfPrintLogo);
if (($vn * 1) == 1) {
$LEFT__TEXT = $databox->get_label($this->app['locale']);
}
}
$collection = \collection::getByBaseId($this->app, $rec->getBaseId());
$vn = "";
if (false !== $str = simplexml_load_string($collection->get_prefs())) {
$vn = (string) ($str->pdfPrintappear);
}
if ($vn == "" || $vn == "1") {
$RIGHT_TEXT = \phrasea::bas_labels($rec->getBaseId(), $this->app);
} elseif ($vn == "2") {
$RIGHT_IMG = $this->app['root.path'] . "/config/minilogos/" . $rec->getBaseId();
}
$xtmp = $this->pdf->GetX();
$ytmp = $this->pdf->GetY();
$this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
$this->pdf->SetFillColor(220, 220, 220);
$y = $this->pdf->GetY();
$this->pdf->MultiCell(95, 7, $LEFT__TEXT, "LTB", "L", 1);
$y2 = $this->pdf->GetY();
$h = $y2 - $y;
$this->pdf->SetY($y);
$this->pdf->SetX(105);
$this->pdf->Cell(95, $h, $RIGHT_TEXT, "TBR", 1, "R", 1);
if($basket) {
$ord = $basket->getElementByRecord($this->app, $rec)->getOrd();
$this->pdf->SetY($y);
$this->pdf->SetX(10);
$this->pdf->Cell(190, $h, $ord, "", 1, "C", 0);
}
if ($LEFT__TEXT == "" && is_file($LEFT__IMG)) {
if ($size = @getimagesize($LEFT__IMG)) {
$wmm = (int) $size[0] * 25.4 / 72;
$hmm = (int) $size[1] * 25.4 / 72;
if ($hmm > 6) {
$coeff = $hmm / 6;
$wmm = (int) $wmm / $coeff;
$hmm = (int) $hmm / $coeff;
}
$this->pdf->Image($LEFT__IMG, $xtmp + 0.5, $ytmp + 0.5, $wmm, $hmm);
}
}
if ($RIGHT_IMG != NULL && is_file($RIGHT_IMG)) {
if ($size = @getimagesize($RIGHT_IMG)) {
if ($size[2] == '1') {
if (!isset($miniConv[$RIGHT_IMG])) {
$tmp_filename = tempnam('minilogos/', 'gif4fpdf');
$img = imagecreatefromgif($RIGHT_IMG);
imageinterlace($img, 0);
imagepng($img, $tmp_filename);
rename($tmp_filename, $tmp_filename . '.png');
$miniConv[$RIGHT_IMG] = $tmp_filename . '.png';
$RIGHT_IMG = $tmp_filename . '.png';
} else
$RIGHT_IMG = $miniConv[$RIGHT_IMG];
$wmm = (int) $size[0] * 25.4 / 72;
$hmm = (int) $size[1] * 25.4 / 72;
if ($hmm > 6) {
$coeff = $hmm / 6;
$wmm = (int) $wmm / $coeff;
$hmm = (int) $hmm / $coeff;
}
$tt = 0;
if ($hmm < 6)
$tt = (6 - $hmm) / 2;
$this->pdf->Image($RIGHT_IMG, 200 - 0.5 - $wmm, $ytmp + 0.5 + $tt);
} else {
$wmm = (int) $size[0] * 25.4 / 72;
$hmm = (int) $size[1] * 25.4 / 72;
if ($hmm > 6) {
$coeff = $hmm / 6;
$wmm = (int) $wmm / $coeff;
$hmm = (int) $hmm / $coeff;
}
$this->pdf->Image($RIGHT_IMG, 200 - 0.5 - $wmm, $ytmp + 0.5);
}
}
}
$y = $this->pdf->GetY() + 5;
$subdef = $rec->get_subdef('preview');
if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) {
$subdef = $rec->get_thumbnail();
}
$f = $subdef->getRealPath();
if (!$this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($rec->getBaseId(), \ACL::NOWATERMARK)
&& $subdef->get_type() == \media_subdef::TYPE_IMAGE)
$f = \recordutils_image::watermark($this->app, $subdef);
// original height / original width x new width = new height
$wimg = $himg = 150; // preview dans un carre de 150 mm
// 1px = 3.77952 mm
$finalWidth = round($subdef->get_width() / 3.779528, 2);
$finalHeight = round($subdef->get_height() / 3.779528, 2);
$aspectH = $finalWidth/$finalHeight;
$aspectW = $finalHeight/$finalWidth;
if ($finalWidth > 0 && $finalHeight > 0) {
if ($finalWidth > $finalHeight && $finalWidth > $wimg) {
$finalWidth = $wimg;
$finalHeight = $wimg * $aspectW;
} else if ($finalHeight > $finalWidth && $finalHeight > $himg) {
$finalHeight = $himg;
$finalWidth = $himg * $aspectH;
} else if ($finalHeight == $finalWidth & $finalWidth > $wimg) {
$finalHeight = $wimg;
$finalWidth = $himg;
}
}
$this->pdf->Image($f, (210 - $finalWidth) / 2, $y, $finalWidth, $finalHeight);
if ($miniConv != NULL) {
foreach ($miniConv as $oneF)
unlink($oneF);
}
$this->pdf->SetXY($lmargin, $y += ( $finalHeight + 5));
$this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
$this->pdf->Write(5, $this->app->trans("print_feedback:: record title: ") . " ");
$this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
$this->pdf->Write(5, $rec->get_title());
$this->pdf->Write(6, "\n");
$this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
$this->pdf->Write(5, $this->app->trans("print_feedback:: record id: ") . " ");
$this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
$this->pdf->Write(5, $rec->getRecordId());
$this->pdf->Write(6, "\n");
$this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
$this->pdf->Write(5, $this->app->trans("print_feedback:: base name: ") . " ");
$this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
$this->pdf->Write(5, $rec->getDatabox()->get_label($this->app['locale']));
$this->pdf->Write(6, "\n");
$this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
$this->pdf->Write(5, $this->app->trans("print_feedback:: originale filename: ") . " ");
$this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
$this->pdf->Write(5, $rec->get_original_name());
$this->pdf->Write(6, "\n");
$this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
$this->pdf->Write(5, $this->app->trans("print_feedback:: document Uuid: ") . " ");
$this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
$this->pdf->Write(5, $rec->getUUID());
$this->pdf->Write(6, "\n");
$nf = 0;
if($basket && $validation) {
/** @var ValidationParticipant $participant */
if ($nf > 0) {
$this->pdf->Write(6, "\n");
}
$this->pdf->Write(12, "\n");
$this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
$this->pdf->Write(5, $this->app->trans("print_feedback:: Votes :"));
$this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
$basketElement = $basket->getElementByRecord($this->app, $rec);
$iparticipant = 0;
foreach ($validation->getParticipants() as $participant) {
$this->pdf->Write(6, "\n");
if($iparticipant++ > 0) {
// $this->pdf->SetY($this->pdf->GetY()+1);
}
$validationData = $basketElement->getUserValidationDatas($participant->getUser());
$this->pdf->Write(5, '- ' . $this->getDisplayName($participant->getUser(), true). " : ");
$r = $validationData->getAgreement();
$this->pdf->SetX(100);
if ($r === null) {
$this->pdf->Write(0, $this->app->trans("print_feedback:: non voté"));
}
else {
if($r) {
$this->pdf->SetTextColor(0, 127, 0);
$this->pdf->Write(0, $this->app->trans("print_feedback:: Oui"));
}
else {
$this->pdf->SetTextColor(200, 0, 0);
$this->pdf->Write(0, $this->app->trans("print_feedback:: Non"));
}
$this->pdf->SetTextColor(0);
$this->pdf->Write(0, " (" . $this->formatDate($validationData->getUpdated()) . ")");
}
if (($note = (string)($validationData->getNote())) !== '') {
$this->pdf->SetFont(PhraseaPDF::FONT, 'I', 11);
$this->pdf->Write(5,"\n");
$this->pdf->SetX(100);
$this->pdf->MultiCell(95, 0, $note, '', "L", false);
$this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
}
$nf++;
}
}
if ($write_caption) {
$this->pdf->Write(12, "\n");
foreach ($rec->get_caption()->get_fields() as $field) {
/* @var $field caption_field */
if ($field->get_databox_field()->get_gui_visible()) {
if ($nf > 0) {
$this->pdf->Write(6, "\n");
}
$this->pdf->SetFont(PhraseaPDF::FONT, 'B', 12);
$this->pdf->Write(5, $field->get_name() . " : ");
$this->pdf->SetFont(PhraseaPDF::FONT, '', 12);
$t = str_replace(
["&lt;", "&gt;", "&amp;"]
, ["<", ">", "&"]
, strip_tags($field->get_serialized_values())
);
$this->pdf->Write(5, $t);
$nf++;
}
}
}
}
return;
}
private function formatDate(\DateTime $date)
{
$locale = $this->app['locale'];
switch ($locale) {
case 'fr':
$fmt = new DateFormatter(
'fr_FR',
DateFormatter::LONG,
DateFormatter::NONE
);
$date_formated = $fmt->format($date);
break;
case 'en':
$fmt = new DateFormatter(
'en_EN',
DateFormatter::LONG,
DateFormatter::NONE
);
$date_formated = $fmt->format($date);
break;
case 'de':
$fmt = new DateFormatter(
'de_DE',
DateFormatter::LONG,
DateFormatter::NONE
);
$date_formated = $fmt->format($date);
break;
default:
$fmt = new DateFormatter(
'en_EN',
DateFormatter::LONG,
DateFormatter::NONE ,
null,
null,
'yyyy/mm/dd'
);
$date_formated = $fmt->format($date);
break;
}
return $date_formated;
}
private function getDisplayName($user, $short = false)
{
$displayName = '';
if (trim($user->getLastName()) !== '' || trim($user->getFirstName()) !== '') {
$displayName = $user->getFirstName() . ('' !== $user->getFirstName() && '' !== $user->getLastName() ? ' ' : '') . $user->getLastName() ;
if ($short) {
return $displayName;
}
}
$email = trim($user->getEmail());
if ($email === '') {
$email = $user->getLogin();
}
if ($displayName !== '') {
return $displayName . ", " . $email;
} else {
return $email;
}
}
}

View File

@@ -668,17 +668,20 @@ class ElasticSearchEngine implements SearchEngineInterface
}
// fields aggregates
$structure = $this->context_factory->getLimitedStructure($options);
foreach ($structure->getFacetFields() as $name => $field) {
// 2015-05-26 (mdarse) Removed databox filtering.
// It was already done by the ACL filter in the query scope, so no
// document that shouldn't be displayed can go this far.
$agg = [
'terms' => [
'field' => $field->getIndexField(true),
'size' => $field->getFacetValuesLimit()
]
];
$aggs[$name] = AggregationHelper::wrapPrivateFieldAggregation($field, $agg);
foreach($structure->getAllFields() as $name => $field) {
$size = $this->options->getAggregableFieldLimit($name);
if ($size !== databox_field::FACET_DISABLED) {
if ($size === databox_field::FACET_NO_LIMIT) {
$size = ESField::FACET_NO_LIMIT;
}
$agg = [
'terms' => [
'field' => $field->getIndexField(true),
'size' => $size
]
];
$aggs[$name] = AggregationHelper::wrapPrivateFieldAggregation($field, $agg);
}
}
return $aggs;

View File

@@ -9,6 +9,10 @@
*/
namespace Alchemy\Phrasea\SearchEngine\Elastic;
use databox_field;
use igorw;
class ElasticsearchOptions
{
const POPULATE_ORDER_RID = "RECORD_ID";
@@ -35,7 +39,7 @@ class ElasticsearchOptions
private $populateDirection;
/** @var int[] */
private $_customValues;
private $_customValues = [];
private $activeTab;
/**
@@ -57,14 +61,10 @@ class ElasticsearchOptions
'populate_order' => self::POPULATE_ORDER_RID,
'populate_direction' => self::POPULATE_DIRECTION_DESC,
'activeTab' => null,
'facets' => []
];
foreach(self::getAggregableTechnicalFields() as $k => $f) {
$defaultOptions[$k.'_limit'] = 0;
}
$options = array_replace($defaultOptions, $options);
$self = new self();
$self->setHost($options['host']);
$self->setPort($options['port']);
@@ -76,11 +76,10 @@ class ElasticsearchOptions
$self->setPopulateOrder($options['populate_order']);
$self->setPopulateDirection($options['populate_direction']);
$self->setActiveTab($options['activeTab']);
foreach(self::getAggregableTechnicalFields() as $k => $f) {
$self->setAggregableFieldLimit($k, $options[$k.'_limit']);
foreach($options['facets'] as $fieldname=>$attributes) {
$self->setAggregableField($fieldname, $attributes);
}
return $self;
}
@@ -99,10 +98,11 @@ class ElasticsearchOptions
'highlight' => $this->highlight,
'populate_order' => $this->populateOrder,
'populate_direction' => $this->populateDirection,
'activeTab' => $this->activeTab
'activeTab' => $this->activeTab,
'facets' => []
];
foreach(self::getAggregableTechnicalFields() as $k => $f) {
$ret[$k.'_limit'] = $this->getAggregableFieldLimit($k);
foreach($this->getAggregableFields() as $fieldname=>$attributes) {
$ret['facets'][$fieldname] = $attributes;
}
return $ret;
@@ -222,12 +222,51 @@ class ElasticsearchOptions
public function setAggregableFieldLimit($key, $value)
{
$this->_customValues[$key.'_limit'] = $value;
if(is_null($this->getAggregableField($key))) {
$this->_customValues['facets'][$key] = [];
}
$this->_customValues['facets'][$key]['limit'] = $value;
}
public function setAggregableField($key, $attributes)
{
$this->getAggregableFields(); // ensure facets exists
$this->_customValues['facets'][$key] = $attributes;
}
public function getAggregableFieldLimit($key)
{
return $this->_customValues[$key.'_limit'];
$facet = $this->getAggregableField($key);
return (is_array($facet) && array_key_exists('limit', $facet)) ? $facet['limit'] : databox_field::FACET_DISABLED;
}
public function getAggregableField($key)
{
$facets = $this->getAggregableFields();
return array_key_exists($key, $facets) ? $facets[$key] : null;
}
/**
* @return array
*/
public function getAggregableFields()
{
if(!array_key_exists('facets', $this->_customValues) || !is_array($this->_customValues['facets'])) {
$this->_customValues['facets'] = [];
}
return $this->_customValues['facets'];
}
// set to change the facets order during admin/form save
public function reorderAggregableFields($facetNames)
{
$newFacets = [];
foreach ($facetNames as $name) {
if(($facet = $this->getAggregableField($name)) !== null) {
$newFacets[$name] = $facet;
}
}
$this->_customValues['facets'] = $newFacets;
}
public function getActiveTab()
@@ -241,56 +280,56 @@ class ElasticsearchOptions
public function __get($key)
{
if(!array_key_exists($key, $this->_customValues)) {
$this->_customValues[$key] = 0;
}
return $this->_customValues[$key];
$keys = explode(':', $key);
return igorw\get_in($this->_customValues, $keys);
}
public function __set($key, $value)
{
$this->_customValues[$key] = $value;
$keys = explode(':', $key);
$this->_customValues = igorw\assoc_in($this->_customValues, $keys, $value);
}
public static function getAggregableTechnicalFields()
{
return [
'base_aggregate' => [
'_base' => [
'type' => 'string',
'label' => 'prod::facet:base_label',
'field' => "database",
'esfield' => 'databox_name',
'query' => 'database:%s',
],
'collection_aggregate' => [
'_collection' => [
'type' => 'string',
'label' => 'prod::facet:collection_label',
'field' => "collection",
'esfield' => 'collection_name',
'query' => 'collection:%s',
],
'doctype_aggregate' => [
'_doctype' => [
'type' => 'string',
'label' => 'prod::facet:doctype_label',
'field' => "type",
'esfield' => 'type',
'query' => 'type:%s',
],
'camera_model_aggregate' => [
'_camera_model' => [
'type' => 'string',
'label' => 'Camera Model',
'field' => "meta.CameraModel",
'esfield' => 'metadata_tags.CameraModel',
'query' => 'meta.CameraModel:%s',
],
'iso_aggregate' => [
'_iso' => [
'type' => 'number',
'label' => 'ISO',
'field' => "meta.ISO",
'esfield' => 'metadata_tags.ISO',
'query' => 'meta.ISO=%s',
],
'aperture_aggregate' => [
'_aperture' => [
'type' => 'number',
'label' => 'Aperture',
'field' => "meta.Aperture",
@@ -300,7 +339,7 @@ class ElasticsearchOptions
return round($value, 1);
},
],
'shutterspeed_aggregate' => [
'_shutterspeed' => [
'type' => 'number',
'label' => 'Shutter speed',
'field' => "meta.ShutterSpeed",
@@ -313,7 +352,7 @@ class ElasticsearchOptions
return $value . ' s.';
},
],
'flashfired_aggregate' => [
'_flashfired' => [
'type' => 'boolean',
'label' => 'FlashFired',
'field' => "meta.FlashFired",
@@ -327,49 +366,49 @@ class ElasticsearchOptions
return array_key_exists($value, $map) ? $map[$value] : $value;
},
],
'framerate_aggregate' => [
'_framerate' => [
'type' => 'number',
'label' => 'FrameRate',
'field' => "meta.FrameRate",
'esfield' => 'metadata_tags.FrameRate',
'query' => 'meta.FrameRate=%s',
],
'audiosamplerate_aggregate' => [
'_audiosamplerate' => [
'type' => 'number',
'label' => 'Audio Samplerate',
'field' => "meta.AudioSamplerate",
'esfield' => 'metadata_tags.AudioSamplerate',
'query' => 'meta.AudioSamplerate=%s',
],
'videocodec_aggregate' => [
'_videocodec' => [
'type' => 'string',
'label' => 'Video codec',
'field' => "meta.VideoCodec",
'esfield' => 'metadata_tags.VideoCodec',
'query' => 'meta.VideoCodec:%s',
],
'audiocodec_aggregate' => [
'_audiocodec' => [
'type' => 'string',
'label' => 'Audio codec',
'field' => "meta.AudioCodec",
'esfield' => 'metadata_tags.AudioCodec',
'query' => 'meta.AudioCodec:%s',
],
'orientation_aggregate' => [
'_orientation' => [
'type' => 'string',
'label' => 'Orientation',
'field' => "meta.Orientation",
'esfield' => 'metadata_tags.Orientation',
'query' => 'meta.Orientation=%s',
],
'colorspace_aggregate' => [
'_colorspace' => [
'type' => 'string',
'label' => 'Colorspace',
'field' => "meta.ColorSpace",
'esfield' => 'metadata_tags.ColorSpace',
'query' => 'meta.ColorSpace:%s',
],
'mimetype_aggregate' => [
'_mimetype' => [
'type' => 'string',
'label' => 'MimeType',
'field' => "meta.MimeType",

View File

@@ -9,6 +9,7 @@
*/
namespace Alchemy\Phrasea\SearchEngine\Elastic;
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\GlobalStructure;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
@@ -17,6 +18,18 @@ use Symfony\Component\Validator\Constraints\Range;
class ElasticsearchSettingsFormType extends AbstractType
{
/** @var GlobalStructure */
private $globalStructure;
/** @var ElasticsearchOptions */
private $esSettings;
public function __construct(GlobalStructure $g, ElasticsearchOptions $settings)
{
$this->globalStructure = $g;
$this->esSettings = $settings;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
@@ -56,59 +69,89 @@ class ElasticsearchSettingsFormType extends AbstractType
->add('minScore', 'integer', [
'label' => 'Thesaurus Min score',
'constraints' => new Range(['min' => 0]),
]);
])
->add('highlight', 'checkbox', [
'label' => 'Activate highlight',
'required' => false
])
// ->add('save', 'submit', [
// 'attr' => ['class' => 'btn btn-primary']
// ])
->add('esSettingFromIndex', 'button', [
'label' => 'Get setting form index',
'attr' => [
'onClick' => 'esSettingFromIndex()',
'class' => 'btn'
]
])
->add('dumpField', 'textarea', [
'label' => false,
'required' => false,
'mapped' => false,
'attr' => ['class' => 'dumpfield hide']
])
->add('activeTab', 'hidden');
foreach(ElasticsearchOptions::getAggregableTechnicalFields() as $k => $f) {
if(array_key_exists('choices', $f)) {
// choices[] : choice_key => choice_value
$choices = $f['choices'];
}
else {
$choices = [
"10 values" => 10,
"20 values" => 20,
"50 values" => 50,
"100 values" => 100,
"all values" => -1
];
}
// array_unshift($choices, "not aggregated"); // always as first choice
$choices = array_merge(["not aggregated" => 0], $choices);
$builder
->add($k.'_limit', ChoiceType::class, [
// 'label' => $f['label'],// . ' ' . 'aggregate limit',
'choices_as_values' => true,
'choices' => $choices,
'attr' => [
'class' => 'aggregate'
]
]);
// keep aggregates in configuration order with this intermediate array
$aggs = [];
// helper fct to add aggregate to a tmp list
$addAgg = function($k, $label, $help, $disabled=false, $choices=null) use (&$aggs) {
if(!$choices) {
$choices = [
"10 values" => 10,
"50 values" => 50,
"100 values" => 100,
"all values" => -1
];
}
$choices = array_merge(["not aggregated" => 0], $choices); // add this option always as first choice
$aggs[$k] = [ // default value will be replaced by hardcoded tech fields & all databoxes fields
'label' => $label,
'choices_as_values' => true,
'choices' => $choices,
'attr' => [
'class' => 'aggregate'
],
'disabled' => $disabled,
'help_message' => $help // todo : not displayed ?
];
};
$builder
->add('highlight', 'checkbox', [
'label' => 'Activate highlight',
'required' => false
])
// ->add('save', 'submit', [
// 'attr' => ['class' => 'btn btn-primary']
// ])
->add('esSettingFromIndex', 'button', [
'label' => 'Get setting form index',
'attr' => [
'onClick' => 'esSettingFromIndex()',
'class' => 'btn'
]
])
->add('dumpField', 'textarea', [
'label' => false,
'required' => false,
'mapped' => false,
'attr' => ['class' => 'dumpfield hide']
])
->add('activeTab', 'hidden');
// all fields fron conf
foreach($this->esSettings->getAggregableFields() as $k=>$f) {
// default value will be replaced by hardcoded tech fields & all databoxes fields
$addAgg($k, "/?\\ " . $k, "This field does not exists in current databoxes.", true);
}
// add or replace hardcoded tech fields
foreach(ElasticsearchOptions::getAggregableTechnicalFields() as $k => $f) {
$choices = array_key_exists('choices', $f) ? $f['choices'] : null; // a tech-field can publish it's own choices
$help = null;
$label = '#' . $k;
if(!array_key_exists($k, $aggs)) {
$label = "/!\\ " . $label;
$help = "New field, please confirm setting.";
}
$addAgg($k, $label, $help, false, $choices);
}
// add or replace all databoxes fields (nb: new db field - unknown in conf - will be a the end)
foreach($this->globalStructure->getAllFields() as $field) {
$k = $label = $field->getName();
$help = null;
if(!array_key_exists($field->getName(), $aggs)) {
$label = "/!\\ " . $label;
$help = "New field, please confirm setting.";
}
$addAgg($k, $label, $help); // default choices
}
// populate aggs to form
foreach($aggs as $k=>$agg) {
$builder->add('facets:' . $k . ':limit', ChoiceType::class, $agg);
}
;
}
public function getName()

View File

@@ -15,7 +15,7 @@ class FacetsResponse
private $escaper;
private $facets = array();
public function __construct(Escaper $escaper, array $response, GlobalStructure $structure)
public function __construct(ElasticsearchOptions $options, Escaper $escaper, array $response, GlobalStructure $structure)
{
$this->escaper = $escaper;
@@ -25,7 +25,13 @@ class FacetsResponse
$atf = ElasticsearchOptions::getAggregableTechnicalFields();
foreach ($response['aggregations'] as $name => $aggregation) {
// sort facets respecting the order defined in options
foreach($options->getAggregableFields() as $name=>$foptions) {
if(!array_key_exists($name, $response['aggregations'])) {
continue;
}
$aggregation = $response['aggregations'][$name];
$tf = null;
$valueFormatter = function($v){ return $v; }; // default equality formatter
@@ -78,6 +84,7 @@ class FacetsResponse
];
}
}
}

View File

@@ -35,11 +35,6 @@ final class GlobalStructure implements Structure
*/
private $private = array();
/**
* @var Field[]
*/
private $facets = array();
/**
* @var Flag[]
*/
@@ -145,9 +140,11 @@ final class GlobalStructure implements Structure
$this->private[$name] = $field;
}
/*
if ($field->isFacet() && $field->isSearchable()) {
$this->facets[$name] = $field;
}
*/
if ($field->hasConceptInference()) {
$this->thesaurus_fields[$name] = $field;
@@ -183,14 +180,6 @@ final class GlobalStructure implements Structure
return $this->private;
}
/**
* @return Field[]
*/
public function getFacetFields()
{
return $this->facets;
}
/**
* @return Field[]
*/

View File

@@ -47,14 +47,6 @@ final class LimitedStructure implements Structure
return $this->limit($this->structure->getPrivateFields());
}
/**
* @return Field[]
*/
public function getFacetFields()
{
return $this->limit($this->structure->getFacetFields());
}
public function getThesaurusEnabledFields()
{
return $this->limit($this->structure->getThesaurusEnabledFields());

View File

@@ -33,11 +33,6 @@ interface Structure
*/
public function getPrivateFields();
/**
* @return Field[]
*/
public function getFacetFields();
/**
* @return Field[]
*/

View File

@@ -60,7 +60,7 @@ class BinariesRequirements extends RequirementCollection implements RequirementI
);
}
$exiftool = __DIR__ . '/../../../../../vendor/phpexiftool/exiftool/exiftool' . (defined('PHP_WINDOWS_VERSION_BUILD') ? '.exe' : '');
$exiftool = __DIR__ . '/../../../../../vendor/exiftool/exiftool/exiftool' . (defined('PHP_WINDOWS_VERSION_BUILD') ? '.exe' : '');
$this->addRequirement(
is_file($exiftool) && is_executable($exiftool),