Merge branch 'master' into PHRAS-3516-advanced-search-sort-result

This commit is contained in:
Nicolas Maillat
2021-09-13 18:39:41 +02:00
committed by GitHub
45 changed files with 421 additions and 172 deletions

View File

@@ -13,5 +13,5 @@ module.exports = {
setupDir: _root + 'tests/setup/node.js',
karmaConf: _root + 'config/karma.conf.js',
// change this version when you change JS file for lazy loading
jsFileVersion: 26
jsFileVersion: 27
};

View File

@@ -96,7 +96,7 @@ return /******/ (function(modules) { // webpackBootstrap
/******/ if (__webpack_require__.nc) {
/******/ script.setAttribute("nonce", __webpack_require__.nc);
/******/ }
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".js?v=26";
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".js?v=27";
/******/ var timeout = setTimeout(onScriptComplete, 120000);
/******/ script.onerror = script.onload = onScriptComplete;
/******/ function onScriptComplete() {

View File

@@ -96,7 +96,7 @@ return /******/ (function(modules) { // webpackBootstrap
/******/ if (__webpack_require__.nc) {
/******/ script.setAttribute("nonce", __webpack_require__.nc);
/******/ }
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".min.js?v=26";
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".min.js?v=27";
/******/ var timeout = setTimeout(onScriptComplete, 120000);
/******/ script.onerror = script.onload = onScriptComplete;
/******/ function onScriptComplete() {

View File

@@ -91,7 +91,7 @@
/******/ if (__webpack_require__.nc) {
/******/ script.setAttribute("nonce", __webpack_require__.nc);
/******/ }
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".js?v=26";
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".js?v=27";
/******/ var timeout = setTimeout(onScriptComplete, 120000);
/******/ script.onerror = script.onload = onScriptComplete;
/******/ function onScriptComplete() {

View File

@@ -91,7 +91,7 @@
/******/ if (__webpack_require__.nc) {
/******/ script.setAttribute("nonce", __webpack_require__.nc);
/******/ }
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".min.js?v=26";
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".min.js?v=27";
/******/ var timeout = setTimeout(onScriptComplete, 120000);
/******/ script.onerror = script.onload = onScriptComplete;
/******/ function onScriptComplete() {

View File

@@ -19323,6 +19323,9 @@ var notifyLayout = function notifyLayout(services) {
markNotificationRead(event.data['id'], $z);
});
date_cont.append($z);
// do not display date in the dialog content beacause it's already grouped by date
(0, _jquery2.default)(".time", $z).hide();
(0, _jquery2.default)(".time-in-dialog", $z).show();
};
for (i in notifications) {

View File

@@ -19323,6 +19323,9 @@ var notifyLayout = function notifyLayout(services) {
markNotificationRead(event.data['id'], $z);
});
date_cont.append($z);
// do not display date in the dialog content beacause it's already grouped by date
(0, _jquery2.default)(".time", $z).hide();
(0, _jquery2.default)(".time-in-dialog", $z).show();
};
for (i in notifications) {

View File

@@ -8846,7 +8846,7 @@ TABLE.explain3 TR TD {
#PREVIEWBOX,
#EDITWINDOW {
z-index: 1200;
z-index: 2000;
background-color: #1a1a1a;
display: none;
border: 1px solid #7f7f7f;

File diff suppressed because one or more lines are too long

View File

@@ -8861,7 +8861,7 @@ TABLE.explain3 TR TD {
#PREVIEWBOX,
#EDITWINDOW {
z-index: 1200;
z-index: 2000;
background-color: #d9d9d9;
display: none;
border: 1px solid silver;

File diff suppressed because one or more lines are too long

View File

@@ -8863,7 +8863,7 @@ TABLE.explain3 TR TD {
#PREVIEWBOX,
#EDITWINDOW {
z-index: 1200;
z-index: 2000;
background-color: #ffffff;
display: none;
border: 1px solid #bfbfbf;

File diff suppressed because one or more lines are too long

View File

@@ -180,6 +180,9 @@ const notifyLayout = (services) => {
markNotificationRead(event.data['id'], $z);
});
date_cont.append($z);
// do not display date in the dialog content beacause it's already grouped by date
$(".time", $z).hide();
$(".time-in-dialog", $z).show();
}
// handle "show more" button

View File

@@ -1,6 +1,6 @@
#PREVIEWBOX,
#EDITWINDOW {
z-index: 1200;
z-index: 2000; // just enough uppur than a dialog z-index
background-color: $modalBackground;
display: none;
border: $modalBorder; //1px solid $darkerBorderColor;

View File

@@ -235,6 +235,8 @@ registry:
api-clients:
api-require-ssl: false
api-auth-token-header-only: false
actions:
export-stamp-choice: false
crossdomain:
site-control: 'master-only'
allow-access-from:

View File

@@ -34,6 +34,8 @@ use Alchemy\Phrasea\Model\Entities\LazaretSession;
use PHPExiftool\Driver\Metadata\Metadata;
use PHPExiftool\Driver\Value\Mono as MonoValue;
use PHPExiftool\Driver\Value\Multi;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
* Phraseanet Border Manager
@@ -381,12 +383,27 @@ class Manager
sprintf("calling replaceMetadata")
), FILE_APPEND | LOCK_EX);
/** @var EventDispatcherInterface $dispatcher */
$dispatcher = $this->app['dispatcher'];
$dispatcher->addListener(
RecordEvents::METADATA_CHANGED,
function (Event $event) {
// we do not want replaceMetadata() to send a writemeta
// file_put_contents(dirname(__FILE__).'/../../../../logs/trace.txt', sprintf("%s [%s] : %s (%s); %s\n", (date('Y-m-d\TH:i:s')), getmypid(), __FILE__, __LINE__,
// sprintf("---------- event METADATA_CHANGED catched !!! Propagation stopped !!!")
// ), FILE_APPEND | LOCK_EX);
// $event->stopPropagation();
},
10
);
/** @var PhraseanetMetadataSetter $phraseanetMetadataSetter */
$phraseanetMetadataSetter = $this->app['phraseanet.metadata-setter'];
$phraseanetMetadataSetter->replaceMetadata($newMetadata, $element);
if(!$nosubdef) {
$this->app['dispatcher']->dispatch(RecordEvents::SUBDEFINITION_CREATE, new SubdefinitionCreateEvent($element, true));
$dispatcher->dispatch(RecordEvents::SUBDEFINITION_CREATE, new SubdefinitionCreateEvent($element, true));
}
return $element;

View File

@@ -91,7 +91,9 @@ abstract class AbstractDelivery
if ($watermark === true && $mediaSubdefinition->get_type() === \media_subdef::TYPE_IMAGE) {
$pathOut = \recordutils_image::watermark($this->app, $mediaSubdefinition);
} elseif ($stamp === true && $mediaSubdefinition->get_type() === \media_subdef::TYPE_IMAGE) {
$pathOut = \recordutils_image::stamp($this->app, $mediaSubdefinition);
if( !is_null($newPath = \recordutils_image::stamp($this->app, $mediaSubdefinition)) ) {
$pathOut = $newPath;
}
}
return $pathOut;

View File

@@ -44,7 +44,8 @@ class DownloadController extends Controller
$this->app['filesystem'],
$subdefs,
$request->request->get('type') === 'title' ? true : false,
$request->request->get('businessfields')
$request->request->get('businessfields'),
$request->request->get('stamp_choice') === "NO_STAMP" ? \set_export::NO_STAMP : \set_export::STAMP_SYNC
);
$list['export_name'] = sprintf('%s.zip', $download->getExportName());

View File

@@ -9,7 +9,6 @@
*/
namespace Alchemy\Phrasea\Controller\Prod;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Application\Helper\DispatcherAware;
use Alchemy\Phrasea\Application\Helper\FilesystemAware;
use Alchemy\Phrasea\Application\Helper\NotifierAware;
@@ -17,11 +16,7 @@ use Alchemy\Phrasea\Controller\Controller;
use Alchemy\Phrasea\Core\Event\ExportFailureEvent;
use Alchemy\Phrasea\Core\Event\ExportMailEvent;
use Alchemy\Phrasea\Core\PhraseaEvents;
use Alchemy\Phrasea\Exception\InvalidArgumentException;
use Alchemy\Phrasea\Model\Manipulator\TokenManipulator;
use Alchemy\Phrasea\Notification\Emitter;
use Alchemy\Phrasea\Notification\Mail\MailRecordsExport;
use Alchemy\Phrasea\Notification\Receiver;
use Alchemy\Phrasea\WorkerManager\Event\ExportFtpEvent;
use Alchemy\Phrasea\WorkerManager\Event\WorkerEvents;
use Symfony\Component\HttpFoundation\JsonResponse;
@@ -118,8 +113,9 @@ class ExportController extends Controller
$this->getFilesystem(),
$request->request->get('obj'),
false,
$request->request->get('businessfields')
);
$request->request->get('businessfields'),
$request->request->get('stamp_choice') === "NO_STAMP" ? \set_export::NO_STAMP : \set_export::STAMP_ASYNC
);
$exportFtpId = $download->export_ftp(
$request->request->get('user_dest'),
@@ -171,7 +167,8 @@ class ExportController extends Controller
$this->getFilesystem(),
(array) $request->request->get('obj'),
$request->request->get("type") == "title" ? : false,
$request->request->get('businessfields')
$request->request->get('businessfields'),
$request->request->get('stamp_choice') === "NO_STAMP" ? \set_export::NO_STAMP : \set_export::STAMP_ASYNC
);
$list['export_name'] = sprintf("%s.zip", $download->getExportName());

View File

@@ -128,6 +128,7 @@ class RegistryFormManipulator
'force-push-authentication' => false,
'enable-feed-notification' => true,
'download-link-validity' => 24,
'export-stamp-choice' => false,
],
'ftp' => [
'ftp-enabled' => false,

View File

@@ -142,6 +142,17 @@ class FilesystemService
return $realPath;
}
/**
* rename file from source to target
*
* @param string $source
* @param string $target
*/
public function rename($source, $target)
{
$this->filesystem->rename($source, $target, true);
}
/**
* Copy file from source to target
*

View File

@@ -12,27 +12,27 @@ namespace Alchemy\Phrasea\Media;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Application\Helper\DispatcherAware;
use Alchemy\Phrasea\Core\Event\Record\SubDefinitionCreatedEvent;
use Alchemy\Phrasea\Core\Event\Record\SubDefinitionsCreatedEvent;
use Alchemy\Phrasea\Core\Event\Record\SubDefinitionCreationEvent;
use Alchemy\Phrasea\Core\Event\Record\SubDefinitionsCreationEvent;
use Alchemy\Phrasea\Core\Event\Record\SubDefinitionCreationFailedEvent;
use Alchemy\Phrasea\Core\Event\Record\RecordEvents;
use Alchemy\Phrasea\Core\Event\Record\SubDefinitionCreatedEvent;
use Alchemy\Phrasea\Core\Event\Record\SubDefinitionCreationEvent;
use Alchemy\Phrasea\Core\Event\Record\SubDefinitionCreationFailedEvent;
use Alchemy\Phrasea\Core\Event\Record\SubDefinitionsCreatedEvent;
use Alchemy\Phrasea\Core\Event\Record\SubDefinitionsCreationEvent;
use Alchemy\Phrasea\Databox\Subdef\MediaSubdefRepository;
use Alchemy\Phrasea\Filesystem\FilesystemService;
use Alchemy\Phrasea\Media\Subdef\Specification\PdfSpecification;
use MediaAlchemyst\Alchemyst;
use MediaAlchemyst\Exception\ExceptionInterface as MediaAlchemystException;
use MediaAlchemyst\Exception\FileNotFoundException;
use MediaAlchemyst\Specification\Image;
use MediaAlchemyst\Specification\Video;
use MediaVorus\Exception\FileNotFoundException as MediaVorusFileNotFoundException;
use MediaVorus\MediaVorus;
use MediaAlchemyst\Exception\ExceptionInterface as MediaAlchemystException;
use Neutron\TemporaryFilesystem\Manager;
use Psr\Log\LoggerInterface;
use Unoconv\Exception\ExceptionInterface as UnoconvException;
use Unoconv\Exception\RuntimeException;
use Unoconv\Unoconv;
use MediaVorus\Exception\FileNotFoundException as MediaVorusFileNotFoundException;
use MediaAlchemyst\Exception\FileNotFoundException;
class SubdefGenerator
{
@@ -107,6 +107,15 @@ class SubdefGenerator
)
);
if(!is_null($hd = $record->get_hd_file())) {
$hd = $hd->getRealPath();
clearstatcache(true, $hd);
file_put_contents(dirname(__FILE__).'/../../../../logs/trace.txt', sprintf("%s [%s] : %s (%s); %s\n", (date('Y-m-d\TH:i:s')), getmypid(), __FILE__, __LINE__,
sprintf("creating subdefs for %s.%s from document \"%s\" (size=%s)", $record->getDataboxId(), $record->getRecordId(), $hd, filesize($hd))
), FILE_APPEND | LOCK_EX);
}
$mediaCreated = [];
foreach ($subdefs as $subdef) {
$subdefname = $subdef->get_name();
@@ -118,7 +127,13 @@ class SubdefGenerator
$pathdest = null;
if ($record->has_subdef($subdefname) && $record->get_subdef($subdefname)->is_physically_present()) {
$pathdest = $record->get_subdef($subdefname)->getRealPath();
file_put_contents(dirname(__FILE__).'/../../../../logs/trace.txt', sprintf("%s [%s] : %s (%s); %s\n", (date('Y-m-d\TH:i:s')), getmypid(), __FILE__, __LINE__,
sprintf("deleting previous subdef \"%s\" (file=\"%s\") for %s.%s", $subdefname, $pathdest, $record->getDataboxId(), $record->getRecordId())
), FILE_APPEND | LOCK_EX);
$record->get_subdef($subdefname)->remove_file();
$this->logger->info(sprintf('Removed old file for %s', $subdefname));
$record->clearSubdefCache($subdefname);

View File

@@ -96,8 +96,37 @@ class PhraseanetMetadataSetter
sprintf("calling set_metadatas for %s.%s", $record->getDataboxId(), $record->getRecordId())
), FILE_APPEND | LOCK_EX);
$record->set_metadatas($metadataInRecordFormat, true);
/*
* todo : tryout to write meta AFTER meta was written in db by set_metadatas()
* how : uncomment section
*
*/
/*
$this->dispatcher->addListener(
RecordEvents::METADATA_CHANGED,
function () use ($record) {
// order to write meta in file
file_put_contents(dirname(__FILE__).'/../../../../logs/trace.txt', sprintf("%s [%s] : %s (%s); %s\n", (date('Y-m-d\TH:i:s')), getmypid(), __FILE__, __LINE__,
sprintf("dispatch WorkerEvents::RECORDS_WRITE_META for %s.%s", $record->getDataboxId(), $record->getRecordId())
), FILE_APPEND | LOCK_EX);
// this event will add a msg to the writemeta q
$this->dispatcher->dispatch(WorkerEvents::RECORDS_WRITE_META,
new RecordsWriteMetaEvent([$record->getRecordId()], $record->getDataboxId()));
},
0
);
*/
/*
* end of section to uncomment
*/
$record->set_metadatas($metadataInRecordFormat, true); // will send METADATA_CHANGED when done
/*
* todo : tryout to write meta AFTER meta was written in db by set_metadatas()
* how : comment section
*
*/
// order to write meta in file
file_put_contents(dirname(__FILE__).'/../../../../logs/trace.txt', sprintf("%s [%s] : %s (%s); %s\n", (date('Y-m-d\TH:i:s')), getmypid(), __FILE__, __LINE__,
sprintf("dispatch WorkerEvents::RECORDS_WRITE_META for %s.%s", $record->getDataboxId(), $record->getRecordId())
@@ -105,6 +134,9 @@ class PhraseanetMetadataSetter
$this->dispatcher->dispatch(WorkerEvents::RECORDS_WRITE_META,
new RecordsWriteMetaEvent([$record->getRecordId()], $record->getDataboxId()));
/*
* end of section to comment
*/
}
else {

View File

@@ -189,7 +189,7 @@ class ApiOrderController extends BaseOrderController
$subdefs = $this->findDataboxSubdefNames();
try {
$exportData = $export->prepare_export($user, $this->getFilesystem(), $subdefs, true, true);
$exportData = $export->prepare_export($user, $this->getFilesystem(), $subdefs, true, true, false);
}
catch (\Exception $e) {
throw new NotFoundHttpException(sprintf('No archive could be downloaded for Order "%d"', $order->getId()));

View File

@@ -59,7 +59,7 @@ class PhraseanetExtension extends \Twig_Extension
{
return [
// change this version when you change JS file to force the navigation to reload js file
'jsFileVersion' => 26
'jsFileVersion' => 27
];
}

View File

@@ -81,6 +81,28 @@ class ExportMailWorker implements WorkerInterface
$list = unserialize($token->getData());
foreach($list['files'] as $k_file => $v_file) {
foreach($v_file['subdefs'] as $k_subdef => $v_subdef) {
if($k_subdef === "document" && $v_subdef['to_stamp']) {
// we must stamp this document
try {
$record = $this->app->getApplicationBox()->get_databox($v_file['databox_id'])->get_record($v_file['record_id']);
$sd = $record->get_subdef($k_subdef);
if(!is_null($path = \recordutils_image::stamp($this->app, $sd))) {
// stamped !
$pi = pathinfo($path);
$list['files'][$k_file]['subdefs'][$k_subdef]['path'] = $pi['dirname'];
$list['files'][$k_file]['subdefs'][$k_subdef]['file'] = $pi['basename'];
$list['files'][$k_file]['subdefs'][$k_subdef]['size'] = filesize($path);
}
}
catch (\Exception $e) {
// failed to stamp ? ignore and send the original file
}
}
}
}
$this->repoWorkerJob->reconnect();
//zip documents
\set_export::build_zip(

View File

@@ -37,7 +37,7 @@ class eventsmanager_notify_autoregister extends eventsmanager_notifyAbstract
}
$ret = [
'text' => $this->app->trans('%user% s\'est enregistre sur une ou plusieurs %before_link% scollections %after_link%', ['%user%' => $user->getDisplayName(), '%before_link%' => '<a href="/admin/?section=users" target="_blank">', '%after_link%' => '</a>'])
'text' => $this->app->trans('%user% s\'est enregistre sur une ou plusieurs %before_link% scollections %after_link%', ['%user%' => htmlentities($user->getDisplayName()), '%before_link%' => '<a href="/admin/?section=users" target="_blank">', '%after_link%' => '</a>'])
, 'class' => ''
];

View File

@@ -37,7 +37,7 @@ class eventsmanager_notify_feed extends eventsmanager_notifyAbstract
}
$ret = [
'text' => $this->app->trans('%user% has published %title%', ['%user%' => $entry->getAuthorName(), '%title%' => '<a href="/lightbox/feeds/entry/' . $entry->getId() . '/" target="_blank">' . $entry->getTitle() . '</a>'])
'text' => $this->app->trans('%user% has published %title%', ['%user%' => htmlentities($entry->getAuthorName()), '%title%' => '<a href="/lightbox/feeds/entry/' . $entry->getId() . '/" target="_blank">' . htmlentities($entry->getTitle()) . '</a>'])
, 'class' => ($unread == 1 ? 'reload_baskets' : '')
];

View File

@@ -41,7 +41,7 @@ class eventsmanager_notify_order extends eventsmanager_notifyAbstract
$ret = [
'text' => $this->app->trans('%user% a passe une %opening_link% commande %end_link%', [
'%user%' => $sender,
'%user%' => htmlentities($sender),
'%opening_link%' => '<a href="#" class="order-notif" data-id="'.$order_id.'" title="'.$this->app->trans('Orders manager').'">',
'%end_link%' => '</a>',])
, 'class' => ''

View File

@@ -63,9 +63,9 @@ class eventsmanager_notify_orderdeliver extends eventsmanager_notifyAbstract
}
$ret = [
'text' => $this->app->trans('%user% vous a delivre %quantity% document(s) pour votre commande %title%', ['%user%' => $sender, '%quantity%' => $n, '%title%' => '<a href="/lightbox/compare/'
'text' => $this->app->trans('%user% vous a delivre %quantity% document(s) pour votre commande %title%', ['%user%' => htmlentities($sender), '%quantity%' => $n, '%title%' => '<a href="/lightbox/compare/'
. $ssel_id . '/" target="_blank">'
. $basket->getName() . '</a>']),
. htmlentities($basket->getName()) . '</a>']),
'class' => ''
];

View File

@@ -39,7 +39,7 @@ class eventsmanager_notify_ordernotdelivered extends eventsmanager_notifyAbstrac
$sender = $user->getDisplayName();
$ret = [
'text' => $this->app->trans('%user% a refuse la livraison de %quantity% document(s) pour votre commande', ['%user%' => $sender, '%quantity%' => $n])
'text' => $this->app->trans('%user% a refuse la livraison de %quantity% document(s) pour votre commande', ['%user%' => htmlentities($sender), '%quantity%' => $n])
, 'class' => ''
];

View File

@@ -39,11 +39,11 @@ class eventsmanager_notify_push extends eventsmanager_notifyAbstract
$sender = $user->getDisplayName();
$ret = [
'text' => $this->app->trans('%user% vous a envoye un %before_link% panier %after_link%', ['%user%' => $sender, '%before_link%' => '<a href="#"
'text' => $this->app->trans('%user% vous a envoye un %before_link% panier %after_link%', ['%user%' => htmlentities($sender), '%before_link%' => '<a href="#"
data-kind="BASK"
data-position="1"
data-id="'. $data['ssel_id'] . '"
class="open-preview-action">', '%after_link%' => '</a>'])
class="to-open-preview-action">', '%after_link%' => '</a>'])
, 'class' => ($unread == 1 ? 'reload_baskets' : '')
];

View File

@@ -39,7 +39,7 @@ class eventsmanager_notify_register extends eventsmanager_notifyAbstract
$sender = $user->getDisplayName();
$ret = [
'text' => $this->app->trans('%user% demande votre approbation sur une ou plusieurs %before_link% collections %after_link%', ['%user%' => $sender, '%before_link%' => '<a href="' . $this->app->url('admin', ['section' => 'registrations']) . '" target="_blank">', '%after_link%' => '</a>'])
'text' => $this->app->trans('%user% demande votre approbation sur une ou plusieurs %before_link% collections %after_link%', ['%user%' => htmlentities($sender), '%before_link%' => '<a href="' . $this->app->url('admin', ['section' => 'registrations']) . '" target="_blank">', '%after_link%' => '</a>'])
, 'class' => ''
];

View File

@@ -41,7 +41,7 @@ class eventsmanager_notify_uploadquarantine extends eventsmanager_notifyAbstract
$filename = $data['filename'];
$text = $this->app->trans('The document %name% has been quarantined', ['%name%' => $filename]);
$text = $this->app->trans('The document %name% has been quarantined', ['%name%' => htmlentities($filename)]);
if ($reasons) {
$text .= ' ' . $this->app->trans('for the following reasons : %reasons%', ['%reasons%' => implode(', ', $reasons)]);

View File

@@ -56,11 +56,11 @@ class eventsmanager_notify_validate extends eventsmanager_notifyAbstract
$bask_link = '<a href="'
. $this->app->url('lightbox_validation', ['basket' => $ssel_id])
. '" target="_blank">'
. $basket_name . '</a>';
. htmlentities($basket_name) . '</a>';
$ret = [
'text' => $this->app->trans('%user% vous demande de valider %title%', [
'%user%' => $sender,
'%user%' => htmlentities($sender),
'%title%' => $bask_link,
])
, 'class' => ($unread == 1 ? 'reload_baskets' : '')

View File

@@ -62,9 +62,9 @@ class eventsmanager_notify_validationdone extends eventsmanager_notifyAbstract
}
$ret = [
'text' => $this->app->trans('%user% a envoye son rapport de validation de %title%', ['%user%' => $sender, '%title%' => '<a href="/lightbox/validate/'
'text' => $this->app->trans('%user% a envoye son rapport de validation de %title%', ['%user%' => htmlentities($sender), '%title%' => '<a href="/lightbox/validate/'
. $ssel_id . '/" target="_blank">'
. $basket->getName() . '</a>']),
. htmlentities($basket->getName()) . '</a>']),
'class' => ''
];

View File

@@ -59,11 +59,11 @@ class eventsmanager_notify_validationreminder extends eventsmanager_notifyAbstra
$basket_name = $this->app->trans('Une selection');
}
$bask_link = '<a href="#" data-kind="BASK" data-position="1" data-id="'. $ssel_id . '" class="open-preview-action">'
$bask_link = '<a href="#" data-kind="BASK" data-position="1" data-id="'. $ssel_id . '" class="to-open-preview-action">'
. $basket_name . '</a>';
$ret = [
'text' => $this->app->trans('Rappel : Il vous reste %timeLeft% pour valider %title% de %user%', ['%timeLeft%' => $timeLeft, '%title%' => $bask_link, '%user%' => $sender])
'text' => $this->app->trans('Rappel : Il vous reste %timeLeft% pour valider %title% de %user%', ['%timeLeft%' => $timeLeft, '%title%' => $bask_link, '%user%' => htmlentities($sender)])
, 'class' => ($unread == 1 ? 'reload_baskets' : '')
];

View File

@@ -1700,12 +1700,31 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
$pathhd = $filesystem->generateDataboxDocumentBasePath($databox);
$newname = $filesystem->generateDocumentFilename($record, $file->getFile());
$newname_tmp = $newname.".tmp";
clearstatcache(true, $file->getFile()->getRealPath());
file_put_contents(dirname(__FILE__).'/../../../logs/trace.txt', sprintf("%s [%s] : %s (%s); %s\n", (date('Y-m-d\TH:i:s')), getmypid(), __FILE__, __LINE__,
sprintf("copy \"%s\" to \"%s\"", $file->getFile()->getRealPath(), $pathhd . $newname)
sprintf("copying \"%s\" (size=%s) to \"%s\"", $file->getFile()->getRealPath(), filesize($file->getFile()->getRealPath()), $pathhd . $newname_tmp)
), FILE_APPEND | LOCK_EX);
$filesystem->copy($file->getFile()->getRealPath(), $pathhd . $newname_tmp);
clearstatcache(true, $pathhd . $newname_tmp);
file_put_contents(dirname(__FILE__).'/../../../logs/trace.txt', sprintf("%s [%s] : %s (%s); %s\n", (date('Y-m-d\TH:i:s')), getmypid(), __FILE__, __LINE__,
sprintf("copied \"%s\" to \"%s\" (size=%s)", $file->getFile()->getRealPath(), $pathhd . $newname_tmp, filesize($pathhd . $newname_tmp))
), FILE_APPEND | LOCK_EX);
file_put_contents(dirname(__FILE__).'/../../../logs/trace.txt', sprintf("%s [%s] : %s (%s); %s\n", (date('Y-m-d\TH:i:s')), getmypid(), __FILE__, __LINE__,
sprintf("moving \"%s\" (size=%s) to \"%s\"", $pathhd . $newname_tmp, filesize($pathhd . $newname_tmp), $pathhd . $newname)
), FILE_APPEND | LOCK_EX);
$filesystem->rename($pathhd . $newname_tmp, $pathhd . $newname);
clearstatcache(true, $pathhd . $newname);
file_put_contents(dirname(__FILE__).'/../../../logs/trace.txt', sprintf("%s [%s] : %s (%s); %s\n", (date('Y-m-d\TH:i:s')), getmypid(), __FILE__, __LINE__,
sprintf("moved \"%s\"to \"%s\" (size=%s) ", $pathhd . $newname_tmp, $pathhd . $newname, filesize($pathhd . $newname))
), FILE_APPEND | LOCK_EX);
$filesystem->copy($file->getFile()->getRealPath(), $pathhd . $newname);
$media = $app->getMediaFromUri($pathhd . $newname);
media_subdef::create($app, $record, 'document', $media);

View File

@@ -11,26 +11,37 @@
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Model\Serializer\CaptionSerializer;
use Imagine\Exception\Exception as ImagineException;
use Imagine\Image\Box;
use Imagine\Image\ImagineInterface;
use Imagine\Image\Palette\RGB;
use Imagine\Image\Box;
use Imagine\Image\Point;
use Imagine\Exception\Exception as ImagineException;
use MediaVorus\Media\MediaInterface;
use MediaVorus\Media\Image;
use MediaVorus\Media\MediaInterface;
class recordutils_image
{
/**
* @param Application $app
* @param \media_subdef $subdef
* @param Application $app
* @param media_subdef $subdef
*
* @return string The path to the stamped file
* @return string|null The path to the stamped file, or null if stamp is not required
*/
public static function stamp(Application $app, \media_subdef $subdef)
public static function stamp(Application $app, media_subdef $subdef)
{
static $palette;
$domprefs = new DOMDocument();
if (false === $domprefs->loadXML($subdef->get_record()->getCollection()->get_prefs())) {
return null;
}
$xpprefs = new DOMXPath($domprefs);
$stampNodes = $xpprefs->query('/baseprefs/stamp');
if ($stampNodes->length == 0) {
return null;
}
if (null === $palette) {
$palette = new RGB();
}
@@ -39,50 +50,42 @@ class recordutils_image
try {
$alpha = 100;
$attr = explode(',', $attr);
if(count($attr) == 4) {
if (count($attr) == 4) {
// 0..127 -> 100..0
$alpha = (int)((127 - (int)array_pop($attr)) / 1.27);
}
return $palette->color($attr, $alpha);
} catch (ImagineException $e) {
}
catch (ImagineException $e) {
return $palette->color($ret);
}
};
$base_id = $subdef->get_record()->getBaseId();
if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) {
return $subdef->getRealPath();
if ($subdef->get_type() !== media_subdef::TYPE_IMAGE) {
return null;
}
if (!$subdef->is_physically_present()) {
return $subdef->getRealPath();
return null;
}
$rotation = null;
$rotation = "?";
try {
$image = $app->getMediaFromUri($subdef->getRealPath());
if (MediaInterface::TYPE_IMAGE === $image->getType()) {
$rotation = $image->getOrientation();
}
} catch (\Exception $e) {
}
catch (Exception $e) {
// getting orientation failed but we don't care the reason
}
$domprefs = new DOMDocument();
if (false === $domprefs->loadXML($subdef->get_record()->getCollection()->get_prefs())) {
return $subdef->getRealPath();
}
if (false === $sxxml = simplexml_load_string($app['serializer.caption']->serialize($subdef->get_record()->get_caption(), CaptionSerializer::SERIALIZE_XML))) {
return $subdef->getRealPath();
}
$xpprefs = new DOMXPath($domprefs);
$stampNodes = $xpprefs->query('/baseprefs/stamp');
if ($stampNodes->length == 0) {
return $subdef->getRealPath();
return null;
}
$pathIn = $subdef->getRealPath();
@@ -103,25 +106,38 @@ class recordutils_image
return $pathOut;
}
/** @var Imagine\Imagick\Imagine $imageine */
$imagine = $app['imagine'];
// open the document
$image_in = $app['imagine']->open($pathIn);
try {
$image_in = $imagine->open($pathIn);
}
catch (Exception $e) {
return $pathIn;
}
$image_size = $image_in->getSize();
$back_rotation = 0;
switch ($rotation) {
case Image::ORIENTATION_90:
$image_width = $image_size->getHeight();
$image_height = $image_size->getWidth();
$image_in->rotate(90);
$rotation = '90';
$back_rotation = 270;
break;
case Image::ORIENTATION_270:
$image_width = $image_size->getHeight();
$image_height = $image_size->getWidth();
$image_in->rotate(270);
$back_rotation = 90;
break;
case Image::ORIENTATION_180:
$image_width = $image_size->getWidth();
$image_height = $image_size->getHeight();
$image_in->rotate(180);
$back_rotation = 180;
break;
default:
$image_width = $image_size->getWidth();
@@ -132,20 +148,22 @@ class recordutils_image
// open the logo
$logo_phywidth = $logo_phyheight = 0; // physical size
$logo_file = $app['root.path'] . '/config/stamp/' . $base_id;
$logo_obj = null;
try {
$logo_obj = $app['imagine']->open($logo_file);
$logo_obj = $imagine->open($logo_file);
$logo_size = $logo_obj->getSize();
$logo_phywidth = $logo_size->getWidth();
$logo_phyheight = $logo_size->getHeight();
} catch (ImagineException $e) {
}
catch (ImagineException $e) {
// missing logo : ignore
}
$tables = [
'TOP' => ['h' => 0, 'rows' => []],
'TOP-OVER' => ['h' => 0, 'rows' => []],
'BOTTOM' => ['h' => 0, 'rows' => []],
'BOTTOM-OVER' => ['h' => 0, 'rows' => []]
'TOP' => ['h' => 0, 'rows' => []],
'TOP-OVER' => ['h' => 0, 'rows' => []],
'BOTTOM' => ['h' => 0, 'rows' => []],
'BOTTOM-OVER' => ['h' => 0, 'rows' => []]
];
for ($istamp = 0; $istamp < $stampNodes->length; $istamp++) {
@@ -188,10 +206,11 @@ class recordutils_image
$x = $sxxml->description->{$fieldname};
if (is_array($x)) {
foreach ($x as $v) {
$fldval .= ( $fldval ? '; ' : '') . (string) $v;
$fldval .= ($fldval ? '; ' : '') . (string)$v;
}
} else {
$fldval .= ( $fldval ? '; ' : '') . (string) $x;
}
else {
$fldval .= ($fldval ? '; ' : '') . (string)$x;
}
$n->parentNode->replaceChild($domprefs->createTextNode($fldval), $n);
}
@@ -205,6 +224,7 @@ class recordutils_image
// compute logo position / size
$logo_reswidth = 0;
$logo_resheight = 0;
$logo_xpos = null;
if ($logo_phywidth > 0 && $logo_phyheight > 0) {
$v = $xpprefs->query('logo', $stamp);
@@ -214,23 +234,25 @@ class recordutils_image
$logopos = @strtoupper($v->item(0)->getAttribute('position'));
if (($logowidth = trim($v->item(0)->getAttribute('width'))) != '') {
if (substr($logowidth, -1) == '%') {
$logo_reswidth = (int) ($logowidth * $image_width / 100);
} else {
$logo_reswidth = (int) $logowidth;
$logo_reswidth = (int)($logowidth * $image_width / 100);
}
$logo_resheight = (int) ($logo_phyheight * ($logo_reswidth / $logo_phywidth));
else {
$logo_reswidth = (int)$logowidth;
}
$logo_resheight = (int)($logo_phyheight * ($logo_reswidth / $logo_phywidth));
}
if ($logopos == 'LEFT' || $logopos == 'RIGHT') {
if ($logo_reswidth > $image_width / 2) {
// logo too large, resize please
$logo_reswidth = (int) ($image_width / 2);
$logo_resheight = (int) ($logo_phyheight * ($logo_reswidth / $logo_phywidth));
$logo_reswidth = (int)($image_width / 2);
$logo_resheight = (int)($logo_phyheight * ($logo_reswidth / $logo_phywidth));
}
$text_width -= $logo_reswidth;
if ($logopos == 'LEFT') {
$logo_xpos = 0;
} else {
}
else {
$logo_xpos = ($image_width - $logo_reswidth);
}
}
@@ -245,28 +267,30 @@ class recordutils_image
for ($i = 0; $i < $texts->length; $i++) {
if (($tmpfontsize = trim($texts->item($i)->getAttribute('size'))) != '') {
if (substr($tmpfontsize, -1) == '%') {
$tmpfontsize = (int) ($tmpfontsize * $image_width / 4000);
} else {
$tmpfontsize = (int) $tmpfontsize;
$tmpfontsize = (int)($tmpfontsize * $image_width / 4000);
}
else {
$tmpfontsize = (int)$tmpfontsize;
}
$fontsize = $tmpfontsize;
}
if ($fontsize < 2) {
$fontsize = 2;
} elseif ($fontsize > 300) {
}
elseif ($fontsize > 300) {
$fontsize = 300;
}
$txtline = $texts->item($i)->nodeValue;
if ($txtline != '') {
$wrap = static::wrap($app['imagine'], $fontsize, 0, __DIR__ . '/arial.ttf', $txtline, $text_width);
$wrap = static::wrap($imagine, $fontsize, 0, __DIR__ . '/arial.ttf', $txtline, $text_width);
$txtblock[] = [
'fontsize' => $fontsize,
'fontcolor' => $xmlToColor($texts->item($i)->getAttribute('color'), [0, 0, 0]),
'h' => $wrap['toth'],
'lines' => $wrap['l']
'h' => $wrap['toth'],
'lines' => $wrap['l']
];
$txth += $wrap['toth'];
}
@@ -284,7 +308,7 @@ class recordutils_image
}
// create the block
$imfg = $app['imagine']->create(new Box($image_width, $stampheight), $stamp_background);
$imfg = $imagine->create(new Box($image_width, $stampheight), $stamp_background);
// copy the logo
if ($logo_reswidth > 0 && $logo_resheight > 0) {
@@ -293,7 +317,8 @@ class recordutils_image
$logo_obj->copy()->resize(new Box($logo_reswidth, $logo_resheight)),
new Point($logo_xpos, 0)
);
} else {
}
else {
$imfg->paste($logo_obj, new Point($logo_xpos, 0));
}
}
@@ -302,7 +327,7 @@ class recordutils_image
$draw = $imfg->draw();
$txt_ypos = 0;
foreach ($txtblock as $block) {
$font = $app['imagine']->font(__DIR__ . '/arial.ttf', $block['fontsize'], $block['fontcolor']);
$font = $imagine->font(__DIR__ . '/arial.ttf', $block['fontsize'], $block['fontcolor']);
foreach ($block['lines'] as $line) {
if ($line['t'] != '') {
$draw->text($line['t'], $font, new Point($logo_reswidth, $txt_ypos), 0);
@@ -323,14 +348,19 @@ class recordutils_image
$tables[$stamp_position]['h'] += $stampheight;
}
unset($logo_obj);
unset($domprefs);
$newh = $tables['TOP']['h'] + $image_height + $tables['BOTTOM']['h'];
// create the output image
$image_out = $app['imagine']->create(new Box($image_width, $newh), $palette->color("FFFFFF", 64));
$image_out = $imagine->create(new Box($image_width, $newh), $palette->color("FFFFFF", 64));
// paste the input image into
$image_out->paste($image_in, new Point(0, $tables['TOP']['h']));
unset($image_in);
// fix the coordinates
foreach ($tables['TOP-OVER']['rows'] as $k => $row) {
$tables['TOP-OVER']['rows'][$k]['y0'] += $tables['TOP']['h'];
@@ -347,19 +377,30 @@ class recordutils_image
foreach ($tables[$ta]['rows'] as $row) {
if ($row['h'] > 0) {
$image_out->paste($row['img'], new Point($row['x0'], $row['y0']));
unset($row['img']);
}
}
}
// save the output
if($back_rotation != 0) {
$image_out->rotate($back_rotation);
}
$image_out->save($pathOut);
unset($image_out);
gc_collect_cycles();
if (is_file($pathOut)) {
$writer = $app['exiftool.writer'];
// copy metadata to the stamped file if we can
if(method_exists($writer, "copy")) {
if (method_exists($writer, "copy")) {
$writer->copy($subdef->getRealPath(), $pathOut);
}
return $pathOut;
}
@@ -368,12 +409,12 @@ class recordutils_image
/**
*
* @param Application $app
* @param \media_subdef $subdef
* @param Application $app
* @param media_subdef $subdef
*
* @return boolean|string
*/
public static function watermark(Application $app, \media_subdef $subdef)
public static function watermark(Application $app, media_subdef $subdef)
{
static $palette;
@@ -387,7 +428,7 @@ class recordutils_image
return $subdef->getRealPath();
}
if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) {
if ($subdef->get_type() !== media_subdef::TYPE_IMAGE) {
return $subdef->getRealPath();
}
@@ -408,27 +449,32 @@ class recordutils_image
return $pathOut;
}
$in_image = $app['imagine']->open($pathIn);
/** @var Imagine\Imagick\Imagine $imagine */
$imagine = $app['imagine'];
$in_image = $imagine->open($pathIn);
$in_size = $in_image->getSize();
$in_w = $in_size->getWidth();
$in_h = $in_size->getHeight();
$wm_file = $app['root.path'] . '/config/wm/' . $base_id;
if (file_exists($wm_file)) {
$wm_image = $app['imagine']->open($wm_file);
$wm_image = $imagine->open($wm_file);
$wm_size = $wm_image->getSize();
$wm_w = $wm_size->getWidth();
$wm_h = $wm_size->getHeight();
if (($wm_w / $wm_h) > ($in_w / $in_h)) {
$wm_size = $wm_size->widen($in_w);
} else {
}
else {
$wm_size = $wm_size->heighten($in_h);
}
$wm_image->resize($wm_size);
$in_image->paste($wm_image, new Point(($in_w - $wm_size->getWidth()) >> 1, ($in_h - $wm_size->getHeight()) >> 1))->save($pathOut);
} else {
}
else {
$collname = $subdef->get_record()->getCollection()->get_name();
$draw = $in_image->draw();
$black = $palette->color("000000");
@@ -438,10 +484,10 @@ class recordutils_image
$draw->line(new Point(0, $in_h - 2), new Point($in_w - 2, 0), $black);
$draw->line(new Point(1, $in_h - 1), new Point($in_w - 1, 1), $white);
$fsize = max(8, (int) (max($in_w, $in_h) / 30));
$fsize = max(8, (int)(max($in_w, $in_h) / 30));
$fonts = [
$app['imagine']->font(__DIR__ . '/arial.ttf', $fsize, $black),
$app['imagine']->font(__DIR__ . '/arial.ttf', $fsize, $white)
$imagine->font(__DIR__ . '/arial.ttf', $fsize, $black),
$imagine->font(__DIR__ . '/arial.ttf', $fsize, $white)
];
$testbox = $fonts[0]->box($collname, 0);
$tx_w = min($in_w, $testbox->getWidth());
@@ -451,14 +497,14 @@ class recordutils_image
$y0 = max(1, ($in_h - $tx_h) >> 1);
for ($i = 0; $i <= 1; $i++) {
$x = max(1, ($in_w >> 2) - ($tx_w >> 1));
$draw->text($collname, $fonts[$i], new Point($x - $i, $y0 - $i), 0);
$draw->text($collname, $fonts[$i], new Point($x - $i, $y0 - $i));
$x = max(1, $in_w - $x - $tx_w);
$draw->text($collname, $fonts[$i], new Point($x - $i, $y0 - $i), 0);
$draw->text($collname, $fonts[$i], new Point($x - $i, $y0 - $i));
$y = max(1, ($in_h >> 2) - ($tx_h >> 1));
$draw->text($collname, $fonts[$i], new Point($x0 - $i, $y - $i), 0);
$draw->text($collname, $fonts[$i], new Point($x0 - $i, $y - $i));
$y = max(1, $in_h - $y - $tx_h);
$draw->text($collname, $fonts[$i], new Point($x0 - $i, $y - $i), 0);
$draw->text($collname, $fonts[$i], new Point($x0 - $i, $y - $i));
}
}
@@ -470,13 +516,14 @@ class recordutils_image
return false;
}
/**
*
* @param int $fontSize
* @param int $angle
* @param string $fontFace
* @param string $string
* @param int $width
* @param int $fontSize
* @param int $angle
* @param string $fontFace
* @param string $string
* @param int $width
* @return array
*/
protected static function wrap(ImagineInterface $imagine, $fontSize, $angle, $fontFace, $string, $width)
@@ -500,15 +547,17 @@ class recordutils_image
if ($lig == '') {
$ret[] = ['w' => 0, 'h' => $dy, 't' => ''];
$toth += $dy;
} else {
}
else {
$twords = [];
$iword = -1;
$lastc = '';
$length = strlen($lig);
$part = 0;
for ($i = 0; $i < $length; $i++) {
$c = $lig[$i];
if ($iword == -1 || (ctype_space($c) && !ctype_space($lastc))) {
$twords[++$iword] = [($part = 0) => '', 1 => ''];
$twords[++$iword] = [($part = 0) => '', 1 => ''];
}
if (!ctype_space($c) && $part == 0) {
$part++;
@@ -524,10 +573,11 @@ class recordutils_image
$w = $testbox->getWidth();
$h = $testbox->getHeight();
if ($i > 0 && $testbox->getWidth() > $width) {
$ret[] = ['w' => $lastw, 'h' => $lasth, 't' => $buff];
$ret[] = ['w' => $lastw, 'h' => $lasth, 't' => $buff];
$toth += $lasth;
$buff = $wrd[1];
} else {
}
else {
$buff = $test;
}
$lastw = $w;
@@ -541,6 +591,6 @@ class recordutils_image
}
}
return ['toth' => $toth, 'l' => $ret, 'h' => $height, 'dy' => $dy];
return ['toth' => $toth, 'l' => $ret, 'h' => $height, 'dy' => $dy];
}
}

View File

@@ -389,22 +389,29 @@ class set_export extends set_abstract
return $this->total_ftp;
}
const NO_STAMP = 'NO_STAMP';
const STAMP_SYNC = 'STAMP_SYNC';
const STAMP_ASYNC = 'STAMP_ASYNC';
/**
* @param User $user
* @param Filesystem $filesystem
* @param array $wantedSubdefs
* @param bool $rename_title
* @param bool $includeBusinessFields
* @param $stampChoice
* @param $no_stamp
* @return array
* @throws Exception
*/
public function prepare_export(User $user, Filesystem $filesystem, Array $wantedSubdefs, $rename_title, $includeBusinessFields, $stampChoice = null)
public function prepare_export(User $user, Filesystem $filesystem, Array $wantedSubdefs, $rename_title, $includeBusinessFields, $stampMethod)
{
if (!is_array($wantedSubdefs)) {
throw new Exception('No subdefs given');
}
if(!$stampMethod) {
$stampMethod = self::STAMP_SYNC;
}
$includeBusinessFields = (bool) $includeBusinessFields;
$files = [];
$n_files = 0;
@@ -509,7 +516,9 @@ class set_export extends set_abstract
$subdef_ok = true;
$tmp_pathfile = [
'path' => $sd[$subdefName]->get_path(),
'file' => $sd[$subdefName]->get_file()
'file' => $sd[$subdefName]->get_file(),
'to_stamp' => false,
'to_watermark' => false
];
break;
@@ -517,16 +526,28 @@ class set_export extends set_abstract
$subdef_ok = true;
$tmp_pathfile = [
'path' => $sd[$subdefName]->get_path(),
'file' => $sd[$subdefName]->get_file()
'file' => $sd[$subdefName]->get_file(),
'to_stamp' => false,
'to_watermark' => false
];
if($this->app['conf']->get(['registry', 'actions', 'export-stamp-choice']) !== true || is_null($stampChoice) ){
$path = \recordutils_image::stamp($this->app , $sd[$subdefName]);
if (file_exists($path)) {
$tmp_pathfile = [
'path' => dirname($path),
'file' => basename($path)
];
if($this->app['conf']->get(['registry', 'actions', 'export-stamp-choice']) !== true || $stampMethod !== self::NO_STAMP ){
// stamp is mandatory, or user did not check "no stamp" : we must apply stamp
if($stampMethod === self::STAMP_SYNC) {
// we prepare a direct download, we must stamp now
$path = \recordutils_image::stamp($this->app, $sd[$subdefName]);
if ($path && file_exists($path)) {
$tmp_pathfile = [
'path' => dirname($path),
'file' => basename($path),
'to_stamp' => false,
'to_watermark' => false
];
}
}
else {
// we prepare an email or ftp download : the worker will apply stamp
$tmp_pathfile ['to_stamp'] = true;
}
}
@@ -534,7 +555,9 @@ class set_export extends set_abstract
case 'preview':
$tmp_pathfile = [
'path' => $sd[$subdefName]->get_path(),
'file' => $sd[$subdefName]->get_file()
'file' => $sd[$subdefName]->get_file(),
'to_stamp' => false,
'to_watermark' => false
];
if (!$this->app->getAclForUser($user)->has_right_on_base($download_element->getBaseId(), \ACL::NOWATERMARK)
@@ -545,7 +568,9 @@ class set_export extends set_abstract
if (file_exists($path)) {
$tmp_pathfile = [
'path' => dirname($path),
'file' => basename($path)
'file' => basename($path),
'to_stamp' => false,
'to_watermark' => false
];
$subdef_ok = true;
}
@@ -569,14 +594,17 @@ class set_export extends set_abstract
$mime = 'text/xml';
}
$files[$id]["subdefs"][$subdefName]["ajout"] = $ajout;
$files[$id]["subdefs"][$subdefName]["exportExt"] = $ext;
$files[$id]["subdefs"][$subdefName]["label"] = $properties['label'];
$files[$id]["subdefs"][$subdefName]["path"] = null;
$files[$id]["subdefs"][$subdefName]["file"] = null;
$files[$id]["subdefs"][$subdefName]["size"] = 0;
$files[$id]["subdefs"][$subdefName]["mime"] = $mime;
$files[$id]["subdefs"][$subdefName]["folder"] = $download_element->get_directory();
$files[$id]["subdefs"][$subdefName] = [
"ajout" => $ajout,
"exportExt" => $ext,
"label" => $properties['label'],
"path" => null,
"file" => null,
"to_stamp" => false,
"size" => 0,
"mime" => $mime,
"folder" => $download_element->get_directory()
];
break;
case 'document':
@@ -586,19 +614,22 @@ class set_export extends set_abstract
$infos = pathinfo(p4string::addEndSlash($tmp_pathfile["path"]) . $tmp_pathfile["file"]);
$ext = isset($infos['extension']) ? $infos['extension'] : '';
$files[$id]["subdefs"][$subdefName]["ajout"] = $ajout;
$files[$id]["subdefs"][$subdefName]["exportExt"] = $ext;
$files[$id]["subdefs"][$subdefName]["label"] = $properties['label'];
$files[$id]["subdefs"][$subdefName]["path"] = $tmp_pathfile["path"];
$files[$id]["subdefs"][$subdefName]["file"] = $tmp_pathfile["file"];
$files[$id]["subdefs"][$subdefName]["size"] = $sd[$subdefName]->get_size();
$files[$id]["subdefs"][$subdefName]["mime"] = $sd[$subdefName]->get_mime();
$files[$id]["subdefs"][$subdefName]["folder"] = $download_element->get_directory();
$files[$id]["subdefs"][$subdefName] = [
"ajout" => $ajout,
"exportExt" => $ext,
"label" => $properties['label'],
"path" => $tmp_pathfile["path"],
"file" => $tmp_pathfile["file"],
"to_stamp" => $tmp_pathfile["to_stamp"],
"size" => $sd[$subdefName]->get_size(),
"mime" => $sd[$subdefName]->get_mime(),
"folder" => $download_element->get_directory()
];
$size += $sd[$subdefName]->get_size();
break;
default: // should no happen
default: // should not happen
$ajout = $ext = '';
break;
@@ -824,4 +855,27 @@ class set_export extends set_abstract
$stmt->closeCursor();
}
}
public function has_stamp_option()
{
if ($this->total_download == 0) {
return false;
}
$domprefs = new DOMDocument();
foreach ($this->elements as $download_element) {
if ( ($domprefs->loadXML($download_element->getCollection()->get_prefs())) === false) {
continue;
}
$xpprefs = new DOMXPath($domprefs);
$stampNodes = $xpprefs->query('/baseprefs/stamp');
if ($stampNodes->length != 0) {
return true;
}
}
return false;
}
}

View File

@@ -47,7 +47,7 @@
}
a {
color: #414141;
color: #08c;
}
}
@@ -62,7 +62,7 @@
}
a {
color: #999999;
color: #08c;
}
}

View File

@@ -409,9 +409,9 @@ function write_valsug()
function desactivall4VS()
{
activer_bout('bout_supp',true);
activer_bout('bout_mont',true);
activer_bout('bout_desc',true);
activer_bout('bout_supp', false);
activer_bout('bout_mont', false);
activer_bout('bout_desc', false);
o2 = $("#valsug2");
@@ -430,7 +430,7 @@ function desactiv4VS()
var optionLength = o2.find("option").length;
var index = o2.prop("selectedIndex");
if ( optionLength > 1) {
if ( optionLength > 1 && index != -1) {
if ((index+1) == optionLength) {
activer_bout('bout_desc',false);
} else {
@@ -483,7 +483,7 @@ function supprimer()
{
if(aa != o2.prop("selectedIndex")) {
pref[o.val()].valsug[bb]=pref[o.val()].valsug[aa];
if(aa+1 == pref[o.val()].valsug.length) {
if(parseInt(aa)+1 == pref[o.val()].valsug.length) {
pref[o.val()].valsug[bb]=null;
}
bb++;

View File

@@ -156,6 +156,14 @@
</label>
</div>
{% endif %}
{% if app['conf'].get(['registry', 'actions', 'export-stamp-choice']) == true and download.has_stamp_option() == true %}
<div id="download_stamp_choice" class="well-small hide" style="margin-left: 20px;" >
<label for="option_stamp" class="checkbox">
<input class="stamp_choice" type="checkbox" id="stamp_choice" name="stamp_choice" value="NO_STAMP" />
{{ 'prod::download: delete-marking-stamp' | trans }}
</label>
</div>
{% endif %}
<div class="buttons_line">
<button type="button" class="download_button btn btn-inverse">{{ 'boutton::telecharger' | trans }}</button>
<button type="button" class="close_button btn btn-inverse">{{ 'boutton::annuler' | trans }}</button>
@@ -519,6 +527,14 @@
$(document).find(".tagsinput").tagsinput('add', $(this).val());
$(this).val('');
});
$('#download_document').click(function(){
if($(this).is(':checked')){
$('#download_stamp_choice').show();
} else{
$('#download_stamp_choice').hide();
}
});
</script>
{% endif %}

View File

@@ -6,8 +6,9 @@
<img src="{{notification['icon']}}" style="vertical-align:middle;width:16px;margin:2px;" />
</td>
<td class="{{notification['class']}}">
{{notification['text'] | e | raw}}
{{notification['text'] | raw}}
<span class="time">{{notification['created_on']}}</span>
<span class="time-in-dialog" style="color: #666666;display: none;" >{{notification['time']}}</span>
</td>
<td style="width:25px; vertical-align: bottom;">
<span class="icon_read" title="{{ 'notification::read:tooltip' | trans }}"></span>