mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-23 18:03:17 +00:00
merge
This commit is contained in:
@@ -15,7 +15,7 @@ jobs:
|
|||||||
CIRCLE_TEST_REPORTS: /tmp/circleci-test-results
|
CIRCLE_TEST_REPORTS: /tmp/circleci-test-results
|
||||||
docker:
|
docker:
|
||||||
- image: circleci/build-image:ubuntu-14.04-XXL-upstart-1189-5614f37
|
- image: circleci/build-image:ubuntu-14.04-XXL-upstart-1189-5614f37
|
||||||
command: /sbin/init
|
- image: circleci/rabbitmq:3.7.7
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- run: mkdir -p $CIRCLE_ARTIFACTS $CIRCLE_TEST_REPORTS
|
- run: mkdir -p $CIRCLE_ARTIFACTS $CIRCLE_TEST_REPORTS
|
||||||
@@ -24,10 +24,7 @@ jobs:
|
|||||||
command: nvm install v10.12.0 && nvm alias default v10.12.0
|
command: nvm install v10.12.0 && nvm alias default v10.12.0
|
||||||
- run:
|
- run:
|
||||||
working_directory: ~/alchemy-fr/Phraseanet
|
working_directory: ~/alchemy-fr/Phraseanet
|
||||||
command: 'sudo service memcached status || sudo service memcached start; sudo
|
command: 'sudo service mysql status || sudo service mysql start;'
|
||||||
redis-cli ping >/dev/null 2>&1 || sudo service redis-server start; sudo
|
|
||||||
service mysql status || sudo service mysql start; sudo service rabbitmq-server
|
|
||||||
status || sudo service rabbitmq-server start; '
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
# This would typically go in either a build or a build-and-test job when using workflows
|
# This would typically go in either a build or a build-and-test job when using workflows
|
||||||
# Restore the dependency cache
|
# Restore the dependency cache
|
||||||
@@ -124,7 +121,7 @@ workflows:
|
|||||||
context: "AWS London"
|
context: "AWS London"
|
||||||
create-repo: true
|
create-repo: true
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
extra-build-args: "--target phraseanet"
|
extra-build-args: "--target phraseanet-fpm"
|
||||||
region: AWS_DEFAULT_REGION
|
region: AWS_DEFAULT_REGION
|
||||||
repo: "${AWS_RESOURCE_NAME_PREFIX}/phraseanet"
|
repo: "${AWS_RESOURCE_NAME_PREFIX}/phraseanet"
|
||||||
tag: "alpha-0.1"
|
tag: "alpha-0.1"
|
||||||
@@ -139,3 +136,14 @@ workflows:
|
|||||||
region: AWS_DEFAULT_REGION
|
region: AWS_DEFAULT_REGION
|
||||||
repo: "${AWS_RESOURCE_NAME_PREFIX}/phraseanet-nginx"
|
repo: "${AWS_RESOURCE_NAME_PREFIX}/phraseanet-nginx"
|
||||||
tag: "alpha-0.1"
|
tag: "alpha-0.1"
|
||||||
|
- aws-ecr/build_and_push_image:
|
||||||
|
account-url: AWS_ACCOUNT_URL
|
||||||
|
aws-access-key-id: AWS_ACCESS_KEY_ID
|
||||||
|
aws-secret-access-key: AWS_SECRET_ACCESS_KEY
|
||||||
|
context: "AWS London"
|
||||||
|
create-repo: true
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
extra-build-args: "--target phraseanet-worker"
|
||||||
|
region: AWS_DEFAULT_REGION
|
||||||
|
repo: "${AWS_RESOURCE_NAME_PREFIX}/phraseanet"
|
||||||
|
tag: "alpha-0.1"
|
||||||
|
@@ -40,7 +40,7 @@ RUN apt-get update \
|
|||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
|
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
|
||||||
&& php -r "if (hash_file('sha384', 'composer-setup.php') === '48e3236262b34d30969dca3c37281b3b4bbe3221bda826ac6a9a62d6444cdb0dcd0615698a5cbe587c3f0fe57a54d8f5') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
|
&& php -r "if (hash_file('sha384', 'composer-setup.php') === 'a5c698ffe4b8e849a443b120cd5ba38043260d5c4023dbf93e1558871f1f07f58274fc6f4c93bcfd858c6bd0775cd8d1') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
|
||||||
&& php composer-setup.php --install-dir=/usr/local/bin --filename=composer \
|
&& php composer-setup.php --install-dir=/usr/local/bin --filename=composer \
|
||||||
&& php -r "unlink('composer-setup.php');"
|
&& php -r "unlink('composer-setup.php');"
|
||||||
|
|
||||||
|
66
Vagrantfile
vendored
66
Vagrantfile
vendored
@@ -1,16 +1,5 @@
|
|||||||
Vagrant.require_version ">= 1.5"
|
Vagrant.require_version ">= 1.5"
|
||||||
|
require 'json'
|
||||||
class MyCustomError < StandardError
|
|
||||||
attr_reader :code
|
|
||||||
|
|
||||||
def initialize(code)
|
|
||||||
@code = code
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s
|
|
||||||
"[#{code} #{super}]"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Check to determine whether we're on a windows or linux/os-x host,
|
# Check to determine whether we're on a windows or linux/os-x host,
|
||||||
# later on we use this to launch ansible in the supported way
|
# later on we use this to launch ansible in the supported way
|
||||||
@@ -39,7 +28,16 @@ unless Vagrant.has_plugin?('vagrant-hostmanager')
|
|||||||
raise "vagrant-hostmanager is not installed! Please run\n vagrant plugin install vagrant-hostmanager\n\n"
|
raise "vagrant-hostmanager is not installed! Please run\n vagrant plugin install vagrant-hostmanager\n\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
if ARGV[1] == '--provision'
|
# Check to determine if box_meta JSON is present
|
||||||
|
# if provisionned : pick name of box
|
||||||
|
if File.file?(".vagrant/machines/default/virtualbox/box_meta")
|
||||||
|
data = File.read(".vagrant/machines/default/virtualbox/box_meta")
|
||||||
|
parsed_json = JSON.parse(data)
|
||||||
|
$box = parsed_json["name"]
|
||||||
|
end
|
||||||
|
|
||||||
|
# if not : run prompt to configure provisioning
|
||||||
|
if !File.file?(".vagrant/machines/default/virtualbox/box_meta") && ARGV[0] == 'up'
|
||||||
print "\033[34m \nChoose a Build type :\n\n(1) Use prebuilt Phraseanet Box\n(2) Build Phraseanet from scratch (xenial)\n\033[00m"
|
print "\033[34m \nChoose a Build type :\n\n(1) Use prebuilt Phraseanet Box\n(2) Build Phraseanet from scratch (xenial)\n\033[00m"
|
||||||
type = STDIN.gets.chomp
|
type = STDIN.gets.chomp
|
||||||
print "\n"
|
print "\n"
|
||||||
@@ -47,9 +45,10 @@ if ARGV[1] == '--provision'
|
|||||||
case (type)
|
case (type)
|
||||||
when '1'
|
when '1'
|
||||||
$box = "alchemy/Phraseanet-vagrant-dev_php"
|
$box = "alchemy/Phraseanet-vagrant-dev_php"
|
||||||
|
$playbook = "resources/ansible/playbook-boxes.yml"
|
||||||
when '2'
|
when '2'
|
||||||
$box = "ubuntu/xenial64"
|
$box = "ubuntu/xenial64"
|
||||||
print("\033[91mComplete build selected, don't forget to uncomment all roles on playbook.yml\n\n\033[00m")
|
$playbook = "resources/ansible/playbook.yml"
|
||||||
else
|
else
|
||||||
raise "\033[31mYou should specify Build type before running vagrant\n\n (Available : 1, 2)\n\n\033[00m"
|
raise "\033[31mYou should specify Build type before running vagrant\n\n (Available : 1, 2)\n\n\033[00m"
|
||||||
end
|
end
|
||||||
@@ -133,8 +132,6 @@ else if $env == "linux"
|
|||||||
$hostIps = `ifconfig | sed -nE 's/[[:space:]]*inet ([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})(.*)$/\\1/p'`.split("\n");
|
$hostIps = `ifconfig | sed -nE 's/[[:space:]]*inet ([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})(.*)$/\\1/p'`.split("\n");
|
||||||
else
|
else
|
||||||
$hostIps = `resources/ansible/inventories/GetIpAdresses.cmd`;
|
$hostIps = `resources/ansible/inventories/GetIpAdresses.cmd`;
|
||||||
# raise MyCustomError.new($hostIps), "HOST IP"
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -157,31 +154,28 @@ Vagrant.configure("2") do |config|
|
|||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
config.vm.box = ($box) ? $box : "ubuntu/xenial64"
|
config.vm.box = $box
|
||||||
|
|
||||||
# In case, Phraseanet box, choose the php version
|
|
||||||
# For php 7.0 use box 0.0.1
|
|
||||||
# For php 7.1 use box 0.0.2
|
|
||||||
#config.vm.box_version = "0.0.1"
|
|
||||||
|
|
||||||
config.ssh.forward_agent = true
|
config.ssh.forward_agent = true
|
||||||
config_net(config)
|
config_net(config)
|
||||||
|
|
||||||
# If ansible is in your path it will provision from your HOST machine
|
# If ansible is in your path it will provision from your HOST machine
|
||||||
# If ansible is not found in the path it will be instaled in the VM and provisioned from there
|
# If ansible is not found in the path it will be instaled in the VM and provisioned from there
|
||||||
if which('ansible-playbook')
|
if which('ansible-playbook')
|
||||||
config.vm.provision "ansible_local" do |ansible|
|
|
||||||
ansible.playbook = "resources/ansible/playbook.yml"
|
if $playbook
|
||||||
ansible.limit = 'all'
|
config.vm.provision "ansible_local" do |ansible|
|
||||||
ansible.verbose = 'vvv'
|
ansible.playbook = $playbook
|
||||||
ansible.extra_vars = {
|
ansible.limit = 'all'
|
||||||
hostname: $hostname,
|
ansible.verbose = 'vvv'
|
||||||
host_addresses: $hostIps,
|
ansible.extra_vars = {
|
||||||
phpversion: phpversion,
|
hostname: $hostname,
|
||||||
postfix: {
|
host_addresses: $hostIps,
|
||||||
postfix_domain: $hostname + ".vb"
|
phpversion: phpversion,
|
||||||
|
postfix: {
|
||||||
|
postfix_domain: $hostname + ".vb"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
config.vm.provision "ansible_local", run: "always" do |ansible|
|
config.vm.provision "ansible_local", run: "always" do |ansible|
|
||||||
@@ -194,10 +188,6 @@ Vagrant.configure("2") do |config|
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
# raise MyCustomError.new([$hostname, $phpVersion, $hostIps]), "HOST IP"
|
|
||||||
# raise MyCustomError.new($hostIps), "HOST IP"
|
|
||||||
# raise MyCustomError.new($hostIps), "HOST IP"
|
|
||||||
|
|
||||||
config.vm.provision :shell, path: "resources/ansible/windows.sh", args: [$hostname, $phpVersion, $hostIps]
|
config.vm.provision :shell, path: "resources/ansible/windows.sh", args: [$hostname, $phpVersion, $hostIps]
|
||||||
# config.vm.provision :shell, run: "always", path: "resources/ansible/windows-always.sh", args: ["default"]
|
# config.vm.provision :shell, run: "always", path: "resources/ansible/windows-always.sh", args: ["default"]
|
||||||
end
|
end
|
||||||
|
0
cache/.gitkeep
vendored
0
cache/.gitkeep
vendored
@@ -47,7 +47,7 @@
|
|||||||
"php": ">=5.5.9",
|
"php": ">=5.5.9",
|
||||||
"ext-intl": "*",
|
"ext-intl": "*",
|
||||||
"alchemy-fr/tcpdf-clone": "~6.0",
|
"alchemy-fr/tcpdf-clone": "~6.0",
|
||||||
"alchemy/embed-bundle": "^2.0.6",
|
"alchemy/embed-bundle": "^2.0.7",
|
||||||
"alchemy/geonames-api-consumer": "~0.1.0",
|
"alchemy/geonames-api-consumer": "~0.1.0",
|
||||||
"alchemy/mediavorus": "^0.4.4",
|
"alchemy/mediavorus": "^0.4.4",
|
||||||
"alchemy/oauth2php": "1.1.0",
|
"alchemy/oauth2php": "1.1.0",
|
||||||
|
14
composer.lock
generated
14
composer.lock
generated
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "6341722edcd5bfa22e933f5411225144",
|
"content-hash": "f3b1fc0a30bf14b05e57ce673550d9c0",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "alchemy-fr/tcpdf-clone",
|
"name": "alchemy-fr/tcpdf-clone",
|
||||||
@@ -131,16 +131,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "alchemy/embed-bundle",
|
"name": "alchemy/embed-bundle",
|
||||||
"version": "2.0.6",
|
"version": "2.0.7",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/alchemy-fr/embed-bundle.git",
|
"url": "https://github.com/alchemy-fr/embed-bundle.git",
|
||||||
"reference": "53ba295dfd0554a31c35e93902a5ef6cb8eca31a"
|
"reference": "c585ccf18e53a9a6f2b696ddbbc39521732dfdde"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/alchemy-fr/embed-bundle/zipball/53ba295dfd0554a31c35e93902a5ef6cb8eca31a",
|
"url": "https://api.github.com/repos/alchemy-fr/embed-bundle/zipball/c585ccf18e53a9a6f2b696ddbbc39521732dfdde",
|
||||||
"reference": "53ba295dfd0554a31c35e93902a5ef6cb8eca31a",
|
"reference": "c585ccf18e53a9a6f2b696ddbbc39521732dfdde",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
@@ -178,10 +178,10 @@
|
|||||||
],
|
],
|
||||||
"description": "Embed resources bundle",
|
"description": "Embed resources bundle",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/alchemy-fr/embed-bundle/tree/2.0.6",
|
"source": "https://github.com/alchemy-fr/embed-bundle/tree/2.0.7",
|
||||||
"issues": "https://github.com/alchemy-fr/embed-bundle/issues"
|
"issues": "https://github.com/alchemy-fr/embed-bundle/issues"
|
||||||
},
|
},
|
||||||
"time": "2019-07-11T12:59:49+00:00"
|
"time": "2019-09-02T12:28:19+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "alchemy/geonames-api-consumer",
|
"name": "alchemy/geonames-api-consumer",
|
||||||
|
@@ -115,6 +115,7 @@ use Symfony\Component\Form\FormBuilderInterface;
|
|||||||
use Symfony\Component\Form\FormInterface;
|
use Symfony\Component\Form\FormInterface;
|
||||||
use Symfony\Component\Form\FormTypeInterface;
|
use Symfony\Component\Form\FormTypeInterface;
|
||||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||||
|
use Symfony\Component\Process\ExecutableFinder;
|
||||||
use Unoconv\UnoconvServiceProvider;
|
use Unoconv\UnoconvServiceProvider;
|
||||||
use XPDF\PdfToText;
|
use XPDF\PdfToText;
|
||||||
use XPDF\XPDFServiceProvider;
|
use XPDF\XPDFServiceProvider;
|
||||||
@@ -237,8 +238,19 @@ class Application extends SilexApplication
|
|||||||
|
|
||||||
$this->register(new UnicodeServiceProvider());
|
$this->register(new UnicodeServiceProvider());
|
||||||
$this->register(new ValidatorServiceProvider());
|
$this->register(new ValidatorServiceProvider());
|
||||||
$this->register(new XPDFServiceProvider());
|
|
||||||
$this->setupXpdf();
|
if ($this['configuration.store']->isSetup()) {
|
||||||
|
$binariesConfig = $this['conf']->get(['main', 'binaries']);
|
||||||
|
$executableFinder = new ExecutableFinder();
|
||||||
|
$this->register(new XPDFServiceProvider(), [
|
||||||
|
'xpdf.configuration' => [
|
||||||
|
'pdftotext.binaries' => isset($binariesConfig['pdftotext_binary']) ? $binariesConfig['pdftotext_binary'] : $executableFinder->find('pdftotext'),
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->setupXpdf();
|
||||||
|
}
|
||||||
|
|
||||||
$this->register(new FileServeServiceProvider());
|
$this->register(new FileServeServiceProvider());
|
||||||
$this->register(new ManipulatorServiceProvider());
|
$this->register(new ManipulatorServiceProvider());
|
||||||
$this->register(new PluginServiceProvider());
|
$this->register(new PluginServiceProvider());
|
||||||
@@ -653,7 +665,7 @@ class Application extends SilexApplication
|
|||||||
private function setupGeonames()
|
private function setupGeonames()
|
||||||
{
|
{
|
||||||
$this['geonames.server-uri'] = $this->share(function (Application $app) {
|
$this['geonames.server-uri'] = $this->share(function (Application $app) {
|
||||||
return $app['conf']->get(['registry', 'webservices', 'geonames-server'], 'http://geonames.alchemyasp.com/');
|
return $app['conf']->get(['registry', 'webservices', 'geonames-server'], 'https://geonames.alchemyasp.com/');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -944,7 +944,7 @@ class V1Controller extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
$originalName = $pi['filename'] . '.' . $pi['extension'];
|
$originalName = $pi['filename'] . '.' . $pi['extension'];
|
||||||
$newPathname = $tempfile;
|
$uploadedFilename = $newPathname = $tempfile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -956,8 +956,11 @@ class V1Controller extends Controller
|
|||||||
if (!$file->isValid()) {
|
if (!$file->isValid()) {
|
||||||
return $this->getBadRequestAction($request, 'Data corrupted, please try again');
|
return $this->getBadRequestAction($request, 'Data corrupted, please try again');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$uploadedFilename = $file->getPathname();
|
||||||
$originalName = $file->getClientOriginalName();
|
$originalName = $file->getClientOriginalName();
|
||||||
$newPathname = $file->getPathname() . '.' . $file->getClientOriginalExtension();
|
$newPathname = $file->getPathname() . '.' . $file->getClientOriginalExtension();
|
||||||
|
|
||||||
if (false === rename($file->getPathname(), $newPathname)) {
|
if (false === rename($file->getPathname(), $newPathname)) {
|
||||||
return Result::createError($request, 403, 'Error while renaming file')->createResponse();
|
return Result::createError($request, 403, 'Error while renaming file')->createResponse();
|
||||||
}
|
}
|
||||||
@@ -1010,6 +1013,11 @@ class V1Controller extends Controller
|
|||||||
$nosubdef = $request->get('nosubdefs') === '' || \p4field::isyes($request->get('nosubdefs'));
|
$nosubdef = $request->get('nosubdefs') === '' || \p4field::isyes($request->get('nosubdefs'));
|
||||||
$this->getBorderManager()->process($session, $Package, $callback, $behavior, $nosubdef);
|
$this->getBorderManager()->process($session, $Package, $callback, $behavior, $nosubdef);
|
||||||
|
|
||||||
|
// remove $newPathname on temporary directory
|
||||||
|
if ($newPathname !== $uploadedFilename) {
|
||||||
|
@rename($newPathname, $uploadedFilename);
|
||||||
|
}
|
||||||
|
|
||||||
$ret = ['entity' => null];
|
$ret = ['entity' => null];
|
||||||
|
|
||||||
if ($output instanceof \record_adapter) {
|
if ($output instanceof \record_adapter) {
|
||||||
@@ -1081,6 +1089,11 @@ class V1Controller extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove $newPathname on temporary directory
|
||||||
|
if ($renamedFilename !== $uploadedFilename) {
|
||||||
|
@rename($renamedFilename, $uploadedFilename);
|
||||||
|
}
|
||||||
|
|
||||||
return Result::create($request, $ret)->createResponse();
|
return Result::create($request, $ret)->createResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1984,7 +1997,7 @@ class V1Controller extends Controller
|
|||||||
return $this->getBadRequestAction($request);
|
return $this->getBadRequestAction($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
$datas = substr($datas, 0, ($n)) . $value . substr($datas, ($n + 2));
|
$datas = substr($datas, 0, ($n)) . $value . substr($datas, ($n + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
$record->setStatus(strrev($datas));
|
$record->setStatus(strrev($datas));
|
||||||
|
@@ -463,6 +463,8 @@ class PushController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
$manager = $this->getEntityManager();
|
||||||
|
|
||||||
$password = $this->getRandomGenerator()->generateString(128);
|
$password = $this->getRandomGenerator()->generateString(128);
|
||||||
|
|
||||||
$user = $this->getUserManipulator()->createUser($email, $password, $email);
|
$user = $this->getUserManipulator()->createUser($email, $password, $email);
|
||||||
@@ -476,12 +478,15 @@ class PushController extends Controller
|
|||||||
$user->setCompany($request->request->get('company'));
|
$user->setCompany($request->request->get('company'));
|
||||||
}
|
}
|
||||||
if ($request->request->get('job')) {
|
if ($request->request->get('job')) {
|
||||||
$user->setCompany($request->request->get('job'));
|
$user->setJob($request->request->get('job'));
|
||||||
}
|
}
|
||||||
if ($request->request->get('form_geonameid')) {
|
if ($request->request->get('city')) {
|
||||||
$this->getUserManipulator()->setGeonameId($user, $request->request->get('form_geonameid'));
|
$this->getUserManipulator()->setGeonameId($user, $request->request->get('city'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$manager->persist($user);
|
||||||
|
$manager->flush();
|
||||||
|
|
||||||
$result['message'] = $this->app->trans('User successfully created');
|
$result['message'] = $this->app->trans('User successfully created');
|
||||||
$result['success'] = true;
|
$result['success'] = true;
|
||||||
$result['user'] = $this->formatUser($user);
|
$result['user'] = $this->formatUser($user);
|
||||||
|
@@ -179,7 +179,6 @@ class QueryController extends Controller
|
|||||||
};
|
};
|
||||||
|
|
||||||
$userManipulator->setUserSetting($user, 'last_jsonquery', (string)$request->request->get('jsQuery'));
|
$userManipulator->setUserSetting($user, 'last_jsonquery', (string)$request->request->get('jsQuery'));
|
||||||
|
|
||||||
$jsQuery = @json_decode((string)$request->request->get('jsQuery'), true);
|
$jsQuery = @json_decode((string)$request->request->get('jsQuery'), true);
|
||||||
if(($ft = $findFulltext($jsQuery['query'])) !== null) {
|
if(($ft = $findFulltext($jsQuery['query'])) !== null) {
|
||||||
$userManipulator->setUserSetting($user, 'start_page_query', $ft);
|
$userManipulator->setUserSetting($user, 'start_page_query', $ft);
|
||||||
@@ -317,7 +316,7 @@ class QueryController extends Controller
|
|||||||
</tfoot>
|
</tfoot>
|
||||||
</table></div></div>'
|
</table></div></div>'
|
||||||
. '</div><a href="#" class="search-display-info" data-infos="' . str_replace('"', '"', $explain) . '">'
|
. '</div><a href="#" class="search-display-info" data-infos="' . str_replace('"', '"', $explain) . '">'
|
||||||
. $this->app->trans('%total% reponses', ['%total%' => '<span>'.$result->getTotal().'</span>']) . '</a>';
|
. $this->app->trans('%total% reponses', ['%total%' => '<span>'.number_format($result->getTotal(),null, null, ' ').'</span>']) . '</a>';
|
||||||
|
|
||||||
$json['infos'] = $infoResult;
|
$json['infos'] = $infoResult;
|
||||||
$json['navigationTpl'] = $string;
|
$json['navigationTpl'] = $string;
|
||||||
|
@@ -265,7 +265,7 @@ class LoginController extends Controller
|
|||||||
return $this->render('login/register-classic.html.twig', array_merge(
|
return $this->render('login/register-classic.html.twig', array_merge(
|
||||||
$this->getDefaultTemplateVariables($request),
|
$this->getDefaultTemplateVariables($request),
|
||||||
[
|
[
|
||||||
'geonames_server_uri' => str_replace(sprintf('%s:', parse_url($url, PHP_URL_SCHEME)), '', $url),
|
'geonames_server_uri' => $url,
|
||||||
'form' => $form->createView()
|
'form' => $form->createView()
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
@@ -146,7 +146,7 @@ class RegistryFormManipulator
|
|||||||
],
|
],
|
||||||
'webservices' => [
|
'webservices' => [
|
||||||
'google-charts-enabled' => true,
|
'google-charts-enabled' => true,
|
||||||
'geonames-server' => 'http://geonames.alchemyasp.com/',
|
'geonames-server' => 'https://geonames.alchemyasp.com/',
|
||||||
'captchas-enabled' => false,
|
'captchas-enabled' => false,
|
||||||
'recaptcha-public-key' => '',
|
'recaptcha-public-key' => '',
|
||||||
'recaptcha-private-key' => '',
|
'recaptcha-private-key' => '',
|
||||||
|
@@ -16,7 +16,7 @@ class Version
|
|||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $number = '4.1.0-alpha.14a';
|
private $number = '4.1.0-alpha.15a';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
|
@@ -14,6 +14,7 @@ namespace Alchemy\Phrasea\Metadata;
|
|||||||
use Alchemy\Phrasea\Border\File;
|
use Alchemy\Phrasea\Border\File;
|
||||||
use Alchemy\Phrasea\Databox\DataboxRepository;
|
use Alchemy\Phrasea\Databox\DataboxRepository;
|
||||||
use Alchemy\Phrasea\Metadata\Tag\NoSource;
|
use Alchemy\Phrasea\Metadata\Tag\NoSource;
|
||||||
|
use DateTime;
|
||||||
use PHPExiftool\Driver\Metadata\Metadata;
|
use PHPExiftool\Driver\Metadata\Metadata;
|
||||||
|
|
||||||
class PhraseanetMetadataSetter
|
class PhraseanetMetadataSetter
|
||||||
@@ -66,8 +67,16 @@ class PhraseanetMetadataSetter
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$data['value'] = $value;
|
if ($field->get_type() == 'date') {
|
||||||
|
try {
|
||||||
|
$dateTime = new DateTime($value);
|
||||||
|
$value = $dateTime->format('Y/m/d H:i:s');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// $value unchanged
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['value'] = $value;
|
||||||
$metadataInRecordFormat[] = $data;
|
$metadataInRecordFormat[] = $data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -212,8 +212,7 @@ class BasketRepository extends EntityRepository
|
|||||||
case self::RECEIVED:
|
case self::RECEIVED:
|
||||||
$dql = 'SELECT b
|
$dql = 'SELECT b
|
||||||
FROM Phraseanet:Basket b
|
FROM Phraseanet:Basket b
|
||||||
JOIN b.elements e
|
JOIN b.elements e';
|
||||||
WHERE b.user = :usr_id AND b.pusher_id IS NOT NULL';
|
|
||||||
$params = [
|
$params = [
|
||||||
'usr_id' => $user->getId()
|
'usr_id' => $user->getId()
|
||||||
];
|
];
|
||||||
|
@@ -30,6 +30,11 @@ class FieldKey implements Key, QueryPostProcessor
|
|||||||
return $this->getField($context)->getIndexField($raw);
|
return $this->getField($context)->getIndexField($raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getFieldType(QueryContext $context)
|
||||||
|
{
|
||||||
|
return $this->getField($context)->getType();
|
||||||
|
}
|
||||||
|
|
||||||
public function isValueCompatible($value, QueryContext $context)
|
public function isValueCompatible($value, QueryContext $context)
|
||||||
{
|
{
|
||||||
return ValueChecker::isValueCompatible($this->getField($context), $value);
|
return ValueChecker::isValueCompatible($this->getField($context), $value);
|
||||||
|
@@ -6,6 +6,7 @@ use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryContext;
|
|||||||
|
|
||||||
interface Key
|
interface Key
|
||||||
{
|
{
|
||||||
|
public function getFieldType(QueryContext $context);
|
||||||
public function getIndexField(QueryContext $context, $raw = false);
|
public function getIndexField(QueryContext $context, $raw = false);
|
||||||
public function isValueCompatible($value, QueryContext $context);
|
public function isValueCompatible($value, QueryContext $context);
|
||||||
public function __toString();
|
public function __toString();
|
||||||
|
@@ -23,6 +23,11 @@ class MetadataKey implements Key
|
|||||||
return $this->getTag($context)->getIndexField($raw);
|
return $this->getTag($context)->getIndexField($raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getFieldType(QueryContext $context)
|
||||||
|
{
|
||||||
|
return $this->getTag($context)->getType();
|
||||||
|
}
|
||||||
|
|
||||||
public function isValueCompatible($value, QueryContext $context)
|
public function isValueCompatible($value, QueryContext $context)
|
||||||
{
|
{
|
||||||
return ValueChecker::isValueCompatible($this->getTag($context), $value);
|
return ValueChecker::isValueCompatible($this->getTag($context), $value);
|
||||||
|
@@ -52,6 +52,11 @@ class NativeKey implements Key
|
|||||||
$this->key = $key;
|
$this->key = $key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getFieldType(QueryContext $context)
|
||||||
|
{
|
||||||
|
return $this->type;
|
||||||
|
}
|
||||||
|
|
||||||
public function getIndexField(QueryContext $context, $raw = false)
|
public function getIndexField(QueryContext $context, $raw = false)
|
||||||
{
|
{
|
||||||
return $this->key;
|
return $this->key;
|
||||||
|
@@ -2,18 +2,20 @@
|
|||||||
|
|
||||||
namespace Alchemy\Phrasea\SearchEngine\Elastic\AST\KeyValue;
|
namespace Alchemy\Phrasea\SearchEngine\Elastic\AST\KeyValue;
|
||||||
|
|
||||||
|
use Alchemy\Phrasea\SearchEngine\Elastic\FieldMapping;
|
||||||
|
use Alchemy\Phrasea\SearchEngine\Elastic\RecordHelper;
|
||||||
|
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\Field as StructureField;
|
||||||
use Assert\Assertion;
|
use Assert\Assertion;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\AST\KeyValue\FieldKey;
|
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\AST\KeyValue\Key;
|
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\AST\Node;
|
use Alchemy\Phrasea\SearchEngine\Elastic\AST\Node;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Exception\QueryException;
|
use Alchemy\Phrasea\SearchEngine\Elastic\Exception\QueryException;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryContext;
|
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryContext;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryHelper;
|
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryPostProcessor;
|
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryPostProcessor;
|
||||||
|
|
||||||
class RangeExpression extends Node
|
class RangeExpression extends Node
|
||||||
{
|
{
|
||||||
|
/** @var FieldKey */
|
||||||
private $key;
|
private $key;
|
||||||
|
|
||||||
private $lower_bound;
|
private $lower_bound;
|
||||||
private $lower_inclusive;
|
private $lower_inclusive;
|
||||||
private $higher_bound;
|
private $higher_bound;
|
||||||
@@ -55,20 +57,34 @@ class RangeExpression extends Node
|
|||||||
public function buildQuery(QueryContext $context)
|
public function buildQuery(QueryContext $context)
|
||||||
{
|
{
|
||||||
$params = array();
|
$params = array();
|
||||||
if ($this->lower_bound !== null) {
|
/** @var StructureField $field */
|
||||||
$this->assertValueCompatible($this->lower_bound, $context);
|
// $field = $this->key->getField($context);
|
||||||
if ($this->lower_inclusive) {
|
$lower_bound = $this->lower_bound;
|
||||||
$params['gte'] = $this->lower_bound;
|
$higher_bound = $this->higher_bound;
|
||||||
} else {
|
|
||||||
$params['gt'] = $this->lower_bound;
|
if($this->key->getFieldType($context) === FieldMapping::TYPE_DATE) {
|
||||||
|
if($lower_bound !== null) {
|
||||||
|
$lower_bound = RecordHelper::sanitizeDate($lower_bound);
|
||||||
|
}
|
||||||
|
if($higher_bound !== null) {
|
||||||
|
$higher_bound = RecordHelper::sanitizeDate($higher_bound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($this->higher_bound !== null) {
|
|
||||||
$this->assertValueCompatible($this->higher_bound, $context);
|
if ($lower_bound !== null) {
|
||||||
if ($this->higher_inclusive) {
|
$this->assertValueCompatible($lower_bound, $context);
|
||||||
$params['lte'] = $this->higher_bound;
|
if ($this->lower_inclusive) {
|
||||||
|
$params['gte'] = $lower_bound;
|
||||||
} else {
|
} else {
|
||||||
$params['lt'] = $this->higher_bound;
|
$params['gt'] = $lower_bound;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($higher_bound !== null) {
|
||||||
|
$this->assertValueCompatible($higher_bound, $context);
|
||||||
|
if ($this->higher_inclusive) {
|
||||||
|
$params['lte'] = $higher_bound;
|
||||||
|
} else {
|
||||||
|
$params['lt'] = $higher_bound;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -34,6 +34,11 @@ class TimestampKey implements Key, Typed
|
|||||||
return FieldMapping::TYPE_DATE;
|
return FieldMapping::TYPE_DATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getFieldType(QueryContext $context)
|
||||||
|
{
|
||||||
|
return FieldMapping::TYPE_DATE;
|
||||||
|
}
|
||||||
|
|
||||||
public function getIndexField(QueryContext $context, $raw = false)
|
public function getIndexField(QueryContext $context, $raw = false)
|
||||||
{
|
{
|
||||||
return $this->index_field;
|
return $this->index_field;
|
||||||
|
@@ -396,10 +396,10 @@ class ElasticSearchEngine implements SearchEngineInterface
|
|||||||
if ($options->getDateFields() && ($options->getMaxDate() || $options->getMinDate())) {
|
if ($options->getDateFields() && ($options->getMaxDate() || $options->getMinDate())) {
|
||||||
$range = [];
|
$range = [];
|
||||||
if ($options->getMaxDate()) {
|
if ($options->getMaxDate()) {
|
||||||
$range['lte'] = $options->getMaxDate()->format(FieldMapping::DATE_FORMAT_CAPTION_PHP);
|
$range['lte'] = $options->getMaxDate()->format('Y-m-d');
|
||||||
}
|
}
|
||||||
if ($options->getMinDate()) {
|
if ($options->getMinDate()) {
|
||||||
$range['gte'] = $options->getMinDate()->format(FieldMapping::DATE_FORMAT_CAPTION_PHP);
|
$range['gte'] = $options->getMinDate()->format('Y-m-d');
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($options->getDateFields() as $dateField) {
|
foreach ($options->getDateFields() as $dateField) {
|
||||||
|
@@ -16,8 +16,7 @@ class FieldMapping
|
|||||||
|
|
||||||
const DATE_FORMAT_MYSQL = 'yyyy-MM-dd HH:mm:ss';
|
const DATE_FORMAT_MYSQL = 'yyyy-MM-dd HH:mm:ss';
|
||||||
const DATE_FORMAT_CAPTION = 'yyyy/MM/dd'; // ES format
|
const DATE_FORMAT_CAPTION = 'yyyy/MM/dd'; // ES format
|
||||||
const DATE_FORMAT_MYSQL_OR_CAPTION = 'yyyy-MM-dd HH:mm:ss||yyyy/MM/dd';
|
const DATE_FORMAT_MYSQL_OR_CAPTION = 'yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||yyyy-MM||yyyy';
|
||||||
const DATE_FORMAT_CAPTION_PHP = 'Y/m/d'; // PHP format
|
|
||||||
|
|
||||||
// Core types
|
// Core types
|
||||||
const TYPE_STRING = 'string';
|
const TYPE_STRING = 'string';
|
||||||
|
@@ -155,15 +155,16 @@ class BulkOperation
|
|||||||
// nb: results (items) are returned IN THE SAME ORDER as commands were pushed in the stack
|
// nb: results (items) are returned IN THE SAME ORDER as commands were pushed in the stack
|
||||||
// so the items[X] match the operationIdentifiers[X]
|
// so the items[X] match the operationIdentifiers[X]
|
||||||
foreach ($response['items'] as $key => $item) {
|
foreach ($response['items'] as $key => $item) {
|
||||||
foreach($item as $command=>$result) { // command may be "index" or "delete"
|
foreach ($item as $command=>$result) { // command may be "index" or "delete"
|
||||||
if($response['errors'] && $result['status'] >= 400) { // 4xx or 5xx error
|
if ($response['errors'] && $result['status'] >= 400) { // 4xx or 5xx
|
||||||
throw new Exception(sprintf('%d: %s', $key, var_export($result, true)));
|
$err = array_key_exists('error', $result) ? var_export($result['error'], true) : ($command . " error " . $result['status']);
|
||||||
|
throw new Exception(sprintf('%d: %s', $key, $err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$operationIdentifier = $this->operationIdentifiers[$key];
|
$operationIdentifier = $this->operationIdentifiers[$key];
|
||||||
|
|
||||||
if(is_string($operationIdentifier) || is_int($operationIdentifier)) { // dont include null keys
|
if (is_string($operationIdentifier) || is_int($operationIdentifier)) { // dont include null keys
|
||||||
$callbackData[$operationIdentifier] = $response['items'][$key];
|
$callbackData[$operationIdentifier] = $response['items'][$key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -39,18 +39,13 @@ class MetadataHydrator implements HydratorInterface
|
|||||||
|
|
||||||
public function hydrateRecords(array &$records)
|
public function hydrateRecords(array &$records)
|
||||||
{
|
{
|
||||||
$sql = <<<SQL
|
$sql = "(SELECT record_id, ms.name AS `key`, m.value AS value, 'caption' AS type, ms.business AS private\n"
|
||||||
(SELECT record_id, ms.name AS `key`, m.value AS value, 'caption' AS type, ms.business AS private
|
. " FROM metadatas AS m INNER JOIN metadatas_structure AS ms ON (ms.id = m.meta_struct_id)\n"
|
||||||
FROM metadatas AS m
|
. " WHERE record_id IN (?))\n"
|
||||||
INNER JOIN metadatas_structure AS ms ON (ms.id = m.meta_struct_id)
|
. "UNION\n"
|
||||||
WHERE record_id IN (?))
|
. "(SELECT record_id, t.name AS `key`, t.value AS value, 'exif' AS type, 0 AS private\n"
|
||||||
|
. " FROM technical_datas AS t\n"
|
||||||
UNION
|
. " WHERE record_id IN (?))\n";
|
||||||
|
|
||||||
(SELECT record_id, t.name AS `key`, t.value AS value, 'exif' AS type, 0 AS private
|
|
||||||
FROM technical_datas AS t
|
|
||||||
WHERE record_id IN (?))
|
|
||||||
SQL;
|
|
||||||
|
|
||||||
$ids = array_keys($records);
|
$ids = array_keys($records);
|
||||||
$statement = $this->connection->executeQuery(
|
$statement = $this->connection->executeQuery(
|
||||||
@@ -62,7 +57,7 @@ SQL;
|
|||||||
while ($metadata = $statement->fetch()) {
|
while ($metadata = $statement->fetch()) {
|
||||||
// Store metadata value
|
// Store metadata value
|
||||||
$key = $metadata['key'];
|
$key = $metadata['key'];
|
||||||
$value = $metadata['value'];
|
$value = trim($metadata['value']);
|
||||||
|
|
||||||
// Do not keep empty values
|
// Do not keep empty values
|
||||||
if ($key === '' || $value === '') {
|
if ($key === '' || $value === '') {
|
||||||
@@ -80,7 +75,7 @@ SQL;
|
|||||||
case 'caption':
|
case 'caption':
|
||||||
// Sanitize fields
|
// Sanitize fields
|
||||||
$value = StringHelper::crlfNormalize($value);
|
$value = StringHelper::crlfNormalize($value);
|
||||||
$value = $this->sanitizeValue($value, $this->structure->typeOf($key));
|
$value = $this->helper->sanitizeValue($value, $this->structure->typeOf($key));
|
||||||
// Private caption fields are kept apart
|
// Private caption fields are kept apart
|
||||||
$type = $metadata['private'] ? 'private_caption' : 'caption';
|
$type = $metadata['private'] ? 'private_caption' : 'caption';
|
||||||
// Caption are multi-valued
|
// Caption are multi-valued
|
||||||
@@ -103,7 +98,7 @@ SQL;
|
|||||||
}
|
}
|
||||||
$tag = $this->structure->getMetadataTagByName($key);
|
$tag = $this->structure->getMetadataTagByName($key);
|
||||||
if ($tag) {
|
if ($tag) {
|
||||||
$value = $this->sanitizeValue($value, $tag->getType());
|
$value = $this->helper->sanitizeValue($value, $tag->getType());
|
||||||
}
|
}
|
||||||
// EXIF data is single-valued
|
// EXIF data is single-valued
|
||||||
$record['metadata_tags'][$key] = $value;
|
$record['metadata_tags'][$key] = $value;
|
||||||
@@ -118,33 +113,6 @@ SQL;
|
|||||||
$this->clearGpsPositionBuffer();
|
$this->clearGpsPositionBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function sanitizeValue($value, $type)
|
|
||||||
{
|
|
||||||
switch ($type) {
|
|
||||||
case FieldMapping::TYPE_STRING:
|
|
||||||
return str_replace("\0", "", $value);
|
|
||||||
|
|
||||||
case FieldMapping::TYPE_DATE:
|
|
||||||
return $this->helper->sanitizeDate($value);
|
|
||||||
|
|
||||||
case FieldMapping::TYPE_FLOAT:
|
|
||||||
case FieldMapping::TYPE_DOUBLE:
|
|
||||||
return (float) $value;
|
|
||||||
|
|
||||||
case FieldMapping::TYPE_INTEGER:
|
|
||||||
case FieldMapping::TYPE_LONG:
|
|
||||||
case FieldMapping::TYPE_SHORT:
|
|
||||||
case FieldMapping::TYPE_BYTE:
|
|
||||||
return (int) $value;
|
|
||||||
|
|
||||||
case FieldMapping::TYPE_BOOLEAN:
|
|
||||||
return (bool) $value;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function handleGpsPosition(&$records, $id, $tag_name, $value)
|
private function handleGpsPosition(&$records, $id, $tag_name, $value)
|
||||||
{
|
{
|
||||||
// Get position object
|
// Get position object
|
||||||
|
@@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
namespace Alchemy\Phrasea\SearchEngine\Elastic\Indexer\Record\Hydrator;
|
namespace Alchemy\Phrasea\SearchEngine\Elastic\Indexer\Record\Hydrator;
|
||||||
|
|
||||||
|
use Alchemy\Phrasea\SearchEngine\Elastic\FieldMapping;
|
||||||
|
use Alchemy\Phrasea\SearchEngine\Elastic\RecordHelper;
|
||||||
use Doctrine\DBAL\Connection;
|
use Doctrine\DBAL\Connection;
|
||||||
use Doctrine\DBAL\Driver\Connection as DriverConnection;
|
use Doctrine\DBAL\Driver\Connection as DriverConnection;
|
||||||
|
|
||||||
@@ -18,31 +20,34 @@ class TitleHydrator implements HydratorInterface
|
|||||||
{
|
{
|
||||||
private $connection;
|
private $connection;
|
||||||
|
|
||||||
public function __construct(DriverConnection $connection)
|
/** @var RecordHelper */
|
||||||
|
private $helper;
|
||||||
|
|
||||||
|
public function __construct(DriverConnection $connection, RecordHelper $helper)
|
||||||
{
|
{
|
||||||
$this->connection = $connection;
|
$this->connection = $connection;
|
||||||
|
$this->helper = $helper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function hydrateRecords(array &$records)
|
public function hydrateRecords(array &$records)
|
||||||
{
|
{
|
||||||
$sql = <<<SQL
|
$sql = "SELECT\n"
|
||||||
SELECT
|
. "m.`record_id`,\n"
|
||||||
m.`record_id`,
|
. " CASE ms.`thumbtitle`\n"
|
||||||
CASE ms.`thumbtitle`
|
. " WHEN '1' THEN 'default'\n"
|
||||||
WHEN "1" THEN "default"
|
. " WHEN '0' THEN 'default'\n"
|
||||||
WHEN "0" THEN "default"
|
. " ELSE ms.`thumbtitle`\n"
|
||||||
ELSE ms.`thumbtitle`
|
. " END AS locale,\n"
|
||||||
END AS locale,
|
. " CASE ms.`thumbtitle`\n"
|
||||||
CASE ms.`thumbtitle`
|
. " WHEN '0' THEN r.`originalname`\n"
|
||||||
WHEN "0" THEN r.`originalname`
|
. " ELSE GROUP_CONCAT(m.`value` ORDER BY ms.`thumbtitle`, ms.`sorter` SEPARATOR ' - ')\n"
|
||||||
ELSE GROUP_CONCAT(m.`value` ORDER BY ms.`thumbtitle`, ms.`sorter` SEPARATOR " - ")
|
. " END AS title\n"
|
||||||
END AS title
|
. "FROM metadatas AS m FORCE INDEX(`record_id`)\n"
|
||||||
FROM metadatas AS m FORCE INDEX(`record_id`)
|
. "STRAIGHT_JOIN metadatas_structure AS ms ON (ms.`id` = m.`meta_struct_id`)\n"
|
||||||
STRAIGHT_JOIN metadatas_structure AS ms ON (ms.`id` = m.`meta_struct_id`)
|
. "STRAIGHT_JOIN record AS r ON (r.`record_id` = m.`record_id`)\n"
|
||||||
STRAIGHT_JOIN record AS r ON (r.`record_id` = m.`record_id`)
|
. "WHERE m.`record_id` IN (?)\n"
|
||||||
WHERE m.`record_id` IN (?)
|
. "GROUP BY m.`record_id`, ms.`thumbtitle`\n";
|
||||||
GROUP BY m.`record_id`, ms.`thumbtitle`
|
|
||||||
SQL;
|
|
||||||
$statement = $this->connection->executeQuery(
|
$statement = $this->connection->executeQuery(
|
||||||
$sql,
|
$sql,
|
||||||
array(array_keys($records)),
|
array(array_keys($records)),
|
||||||
@@ -50,7 +55,7 @@ SQL;
|
|||||||
);
|
);
|
||||||
|
|
||||||
while ($row = $statement->fetch()) {
|
while ($row = $statement->fetch()) {
|
||||||
$records[$row['record_id']]['title'][$row['locale']] = $row['title'];
|
$records[$row['record_id']]['title'][$row['locale']] = $this->helper->sanitizeValue($row['title'], FieldMapping::TYPE_STRING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -57,6 +57,9 @@ class DateFieldMapping extends ComplexFieldMapping
|
|||||||
*/
|
*/
|
||||||
protected function getProperties()
|
protected function getProperties()
|
||||||
{
|
{
|
||||||
return array_merge([ 'format' => $this->format ], parent::getProperties());
|
return array_merge([
|
||||||
|
'format' => $this->format,
|
||||||
|
'ignore_malformed' => true
|
||||||
|
], parent::getProperties());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -89,31 +89,72 @@ class RecordHelper
|
|||||||
return $this->collectionMap;
|
return $this->collectionMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $date
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function validateDate($date)
|
|
||||||
{
|
|
||||||
$d = DateTime::createFromFormat(FieldMapping::DATE_FORMAT_CAPTION_PHP, $date);
|
|
||||||
|
|
||||||
return $d && $d->format(FieldMapping::DATE_FORMAT_CAPTION_PHP) == $date;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $value
|
* @param string $value
|
||||||
* @return null|string
|
* @return null|string
|
||||||
*/
|
*/
|
||||||
public static function sanitizeDate($value)
|
public static function sanitizeDate($value)
|
||||||
{
|
{
|
||||||
// introduced in https://github.com/alchemy-fr/Phraseanet/commit/775ce804e0257d3a06e4e068bd17330a79eb8370#diff-bee690ed259e0cf73a31dee5295d2edcR286
|
$v_fix = null;
|
||||||
// not sure if it's really needed
|
|
||||||
try {
|
try {
|
||||||
$date = new \DateTime($value);
|
$a = explode(';', preg_replace('/\D+/', ';', trim($value)));
|
||||||
|
switch (count($a)) {
|
||||||
return $date->format(FieldMapping::DATE_FORMAT_CAPTION_PHP);
|
case 1: // yyyy
|
||||||
|
$date = new \DateTime($a[0] . '-01-01'); // will throw if date is not valid
|
||||||
|
$v_fix = $date->format('Y');
|
||||||
|
break;
|
||||||
|
case 2: // yyyy;mm
|
||||||
|
$date = new \DateTime( $a[0] . '-' . $a[1] . '-01');
|
||||||
|
$v_fix = $date->format('Y-m');
|
||||||
|
break;
|
||||||
|
case 3: // yyyy;mm;dd
|
||||||
|
$date = new \DateTime($a[0] . '-' . $a[1] . '-' . $a[2]);
|
||||||
|
$v_fix = $date->format('Y-m-d');
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
$date = new \DateTime($a[0] . '-' . $a[1] . '-' . $a[2] . ' ' . $a[3] . ':00:00');
|
||||||
|
$v_fix = $date->format('Y-m-d H:i:s');
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
$date = new \DateTime($a[0] . '-' . $a[1] . '-' . $a[2] . ' ' . $a[3] . ':' . $a[4] . ':00');
|
||||||
|
$v_fix = $date->format('Y-m-d H:i:s');
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
$date = new \DateTime($a[0] . '-' . $a[1] . '-' . $a[2] . ' ' . $a[3] . ':' . $a[4] . ':' . $a[5]);
|
||||||
|
$v_fix = $date->format('Y-m-d H:i:s');
|
||||||
|
break;
|
||||||
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
return null;
|
// no-op, v_fix = null
|
||||||
|
}
|
||||||
|
|
||||||
|
return $v_fix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sanitizeValue($value, $type)
|
||||||
|
{
|
||||||
|
switch ($type) {
|
||||||
|
case FieldMapping::TYPE_DATE:
|
||||||
|
return self::sanitizeDate($value);
|
||||||
|
|
||||||
|
case FieldMapping::TYPE_FLOAT:
|
||||||
|
case FieldMapping::TYPE_DOUBLE:
|
||||||
|
return (float) $value;
|
||||||
|
|
||||||
|
case FieldMapping::TYPE_INTEGER:
|
||||||
|
case FieldMapping::TYPE_LONG:
|
||||||
|
case FieldMapping::TYPE_SHORT:
|
||||||
|
case FieldMapping::TYPE_BYTE:
|
||||||
|
return (int) $value;
|
||||||
|
|
||||||
|
case FieldMapping::TYPE_BOOLEAN:
|
||||||
|
return (bool) $value;
|
||||||
|
|
||||||
|
case FieldMapping::TYPE_STRING:
|
||||||
|
return str_replace("\0", '', $value);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -110,41 +110,50 @@ class QueryHelper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getRangeFromDateString($string)
|
public static function getRangeFromDateString($value)
|
||||||
{
|
{
|
||||||
$formats = ['Y/m/d', 'Y/m', 'Y'];
|
$date_from = null;
|
||||||
$deltas = ['+1 day', '+1 month', '+1 year'];
|
$date_to = null;
|
||||||
$to = null;
|
try {
|
||||||
while ($format = array_pop($formats)) {
|
$a = explode(';', preg_replace('/\D+/', ';', trim($value)));
|
||||||
$delta = array_pop($deltas);
|
switch (count($a)) {
|
||||||
$from = date_create_from_format($format, $string);
|
case 1: // yyyy
|
||||||
if ($from !== false) {
|
$date_to = clone($date_from = new \DateTime($a[0] . '-01-01 00:00:00')); // will throw if date is not valid
|
||||||
// Rewind to start of range
|
$date_to->add(new \DateInterval('P1Y'));
|
||||||
$month = 1;
|
break;
|
||||||
$day = 1;
|
case 2: // yyyy;mm
|
||||||
switch ($format) {
|
$date_to = clone($date_from = new \DateTime($a[0] . '-' . $a[1] . '-01 00:00:00')); // will throw if date is not valid
|
||||||
case 'Y/m/d':
|
$date_to->add(new \DateInterval('P1M'));
|
||||||
$day = (int) $from->format('d');
|
break;
|
||||||
case 'Y/m':
|
case 3: // yyyy;mm;dd
|
||||||
$month = (int) $from->format('m');
|
$date_to = clone($date_from = new \DateTime($a[0] . '-' . $a[1] . '-' . $a[2] . ' 00:00:00')); // will throw if date is not valid
|
||||||
case 'Y':
|
$date_to->add(new \DateInterval('P1D'));
|
||||||
$year = (int) $from->format('Y');
|
break;
|
||||||
}
|
case 4:
|
||||||
date_date_set($from, $year, $month, $day);
|
$date_to = clone($date_from = new \DateTime($a[0] . '-' . $a[1] . '-' . $a[2] . ' ' . $a[3] . ':00:00'));
|
||||||
date_time_set($from, 0, 0, 0);
|
$date_to->add(new \DateInterval('PT1H'));
|
||||||
// Create end of the the range
|
break;
|
||||||
$to = date_modify(clone $from, $delta);
|
case 5:
|
||||||
break;
|
$date_to = clone($date_from = new \DateTime($a[0] . '-' . $a[1] . '-' . $a[2] . ' ' . $a[3] . ':' . $a[4] . ':00'));
|
||||||
|
$date_to->add(new \DateInterval('PT1M'));
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
$date_to = clone($date_from = new \DateTime($a[0] . '-' . $a[1] . '-' . $a[2] . ' ' . $a[3] . ':' . $a[4] . ':' . $a[5]));
|
||||||
|
// $date_to->add(new \DateInterval('PT1S')); // no need since precision is 1 sec, a "equal" will be generated when from==to
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (\Exception $e) {
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
|
|
||||||
if (!$from || !$to) {
|
if ($date_from === null || $date_to === null) {
|
||||||
throw new \InvalidArgumentException(sprintf('Invalid date "%s".', $string));
|
throw new \InvalidArgumentException(sprintf('Invalid date "%s".', $value));
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'from' => $from->format(FieldMapping::DATE_FORMAT_CAPTION_PHP),
|
'from' => $date_from->format('Y-m-d H:i:s'),
|
||||||
'to' => $to->format(FieldMapping::DATE_FORMAT_CAPTION_PHP)
|
'to' => $date_to->format('Y-m-d H:i:s')
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,7 +5,7 @@ namespace Alchemy\Phrasea\SearchEngine\Elastic\Search;
|
|||||||
use Alchemy\Phrasea\SearchEngine\Elastic\AST;
|
use Alchemy\Phrasea\SearchEngine\Elastic\AST;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Exception\Exception;
|
use Alchemy\Phrasea\SearchEngine\Elastic\Exception\Exception;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\FieldMapping;
|
use Alchemy\Phrasea\SearchEngine\Elastic\FieldMapping;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Mapping;
|
use Alchemy\Phrasea\SearchEngine\Elastic\RecordHelper;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\Structure;
|
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\Structure;
|
||||||
use Hoa\Compiler\Llk\TreeNode;
|
use Hoa\Compiler\Llk\TreeNode;
|
||||||
use Hoa\Visitor\Element;
|
use Hoa\Visitor\Element;
|
||||||
@@ -166,6 +166,12 @@ class QueryVisitor implements Visit
|
|||||||
$key = $node->getChild(0)->accept($this);
|
$key = $node->getChild(0)->accept($this);
|
||||||
$boundary = $node->getChild(1)->accept($this);
|
$boundary = $node->getChild(1)->accept($this);
|
||||||
|
|
||||||
|
if ($this->isDateKey($key)) {
|
||||||
|
if(($v = RecordHelper::sanitizeDate($boundary)) !== null) {
|
||||||
|
$boundary = $v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch ($node->getId()) {
|
switch ($node->getId()) {
|
||||||
case NodeTypes::LT_EXPR:
|
case NodeTypes::LT_EXPR:
|
||||||
return AST\KeyValue\RangeExpression::lessThan($key, $boundary);
|
return AST\KeyValue\RangeExpression::lessThan($key, $boundary);
|
||||||
@@ -195,11 +201,15 @@ class QueryVisitor implements Visit
|
|||||||
try {
|
try {
|
||||||
// Try to create a range for incomplete dates
|
// Try to create a range for incomplete dates
|
||||||
$range = QueryHelper::getRangeFromDateString($right);
|
$range = QueryHelper::getRangeFromDateString($right);
|
||||||
return new AST\KeyValue\RangeExpression(
|
if ($range['from'] === $range['to']) {
|
||||||
$left,
|
return new AST\KeyValue\EqualExpression($left, $range['from']);
|
||||||
$range['from'], true,
|
} else {
|
||||||
$range['to'], false
|
return new AST\KeyValue\RangeExpression(
|
||||||
);
|
$left,
|
||||||
|
$range['from'], true,
|
||||||
|
$range['to'], false
|
||||||
|
);
|
||||||
|
}
|
||||||
} catch (\InvalidArgumentException $e) {
|
} catch (\InvalidArgumentException $e) {
|
||||||
// Fall back to equal expression
|
// Fall back to equal expression
|
||||||
}
|
}
|
||||||
|
@@ -3,7 +3,6 @@
|
|||||||
namespace Alchemy\Phrasea\SearchEngine\Elastic\Structure;
|
namespace Alchemy\Phrasea\SearchEngine\Elastic\Structure;
|
||||||
|
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\FieldMapping;
|
use Alchemy\Phrasea\SearchEngine\Elastic\FieldMapping;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Mapping;
|
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\RecordHelper;
|
use Alchemy\Phrasea\SearchEngine\Elastic\RecordHelper;
|
||||||
use Assert\Assertion;
|
use Assert\Assertion;
|
||||||
|
|
||||||
@@ -20,7 +19,7 @@ class ValueChecker
|
|||||||
{
|
{
|
||||||
Assertion::allIsInstanceOf($list, Typed::class);
|
Assertion::allIsInstanceOf($list, Typed::class);
|
||||||
$is_numeric = is_numeric($value);
|
$is_numeric = is_numeric($value);
|
||||||
$is_valid_date = RecordHelper::validateDate($value);
|
$is_valid_date = (RecordHelper::sanitizeDate($value) !== null);
|
||||||
$filtered = [];
|
$filtered = [];
|
||||||
foreach ($list as $item) {
|
foreach ($list as $item) {
|
||||||
switch ($item->getType()) {
|
switch ($item->getType()) {
|
||||||
|
@@ -127,7 +127,10 @@ class WriteMetadataJob extends AbstractJob
|
|||||||
|
|
||||||
// check exiftool known tags to skip Phraseanet:tf-*
|
// check exiftool known tags to skip Phraseanet:tf-*
|
||||||
try {
|
try {
|
||||||
TagFactory::getFromRDFTagname($tagName);
|
$tag = TagFactory::getFromRDFTagname($tagName);
|
||||||
|
if(!$tag->isWritable()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
} catch (TagUnknown $e) {
|
} catch (TagUnknown $e) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -147,21 +150,34 @@ class WriteMetadataJob extends AbstractJob
|
|||||||
$fieldValue = array_pop($fieldValues);
|
$fieldValue = array_pop($fieldValues);
|
||||||
$value = $this->removeNulChar($fieldValue->getValue());
|
$value = $this->removeNulChar($fieldValue->getValue());
|
||||||
|
|
||||||
$value = new Value\Mono($value);
|
// fix the dates edited into phraseanet
|
||||||
|
if($fieldStructure->get_type() === $fieldStructure::TYPE_DATE) {
|
||||||
|
try {
|
||||||
|
$value = self::fixDate($value); // will return NULL if the date is not valid
|
||||||
|
}
|
||||||
|
catch (\Exception $e) {
|
||||||
|
$value = null; // do NOT write back to iptc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($value !== null) { // do not write invalid dates
|
||||||
|
$value = new Value\Mono($value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch(\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
// the field is not set in the record, erase it
|
// the field is not set in the record, erase it
|
||||||
if ($fieldStructure->is_multi()) {
|
if ($fieldStructure->is_multi()) {
|
||||||
$value = new Value\Multi(array(''));
|
$value = new Value\Multi(array(''));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
$value = new Value\Mono('');
|
$value = new Value\Mono('');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$metadata->add(
|
if($value !== null) { // do not write invalid data
|
||||||
new Metadata\Metadata($fieldStructure->get_tag(), $value)
|
$metadata->add(
|
||||||
);
|
new Metadata\Metadata($fieldStructure->get_tag(), $value)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$writer = $this->getMetadataWriter($jobData->getApplication());
|
$writer = $this->getMetadataWriter($jobData->getApplication());
|
||||||
@@ -220,4 +236,34 @@ class WriteMetadataJob extends AbstractJob
|
|||||||
{
|
{
|
||||||
return str_replace("\0", "", $value);
|
return str_replace("\0", "", $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* re-format a phraseanet date for iptc writing
|
||||||
|
* return NULL if the date is not valid
|
||||||
|
*
|
||||||
|
* @param string $value
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
private static function fixDate($value)
|
||||||
|
{
|
||||||
|
$date = null;
|
||||||
|
try {
|
||||||
|
$a = explode(';', preg_replace('/\D+/', ';', trim($value)));
|
||||||
|
switch (count($a)) {
|
||||||
|
case 3: // yyyy;mm;dd
|
||||||
|
$date = new \DateTime($a[0] . '-' . $a[1] . '-' . $a[2]);
|
||||||
|
$date = $date->format('Y-m-d H:i:s');
|
||||||
|
break;
|
||||||
|
case 6: // yyyy;mm;dd;hh;mm;ss
|
||||||
|
$date = new \DateTime($a[0] . '-' . $a[1] . '-' . $a[2] . ' ' . $a[3] . ':' . $a[4] . ':' . $a[5]);
|
||||||
|
$date = $date->format('Y-m-d H:i:s');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (\Exception $e) {
|
||||||
|
$date = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $date;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
4
lib/classes/cache/databox.php
vendored
4
lib/classes/cache/databox.php
vendored
@@ -121,9 +121,9 @@ class cache_databox
|
|||||||
|
|
||||||
$conn = $app->getApplicationBox()->get_connection();
|
$conn = $app->getApplicationBox()->get_connection();
|
||||||
|
|
||||||
$sql = 'UPDATE sitepreff SET memcached_update = :date';
|
$sql = 'UPDATE sitepreff SET memcached_update = current_timestamp()';
|
||||||
$stmt = $conn->prepare($sql);
|
$stmt = $conn->prepare($sql);
|
||||||
$stmt->execute([':date' => $now]);
|
$stmt->execute();
|
||||||
$stmt->closeCursor();
|
$stmt->closeCursor();
|
||||||
|
|
||||||
self::$refreshing = false;
|
self::$refreshing = false;
|
||||||
|
@@ -1278,6 +1278,27 @@
|
|||||||
<field>id</field>
|
<field>id</field>
|
||||||
</fields>
|
</fields>
|
||||||
</index>
|
</index>
|
||||||
|
<index>
|
||||||
|
<name>usr_id</name>
|
||||||
|
<type>INDEX</type>
|
||||||
|
<fields>
|
||||||
|
<field>usr_id</field>
|
||||||
|
</fields>
|
||||||
|
</index>
|
||||||
|
<index>
|
||||||
|
<name>unread</name>
|
||||||
|
<type>INDEX</type>
|
||||||
|
<fields>
|
||||||
|
<field>unread</field>
|
||||||
|
</fields>
|
||||||
|
</index>
|
||||||
|
<index>
|
||||||
|
<name>created_on</name>
|
||||||
|
<type>INDEX</type>
|
||||||
|
<fields>
|
||||||
|
<field>created_on</field>
|
||||||
|
</fields>
|
||||||
|
</index>
|
||||||
</indexes>
|
</indexes>
|
||||||
<engine>InnoDB</engine>
|
<engine>InnoDB</engine>
|
||||||
</table>
|
</table>
|
||||||
|
@@ -65,7 +65,7 @@
|
|||||||
"normalize-css": "^2.1.0",
|
"normalize-css": "^2.1.0",
|
||||||
"npm": "^6.0.0",
|
"npm": "^6.0.0",
|
||||||
"npm-modernizr": "^2.8.3",
|
"npm-modernizr": "^2.8.3",
|
||||||
"phraseanet-production-client": "^0.34.53-d",
|
"phraseanet-production-client": "0.34.72-d",
|
||||||
"requirejs": "^2.3.5",
|
"requirejs": "^2.3.5",
|
||||||
"tinymce": "^4.0.28",
|
"tinymce": "^4.0.28",
|
||||||
"underscore": "^1.8.3",
|
"underscore": "^1.8.3",
|
||||||
|
21
resources/ansible/playbook-boxes.yml
Normal file
21
resources/ansible/playbook-boxes.yml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
- hosts: all
|
||||||
|
sudo: true
|
||||||
|
vars_files:
|
||||||
|
- vars/all.yml
|
||||||
|
roles:
|
||||||
|
# - server
|
||||||
|
# - repositories
|
||||||
|
# - vagrant_local
|
||||||
|
- nginx
|
||||||
|
# - mariadb
|
||||||
|
# - elasticsearch
|
||||||
|
# - rabbitmq
|
||||||
|
# - php
|
||||||
|
- xdebug
|
||||||
|
# - composer
|
||||||
|
- mailcatcher
|
||||||
|
# - node
|
||||||
|
# - yarn
|
||||||
|
# - ffmpeg
|
||||||
|
- app
|
@@ -4,18 +4,18 @@
|
|||||||
vars_files:
|
vars_files:
|
||||||
- vars/all.yml
|
- vars/all.yml
|
||||||
roles:
|
roles:
|
||||||
# - server
|
- server
|
||||||
# - repositories
|
- repositories
|
||||||
# - vagrant_local
|
- vagrant_local
|
||||||
- nginx
|
- nginx
|
||||||
# - mariadb
|
- mariadb
|
||||||
# - elasticsearch
|
- elasticsearch
|
||||||
# - rabbitmq
|
- rabbitmq
|
||||||
# - php
|
- php
|
||||||
- xdebug
|
- xdebug
|
||||||
# - composer
|
- composer
|
||||||
# - mailcatcher
|
- mailcatcher
|
||||||
# - node
|
- node
|
||||||
# - yarn
|
- yarn
|
||||||
# - ffmpeg
|
- ffmpeg
|
||||||
- app
|
- app
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
- name: Install mailcatcher gem
|
- name: Install mailcatcher gem
|
||||||
# gem module is flaky, this is consistent
|
# gem module is flaky, this is consistent
|
||||||
command: gem install mailcatcher --conservative
|
command: gem install mailcatcher -v 0.6.4 --conservative
|
||||||
ignore_errors: yes
|
ignore_errors: yes
|
||||||
|
|
||||||
- name: Install mailcatcher supervisord conf
|
- name: Install mailcatcher supervisord conf
|
||||||
|
@@ -31,17 +31,13 @@ var commonModule = (function ($, p4) {
|
|||||||
$(this).removeClass('context-menu-item-hover');
|
$(this).removeClass('context-menu-item-hover');
|
||||||
});
|
});
|
||||||
|
|
||||||
// $('#help-trigger').contextMenu('#mainMenu .helpcontextmenu', {openEvt: 'click', dropDown: true, theme: 'vista', dropDown: true,
|
|
||||||
// showTransition: 'slideDown',
|
|
||||||
// hideTransition: 'hide',
|
|
||||||
// shadow: false
|
|
||||||
// });
|
|
||||||
|
|
||||||
$('body').on('click', '.infoDialog', function (event) {
|
$('body').on('click', '.infoDialog', function (event) {
|
||||||
infoDialog($(this));
|
infoDialog($(this));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
function showOverlay(n, appendto, callback, zIndex) {
|
function showOverlay(n, appendto, callback, zIndex) {
|
||||||
|
|
||||||
var div = "OVERLAY";
|
var div = "OVERLAY";
|
||||||
|
@@ -88,4 +88,20 @@ $mainMenuLinkBackgroundHoverColor: transparent;
|
|||||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.39);
|
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.39);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*Help menu*/
|
||||||
|
.contextMenu.helpcontextmenu {
|
||||||
|
display: none;
|
||||||
|
&.shown {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 101;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.help-trigger {
|
||||||
|
display:inline-block;
|
||||||
|
cursor:pointer;
|
||||||
|
padding: 0 4px;
|
||||||
|
border:none;
|
||||||
|
margin-left: -12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 682 B After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
Before Width: | Height: | Size: 802 B After Width: | Height: | Size: 1.7 KiB |
@@ -356,3 +356,7 @@ $select-height: 26px;
|
|||||||
background-color: #212121;
|
background-color: #212121;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#mainMenu li .context-menu-item-inner a:hover {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
@@ -512,7 +512,7 @@
|
|||||||
{{ 'admin::compte-utilisateur poste' | trans }}
|
{{ 'admin::compte-utilisateur poste' | trans }}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="text" name="function" value="{{main_user.getActivity()}}"/>
|
<input type="text" name="function" value="{{main_user.getJob()}}"/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -528,7 +528,7 @@
|
|||||||
{{ 'admin::compte-utilisateur activite' | trans }}
|
{{ 'admin::compte-utilisateur activite' | trans }}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="text" name="activite" value="{{main_user.getJob()}}"/>
|
<input type="text" name="activite" value="{{main_user.getActivity()}}"/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
@@ -32,7 +32,7 @@
|
|||||||
<script type="text/javascript" src="/assets/vendors/jquery-ui/jquery-ui.js"></script>
|
<script type="text/javascript" src="/assets/vendors/jquery-ui/jquery-ui.js"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
<body class="PNB {{ cssfile }}">
|
<body class="PNB">
|
||||||
<div id="mainContainer" class="PNB">
|
<div id="mainContainer" class="PNB">
|
||||||
{% include 'common/menubar.html.twig' %}
|
{% include 'common/menubar.html.twig' %}
|
||||||
<div class="PNB" id="mainContent" style="overflow: auto">
|
<div class="PNB" id="mainContent" style="overflow: auto">
|
||||||
|
@@ -25,103 +25,103 @@
|
|||||||
<div id="nav_menu_container" class="desktopmenu">
|
<div id="nav_menu_container" class="desktopmenu">
|
||||||
<div class="arrow-up"></div>
|
<div class="arrow-up"></div>
|
||||||
<ol class="nav_menu">
|
<ol class="nav_menu">
|
||||||
<li class="menu-bar-item">
|
<li class="menu-bar-item">
|
||||||
<a target="_blank" href="{{ path('prod') }}">
|
<a target="_blank" href="{{ path('prod') }}">
|
||||||
<img src="/assets/common/images/icons/menu-prod.png" class="mobilemenu"/>
|
<img src="/assets/common/images/icons/menu-prod.png" class="mobilemenu"/>
|
||||||
<span class="{% if module is defined and module == "prod" %}selected{% endif %}">
|
<span class="{% if module is defined and module == "prod" %}selected{% endif %}">
|
||||||
{{ 'admin::monitor: production' | trans }}
|
{{ 'admin::monitor: production' | trans }}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
{% if app['browser'].isNewGeneration and app['conf'].get(['registry', 'modules', 'thesaurus']) == true and app.getAclForUser(app.getAuthenticatedUser()).has_access_to_module('thesaurus') %}
|
{% if app['browser'].isNewGeneration and app['conf'].get(['registry', 'modules', 'thesaurus']) == true and app.getAclForUser(app.getAuthenticatedUser()).has_access_to_module('thesaurus') %}
|
||||||
<li class="menu-bar-item">
|
<li class="menu-bar-item">
|
||||||
<a target="_blank" href="{{ path('thesaurus') }}">
|
<a target="_blank" href="{{ path('thesaurus') }}">
|
||||||
<img src="/assets/common/images/icons/menu-thesaurus.png" class="mobilemenu"/>
|
<img src="/assets/common/images/icons/menu-thesaurus.png" class="mobilemenu"/>
|
||||||
<span class="{% if module is defined and module == "thesaurus" %}selected{% endif %}">
|
<span class="{% if module is defined and module == "thesaurus" %}selected{% endif %}">
|
||||||
{{ 'admin::monitor: module thesaurus' | trans }}
|
{{ 'admin::monitor: module thesaurus' | trans }}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
|
|
||||||
{# MODULE #}
|
|
||||||
{% if app.getAclForUser(app.getAuthenticatedUser()).has_access_to_module('admin') %}
|
|
||||||
<li class="menu-bar-item">
|
|
||||||
<a target="_blank" href="{{ path('admin') }}">
|
|
||||||
<img src="/assets/common/images/icons/menu-admin.png" class="mobilemenu"/>
|
|
||||||
<span class="{% if module is defined and module == "admin" %}selected{% endif %}">
|
|
||||||
{{ 'admin::monitor: module admin' | trans }}
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{# MODULE #}
|
|
||||||
{% if app.getAclForUser(app.getAuthenticatedUser()).has_access_to_module('report') %}
|
|
||||||
<li class="menu-bar-item">
|
|
||||||
<a target="_blank" href="{{ path('report_dashboard') }}">
|
|
||||||
<img src="/assets/common/images/icons/menu-report.png" class="mobilemenu"/>
|
|
||||||
<span class="{% if module is defined and module == "report" %}selected{% endif %}">
|
|
||||||
{{ 'admin::monitor: module report' | trans }}
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{# MODULE #}
|
|
||||||
<li class="menu-bar-item">
|
|
||||||
<a id="validation_link" target="_blank" href="{{ path('lightbox') }}">
|
|
||||||
<img src="/assets/common/images/icons/menu-lightbox.png" class="mobilemenu"/>
|
|
||||||
<span>
|
|
||||||
{{ 'admin::monitor: module validation' | trans }}
|
|
||||||
</span>
|
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{# MODULE #}
|
|
||||||
{% if module is defined and module == "prod" %}
|
|
||||||
{% if app.getAclForUser(app.getAuthenticatedUser()).has_access_to_module('upload') %}
|
|
||||||
<li class="menu-bar-item">
|
|
||||||
{% set link = path('upload_html5_form') %}
|
|
||||||
|
|
||||||
{% if not app['browser'].supportFileAPI() %}
|
{# MODULE #}
|
||||||
{% set link = path('upload_flash_form') %}
|
{% if app.getAclForUser(app.getAuthenticatedUser()).has_access_to_module('admin') %}
|
||||||
{% endif %}
|
<li class="menu-bar-item">
|
||||||
|
<a target="_blank" href="{{ path('admin') }}">
|
||||||
|
<img src="/assets/common/images/icons/menu-admin.png" class="mobilemenu"/>
|
||||||
|
<span class="{% if module is defined and module == "admin" %}selected{% endif %}">
|
||||||
|
{{ 'admin::monitor: module admin' | trans }}
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<a href="{{ link }}" class="uploader-open-action"
|
{# MODULE #}
|
||||||
title="{{ 'Upload' | trans }}">
|
{% if app.getAclForUser(app.getAuthenticatedUser()).has_access_to_module('report') %}
|
||||||
<img src="/assets/common/images/icons/menu-upload.png" class="mobilemenu"/>
|
<li class="menu-bar-item">
|
||||||
<span>
|
<a target="_blank" href="{{ path('report_dashboard') }}">
|
||||||
|
<img src="/assets/common/images/icons/menu-report.png" class="mobilemenu"/>
|
||||||
|
<span class="{% if module is defined and module == "report" %}selected{% endif %}">
|
||||||
|
{{ 'admin::monitor: module report' | trans }}
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{# MODULE #}
|
||||||
|
<li class="menu-bar-item">
|
||||||
|
<a id="validation_link" target="_blank" href="{{ path('lightbox') }}">
|
||||||
|
<img src="/assets/common/images/icons/menu-lightbox.png" class="mobilemenu"/>
|
||||||
|
<span>
|
||||||
|
{{ 'admin::monitor: module validation' | trans }}
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{# MODULE #}
|
||||||
|
{% if module is defined and module == "prod" %}
|
||||||
|
{% if app.getAclForUser(app.getAuthenticatedUser()).has_access_to_module('upload') %}
|
||||||
|
<li class="menu-bar-item">
|
||||||
|
{% set link = path('upload_html5_form') %}
|
||||||
|
|
||||||
|
{% if not app['browser'].supportFileAPI() %}
|
||||||
|
{% set link = path('upload_flash_form') %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<a href="{{ link }}" class="uploader-open-action"
|
||||||
|
title="{{ 'Upload' | trans }}">
|
||||||
|
<img src="/assets/common/images/icons/menu-upload.png" class="mobilemenu"/>
|
||||||
|
<span>
|
||||||
{{ 'admin::monitor: module upload' | trans }}
|
{{ 'admin::monitor: module upload' | trans }}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{# MODULE #}
|
|
||||||
{% if module == "prod" %}
|
|
||||||
<li class="menu-bar-item">
|
|
||||||
<a href="#" class="state-navigation" data-state="publication">
|
|
||||||
<img src="/assets/common/images/icons/menu-publication.png" class="mobilemenu"/>
|
|
||||||
<span>
|
|
||||||
{{ 'Publications' | trans }}
|
|
||||||
</span>
|
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if module is defined and module == "prod" and app.getAclForUser(app.getAuthenticatedUser()).has_right(constant('\\ACL::ORDER_MASTER')) %}
|
{# MODULE #}
|
||||||
<li class="menu-bar-item">
|
{% if module == "prod" %}
|
||||||
<a href="#" class="order-open-action" title="{{ 'Orders manager' | trans }}">
|
<li class="menu-bar-item">
|
||||||
|
<a href="#" class="state-navigation" data-state="publication">
|
||||||
|
<img src="/assets/common/images/icons/menu-publication.png" class="mobilemenu"/>
|
||||||
|
<span>
|
||||||
|
{{ 'Publications' | trans }}
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if module is defined and module == "prod" and app.getAclForUser(app.getAuthenticatedUser()).has_right(constant('\\ACL::ORDER_MASTER')) %}
|
||||||
|
<li class="menu-bar-item">
|
||||||
|
<a href="#" class="order-open-action" title="{{ 'Orders manager' | trans }}">
|
||||||
<span>
|
<span>
|
||||||
{{ 'Commandes' | trans }}
|
{{ 'Commandes' | trans }}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
@@ -235,11 +235,10 @@
|
|||||||
<a target="_blank" href="https://docs.phraseanet.com/4.0/">
|
<a target="_blank" href="https://docs.phraseanet.com/4.0/">
|
||||||
<span>
|
<span>
|
||||||
{{ 'phraseanet:: aide' | trans }}
|
{{ 'phraseanet:: aide' | trans }}
|
||||||
<span style="display:inline-block;cursor:pointer;padding:0;border:none;padding-right:4px;padding-left:4px;"
|
|
||||||
id="help-trigger"> <i class="fa fa-caret-down" aria-hidden="true"></i></span>
|
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
<table cellspacing="0" cellpadding="0" style="display:none;" class="contextMenu helpcontextmenu">
|
<span id="help-trigger" class="help-trigger"> <i class="fa fa-caret-down" aria-hidden="true"></i></span>
|
||||||
|
<table cellspacing="0" cellpadding="0" class="contextMenu helpcontextmenu context-menu-theme-vistamenu-bar">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
@@ -301,6 +300,10 @@
|
|||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
|
$('body').on('click', '#help-trigger', function (event) {
|
||||||
|
$('#mainMenu .helpcontextmenu').toggleClass('shown');
|
||||||
|
console.log('mety');
|
||||||
|
});
|
||||||
// var key = 'help';
|
// var key = 'help';
|
||||||
var configurationSettingLinks = {{ configuration|json_encode|raw }};
|
var configurationSettingLinks = {{ configuration|json_encode|raw }};
|
||||||
//seperate array based on location of link
|
//seperate array based on location of link
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
{% set previewHtml5 = null %}
|
{% set previewHtml5 = null %}
|
||||||
|
|
||||||
{% if app.getAclForUser(app.getAuthenticatedUser()).has_access_to_subdef(record, 'preview') %}
|
{% if app.getAclForUser(app.getAuthenticatedUser()).has_access_to_subdef(record, 'preview') and record.has_preview == true %}
|
||||||
{% set preview_obj = record.get_preview() %}
|
{% set preview_obj = record.get_preview() %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% set preview_obj = record.get_thumbnail() %}
|
{% set preview_obj = record.get_thumbnail() %}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
<div class="PNB" id="BasketBrowser">
|
<div class="PNB BasketBrowser" id="BasketBrowser">
|
||||||
<div class="PNB10 Browser">
|
<div class="PNB10 Browser">
|
||||||
<div class="PNB10" style="width:190px;right:auto;">
|
<div class="PNB10 leftBrowser">
|
||||||
<form name="BasketBrowser" method="GET" action="{{ path('prod_workzone_search') }}">
|
<form name="BasketBrowser" method="GET" action="{{ path('prod_workzone_search') }}">
|
||||||
<input name="Query" class="Query search" placeholder="{{ 'Search baskets' | trans }}" type="text"/>
|
<input name="Query" class="Query search" placeholder="{{ 'Search baskets' | trans }}" type="text"/>
|
||||||
|
|
||||||
@@ -78,9 +78,46 @@
|
|||||||
</form>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="PNB results" style="left:220px;">
|
<div class="PNB results rightBrowser">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="PNB10 Basket">
|
<div class="PNB10 Basket">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<style>
|
||||||
|
.dialog-Medium {
|
||||||
|
height: 523px!important;
|
||||||
|
}
|
||||||
|
.paginator a {
|
||||||
|
background: none!important;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
padding: 0 9px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.result_loader {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
//load the next result page
|
||||||
|
jQuery(document).ready(function(){
|
||||||
|
jQuery('.next_res').click(function(){
|
||||||
|
jQuery('.results').append('<img class="result_loader" src="/assets/common/images/icons/loading.svg">');
|
||||||
|
jQuery('.results').load($(this).attr('href'));
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
//load the prev result page
|
||||||
|
jQuery(document).ready(function(){
|
||||||
|
jQuery('.prev_res').click(function(){
|
||||||
|
jQuery('.results').append('<img class="result_loader" src="/assets/common/images/icons/loading.svg">');
|
||||||
|
jQuery('.results').load($(this).attr('href'));
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
@@ -4,28 +4,9 @@
|
|||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
{% if Total == 0 %}
|
{% transchoice Total %}
|
||||||
{{ 'No results' | trans }}
|
{0} No results|{1} Result|]1,Inf[ Results
|
||||||
{% elseif Total == 1 %}
|
{% endtranschoice %}
|
||||||
{{ '1 result' | trans }}
|
|
||||||
{% else %}
|
|
||||||
{% trans with {'%Total%' : Total} %}%Total% results{% endtrans %}
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
<td class="paginator">
|
|
||||||
{% if Page - 1 > 0 %}
|
|
||||||
<a href="{{ path('prod_workzone_search', { 'Query' : Query, 'Year' : Year, 'Type' : Type, 'Page' : (Page - 1) }) }}" class="result">
|
|
||||||
<img src="/assets/prod/images/Basket/Browser/left.png" />
|
|
||||||
</a>
|
|
||||||
{% endif %}
|
|
||||||
<span>
|
|
||||||
Page {{ Page }} / {{ MaxPage }}
|
|
||||||
</span>
|
|
||||||
{% if Page + 1 <= MaxPage %}
|
|
||||||
<a href="{{ path('prod_workzone_search', { 'Query' : Query, 'Year' : Year, 'Type' : Type, 'Page' : (Page + 1) }) }}" class="result">
|
|
||||||
<img src="/assets/prod/images/Basket/Browser/right.png" />
|
|
||||||
</a>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@@ -33,43 +14,39 @@
|
|||||||
<div class="PNB datas">
|
<div class="PNB datas">
|
||||||
<div class="PNB" style="right:10px">
|
<div class="PNB" style="right:10px">
|
||||||
{% for Basket in Baskets %}
|
{% for Basket in Baskets %}
|
||||||
<div class="result {% if loop.index is odd %}odd{% endif %}">
|
<div class="result {{ Basket.getArchived ? '' : 'unarchived' }}">
|
||||||
<a href="{{ path('basket_delete', {basket: Basket.getId()}) }}" class="delete-basket close" title="{% trans %}Delete basket{% endtrans %}" style="color:#fff;padding:2px">×</a>
|
<a href="{{ path('basket_delete', {basket: Basket.getId()}) }}" class="delete-basket close icon-baseline-close-24px" title="{% trans %}Delete basket{% endtrans %}" style="color:#fff;padding:2px"> </a>
|
||||||
<div class="PNB10" style="right:15px;">
|
<div class="PNB10 rightBrowserInner">
|
||||||
<table>
|
<div class="item-table">
|
||||||
<tr>
|
|
||||||
<td class="thumbnail">
|
<div class="thumbnail">
|
||||||
{% set BasketElement = Basket.getElements().first() %}
|
{% set BasketElement = Basket.getElements().first() %}
|
||||||
{% if BasketElement %}
|
{% if BasketElement %}
|
||||||
{{thumbnail.format(BasketElement.getRecord(app).get_thumbnail(), 80, 80, '', true, false)}}
|
{{thumbnail.format(BasketElement.getRecord(app).get_thumbnail(), 150, 106, '', true, false)}}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="counter">
|
</div>
|
||||||
{{ Basket.getElements().count() }}
|
<div class="content">
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td class="content">
|
|
||||||
<h1 class="title">
|
<h1 class="title">
|
||||||
<img class="loader" src="/assets/prod/images/Basket/Browser/loader.gif" />
|
<img class="loader" src="/assets/prod/images/Basket/Browser/loader.gif" />
|
||||||
{% if Basket.getValidation() is empty or Basket.getValidation().isInitiator(app.getAuthenticatedUser()) %}
|
{% if Basket.getValidation() is empty or Basket.getValidation().isInitiator(app.getAuthenticatedUser()) %}
|
||||||
<a href="{{ path('prod_baskets_basket_archive', { 'basket' : Basket.getId(), 'archive' : 1 }) }}" class="archiver archive_toggler" style="display:{{ Basket.getArchived ? 'none' : '' }};">
|
<a href="{{ path('prod_baskets_basket_archive', { 'basket' : Basket.getId(), 'archive' : 1 }) }}" class="archiver archive_toggler" style="display:{{ Basket.getArchived ? 'none' : '' }};">
|
||||||
<span>
|
|
||||||
<img src="/assets/prod/images/Basket/Browser/archive.png"/>
|
|
||||||
</span>
|
|
||||||
</a>
|
</a>
|
||||||
<a href="{{ path('prod_baskets_basket_archive', { 'basket' : Basket.getId(), 'archive' : 0 }) }}" class="unarchiver archive_toggler" style="display:{{ Basket.getArchived ? '' : 'none' }};">
|
<a href="{{ path('prod_baskets_basket_archive', { 'basket' : Basket.getId(), 'archive' : 0 }) }}" class="unarchiver archive_toggler" style="display:{{ Basket.getArchived ? '' : 'none' }};">
|
||||||
<span>
|
|
||||||
<img src="/assets/prod/images/Basket/Browser/archived.png"/>
|
|
||||||
</span>
|
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a class="basket_link" href="{{ path('prod_workzone_basket', { basket : Basket.getId() }) }}">
|
<a class="basket_link" href="{{ path('prod_workzone_basket', { basket : Basket.getId() }) }}">
|
||||||
{{ Basket.getName() }}
|
<span>{{ Basket.getName() }}</span>
|
||||||
</a>
|
<br><span class="basketCount">
|
||||||
|
{{ Basket.getElements().count() }} {{ ' records' }}
|
||||||
|
</span></a>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
|
|
||||||
{% if Basket.getPusher() %}
|
{% if Basket.getPusher() %}
|
||||||
<p>
|
<p>
|
||||||
{% set user_name = '<a href="/user/' ~ Basket.getPusher().get_id() ~ '/" tooltipsrc="' ~ path('prod_tooltip_user', { 'usr_id' : Basket.getPusher(app).getId() }) ~ '" class="UserTips">' ~ Basket.getPusher(app).get_display_name() ~ '</a>' %}
|
{% set user_name = '<a href="/user/' ~ Basket.getPusher().getId() ~ '/" tooltipsrc="' ~ path('prod_tooltip_user', { 'usr_id' : Basket.getPusher(app).getId() }) ~ '" class="UserTips">' ~ Basket.getPusher(app).getDisplayName() ~ '</a>' %}
|
||||||
{% trans with {'%user_name%' : user_name} %}Received from %user_name%{% endtrans %}
|
{% trans with {'%user_name%' : user_name} %}Received from %user_name%{% endtrans %}
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -92,12 +69,11 @@
|
|||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
</td>
|
</div>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</div>
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@@ -117,19 +93,16 @@
|
|||||||
</td>
|
</td>
|
||||||
<td class="paginator">
|
<td class="paginator">
|
||||||
{% if Page - 1 > 0 %}
|
{% if Page - 1 > 0 %}
|
||||||
<a href="{{ path('prod_workzone_search', { 'Query' : Query, 'Year' : Year, 'Type' : Type, 'Page' : (Page - 1) }) }}" class="result">
|
<a href="{{ path('prod_workzone_search', { 'Query' : Query, 'Year' : Year, 'Type' : Type, 'Page' : (Page - 1) }) }}" class="result prev_res icon-round-chevron_left-24px"> </a>
|
||||||
<img src="/assets/prod/images/Basket/Browser/left.png" />
|
|
||||||
</a>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<span>
|
<span>
|
||||||
Page {{ Page }} / {{ MaxPage }}
|
Page {{ Page }} / {{ MaxPage }}
|
||||||
</span>
|
</span>
|
||||||
{% if Page + 1 <= MaxPage %}
|
{% if Page + 1 <= MaxPage %}
|
||||||
<a href="{{ path('prod_workzone_search', { 'Query' : Query, 'Year' : Year, 'Type' : Type, 'Page' : (Page + 1) }) }}" class="result">
|
<a href="{{ path('prod_workzone_search', { 'Query' : Query, 'Year' : Year, 'Type' : Type, 'Page' : (Page + 1) }) }}" class="result next_res icon-round-chevron_right-24px"> </a>
|
||||||
<img src="/assets/prod/images/Basket/Browser/right.png" />
|
|
||||||
</a>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@@ -45,23 +45,36 @@
|
|||||||
{% set dataH = constant('media_subdef::TC_DATA_HEIGHT') %}
|
{% set dataH = constant('media_subdef::TC_DATA_HEIGHT') %}
|
||||||
|
|
||||||
{% set technical_info = record.get_technical_infos %}
|
{% set technical_info = record.get_technical_infos %}
|
||||||
|
|
||||||
|
{#Set the preview Ratio #}
|
||||||
{% set width = technical_info[dataW].value %}
|
{% set width = technical_info[dataW].value %}
|
||||||
{% set height = technical_info[dataH].value %}
|
{% set height = technical_info[dataH].value %}
|
||||||
|
{% set prevRatio = '' %}
|
||||||
|
|
||||||
{% if width and height %}
|
{% if width and height %}
|
||||||
{% set rawRatio = (width / height)|number_format(3, '.') %}
|
{% set ratio = (width / height)|number_format(2, '.') %}
|
||||||
{% set rawRatioLength = rawRatio|length %}
|
|
||||||
{% set ratio = rawRatio|slice(0,rawRatioLength-1) %}
|
|
||||||
{% else %}
|
|
||||||
{% set ratio = '' %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<video id="thumb_video" controls="" preload="auto" data-ratio="{{ ratio }}">
|
{#Set the document Ratio #}
|
||||||
|
{% for subdef in previewHtml5 %}
|
||||||
|
|
||||||
|
{% set width = subdef.get_width() %}
|
||||||
|
{% set height = subdef.get_height() %}
|
||||||
|
|
||||||
|
{% if width and height %}
|
||||||
|
{% if subdef.get_name()=='preview' %}
|
||||||
|
{% set prevRatio = (width / height)|number_format(2, '.') %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
<video id="thumb_video" controls="" preload="auto" data-ratio="{{ prevRatio }}">
|
||||||
{% for subdef in previewHtml5 %}
|
{% for subdef in previewHtml5 %}
|
||||||
<source type="{{ subdef.get_mime() }}" src="{{ subdef.get_url() }}"/>
|
<source type="{{ subdef.get_mime() }}" src="{{ subdef.get_url() }}"/>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{{ 'No preview available' | trans }}
|
{{ 'No preview available' | trans }}
|
||||||
</video>
|
</video>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="thumb_camera_button"></div>
|
<div id="thumb_camera_button"></div>
|
||||||
@@ -109,7 +122,7 @@
|
|||||||
<canvas data-width="{{ subdef.get_width() }}"
|
<canvas data-width="{{ subdef.get_width() }}"
|
||||||
data-height="{{ subdef.get_height() }}"
|
data-height="{{ subdef.get_height() }}"
|
||||||
data-name="{{ subdef.get_name() }}"
|
data-name="{{ subdef.get_name() }}"
|
||||||
class="alt_canvas" id="{{ subdef.get_name() }}"></canvas>
|
class="alt_canvas" id="{{ subdef.get_name() }}" ></canvas>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@@ -196,8 +196,10 @@
|
|||||||
<div style="position:absolute; top:0px; left:0px; right:70px; height:17px;">
|
<div style="position:absolute; top:0px; left:0px; right:70px; height:17px;">
|
||||||
<input type='text' style="font-size:15px; position:absolute; top:0px; left:0px; width:100%; height:100%;" id="EditTextMultiValued" value="" />
|
<input type='text' style="font-size:15px; position:absolute; top:0px; left:0px; width:100%; height:100%;" id="EditTextMultiValued" value="" />
|
||||||
</div>
|
</div>
|
||||||
<div style="position:absolute; top:6px; width:60px; right:0px; height:11px;">
|
<div style="position:absolute; top:4px; width:60px; right:6px; height:24px;">
|
||||||
<img id="EditButAddMultiValued add-multivalued-field-action" style="cursor:pointer" src="/assets/common/images/icons/plus16.png" />
|
<button type="submit" class="submit-multivalued">
|
||||||
|
<img id="EditButAddMultiValued" style="cursor:pointer" src="/assets/common/images/icons/plus16.png" />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<div id="ZTextMultiValued_values"></div>
|
<div id="ZTextMultiValued_values"></div>
|
||||||
|
@@ -146,7 +146,7 @@
|
|||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
prodApp.appEvents.emit('workzone.doRemoveWarning', "{% if app['settings'].getUserSetting(app.getAuthenticatedUser(), "warning_on_delete_story") %}true{% else %}false{% endif %}");
|
prodApp.appEvents.emit('workzone.doRemoveWarning', "{% if app['settings'].getUserSetting(app.getAuthenticatedUser(), "warning_on_delete_story") %}true{% else %}false{% endif %}");
|
||||||
prodApp.appEvents.emit('search.updateFacetData');
|
prodApp.appEvents.emit('search.updateFacetData');
|
||||||
|
$('body').addClass('{{ cssfile }}');
|
||||||
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@@ -14,6 +14,7 @@ use Alchemy\Phrasea\Model\Entities\LazaretSession;
|
|||||||
use Alchemy\Phrasea\Model\Entities\Task;
|
use Alchemy\Phrasea\Model\Entities\Task;
|
||||||
use Alchemy\Phrasea\Model\Entities\User;
|
use Alchemy\Phrasea\Model\Entities\User;
|
||||||
use Alchemy\Phrasea\SearchEngine\SearchEngineOptions;
|
use Alchemy\Phrasea\SearchEngine\SearchEngineOptions;
|
||||||
|
use Alchemy\Phrasea\Status\StatusStructureProviderInterface;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Guzzle\Common\Exception\GuzzleException;
|
use Guzzle\Common\Exception\GuzzleException;
|
||||||
use Ramsey\Uuid\Uuid;
|
use Ramsey\Uuid\Uuid;
|
||||||
@@ -1256,13 +1257,33 @@ class ApiJsonTest extends ApiTestCase
|
|||||||
$record1 = $this->getRecord1();
|
$record1 = $this->getRecord1();
|
||||||
$route = '/api/v1/records/' . $record1->getDataboxId() . '/' . $record1->getRecordId() . '/setstatus/';
|
$route = '/api/v1/records/' . $record1->getDataboxId() . '/' . $record1->getRecordId() . '/setstatus/';
|
||||||
|
|
||||||
$record_status = strrev($record1->getStatus());
|
$initialRecordStatus = $record_status = strrev($record1->getStatus());
|
||||||
|
|
||||||
|
/** @var StatusStructureProviderInterface $statusProvider */
|
||||||
|
$statusProvider = $app['status.provider'];
|
||||||
|
|
||||||
|
// initialize status structure for test eg: 4 to 15 bit
|
||||||
|
foreach (range(4, 15) as $n) {
|
||||||
|
$properties = [
|
||||||
|
'searchable' => '0',
|
||||||
|
'printable' => '0',
|
||||||
|
'name' => 'status_test_' . $n,
|
||||||
|
'labelon' => '',
|
||||||
|
'labeloff' => '',
|
||||||
|
'labels_on' => [],
|
||||||
|
'labels_off' => [],
|
||||||
|
];
|
||||||
|
|
||||||
|
$statusProvider->updateStatus($record1->getStatusStructure(), $n, $properties);
|
||||||
|
}
|
||||||
|
|
||||||
$statusStructure = $record1->getStatusStructure();
|
$statusStructure = $record1->getStatusStructure();
|
||||||
|
|
||||||
$tochange = [];
|
$tochange = [];
|
||||||
foreach ($statusStructure as $n => $datas) {
|
foreach ($statusStructure as $n => $datas) {
|
||||||
$tochange[$n] = substr($record_status, ($n - 1), 1) == '0' ? '1' : '0';
|
$tochange[$n] = substr($record_status, ($n - 1), 1) == '0' ? '1' : '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->evaluateMethodNotAllowedRoute($route, ['GET', 'PUT', 'DELETE']);
|
$this->evaluateMethodNotAllowedRoute($route, ['GET', 'PUT', 'DELETE']);
|
||||||
|
|
||||||
$response = $this->request('POST', $route, $this->getParameters(['status' => $tochange]), ['HTTP_Accept' => $this->getAcceptMimeType()]);
|
$response = $this->request('POST', $route, $this->getParameters(['status' => $tochange]), ['HTTP_Accept' => $this->getAcceptMimeType()]);
|
||||||
@@ -1281,6 +1302,27 @@ class ApiJsonTest extends ApiTestCase
|
|||||||
$this->assertEquals(substr($record_status, ($n), 1), $tochange[$n]);
|
$this->assertEquals(substr($record_status, ($n), 1), $tochange[$n]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test record_status in string
|
||||||
|
$record_status_expected = $record_status;
|
||||||
|
|
||||||
|
$pos = strpos($record_status, '1');
|
||||||
|
$bitToChange[$pos] = '1';
|
||||||
|
|
||||||
|
$response = $this->request('POST', $route, $this->getParameters(['status' => $bitToChange]), ['HTTP_Accept' => $this->getAcceptMimeType()]);
|
||||||
|
$content = $this->unserialize($response->getContent());
|
||||||
|
|
||||||
|
// Get fresh record_1
|
||||||
|
$testRecord = new \record_adapter($app, $testRecord->getDataboxId(), $testRecord->getRecordId());
|
||||||
|
|
||||||
|
$this->evaluateResponse200($response);
|
||||||
|
$this->evaluateMeta200($content);
|
||||||
|
|
||||||
|
$this->evaluateRecordsStatusResponse($testRecord, $content);
|
||||||
|
|
||||||
|
$record_new_status = strrev($testRecord->getStatus());
|
||||||
|
$this->assertEquals($record_status_expected, $record_new_status);
|
||||||
|
|
||||||
|
|
||||||
foreach ($tochange as $n => $value) {
|
foreach ($tochange as $n => $value) {
|
||||||
$tochange[$n] = $value == '0' ? '1' : '0';
|
$tochange[$n] = $value == '0' ? '1' : '0';
|
||||||
}
|
}
|
||||||
@@ -1301,6 +1343,8 @@ class ApiJsonTest extends ApiTestCase
|
|||||||
$this->assertEquals(substr($record_status, ($n), 1), $tochange[$n]);
|
$this->assertEquals(substr($record_status, ($n), 1), $tochange[$n]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->assertEquals($initialRecordStatus, $record_status);
|
||||||
|
|
||||||
$record1->setStatus(str_repeat('0', 32));
|
$record1->setStatus(str_repeat('0', 32));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -58,6 +58,7 @@ class RangeExpressionTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
$query_context = $this->prophesize(QueryContext::class)->reveal();
|
$query_context = $this->prophesize(QueryContext::class)->reveal();
|
||||||
$key_prophecy = $this->prophesize(Key::class);
|
$key_prophecy = $this->prophesize(Key::class);
|
||||||
|
$key_prophecy->getFieldType($query_context)->willReturn('text');
|
||||||
$key_prophecy->getIndexField($query_context)->willReturn('foo');
|
$key_prophecy->getIndexField($query_context)->willReturn('foo');
|
||||||
$key_prophecy->isValueCompatible('bar', $query_context)->willReturn(true);
|
$key_prophecy->isValueCompatible('bar', $query_context)->willReturn(true);
|
||||||
$key = $key_prophecy->reveal();
|
$key = $key_prophecy->reveal();
|
||||||
@@ -73,6 +74,7 @@ class RangeExpressionTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
$query_context = $this->prophesize(QueryContext::class)->reveal();
|
$query_context = $this->prophesize(QueryContext::class)->reveal();
|
||||||
$key = $this->prophesize(FieldKey::class);
|
$key = $this->prophesize(FieldKey::class);
|
||||||
|
$key->getFieldType($query_context)->willReturn('text');
|
||||||
$key->getIndexField($query_context)->willReturn('baz');
|
$key->getIndexField($query_context)->willReturn('baz');
|
||||||
$key->isValueCompatible('bar', $query_context)->willReturn(true);
|
$key->isValueCompatible('bar', $query_context)->willReturn(true);
|
||||||
$key->postProcessQuery(Argument::any(), $query_context)->willReturnArgument(0);
|
$key->postProcessQuery(Argument::any(), $query_context)->willReturnArgument(0);
|
||||||
|
@@ -53,6 +53,7 @@ foo < 42|<range:field.foo lt="42">
|
|||||||
foo ≤ 42|<range:field.foo lte="42">
|
foo ≤ 42|<range:field.foo lte="42">
|
||||||
foo > 42|<range:field.foo gt="42">
|
foo > 42|<range:field.foo gt="42">
|
||||||
foo ≥ 42|<range:field.foo gte="42">
|
foo ≥ 42|<range:field.foo gte="42">
|
||||||
|
foo = 2015/01/01|(<field.foo> == <value:"2015/01/01">)
|
||||||
foo < 2015/01/01|<range:field.foo lt="2015/01/01">
|
foo < 2015/01/01|<range:field.foo lt="2015/01/01">
|
||||||
foo ≤ 2015/01/01|<range:field.foo lte="2015/01/01">
|
foo ≤ 2015/01/01|<range:field.foo lte="2015/01/01">
|
||||||
foo > 2015/01/01|<range:field.foo gt="2015/01/01">
|
foo > 2015/01/01|<range:field.foo gt="2015/01/01">
|
||||||
@@ -93,19 +94,93 @@ id:90 AND foo|(<record_identifier:"90"> AND <text:"foo">)
|
|||||||
id:90 foo|(<record_identifier:"90"> AND <text:"foo">)
|
id:90 foo|(<record_identifier:"90"> AND <text:"foo">)
|
||||||
recordid:90|<record_identifier:"90">
|
recordid:90|<record_identifier:"90">
|
||||||
|
|
||||||
# Timestamps
|
# Timestamps yyyy
|
||||||
created_on < "2015/01/01"|<range:creation lt="2015/01/01">
|
created_on < "2015"|<range:creation lt="2015">
|
||||||
created_on ≤ "2015/01/01"|<range:creation lte="2015/01/01">
|
created_on ≤ "2015"|<range:creation lte="2015">
|
||||||
created_on = "2015/01/01"|<range:creation gte="2015/01/01" lt="2015/01/02">
|
created_on = "2015"|<range:creation gte="2015-01-01 00:00:00" lt="2016-01-01 00:00:00">
|
||||||
created_on ≥ "2015/01/01"|<range:creation gte="2015/01/01">
|
created_on ≥ "2015"|<range:creation gte="2015">
|
||||||
created_on > "2015/01/01"|<range:creation gt="2015/01/01">
|
created_on > "2015"|<range:creation gt="2015">
|
||||||
updated_on < "2015/01/01"|<range:update lt="2015/01/01">
|
updated_on < "2015"|<range:update lt="2015">
|
||||||
updated_on ≤ "2015/01/01"|<range:update lte="2015/01/01">
|
updated_on ≤ "2015"|<range:update lte="2015">
|
||||||
updated_on = "2015/01/01"|<range:update gte="2015/01/01" lt="2015/01/02">
|
updated_on = "2015"|<range:update gte="2015-01-01 00:00:00" lt="2016-01-01 00:00:00">
|
||||||
updated_on ≥ "2015/01/01"|<range:update gte="2015/01/01">
|
updated_on ≥ "2015"|<range:update gte="2015">
|
||||||
updated_on > "2015/01/01"|<range:update gt="2015/01/01">
|
updated_on > "2015"|<range:update gt="2015">
|
||||||
created_at > "2015/01/01"|<range:creation gt="2015/01/01">
|
created_at > "2015"|<range:creation gt="2015">
|
||||||
updated_at > "2015/01/01"|<range:update gt="2015/01/01">
|
updated_at > "2015"|<range:update gt="2015">
|
||||||
|
|
||||||
|
# Timestamps yyyy/mm
|
||||||
|
created_on < "2015/01"|<range:creation lt="2015-01">
|
||||||
|
created_on ≤ "2015/01"|<range:creation lte="2015-01">
|
||||||
|
created_on = "2015/01"|<range:creation gte="2015-01-01 00:00:00" lt="2015-02-01 00:00:00">
|
||||||
|
created_on ≥ "2015/01"|<range:creation gte="2015-01">
|
||||||
|
created_on > "2015/01"|<range:creation gt="2015-01">
|
||||||
|
updated_on < "2015/01"|<range:update lt="2015-01">
|
||||||
|
updated_on ≤ "2015/01"|<range:update lte="2015-01">
|
||||||
|
updated_on = "2015/01"|<range:update gte="2015-01-01 00:00:00" lt="2015-02-01 00:00:00">
|
||||||
|
updated_on ≥ "2015/01"|<range:update gte="2015-01">
|
||||||
|
updated_on > "2015/01"|<range:update gt="2015-01">
|
||||||
|
created_at > "2015/01"|<range:creation gt="2015-01">
|
||||||
|
updated_at > "2015/01"|<range:update gt="2015-01">
|
||||||
|
|
||||||
|
# Timestamps yyyy/mm/dd
|
||||||
|
created_on < "2015/01/01"|<range:creation lt="2015-01-01">
|
||||||
|
created_on ≤ "2015/01/01"|<range:creation lte="2015-01-01">
|
||||||
|
created_on = "2015/01/01"|<range:creation gte="2015-01-01 00:00:00" lt="2015-01-02 00:00:00">
|
||||||
|
created_on ≥ "2015/01/01"|<range:creation gte="2015-01-01">
|
||||||
|
created_on > "2015/01/01"|<range:creation gt="2015-01-01">
|
||||||
|
updated_on < "2015/01/01"|<range:update lt="2015-01-01">
|
||||||
|
updated_on ≤ "2015/01/01"|<range:update lte="2015-01-01">
|
||||||
|
updated_on = "2015/01/01"|<range:update gte="2015-01-01 00:00:00" lt="2015-01-02 00:00:00">
|
||||||
|
updated_on ≥ "2015/01/01"|<range:update gte="2015-01-01">
|
||||||
|
updated_on > "2015/01/01"|<range:update gt="2015-01-01">
|
||||||
|
created_at > "2015/01/01"|<range:creation gt="2015-01-01">
|
||||||
|
updated_at > "2015/01/01"|<range:update gt="2015-01-01">
|
||||||
|
|
||||||
|
# Timestamps yyyy/mm/dd hh
|
||||||
|
created_on < "2015/01/01 12"|<range:creation lt="2015-01-01 12:00:00">
|
||||||
|
created_on ≤ "2015/01/01 12"|<range:creation lte="2015-01-01 12:00:00">
|
||||||
|
created_on = "2015/01/01 12"|<range:creation gte="2015-01-01 12:00:00" lt="2015-01-01 13:00:00">
|
||||||
|
created_on ≥ "2015/01/01 12"|<range:creation gte="2015-01-01 12:00:00">
|
||||||
|
created_on > "2015/01/01 12"|<range:creation gt="2015-01-01 12:00:00">
|
||||||
|
updated_on < "2015/01/01 12"|<range:update lt="2015-01-01 12:00:00">
|
||||||
|
updated_on ≤ "2015/01/01 12"|<range:update lte="2015-01-01 12:00:00">
|
||||||
|
updated_on = "2015/01/01 12"|<range:update gte="2015-01-01 12:00:00" lt="2015-01-01 13:00:00">
|
||||||
|
updated_on ≥ "2015/01/01 12"|<range:update gte="2015-01-01 12:00:00">
|
||||||
|
updated_on > "2015/01/01 12"|<range:update gt="2015-01-01 12:00:00">
|
||||||
|
created_at > "2015/01/01 12"|<range:creation gt="2015-01-01 12:00:00">
|
||||||
|
updated_at > "2015/01/01 12"|<range:update gt="2015-01-01 12:00:00">
|
||||||
|
|
||||||
|
# Timestamps yyyy/mm/dd hh:mm
|
||||||
|
created_on < "2015/01/01 12.34"|<range:creation lt="2015-01-01 12:34:00">
|
||||||
|
created_on ≤ "2015/01/01 12.34"|<range:creation lte="2015-01-01 12:34:00">
|
||||||
|
created_on = "2015/01/01 12.34"|<range:creation gte="2015-01-01 12:34:00" lt="2015-01-01 12:35:00">
|
||||||
|
created_on ≥ "2015/01/01 12.34"|<range:creation gte="2015-01-01 12:34:00">
|
||||||
|
created_on > "2015/01/01 12.34"|<range:creation gt="2015-01-01 12:34:00">
|
||||||
|
updated_on < "2015/01/01 12.34"|<range:update lt="2015-01-01 12:34:00">
|
||||||
|
updated_on ≤ "2015/01/01 12.34"|<range:update lte="2015-01-01 12:34:00">
|
||||||
|
updated_on = "2015/01/01 12.34"|<range:update gte="2015-01-01 12:34:00" lt="2015-01-01 12:35:00">
|
||||||
|
updated_on ≥ "2015/01/01 12.34"|<range:update gte="2015-01-01 12:34:00">
|
||||||
|
updated_on > "2015/01/01 12.34"|<range:update gt="2015-01-01 12:34:00">
|
||||||
|
created_at > "2015/01/01 12.34"|<range:creation gt="2015-01-01 12:34:00">
|
||||||
|
updated_at > "2015/01/01 12.34"|<range:update gt="2015-01-01 12:34:00">
|
||||||
|
|
||||||
|
# Timestamps yyyy/mm/dd hh.mm.ss
|
||||||
|
created_on < "2015/01/01 12.34.56"|<range:creation lt="2015-01-01 12:34:56">
|
||||||
|
created_on ≤ "2015/01/01 12.34.56"|<range:creation lte="2015-01-01 12:34:56">
|
||||||
|
created_on = "2015/01/01 12.34.56"|(<creation> == <value:"2015-01-01 12:34:56">)
|
||||||
|
created_on ≥ "2015/01/01 12.34.56"|<range:creation gte="2015-01-01 12:34:56">
|
||||||
|
created_on > "2015/01/01 12.34.56"|<range:creation gt="2015-01-01 12:34:56">
|
||||||
|
updated_on < "2015/01/01 12.34.56"|<range:update lt="2015-01-01 12:34:56">
|
||||||
|
updated_on ≤ "2015/01/01 12.34.56"|<range:update lte="2015-01-01 12:34:56">
|
||||||
|
updated_on = "2015/01/01 12.34.56"|(<update> == <value:"2015-01-01 12:34:56">)
|
||||||
|
updated_on ≥ "2015/01/01 12.34.56"|<range:update gte="2015-01-01 12:34:56">
|
||||||
|
updated_on > "2015/01/01 12.34.56"|<range:update gt="2015-01-01 12:34:56">
|
||||||
|
created_at > "2015/01/01 12.34.56"|<range:creation gt="2015-01-01 12:34:56">
|
||||||
|
updated_at > "2015/01/01 12.34.56"|<range:update gt="2015-01-01 12:34:56">
|
||||||
|
|
||||||
|
# timestamps missing zeros
|
||||||
|
created_on = "2015/1/2 1.3.5"|(<creation> == <value:"2015-01-02 01:03:05">)
|
||||||
|
|
||||||
|
|
||||||
# Flag matcher
|
# Flag matcher
|
||||||
flag.foo:true|<flag:foo set>
|
flag.foo:true|<flag:foo set>
|
||||||
|
Can't render this file because it contains an unexpected character in line 1 and column 11.
|
@@ -7555,10 +7555,10 @@ phraseanet-common@^0.4.1:
|
|||||||
js-cookie "^2.1.0"
|
js-cookie "^2.1.0"
|
||||||
pym.js "^1.3.1"
|
pym.js "^1.3.1"
|
||||||
|
|
||||||
phraseanet-production-client@^0.34.53-d:
|
phraseanet-production-client@0.34.72-d:
|
||||||
version "0.34.53-d"
|
version "0.34.72-d"
|
||||||
resolved "https://registry.yarnpkg.com/phraseanet-production-client/-/phraseanet-production-client-0.34.53-d.tgz#517e5d9ccae2f1f0f3cdb7ac194e70579cbcc65f"
|
resolved "https://registry.yarnpkg.com/phraseanet-production-client/-/phraseanet-production-client-0.34.72-d.tgz#028a5ccd589e696b5433eea9d53d9367966613c8"
|
||||||
integrity sha512-/Vd5kd/YRapDpUWzBZZvm5hHwieXdU2cBEtC3D/FPbeSEI3dmYEDnuznDxBafPZvep65KdAtufPw+B6ulWNgBQ==
|
integrity sha512-IPaDRqXwyJegoKmzr56bggxTzN4TnmuAqU4O7rDEhh0aqdCiuC8rlH/yzKoLeEIMSrESCw5mBhrI//ccntvv9w==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@mapbox/mapbox-gl-language" "^0.9.2"
|
"@mapbox/mapbox-gl-language" "^0.9.2"
|
||||||
"@turf/turf" "^5.1.6"
|
"@turf/turf" "^5.1.6"
|
||||||
|
Reference in New Issue
Block a user