Merge remote-tracking branch 'upstream/master' into elastic-indexer

Conflicts:
	composer.lock
	www/scripts/apps/admin/main/app.js
This commit is contained in:
Mathieu Darse
2015-03-10 15:25:20 +01:00
92 changed files with 27708 additions and 28968 deletions

View File

@@ -22,7 +22,7 @@ before_script:
- echo "extension=zmq.so" > ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/zmq.ini - echo "extension=zmq.so" > ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/zmq.ini
- yes | pecl install imagick - yes | pecl install imagick
- mysql -e 'create database update39_test;create database ab_test;create database db_test;' - mysql -e 'create database update39_test;create database ab_test;create database db_test;'
- mysql -e 'SET @@global.sql_mode= "";' - mysql -e 'SET @@global.sql_mode= STRICT_ALL_TABLES;'
- mysql -e 'SET @@global.max_allowed_packet= 33554432;' - mysql -e 'SET @@global.max_allowed_packet= 33554432;'
- mysql -e 'SET @@global.wait_timeout= 999999;' - mysql -e 'SET @@global.wait_timeout= 999999;'
- git clone git://github.com/alchemy-fr/Phraseanet-Extension.git - git clone git://github.com/alchemy-fr/Phraseanet-Extension.git

View File

@@ -332,16 +332,6 @@ module.exports = function(grunt) {
"dest": "<%= path.asset %>/underscore-amd/", "dest": "<%= path.asset %>/underscore-amd/",
"flatten": true "flatten": true
}, },
"web-socket-js": {
"expand": true,
"src": [
"<%= path.bower %>/web-socket-js/LICENSE.txt",
"<%= path.bower %>/web-socket-js/WebSocketMain.swf",
"<%= path.bower %>/web-socket-js/web_socket.js"
],
"dest": "<%= path.asset %>/web-socket-js",
"flatten": true
},
"zxcvbn": { "zxcvbn": {
"expand": true, "expand": true,
"src": [ "src": [
@@ -440,7 +430,6 @@ module.exports = function(grunt) {
"copy:swfobject", "copy:swfobject",
"copy:tinymce", "copy:tinymce",
"copy:underscore", "copy:underscore",
"copy:web-socket-js",
"copy:zxcvbn" "copy:zxcvbn"
]); ]);
grunt.registerTask("install-assets", [ grunt.registerTask("install-assets", [

View File

@@ -27,7 +27,6 @@
"jquery.cookie": "~1.4", "jquery.cookie": "~1.4",
"autobahn": "http://autobahn.s3.amazonaws.com/js/autobahn.min.js", "autobahn": "http://autobahn.s3.amazonaws.com/js/autobahn.min.js",
"when": "~2.7.0", "when": "~2.7.0",
"web-socket-js": "~1.0.1",
"jquery.treeview": "1.4.1", "jquery.treeview": "1.4.1",
"fancytree": "~2.7", "fancytree": "~2.7",
"joyride": "https://github.com/zurb/joyride/archive/v2.0.0.zip" "joyride": "https://github.com/zurb/joyride/archive/v2.0.0.zip"

View File

@@ -21,6 +21,10 @@
{ {
"type": "vcs", "type": "vcs",
"url": "https://github.com/alchemy-fr/phpexiftool" "url": "https://github.com/alchemy-fr/phpexiftool"
},
{
"type": "vcs",
"url": "https://github.com/alchemy-fr/JMSTranslationBundle"
} }
], ],
"require": { "require": {
@@ -29,7 +33,6 @@
"alchemy/phlickr" : "0.2.9", "alchemy/phlickr" : "0.2.9",
"alchemy/task-manager" : "2.0.x-dev@dev", "alchemy/task-manager" : "2.0.x-dev@dev",
"alchemy/zippy" : "0.2.x-dev@dev", "alchemy/zippy" : "0.2.x-dev@dev",
"cboden/ratchet" : "~0.3",
"dailymotion/sdk" : "~1.5", "dailymotion/sdk" : "~1.5",
"data-uri/data-uri" : "~0.1.0", "data-uri/data-uri" : "~0.1.0",
"doctrine/orm" : "~2.4.0", "doctrine/orm" : "~2.4.0",
@@ -45,7 +48,7 @@
"igorw/get-in" : "~1.0", "igorw/get-in" : "~1.0",
"ircmaxell/random-lib" : "~1.0", "ircmaxell/random-lib" : "~1.0",
"jms/serializer" : "~0.10", "jms/serializer" : "~0.10",
"jms/translation-bundle" : "~1.1", "jms/translation-bundle" : "dev-master as 1.1.0",
"justinrainbow/json-schema" : "~1.3", "justinrainbow/json-schema" : "~1.3",
"mediavorus/mediavorus" : "~0.4.0", "mediavorus/mediavorus" : "~0.4.0",
"media-alchemyst/media-alchemyst" : "~0.4", "media-alchemyst/media-alchemyst" : "~0.4",
@@ -60,7 +63,6 @@
"php-ffmpeg/php-ffmpeg" : "~0.5.0", "php-ffmpeg/php-ffmpeg" : "~0.5.0",
"php-xpdf/php-xpdf" : "~0.2.1", "php-xpdf/php-xpdf" : "~0.2.1",
"phpexiftool/phpexiftool" : "dev-0.4.1-mwg-metadata-copy as 0.4.1", "phpexiftool/phpexiftool" : "dev-0.4.1-mwg-metadata-copy as 0.4.1",
"react/zmq" : "~0.2",
"rhumsaa/uuid" : "~2.7", "rhumsaa/uuid" : "~2.7",
"silex/silex" : "1.1.x-dev@dev", "silex/silex" : "1.1.x-dev@dev",
"silex/web-profiler" : "~1.0.0@dev", "silex/web-profiler" : "~1.0.0@dev",

479
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"hash": "f5e0457425e2c151f1a6b27e0bad160d", "hash": "9727062f8f765284d232f9204bdd3a0b",
"packages": [ "packages": [
{ {
"name": "alchemy-fr/tcpdf-clone", "name": "alchemy-fr/tcpdf-clone",
@@ -428,55 +428,6 @@
], ],
"time": "2014-05-05 13:39:00" "time": "2014-05-05 13:39:00"
}, },
{
"name": "cboden/ratchet",
"version": "v0.3.2",
"source": {
"type": "git",
"url": "https://github.com/ratchetphp/Ratchet.git",
"reference": "d36a8699df04354147a4f47845035b1ea8239189"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ratchetphp/Ratchet/zipball/d36a8699df04354147a4f47845035b1ea8239189",
"reference": "d36a8699df04354147a4f47845035b1ea8239189",
"shasum": ""
},
"require": {
"guzzle/http": "~3.6",
"php": ">=5.3.9",
"react/socket": "0.3.*|0.4.*",
"symfony/http-foundation": "~2.2",
"symfony/routing": "~2.2"
},
"type": "library",
"autoload": {
"psr-0": {
"Ratchet": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Chris Boden",
"email": "cboden@gmail.com",
"homepage": "http://res.im",
"role": "Developer"
}
],
"description": "PHP WebSocket library",
"homepage": "http://socketo.me",
"keywords": [
"Ratchet",
"WebSockets",
"server",
"sockets"
],
"time": "2014-06-08 15:19:45"
},
{ {
"name": "dailymotion/sdk", "name": "dailymotion/sdk",
"version": "1.6.2", "version": "1.6.2",
@@ -2368,17 +2319,17 @@
}, },
{ {
"name": "jms/translation-bundle", "name": "jms/translation-bundle",
"version": "1.1.0", "version": "dev-master",
"target-dir": "JMS/TranslationBundle", "target-dir": "JMS/TranslationBundle",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/schmittjoh/JMSTranslationBundle.git", "url": "https://github.com/alchemy-fr/JMSTranslationBundle.git",
"reference": "6f03035a38badaf8c48767c7664c3196df1eebdf" "reference": "808d11543fc9c1abc20dcf6b4d99e066c6a955da"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/schmittjoh/JMSTranslationBundle/zipball/6f03035a38badaf8c48767c7664c3196df1eebdf", "url": "https://api.github.com/repos/alchemy-fr/JMSTranslationBundle/zipball/808d11543fc9c1abc20dcf6b4d99e066c6a955da",
"reference": "6f03035a38badaf8c48767c7664c3196df1eebdf", "reference": "808d11543fc9c1abc20dcf6b4d99e066c6a955da",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2414,16 +2365,13 @@
"JMS\\TranslationBundle": "" "JMS\\TranslationBundle": ""
} }
}, },
"notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"Apache2" "Apache2"
], ],
"authors": [ "authors": [
{ {
"name": "Johannes Schmitt", "name": "Johannes M. Schmitt",
"email": "schmittjoh@gmail.com", "email": "schmittjoh@gmail.com"
"homepage": "https://github.com/schmittjoh",
"role": "Developer of wrapped JMSSerializerBundle"
} }
], ],
"description": "Puts the Symfony2 Translation Component on steroids", "description": "Puts the Symfony2 Translation Component on steroids",
@@ -2438,7 +2386,10 @@
"ui", "ui",
"webinterface" "webinterface"
], ],
"time": "2013-06-08 14:08:19" "support": {
"source": "https://github.com/alchemy-fr/JMSTranslationBundle/tree/master"
},
"time": "2015-03-09 17:01:23"
}, },
{ {
"name": "justinrainbow/json-schema", "name": "justinrainbow/json-schema",
@@ -3591,181 +3542,6 @@
], ],
"time": "2012-12-21 11:40:51" "time": "2012-12-21 11:40:51"
}, },
{
"name": "react/event-loop",
"version": "v0.3.4",
"target-dir": "React/EventLoop",
"source": {
"type": "git",
"url": "https://github.com/reactphp/event-loop.git",
"reference": "235cddfa999a392e7d63dc9bef2e042492608d9f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/event-loop/zipball/235cddfa999a392e7d63dc9bef2e042492608d9f",
"reference": "235cddfa999a392e7d63dc9bef2e042492608d9f",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"suggest": {
"ext-libev": "*",
"ext-libevent": ">=0.0.5"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.3-dev"
}
},
"autoload": {
"psr-0": {
"React\\EventLoop": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Event loop abstraction layer that libraries can use for evented I/O.",
"keywords": [
"event-loop"
],
"time": "2013-07-21 02:23:09"
},
{
"name": "react/socket",
"version": "v0.3.4",
"target-dir": "React/Socket",
"source": {
"type": "git",
"url": "https://github.com/reactphp/socket.git",
"reference": "19bc0c4309243717396022ffb2e59be1cc784327"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/socket/zipball/19bc0c4309243717396022ffb2e59be1cc784327",
"reference": "19bc0c4309243717396022ffb2e59be1cc784327",
"shasum": ""
},
"require": {
"evenement/evenement": "1.0.*",
"php": ">=5.3.3",
"react/event-loop": "0.3.*",
"react/stream": "0.3.*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.3-dev"
}
},
"autoload": {
"psr-0": {
"React\\Socket": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Library for building an evented socket server.",
"keywords": [
"Socket"
],
"time": "2014-02-17 22:32:00"
},
{
"name": "react/stream",
"version": "v0.3.4",
"target-dir": "React/Stream",
"source": {
"type": "git",
"url": "https://github.com/reactphp/stream.git",
"reference": "feef56628afe3fa861f0da5f92c909e029efceac"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/stream/zipball/feef56628afe3fa861f0da5f92c909e029efceac",
"reference": "feef56628afe3fa861f0da5f92c909e029efceac",
"shasum": ""
},
"require": {
"evenement/evenement": "1.0.*",
"php": ">=5.3.3"
},
"suggest": {
"react/event-loop": "0.3.*",
"react/promise": "~1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.3-dev"
}
},
"autoload": {
"psr-0": {
"React\\Stream": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Basic readable and writable stream interfaces that support piping.",
"keywords": [
"pipe",
"stream"
],
"time": "2014-02-16 19:48:52"
},
{
"name": "react/zmq",
"version": "v0.2.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/zmq.git",
"reference": "b69d97f99f2127e27d130d7fe3b2cec2a63b2c4e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/zmq/zipball/b69d97f99f2127e27d130d7fe3b2cec2a63b2c4e",
"reference": "b69d97f99f2127e27d130d7fe3b2cec2a63b2c4e",
"shasum": ""
},
"require": {
"evenement/evenement": "~1.0",
"ext-zmq": "*",
"php": ">=5.3.2",
"react/event-loop": "0.3.*"
},
"require-dev": {
"ext-pcntl": "*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.2-dev"
}
},
"autoload": {
"psr-0": {
"React\\ZMQ": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "ZeroMQ bindings for React.",
"keywords": [
"zeromq",
"zmq"
],
"time": "2013-09-18 11:02:06"
},
{ {
"name": "rhumsaa/uuid", "name": "rhumsaa/uuid",
"version": "2.8.0", "version": "2.8.0",
@@ -5034,6 +4810,55 @@
], ],
"time": "2014-09-29 13:12:12" "time": "2014-09-29 13:12:12"
}, },
{
"name": "cboden/ratchet",
"version": "v0.3.2",
"source": {
"type": "git",
"url": "https://github.com/ratchetphp/Ratchet.git",
"reference": "d36a8699df04354147a4f47845035b1ea8239189"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ratchetphp/Ratchet/zipball/d36a8699df04354147a4f47845035b1ea8239189",
"reference": "d36a8699df04354147a4f47845035b1ea8239189",
"shasum": ""
},
"require": {
"guzzle/http": "~3.6",
"php": ">=5.3.9",
"react/socket": "0.3.*|0.4.*",
"symfony/http-foundation": "~2.2",
"symfony/routing": "~2.2"
},
"type": "library",
"autoload": {
"psr-0": {
"Ratchet": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Chris Boden",
"email": "cboden@gmail.com",
"homepage": "http://res.im",
"role": "Developer"
}
],
"description": "PHP WebSocket library",
"homepage": "http://socketo.me",
"keywords": [
"Ratchet",
"WebSockets",
"server",
"sockets"
],
"time": "2014-06-08 15:19:45"
},
{ {
"name": "fabpot/goutte", "name": "fabpot/goutte",
"version": "v1.0.7", "version": "v1.0.7",
@@ -5749,6 +5574,181 @@
"xunit" "xunit"
], ],
"time": "2013-01-13 10:24:48" "time": "2013-01-13 10:24:48"
},
{
"name": "react/event-loop",
"version": "v0.3.4",
"target-dir": "React/EventLoop",
"source": {
"type": "git",
"url": "https://github.com/reactphp/event-loop.git",
"reference": "235cddfa999a392e7d63dc9bef2e042492608d9f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/event-loop/zipball/235cddfa999a392e7d63dc9bef2e042492608d9f",
"reference": "235cddfa999a392e7d63dc9bef2e042492608d9f",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"suggest": {
"ext-libev": "*",
"ext-libevent": ">=0.0.5"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.3-dev"
}
},
"autoload": {
"psr-0": {
"React\\EventLoop": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Event loop abstraction layer that libraries can use for evented I/O.",
"keywords": [
"event-loop"
],
"time": "2013-07-21 02:23:09"
},
{
"name": "react/socket",
"version": "v0.3.4",
"target-dir": "React/Socket",
"source": {
"type": "git",
"url": "https://github.com/reactphp/socket.git",
"reference": "19bc0c4309243717396022ffb2e59be1cc784327"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/socket/zipball/19bc0c4309243717396022ffb2e59be1cc784327",
"reference": "19bc0c4309243717396022ffb2e59be1cc784327",
"shasum": ""
},
"require": {
"evenement/evenement": "1.0.*",
"php": ">=5.3.3",
"react/event-loop": "0.3.*",
"react/stream": "0.3.*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.3-dev"
}
},
"autoload": {
"psr-0": {
"React\\Socket": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Library for building an evented socket server.",
"keywords": [
"Socket"
],
"time": "2014-02-17 22:32:00"
},
{
"name": "react/stream",
"version": "v0.3.4",
"target-dir": "React/Stream",
"source": {
"type": "git",
"url": "https://github.com/reactphp/stream.git",
"reference": "feef56628afe3fa861f0da5f92c909e029efceac"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/stream/zipball/feef56628afe3fa861f0da5f92c909e029efceac",
"reference": "feef56628afe3fa861f0da5f92c909e029efceac",
"shasum": ""
},
"require": {
"evenement/evenement": "1.0.*",
"php": ">=5.3.3"
},
"suggest": {
"react/event-loop": "0.3.*",
"react/promise": "~1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.3-dev"
}
},
"autoload": {
"psr-0": {
"React\\Stream": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Basic readable and writable stream interfaces that support piping.",
"keywords": [
"pipe",
"stream"
],
"time": "2014-02-16 19:48:52"
},
{
"name": "react/zmq",
"version": "v0.2.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/zmq.git",
"reference": "b69d97f99f2127e27d130d7fe3b2cec2a63b2c4e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/zmq/zipball/b69d97f99f2127e27d130d7fe3b2cec2a63b2c4e",
"reference": "b69d97f99f2127e27d130d7fe3b2cec2a63b2c4e",
"shasum": ""
},
"require": {
"evenement/evenement": "~1.0",
"ext-zmq": "*",
"php": ">=5.3.2",
"react/event-loop": "0.3.*"
},
"require-dev": {
"ext-pcntl": "*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.2-dev"
}
},
"autoload": {
"psr-0": {
"React\\ZMQ": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "ZeroMQ bindings for React.",
"keywords": [
"zeromq",
"zmq"
],
"time": "2013-09-18 11:02:06"
} }
], ],
"aliases": [ "aliases": [
@@ -5758,6 +5758,12 @@
"version": "dev-alchemy-0.6.2", "version": "dev-alchemy-0.6.2",
"package": "imagine/imagine" "package": "imagine/imagine"
}, },
{
"alias": "1.1.0",
"alias_normalized": "1.1.0.0",
"version": "9999999-dev",
"package": "jms/translation-bundle"
},
{ {
"alias": "0.4.1", "alias": "0.4.1",
"alias_normalized": "0.4.1.0", "alias_normalized": "0.4.1.0",
@@ -5771,6 +5777,7 @@
"alchemy/zippy": 20, "alchemy/zippy": 20,
"goodby/csv": 20, "goodby/csv": 20,
"imagine/imagine": 20, "imagine/imagine": 20,
"jms/translation-bundle": 20,
"neutron/process-manager": 20, "neutron/process-manager": 20,
"phpexiftool/phpexiftool": 20, "phpexiftool/phpexiftool": 20,
"silex/silex": 20, "silex/silex": 20,

View File

@@ -32,23 +32,15 @@ main:
task-manager: task-manager:
status: started status: started
enabled: true enabled: true
logger: options:
max-files: 10
enabled: true
level: INFO
listener:
protocol: tcp protocol: tcp
host: 127.0.0.1 host: 127.0.0.1
port: 6660 port: 6660
linger: 500 linger: 500
websocket-server: logger:
host: local.phrasea max-files: 10
port: 9090 enabled: true
ip: 0.0.0.0 level: INFO
subscriber:
protocol: tcp
host: 127.0.0.1
port: 13598
session: session:
type: 'file' type: 'file'
options: [] options: []

View File

@@ -88,13 +88,7 @@ class Authenticator
{ {
$user = $session->getUser(); $user = $session->getUser();
$rights = [];
if ($this->app['acl']->get($user)->has_right('taskmanager')) {
$rights[] = 'task-manager';
}
$this->session->set('usr_id', $user->getId()); $this->session->set('usr_id', $user->getId());
$this->session->set('websockets_rights', $rights);
$this->session->set('session_id', $session->getId()); $this->session->set('session_id', $session->getId());
} }

View File

@@ -13,7 +13,6 @@ namespace Alchemy\Phrasea;
use Alchemy\Phrasea\Command\CommandInterface; use Alchemy\Phrasea\Command\CommandInterface;
use Alchemy\Phrasea\Core\CLIProvider\TranslationExtractorServiceProvider; use Alchemy\Phrasea\Core\CLIProvider\TranslationExtractorServiceProvider;
use Alchemy\Phrasea\Core\CLIProvider\WebsocketServerServiceProvider;
use Alchemy\Phrasea\Core\Event\Subscriber\BridgeSubscriber; use Alchemy\Phrasea\Core\Event\Subscriber\BridgeSubscriber;
use Alchemy\Phrasea\Core\PhraseaCLIExceptionHandler; use Alchemy\Phrasea\Core\PhraseaCLIExceptionHandler;
use Alchemy\Phrasea\Exception\RuntimeException; use Alchemy\Phrasea\Exception\RuntimeException;
@@ -67,7 +66,6 @@ class CLI extends Application
); );
$this->register(new PluginServiceProvider()); $this->register(new PluginServiceProvider());
$this->register(new WebsocketServerServiceProvider());
$this->register(new ComposerSetupServiceProvider()); $this->register(new ComposerSetupServiceProvider());
$this->register(new CLIDriversServiceProvider()); $this->register(new CLIDriversServiceProvider());
$this->register(new LessBuilderServiceProvider()); $this->register(new LessBuilderServiceProvider());

View File

@@ -1,37 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Command;
use Alchemy\Phrasea\Exception\RuntimeException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class WebsocketServer extends Command
{
public function __construct($name = null)
{
parent::__construct($name);
$this->setDescription("Runs the websocket server");
}
public function doExecute(InputInterface $input, OutputInterface $output)
{
$sessionConf = $this->container['conf']->get(['main', 'session', 'type'], 'file');
if (!in_array($sessionConf, ['memcached', 'memcache', 'redis'])) {
throw new RuntimeException(sprintf('Running the websocket server requires a server session storage, type `%s` provided', $sessionConf));
}
$this->container['ws.server']->run();
}
}

View File

@@ -509,17 +509,14 @@ class Push implements ControllerProviderInterface
$user = null; $user = null;
$email = $request->request->get('email'); $email = $request->request->get('email');
try { if (null !== $user = $app['repo.users']->findByEmail($email)) {
$user = $app['repo.users']->findByEmail($email);
$result['message'] = $app->trans('User already exists'); $result['message'] = $app->trans('User already exists');
$result['success'] = true; $result['success'] = true;
$result['user'] = $userFormatter($user); $result['user'] = $userFormatter($user);
} catch (\Exception $e) {
return $app->json($result);
} }
if (!$user instanceof User) {
try { try {
$password = $app['random.medium']->generateString(128); $password = $app['random.medium']->generateString(128);
@@ -544,7 +541,6 @@ class Push implements ControllerProviderInterface
} catch (\Exception $e) { } catch (\Exception $e) {
$result['message'] = $app->trans('Error while creating user'); $result['message'] = $app->trans('Error while creating user');
} }
}
return $app->json($result); return $app->json($result);
})->bind('prod_push_do_add_user'); })->bind('prod_push_do_add_user');

View File

@@ -31,9 +31,9 @@ class TaskManagerServiceProvider implements ServiceProviderInterface
}); });
$app['task-manager'] = $app->share(function (Application $app) { $app['task-manager'] = $app->share(function (Application $app) {
$options = $app['task-manager.listener.options']; $options = $app['task-manager.options'];
$manager = TaskManager::create( return TaskManager::create(
$app['dispatcher'], $app['dispatcher'],
$app['task-manager.logger'], $app['task-manager.logger'],
$app['task-manager.task-list'], $app['task-manager.task-list'],
@@ -44,9 +44,6 @@ class TaskManagerServiceProvider implements ServiceProviderInterface
'tick_period' => 1, 'tick_period' => 1,
] ]
); );
$manager->addSubscriber($app['ws.task-manager.broadcaster']);
return $manager;
}); });
$app['task-manager.logger.configuration'] = $app->share(function (Application $app) { $app['task-manager.logger.configuration'] = $app->share(function (Application $app) {

View File

@@ -1,108 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Core\CLIProvider;
use Alchemy\Phrasea\Websocket\Consumer\ConsumerManager;
use Alchemy\Phrasea\Websocket\Topics\Directive;
use Alchemy\Phrasea\Websocket\Topics\DirectivesManager;
use Alchemy\Phrasea\Websocket\Subscriber\TaskManagerBroadcasterSubscriber;
use Alchemy\Phrasea\Websocket\PhraseanetWampServer;
use Alchemy\Phrasea\Websocket\Topics\Plugin\TaskManagerSubscriberPlugin;
use Alchemy\Phrasea\Websocket\Topics\TopicsManager;
use Ratchet\App;
use Ratchet\Session\SessionProvider;
use Ratchet\Wamp\WampServer;
use Silex\Application;
use Silex\ServiceProviderInterface;
use React\EventLoop\Factory as EventLoopFactory;
class WebsocketServerServiceProvider implements ServiceProviderInterface
{
public function register(Application $app)
{
$app['ws.publisher.options'] = $app->share(function (Application $app) {
return array_replace([
'protocol' => 'tcp',
'host' => '127.0.0.1',
'port' => 13598,
], $app['conf']->get(['main', 'websocket-server', 'subscriber'], []));
});
$app['ws.task-manager.broadcaster'] = $app->share(function (Application $app) {
return TaskManagerBroadcasterSubscriber::create($app['ws.publisher.options']);
});
$app['ws.event-loop'] = $app->share(function () {
return EventLoopFactory::create();
});
$app['ws.server.subscriber'] = $app->share(function (Application $app) {
return new TaskManagerSubscriberPlugin($app['ws.publisher.options'], $app['ws.event-loop'], $app['ws.server.logger']);
});
$app['ws.server.application'] = $app->share(function (Application $app) {
return new SessionProvider(
new WampServer($app['ws.server.phraseanet-server']), $app['session.storage.handler']
);
});
$app['ws.server.phraseanet-server'] = $app->share(function (Application $app) {
return new PhraseanetWampServer($app['ws.server.topics-manager'], $app['ws.server.logger']);
});
$app['ws.server.logger'] = $app->share(function (Application $app) {
return $app['task-manager.logger'];
});
$app['ws.server.topics-manager.directives.conf'] = $app->share(function (Application $app) {
return [
new Directive(TopicsManager::TOPIC_TASK_MANAGER, true, ['task-manager']),
];
});
$app['ws.server.topics-manager.directives'] = $app->share(function (Application $app) {
return new DirectivesManager($app['ws.server.topics-manager.directives.conf']);
});
$app['ws.server.consumer-manager'] = $app->share(function (Application $app) {
return new ConsumerManager();
});
$app['ws.server.topics-manager'] = $app->share(function (Application $app) {
$manager = new TopicsManager($app['ws.server.topics-manager.directives'], $app['ws.server.consumer-manager']);
$manager->attach($app['ws.server.subscriber']);
return $manager;
});
$app['ws.server.options'] = $app->share(function (Application $app) {
return array_replace([
'host' => 'localhost',
'port' => 9090,
'ip' => '127.0.0.1',
], $app['conf']->get(['main', 'websocket-server'], []));
});
$app['ws.server'] = $app->share(function (Application $app) {
$options = $app['ws.server.options'];
$server = new App($options['host'], $options['port'], $options['ip'], $app['ws.event-loop']);
$server->route('/websockets', $app['ws.server.application']);
return $server;
});
}
public function boot(Application $app)
{
}
}

View File

@@ -34,16 +34,16 @@ class TasksServiceProvider implements ServiceProviderInterface
public function register(Application $app) public function register(Application $app)
{ {
$app['task-manager.notifier'] = $app->share(function (Application $app) { $app['task-manager.notifier'] = $app->share(function (Application $app) {
return Notifier::create($app['monolog'], $app['task-manager.listener.options']); return Notifier::create($app['monolog'], $app['task-manager.options']);
}); });
$app['task-manager.listener.options'] = $app->share(function (Application $app) { $app['task-manager.options'] = $app->share(function (Application $app) {
return array_replace([ return array_replace([
'protocol' => 'tcp', 'protocol' => 'tcp',
'host' => '127.0.0.1', 'host' => '127.0.0.1',
'port' => 6660, 'port' => 6660,
'linger' => 500, 'linger' => 500,
], $app['conf']->get(['main', 'task-manager', 'listener'], [])); ], $app['conf']->get(['main', 'task-manager', 'options'], []));
}); });
$app['task-manager.job-factory'] = $app->share(function (Application $app) { $app['task-manager.job-factory'] = $app->share(function (Application $app) {

View File

@@ -44,7 +44,7 @@ class EmailFormType extends AbstractType
'label' => 'SMTP user', 'label' => 'SMTP user',
]); ]);
$builder->add('hidden-password', 'password', [ $builder->add('hidden-password', 'password', [
'label' => false, 'label' => '',
'attr' => [ 'attr' => [
'style' => 'display:none' 'style' => 'display:none'
] ]

View File

@@ -48,7 +48,7 @@ class PhraseaAuthenticationForm extends AbstractType
if ($this->app['phraseanet.configuration']['session']['idle'] < 1) { if ($this->app['phraseanet.configuration']['session']['idle'] < 1) {
$builder->add('remember-me', 'checkbox' , [ $builder->add('remember-me', 'checkbox' , [
'label' => _('Remember me'), 'label' => 'Remember me',
'mapped' => false, 'mapped' => false,
'required' => false, 'required' => false,
'attr' => [ 'attr' => [

View File

@@ -34,7 +34,14 @@ class DatabaseHelper extends Helper
'dbname' => $db_name, 'dbname' => $db_name,
]); ]);
if (false !== $dbOK = $connection->isConnected()) { try {
$connection->connect();
$dbOK = true;
} catch (\Exception $exception) {
$dbOK = false;
}
if ($dbOK && false !== $connection->isConnected()) {
$sql = "SHOW TABLE STATUS"; $sql = "SHOW TABLE STATUS";
$stmt = $connection->prepare($sql); $stmt = $connection->prepare($sql);
$stmt->execute(); $stmt->execute();

View File

@@ -33,7 +33,7 @@ class ApiAccount
/** /**
* @var integer * @var integer
* *
* @ORM\Column(type="boolean") * @ORM\Column(type="boolean", options={"default" = 0})
*/ */
private $revoked = false; private $revoked = false;

View File

@@ -80,14 +80,14 @@ class ApiApplication
/** /**
* @var string * @var string
* *
* @ORM\Column(name="client_id", type="string", length=32, nullable=false) * @ORM\Column(name="client_id", type="string", length=128, nullable=false)
*/ */
private $clientId; private $clientId;
/** /**
* @var string * @var string
* *
* @ORM\Column(name="client_secret", type="string", length=32, nullable=false) * @ORM\Column(name="client_secret", type="string", length=128, nullable=false)
*/ */
private $clientSecret; private $clientSecret;

View File

@@ -51,7 +51,7 @@ class Basket
private $user; private $user;
/** /**
* @ORM\Column(type="boolean") * @ORM\Column(type="boolean", options={"default" = 0})
*/ */
private $is_read = false; private $is_read = false;
@@ -64,7 +64,7 @@ class Basket
private $pusher; private $pusher;
/** /**
* @ORM\Column(type="boolean") * @ORM\Column(type="boolean", options={"default" = 0})
*/ */
private $archived = false; private $archived = false;

View File

@@ -30,12 +30,12 @@ class Feed implements FeedInterface
private $id; private $id;
/** /**
* @ORM\Column(type="boolean") * @ORM\Column(type="boolean", options={"default" = 0})
*/ */
private $public = false; private $public = false;
/** /**
* @ORM\Column(type="boolean", name="icon_url") * @ORM\Column(type="boolean", name="icon_url", options={"default" = 0})
*/ */
private $iconUrl = false; private $iconUrl = false;

View File

@@ -36,7 +36,7 @@ class FeedPublisher
private $user; private $user;
/** /**
* @ORM\Column(type="boolean") * @ORM\Column(type="boolean", options={"default" = 0})
*/ */
private $owner = false; private $owner = false;

View File

@@ -34,47 +34,47 @@ class FtpCredential
private $user; private $user;
/** /**
* @ORM\Column(type="boolean") * @ORM\Column(type="boolean", options={"default" = 0})
*/ */
private $active = false; private $active = false;
/** /**
* @ORM\Column(type="string", length=128) * @ORM\Column(type="string", length=128, options={"default" = ""})
*/ */
private $address = ''; private $address = '';
/** /**
* @ORM\Column(type="string", length=128) * @ORM\Column(type="string", length=128, options={"default" = ""})
*/ */
private $login = ''; private $login = '';
/** /**
* @ORM\Column(type="string", length=128) * @ORM\Column(type="string", length=128, options={"default" = ""})
*/ */
private $password = ''; private $password = '';
/** /**
* @ORM\Column(type="string", length=128, name="reception_folder") * @ORM\Column(type="string", length=128, name="reception_folder", options={"default" = ""})
*/ */
private $receptionFolder = ''; private $receptionFolder = '';
/** /**
* @ORM\Column(type="string", length=128, name="repository_prefix_name") * @ORM\Column(type="string", length=128, name="repository_prefix_name", options={"default" = ""})
*/ */
private $repositoryPrefixName = ''; private $repositoryPrefixName = '';
/** /**
* @ORM\Column(type="boolean") * @ORM\Column(type="boolean", options={"default" = 0})
*/ */
private $passive = false; private $passive = false;
/** /**
* @ORM\Column(type="boolean", name="tls") * @ORM\Column(type="boolean", name="tls", options={"default" = 0})
*/ */
private $ssl = false; private $ssl = false;
/** /**
* @ORM\Column(type="integer", name="max_retry") * @ORM\Column(type="integer", name="max_retry", options={"default" = 5})
*/ */
private $maxRetry = 5; private $maxRetry = 5;

View File

@@ -29,62 +29,62 @@ class FtpExport
private $id; private $id;
/** /**
* @ORM\Column(type="integer") * @ORM\Column(type="integer", options={"default" = 0})
*/ */
private $crash = 0; private $crash = 0;
/** /**
* @ORM\Column(type="integer") * @ORM\Column(type="integer", options={"default" = 3})
*/ */
private $nbretry = 3; private $nbretry = 3;
/** /**
* @ORM\Column(type="text", nullable=true) * @ORM\Column(type="string", length=128, nullable=true)
*/ */
private $mail; private $mail;
/** /**
* @ORM\Column(type="text") * @ORM\Column(type="string", length=128)
*/ */
private $addr; private $addr;
/** /**
* @ORM\Column(type="boolean", name="use_ssl") * @ORM\Column(type="boolean", name="use_ssl", options={"default" = 0})
*/ */
private $ssl = false; private $ssl = false;
/** /**
* @ORM\Column(type="text", nullable=true) * @ORM\Column(type="string", length=128, nullable=true)
*/ */
private $login; private $login;
/** /**
* @ORM\Column(type="text", nullable=true) * @ORM\Column(type="string", length=128, nullable=true)
*/ */
private $pwd; private $pwd;
/** /**
* @ORM\Column(type="boolean") * @ORM\Column(type="boolean", options={"default" = 0})
*/ */
private $passif = false; private $passif = false;
/** /**
* @ORM\Column(type="text") * @ORM\Column(type="string", length=128, options={"default" = "/"})
*/ */
private $destfolder = '/'; private $destfolder = '/';
/** /**
* @ORM\Column(type="text", nullable=true) * @ORM\Column(type="string", length=128, nullable=true, options={"default" = 1})
*/ */
private $sendermail; private $sendermail;
/** /**
* @ORM\Column(type="text", name="text_mail_sender", nullable=true) * @ORM\Column(type="string", length=128, name="text_mail_sender", nullable=true)
*/ */
private $textMailSender; private $textMailSender;
/** /**
* @ORM\Column(type="text", name="text_mail_receiver", nullable=true) * @ORM\Column(type="string", length=128, name="text_mail_receiver", nullable=true)
*/ */
private $textMailReceiver; private $textMailReceiver;
@@ -97,12 +97,12 @@ class FtpExport
private $user; private $user;
/** /**
* @ORM\Column(type="text", nullable=true) * @ORM\Column(type="string", length=128, nullable=true)
*/ */
private $foldertocreate; private $foldertocreate;
/** /**
* @ORM\Column(type="boolean") * @ORM\Column(type="boolean", options={"default" = 0})
*/ */
private $logfile = false; private $logfile = false;

View File

@@ -63,12 +63,12 @@ class FtpExportElement
/** /**
* @var Boolean * @var Boolean
* @ORM\Column(type="boolean") * @ORM\Column(type="boolean", options={"default" = 0})
*/ */
private $error = false; private $error = false;
/** /**
* @ORM\Column(type="boolean") * @ORM\Column(type="boolean", options={"default" = 0})
*/ */
private $done = false; private $done = false;
@@ -79,7 +79,7 @@ class FtpExportElement
private $export; private $export;
/** /**
* @ORM\Column(type="boolean") * @ORM\Column(type="boolean", options={"default" = 0})
*/ */
private $businessfields = false; private $businessfields = false;

View File

@@ -59,7 +59,7 @@ class LazaretFile
private $sha256; private $sha256;
/** /**
* @ORM\Column(type="boolean") * @ORM\Column(type="boolean", options={"default" = 0})
*/ */
private $forced = false; private $forced = false;

View File

@@ -44,12 +44,12 @@ class Registration
private $baseId; private $baseId;
/** /**
* @ORM\Column(type="boolean", name="pending") * @ORM\Column(type="boolean", name="pending", options={"default" = 1})
*/ */
private $pending = true; private $pending = true;
/** /**
* @ORM\Column(type="boolean", name="rejected") * @ORM\Column(type="boolean", name="rejected", options={"default" = 0})
*/ */
private $rejected = false; private $rejected = false;

View File

@@ -47,22 +47,22 @@ class Task
private $settings = '<?xml version="1.0" encoding="UTF-8"?><tasksettings></tasksettings>'; private $settings = '<?xml version="1.0" encoding="UTF-8"?><tasksettings></tasksettings>';
/** /**
* @ORM\Column(type="boolean") * @ORM\Column(type="boolean", options={"default" = 0})
*/ */
private $completed = false; private $completed = false;
/** /**
* @ORM\Column(type="string") * @ORM\Column(type="string", options={"default" = "started"})
*/ */
private $status = self::STATUS_STARTED; private $status = self::STATUS_STARTED;
/** /**
* @ORM\Column(type="integer") * @ORM\Column(type="integer", options={"default" = 0})
*/ */
private $crashed = 0; private $crashed = 0;
/** /**
* @ORM\Column(type="boolean", name="single_run") * @ORM\Column(type="boolean", name="single_run", options={"default" = 0})
*/ */
private $singleRun = false; private $singleRun = false;
@@ -84,7 +84,7 @@ class Task
private $lastExecution; private $lastExecution;
/** /**
* @ORM\Column(type="integer") * @ORM\Column(type="integer", options={"default" = 0})
*/ */
private $period = 0; private $period = 0;

View File

@@ -22,7 +22,7 @@ class Token
{ {
/** /**
* @ORM\Id * @ORM\Id
* @ORM\Column(type="string", length=16) * @ORM\Column(type="string", length=128)
*/ */
private $value; private $value;

View File

@@ -73,17 +73,17 @@ class User
private $nonce; private $nonce;
/** /**
* @ORM\Column(type="boolean", name="salted_password") * @ORM\Column(type="boolean", name="salted_password", options={"default" = 1})
*/ */
private $saltedPassword = true; private $saltedPassword = true;
/** /**
* @ORM\Column(type="string", length=64, name="first_name") * @ORM\Column(type="string", length=64, name="first_name", options={"default" = ""})
*/ */
private $firstName = ''; private $firstName = '';
/** /**
* @ORM\Column(type="string", length=64, name="last_name") * @ORM\Column(type="string", length=64, name="last_name", options={"default" = ""})
*/ */
private $lastName = ''; private $lastName = '';
@@ -93,22 +93,22 @@ class User
private $gender; private $gender;
/** /**
* @ORM\Column(type="text") * @ORM\Column(type="string", length=255, options={"default" = ""})
*/ */
private $address = ''; private $address = '';
/** /**
* @ORM\Column(type="string", length=64) * @ORM\Column(type="string", length=64, options={"default" = ""})
*/ */
private $city = ''; private $city = '';
/** /**
* @ORM\Column(type="string", length=64, nullable=true) * @ORM\Column(type="string", length=64, nullable=true, options={"default" = ""})
*/ */
private $country = ''; private $country = '';
/** /**
* @ORM\Column(type="string", length=32, name="zip_code") * @ORM\Column(type="string", length=32, name="zip_code", options={"default" = ""})
*/ */
private $zipCode = ''; private $zipCode = '';
@@ -123,57 +123,57 @@ class User
private $locale; private $locale;
/** /**
* @ORM\Column(type="string", length=128) * @ORM\Column(type="string", length=128, options={"default" = ""})
*/ */
private $timezone = ''; private $timezone = '';
/** /**
* @ORM\Column(type="string", length=128) * @ORM\Column(type="string", length=128, options={"default" = ""})
*/ */
private $job = ''; private $job = '';
/** /**
* @ORM\Column(type="string", length=256) * @ORM\Column(type="string", length=256, options={"default" = ""})
*/ */
private $activity = ''; private $activity = '';
/** /**
* @ORM\Column(type="string", length=64) * @ORM\Column(type="string", length=64, options={"default" = ""})
*/ */
private $company = ''; private $company = '';
/** /**
* @ORM\Column(type="string", length=32) * @ORM\Column(type="string", length=32, options={"default" = ""})
*/ */
private $phone = ''; private $phone = '';
/** /**
* @ORM\Column(type="string", length=32) * @ORM\Column(type="string", length=32, options={"default" = ""})
*/ */
private $fax = ''; private $fax = '';
/** /**
* @ORM\Column(type="boolean") * @ORM\Column(type="boolean", options={"default" = 0})
*/ */
private $admin = false; private $admin = false;
/** /**
* @ORM\Column(type="boolean") * @ORM\Column(type="boolean", options={"default" = 0})
*/ */
private $guest = false; private $guest = false;
/** /**
* @ORM\Column(type="boolean", name="mail_notifications") * @ORM\Column(type="boolean", name="mail_notifications", options={"default" = 0})
*/ */
private $mailNotificationsActivated = false; private $mailNotificationsActivated = false;
/** /**
* @ORM\Column(type="boolean", name="request_notifications") * @ORM\Column(type="boolean", name="request_notifications", options={"default" = 0})
*/ */
private $requestNotificationsActivated = false; private $requestNotificationsActivated = false;
/** /**
* @ORM\Column(type="boolean", name="ldap_created") * @ORM\Column(type="boolean", name="ldap_created", options={"default" = 0})
*/ */
private $ldapCreated = false; private $ldapCreated = false;
@@ -184,17 +184,17 @@ class User
private $lastAppliedTemplate; private $lastAppliedTemplate;
/** /**
* @ORM\Column(type="text", name="push_list") * @ORM\Column(type="string", length=255, name="push_list", options={"default" = ""})
*/ */
private $pushList = ''; private $pushList = '';
/** /**
* @ORM\Column(type="boolean", name="can_change_profil") * @ORM\Column(type="boolean", name="can_change_profil", options={"default" = 1})
*/ */
private $canChangeProfil = true; private $canChangeProfil = true;
/** /**
* @ORM\Column(type="boolean", name="can_change_ftp_profil") * @ORM\Column(type="boolean", name="can_change_ftp_profil", options={"default" = 1})
*/ */
private $canChangeFtpProfil = true; private $canChangeFtpProfil = true;
@@ -204,12 +204,12 @@ class User
private $lastConnection; private $lastConnection;
/** /**
* @ORM\Column(type="boolean", name="mail_locked") * @ORM\Column(type="boolean", name="mail_locked", options={"default" = 0})
*/ */
private $mailLocked = false; private $mailLocked = false;
/** /**
* @ORM\Column(type="boolean") * @ORM\Column(type="boolean", options={"default" = 0})
*/ */
private $deleted = false; private $deleted = false;

View File

@@ -27,22 +27,22 @@ class ValidationParticipant
private $id; private $id;
/** /**
* @ORM\Column(type="boolean") * @ORM\Column(type="boolean", options={"default" = 0})
*/ */
private $is_aware = false; private $is_aware = false;
/** /**
* @ORM\Column(type="boolean") * @ORM\Column(type="boolean", options={"default" = 0})
*/ */
private $is_confirmed = false; private $is_confirmed = false;
/** /**
* @ORM\Column(type="boolean") * @ORM\Column(type="boolean", options={"default" = 0})
*/ */
private $can_agree = false; private $can_agree = false;
/** /**
* @ORM\Column(type="boolean") * @ORM\Column(type="boolean", options={"default" = 0})
*/ */
private $can_see_others = false; private $can_see_others = false;

View File

@@ -41,7 +41,7 @@ class WebhookEvent
/** /**
* @var boolean * @var boolean
* *
* @ORM\Column(type="boolean", nullable=false) * @ORM\Column(type="boolean", nullable=false, options={"default" = 0})
*/ */
private $processed = false; private $processed = false;

View File

@@ -41,12 +41,12 @@ class WebhookEventDelivery
private $event; private $event;
/** /**
* @ORM\Column(type="boolean", nullable=false) * @ORM\Column(type="boolean", nullable=false, options={"default" = 0})
*/ */
private $delivered = false; private $delivered = false;
/** /**
* @ORM\Column(type="integer", nullable=false) * @ORM\Column(type="integer", nullable=false, options={"default" = 0})
*/ */
private $deliveryTries = 0; private $deliveryTries = 0;

View File

@@ -35,10 +35,22 @@ class ApiMigration extends AbstractMigration
$this->addSql("ALTER TABLE ApiOauthTokens ADD CONSTRAINT FK_4FD469539B6B5FBA FOREIGN KEY (account_id) REFERENCES ApiAccounts (id)"); $this->addSql("ALTER TABLE ApiOauthTokens ADD CONSTRAINT FK_4FD469539B6B5FBA FOREIGN KEY (account_id) REFERENCES ApiAccounts (id)");
$this->addSql("ALTER TABLE ApiAccounts ADD CONSTRAINT FK_2C54E637A76ED395 FOREIGN KEY (user_id) REFERENCES Users (id)"); $this->addSql("ALTER TABLE ApiAccounts ADD CONSTRAINT FK_2C54E637A76ED395 FOREIGN KEY (user_id) REFERENCES Users (id)");
$this->addSql("ALTER TABLE ApiAccounts ADD CONSTRAINT FK_2C54E6373E030ACD FOREIGN KEY (application_id) REFERENCES ApiApplications (id)"); $this->addSql("ALTER TABLE ApiAccounts ADD CONSTRAINT FK_2C54E6373E030ACD FOREIGN KEY (application_id) REFERENCES ApiApplications (id)");
$this->addSql('ALTER TABLE ApiAccounts CHANGE revoked revoked TINYINT(1) DEFAULT \'0\' NOT NULL');
$this->addSql('ALTER TABLE ApiApplications CHANGE client_id client_id VARCHAR(128) NOT NULL, CHANGE client_secret client_secret VARCHAR(128) NOT NULL');
$this->addSql('ALTER TABLE ApiOauthCodes CHANGE expires expires INT NOT NULL');
$this->addSql('ALTER TABLE ApiOauthRefreshTokens CHANGE expires expires INT NOT NULL');
$this->addSql('ALTER TABLE ApiOauthTokens CHANGE expires expires INT DEFAULT NULL');
} }
public function doDownSql(Schema $schema) public function doDownSql(Schema $schema)
{ {
$this->addSql('ALTER TABLE ApiAccounts CHANGE revoked revoked TINYINT(1) NOT NULL');
$this->addSql('ALTER TABLE ApiApplications CHANGE client_id client_id VARCHAR(32) NOT NULL, CHANGE client_secret client_secret VARCHAR(32) NOT NULL');
$this->addSql('ALTER TABLE ApiOauthCodes CHANGE expires expires DATETIME DEFAULT NULL');
$this->addSql('ALTER TABLE ApiOauthRefreshTokens CHANGE expires expires DATETIME NOT NULL');
$this->addSql('ALTER TABLE ApiOauthTokens CHANGE expires expires DATETIME DEFAULT NULL');
$this->addSql("ALTER TABLE ApiAccounts DROP FOREIGN KEY FK_2C54E6373E030ACD"); $this->addSql("ALTER TABLE ApiAccounts DROP FOREIGN KEY FK_2C54E6373E030ACD");
$this->addSql("ALTER TABLE ApiLogs DROP FOREIGN KEY FK_91E90F309B6B5FBA"); $this->addSql("ALTER TABLE ApiLogs DROP FOREIGN KEY FK_91E90F309B6B5FBA");
$this->addSql("ALTER TABLE ApiOauthCodes DROP FOREIGN KEY FK_BE6B11809B6B5FBA"); $this->addSql("ALTER TABLE ApiOauthCodes DROP FOREIGN KEY FK_BE6B11809B6B5FBA");

View File

@@ -34,10 +34,18 @@ class FeedMigration extends AbstractMigration
$this->addSql("ALTER TABLE FeedItems ADD CONSTRAINT FK_7F9CDFA6BA364942 FOREIGN KEY (entry_id) REFERENCES FeedEntries (id)"); $this->addSql("ALTER TABLE FeedItems ADD CONSTRAINT FK_7F9CDFA6BA364942 FOREIGN KEY (entry_id) REFERENCES FeedEntries (id)");
$this->addSql("ALTER TABLE FeedTokens ADD CONSTRAINT FK_9D1CA848A76ED395 FOREIGN KEY (user_id) REFERENCES Users (id)"); $this->addSql("ALTER TABLE FeedTokens ADD CONSTRAINT FK_9D1CA848A76ED395 FOREIGN KEY (user_id) REFERENCES Users (id)");
$this->addSql("ALTER TABLE FeedTokens ADD CONSTRAINT FK_9D1CA84851A5BC03 FOREIGN KEY (feed_id) REFERENCES Feeds (id)"); $this->addSql("ALTER TABLE FeedTokens ADD CONSTRAINT FK_9D1CA84851A5BC03 FOREIGN KEY (feed_id) REFERENCES Feeds (id)");
$this->addSql('ALTER TABLE Feeds CHANGE public public TINYINT(1) DEFAULT \'0\' NOT NULL, CHANGE icon_url icon_url TINYINT(1) DEFAULT \'0\' NOT NULL');
$this->addSql('ALTER TABLE FeedPublishers CHANGE owner owner TINYINT(1) DEFAULT \'0\' NOT NULL');
$this->addSql('ALTER TABLE FeedTokens CHANGE value value VARCHAR(64) DEFAULT NULL');
} }
public function doDownSql(Schema $schema) public function doDownSql(Schema $schema)
{ {
$this->addSql('ALTER TABLE FeedPublishers CHANGE owner owner TINYINT(1) NOT NULL');
$this->addSql('ALTER TABLE FeedTokens CHANGE value value VARCHAR(12) DEFAULT NULL');
$this->addSql('ALTER TABLE Feeds CHANGE public public TINYINT(1) NOT NULL, CHANGE icon_url icon_url TINYINT(1) NOT NULL');
$this->addSql("ALTER TABLE FeedPublishers DROP FOREIGN KEY FK_31AFAB251A5BC03"); $this->addSql("ALTER TABLE FeedPublishers DROP FOREIGN KEY FK_31AFAB251A5BC03");
$this->addSql("ALTER TABLE FeedEntries DROP FOREIGN KEY FK_5FC892F951A5BC03"); $this->addSql("ALTER TABLE FeedEntries DROP FOREIGN KEY FK_5FC892F951A5BC03");
$this->addSql("ALTER TABLE FeedTokens DROP FOREIGN KEY FK_9D1CA84851A5BC03"); $this->addSql("ALTER TABLE FeedTokens DROP FOREIGN KEY FK_9D1CA84851A5BC03");

View File

@@ -24,10 +24,12 @@ class FtpCredentialMigration extends AbstractMigration
{ {
$this->addSql("CREATE TABLE FtpCredential (id INT AUTO_INCREMENT NOT NULL, user_id INT NOT NULL, active TINYINT(1) NOT NULL, address VARCHAR(128) NOT NULL, login VARCHAR(128) NOT NULL, password VARCHAR(128) NOT NULL, reception_folder VARCHAR(128) NOT NULL, repository_prefix_name VARCHAR(128) NOT NULL, passive TINYINT(1) NOT NULL, tls TINYINT(1) NOT NULL, max_retry INT NOT NULL, updated DATETIME NOT NULL, UNIQUE INDEX UNIQ_62DA9661A76ED395 (user_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB"); $this->addSql("CREATE TABLE FtpCredential (id INT AUTO_INCREMENT NOT NULL, user_id INT NOT NULL, active TINYINT(1) NOT NULL, address VARCHAR(128) NOT NULL, login VARCHAR(128) NOT NULL, password VARCHAR(128) NOT NULL, reception_folder VARCHAR(128) NOT NULL, repository_prefix_name VARCHAR(128) NOT NULL, passive TINYINT(1) NOT NULL, tls TINYINT(1) NOT NULL, max_retry INT NOT NULL, updated DATETIME NOT NULL, UNIQUE INDEX UNIQ_62DA9661A76ED395 (user_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB");
$this->addSql("ALTER TABLE FtpCredential ADD CONSTRAINT FK_62DA9661A76ED395 FOREIGN KEY (user_id) REFERENCES Users (id)"); $this->addSql("ALTER TABLE FtpCredential ADD CONSTRAINT FK_62DA9661A76ED395 FOREIGN KEY (user_id) REFERENCES Users (id)");
$this->addSql('ALTER TABLE FtpCredential CHANGE active active TINYINT(1) DEFAULT \'0\' NOT NULL, CHANGE address address VARCHAR(128) DEFAULT \'\' NOT NULL, CHANGE login login VARCHAR(128) DEFAULT \'\' NOT NULL, CHANGE password password VARCHAR(128) DEFAULT \'\' NOT NULL, CHANGE reception_folder reception_folder VARCHAR(128) DEFAULT \'\' NOT NULL, CHANGE repository_prefix_name repository_prefix_name VARCHAR(128) DEFAULT \'\' NOT NULL, CHANGE passive passive TINYINT(1) DEFAULT \'0\' NOT NULL, CHANGE tls tls TINYINT(1) DEFAULT \'0\' NOT NULL, CHANGE max_retry max_retry INT DEFAULT 5 NOT NULL');
} }
public function doDownSql(Schema $schema) public function doDownSql(Schema $schema)
{ {
$this->addSql('ALTER TABLE FtpCredential CHANGE active active TINYINT(1) NOT NULL, CHANGE address address VARCHAR(128) NOT NULL, CHANGE login login VARCHAR(128) NOT NULL, CHANGE password password VARCHAR(128) NOT NULL, CHANGE reception_folder reception_folder VARCHAR(128) NOT NULL, CHANGE repository_prefix_name repository_prefix_name VARCHAR(128) NOT NULL, CHANGE passive passive TINYINT(1) NOT NULL, CHANGE tls tls TINYINT(1) NOT NULL, CHANGE max_retry max_retry INT NOT NULL');
$this->addSql("DROP TABLE FtpCredential"); $this->addSql("DROP TABLE FtpCredential");
} }
} }

View File

@@ -25,10 +25,12 @@ class UserMigration extends AbstractMigration
$this->addSql("CREATE TABLE Users (id INT AUTO_INCREMENT NOT NULL, last_model INT DEFAULT NULL, model_of INT DEFAULT NULL, login VARCHAR(128) NOT NULL, email VARCHAR(128) DEFAULT NULL, password VARCHAR(128) DEFAULT NULL, nonce VARCHAR(64) DEFAULT NULL, salted_password TINYINT(1) NOT NULL, first_name VARCHAR(64) NOT NULL, last_name VARCHAR(64) NOT NULL, gender SMALLINT DEFAULT NULL, address LONGTEXT NOT NULL, city VARCHAR(64) NOT NULL, country VARCHAR(64) DEFAULT NULL, zip_code VARCHAR(32) NOT NULL, geoname_id INT DEFAULT NULL, locale VARCHAR(8) DEFAULT NULL, timezone VARCHAR(128) NOT NULL, job VARCHAR(128) NOT NULL, activity VARCHAR(256) NOT NULL, company VARCHAR(64) NOT NULL, phone VARCHAR(32) NOT NULL, fax VARCHAR(32) NOT NULL, admin TINYINT(1) NOT NULL, guest TINYINT(1) NOT NULL, mail_notifications TINYINT(1) NOT NULL, request_notifications TINYINT(1) NOT NULL, ldap_created TINYINT(1) NOT NULL, push_list LONGTEXT NOT NULL, can_change_profil TINYINT(1) NOT NULL, can_change_ftp_profil TINYINT(1) NOT NULL, last_connection DATETIME DEFAULT NULL, mail_locked TINYINT(1) NOT NULL, deleted TINYINT(1) NOT NULL, created DATETIME NOT NULL, updated DATETIME NOT NULL, INDEX IDX_D5428AEDB5DE44C2 (last_model), INDEX IDX_D5428AEDC121714D (model_of), INDEX salted_password (salted_password), INDEX admin (admin), INDEX guest (guest), UNIQUE INDEX email_unique (email), UNIQUE INDEX login_unique (login), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB"); $this->addSql("CREATE TABLE Users (id INT AUTO_INCREMENT NOT NULL, last_model INT DEFAULT NULL, model_of INT DEFAULT NULL, login VARCHAR(128) NOT NULL, email VARCHAR(128) DEFAULT NULL, password VARCHAR(128) DEFAULT NULL, nonce VARCHAR(64) DEFAULT NULL, salted_password TINYINT(1) NOT NULL, first_name VARCHAR(64) NOT NULL, last_name VARCHAR(64) NOT NULL, gender SMALLINT DEFAULT NULL, address LONGTEXT NOT NULL, city VARCHAR(64) NOT NULL, country VARCHAR(64) DEFAULT NULL, zip_code VARCHAR(32) NOT NULL, geoname_id INT DEFAULT NULL, locale VARCHAR(8) DEFAULT NULL, timezone VARCHAR(128) NOT NULL, job VARCHAR(128) NOT NULL, activity VARCHAR(256) NOT NULL, company VARCHAR(64) NOT NULL, phone VARCHAR(32) NOT NULL, fax VARCHAR(32) NOT NULL, admin TINYINT(1) NOT NULL, guest TINYINT(1) NOT NULL, mail_notifications TINYINT(1) NOT NULL, request_notifications TINYINT(1) NOT NULL, ldap_created TINYINT(1) NOT NULL, push_list LONGTEXT NOT NULL, can_change_profil TINYINT(1) NOT NULL, can_change_ftp_profil TINYINT(1) NOT NULL, last_connection DATETIME DEFAULT NULL, mail_locked TINYINT(1) NOT NULL, deleted TINYINT(1) NOT NULL, created DATETIME NOT NULL, updated DATETIME NOT NULL, INDEX IDX_D5428AEDB5DE44C2 (last_model), INDEX IDX_D5428AEDC121714D (model_of), INDEX salted_password (salted_password), INDEX admin (admin), INDEX guest (guest), UNIQUE INDEX email_unique (email), UNIQUE INDEX login_unique (login), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB");
$this->addSql("ALTER TABLE Users ADD CONSTRAINT FK_D5428AEDB5DE44C2 FOREIGN KEY (last_model) REFERENCES Users (id)"); $this->addSql("ALTER TABLE Users ADD CONSTRAINT FK_D5428AEDB5DE44C2 FOREIGN KEY (last_model) REFERENCES Users (id)");
$this->addSql("ALTER TABLE Users ADD CONSTRAINT FK_D5428AEDC121714D FOREIGN KEY (model_of) REFERENCES Users (id)"); $this->addSql("ALTER TABLE Users ADD CONSTRAINT FK_D5428AEDC121714D FOREIGN KEY (model_of) REFERENCES Users (id)");
$this->addSql('ALTER TABLE Users CHANGE login login VARCHAR(128) COLLATE utf8_bin NOT NULL, CHANGE password password VARCHAR(128) COLLATE utf8_bin DEFAULT NULL, CHANGE nonce nonce VARCHAR(64) COLLATE utf8_bin DEFAULT NULL, CHANGE salted_password salted_password TINYINT(1) DEFAULT \'1\' NOT NULL, CHANGE first_name first_name VARCHAR(64) DEFAULT \'\' NOT NULL, CHANGE last_name last_name VARCHAR(64) DEFAULT \'\' NOT NULL, CHANGE address address VARCHAR(255) DEFAULT \'\' NOT NULL, CHANGE city city VARCHAR(64) DEFAULT \'\' NOT NULL, CHANGE country country VARCHAR(64) DEFAULT \'\', CHANGE zip_code zip_code VARCHAR(32) DEFAULT \'\' NOT NULL, CHANGE timezone timezone VARCHAR(128) DEFAULT \'\' NOT NULL, CHANGE job job VARCHAR(128) DEFAULT \'\' NOT NULL, CHANGE activity activity VARCHAR(256) DEFAULT \'\' NOT NULL, CHANGE company company VARCHAR(64) DEFAULT \'\' NOT NULL, CHANGE phone phone VARCHAR(32) DEFAULT \'\' NOT NULL, CHANGE fax fax VARCHAR(32) DEFAULT \'\' NOT NULL, CHANGE admin admin TINYINT(1) DEFAULT \'0\' NOT NULL, CHANGE guest guest TINYINT(1) DEFAULT \'0\' NOT NULL, CHANGE mail_notifications mail_notifications TINYINT(1) DEFAULT \'0\' NOT NULL, CHANGE request_notifications request_notifications TINYINT(1) DEFAULT \'0\' NOT NULL, CHANGE ldap_created ldap_created TINYINT(1) DEFAULT \'0\' NOT NULL, CHANGE push_list push_list VARCHAR(255) DEFAULT \'\' NOT NULL, CHANGE can_change_profil can_change_profil TINYINT(1) DEFAULT \'1\' NOT NULL, CHANGE can_change_ftp_profil can_change_ftp_profil TINYINT(1) DEFAULT \'1\' NOT NULL, CHANGE mail_locked mail_locked TINYINT(1) DEFAULT \'0\' NOT NULL, CHANGE deleted deleted TINYINT(1) DEFAULT \'0\' NOT NULL');
} }
public function doDownSql(Schema $schema) public function doDownSql(Schema $schema)
{ {
$this->addSql('ALTER TABLE Users CHANGE login login VARCHAR(128) NOT NULL, CHANGE password password VARCHAR(128) DEFAULT NULL, CHANGE nonce nonce VARCHAR(64) DEFAULT NULL, CHANGE salted_password salted_password TINYINT(1) NOT NULL, CHANGE first_name first_name VARCHAR(64) NOT NULL, CHANGE last_name last_name VARCHAR(64) NOT NULL, CHANGE address address LONGTEXT NOT NULL, CHANGE city city VARCHAR(64) NOT NULL, CHANGE country country VARCHAR(64) DEFAULT NULL, CHANGE zip_code zip_code VARCHAR(32) NOT NULL, CHANGE timezone timezone VARCHAR(128) NOT NULL, CHANGE job job VARCHAR(128) NOT NULL, CHANGE activity activity VARCHAR(256) NOT NULL, CHANGE company company VARCHAR(64) NOT NULL, CHANGE phone phone VARCHAR(32) NOT NULL, CHANGE fax fax VARCHAR(32) NOT NULL, CHANGE admin admin TINYINT(1) NOT NULL, CHANGE guest guest TINYINT(1) NOT NULL, CHANGE mail_notifications mail_notifications TINYINT(1) NOT NULL, CHANGE request_notifications request_notifications TINYINT(1) NOT NULL, CHANGE ldap_created ldap_created TINYINT(1) NOT NULL, CHANGE push_list push_list LONGTEXT NOT NULL, CHANGE can_change_profil can_change_profil TINYINT(1) NOT NULL, CHANGE can_change_ftp_profil can_change_ftp_profil TINYINT(1) NOT NULL, CHANGE mail_locked mail_locked TINYINT(1) NOT NULL, CHANGE deleted deleted TINYINT(1) NOT NULL');
$this->addSql("ALTER TABLE Users DROP FOREIGN KEY FK_D5428AEDB5DE44C2"); $this->addSql("ALTER TABLE Users DROP FOREIGN KEY FK_D5428AEDB5DE44C2");
$this->addSql("ALTER TABLE Users DROP FOREIGN KEY FK_D5428AEDC121714D"); $this->addSql("ALTER TABLE Users DROP FOREIGN KEY FK_D5428AEDC121714D");
$this->addSql("DROP TABLE Users"); $this->addSql("DROP TABLE Users");

View File

@@ -242,12 +242,6 @@ class SystemRequirements extends RequirementCollection implements RequirementInt
'Install and enable the <strong>twig</strong> extension.' 'Install and enable the <strong>twig</strong> extension.'
); );
$this->addRecommendation(
function_exists('event_base_new'),
'LibEvent extension is strongly recommended in production',
'Install and enable the <strong>LibEvent</strong> extension.'
);
$this->addRequirement( $this->addRequirement(
extension_loaded('zmq'), extension_loaded('zmq'),
'ZMQ extension is required.', 'ZMQ extension is required.',

View File

@@ -339,7 +339,7 @@ class Upgrade39Users implements PreSchemaUpgradeInterface
mail_locked, last_model, mail_notifications, nonce, mail_locked, last_model, mail_notifications, nonce,
password, push_list, request_notifications, salted_password, password, push_list, request_notifications, salted_password,
gender, phone, timezone, zip_code, gender, phone, timezone, zip_code,
created, updated created, updated, deleted
) )
( (
SELECT SELECT
@@ -351,7 +351,7 @@ class Upgrade39Users implements PreSchemaUpgradeInterface
mail_locked, NULL AS lastModel, mail_notifications, '.($this->hasField($em, 'nonce') ? 'nonce' : 'NULL AS nonce').', mail_locked, NULL AS lastModel, mail_notifications, '.($this->hasField($em, 'nonce') ? 'nonce' : 'NULL AS nonce').',
usr_password, push_list, request_notifications, '.($this->hasField($em, 'salted_password') ? 'salted_password' : '0 AS salted_password').', usr_password, push_list, request_notifications, '.($this->hasField($em, 'salted_password') ? 'salted_password' : '0 AS salted_password').',
usr_sexe, tel, timezone, cpostal, usr_sexe, tel, timezone, cpostal,
usr_creationdate, usr_modificationdate usr_creationdate, usr_modificationdate, 0
FROM usr FROM usr
)' )'
); );

View File

@@ -1,43 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Websocket\Consumer;
/**
* Websocket consumer
*/
class Consumer implements ConsumerInterface
{
private $usrId;
private $rights;
public function __construct($usrId, array $rights)
{
$this->usrId = $usrId;
$this->rights = $rights;
}
/**
* {@inheritdoc}
*/
public function isAuthenticated()
{
return $this->usrId !== null;
}
/**
* {@inheritdoc}
*/
public function hasRights($rights)
{
return count(array_intersect($this->rights, (array) $rights)) === count($rights);
}
}

View File

@@ -1,31 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Websocket\Consumer;
interface ConsumerInterface
{
/**
* Return true if the consumer is authenticated in Phraseanet
*
* @return Boolean
*/
public function isAuthenticated();
/**
* Return true if the user has the given rights
*
* @param string\array $rights A right or an array of rights
*
* @return Boolean
*/
public function hasRights($rights);
}

View File

@@ -1,32 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Websocket\Consumer;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
class ConsumerManager
{
/**
* Creates a consumer given a Session
*
* @param Session $session
*
* @return Consumer
*/
public function create(SessionInterface $session)
{
$usrId = $session->has('usr_id') ? $session->get('usr_id') : null;
$rights = $session->has('websockets_rights') ? $session->get('websockets_rights') : [];
return new Consumer($usrId, $rights);;
}
}

View File

@@ -1,94 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Websocket;
use Alchemy\Phrasea\Websocket\Topics\TopicsManager;
use Psr\Log\LoggerInterface;
use Ratchet\ConnectionInterface as Conn;
use Ratchet\Wamp\WampServerInterface;
class PhraseanetWampServer implements WampServerInterface
{
private $logger;
private $manager;
public function __construct(TopicsManager $manager, LoggerInterface $logger)
{
$this->logger = $logger;
$this->manager = $manager;
}
/**
* {@inheritdoc}
*/
public function onPublish(Conn $conn, $topic, $event, array $exclude, array $eligible)
{
$this->logger->error(sprintf('Publishing on topic %s', $topic->getId()), ['event' => $event, 'topic' => $topic]);
$topic->broadcast($event);
}
/**
* {@inheritdoc}
*/
public function onCall(Conn $conn, $id, $topic, array $params)
{
$this->logger->error(sprintf('Received RPC call on topic %s', $topic->getId()), ['topic' => $topic]);
$conn->callError($id, $topic, 'RPC not supported on this demo');
}
/**
* {@inheritdoc}
*/
public function onSubscribe(Conn $conn, $topic)
{
if ($this->manager->subscribe($conn, $topic)) {
$this->logger->debug(sprintf('Subscription received on topic %s', $topic->getId()), ['topic' => $topic]);
} else {
$this->logger->error(sprintf('Subscription received on topic %s, user is not allowed', $topic->getId()), ['topic' => $topic]);
}
}
/**
* {@inheritdoc}
*/
public function onUnSubscribe(Conn $conn, $topic)
{
$this->logger->debug(sprintf('Unsubscription received on topic %s', $topic->getId()), ['topic' => $topic]);
$this->manager->unsubscribe($conn, $topic);
}
/**
* {@inheritdoc}
*/
public function onOpen(Conn $conn)
{
$this->logger->debug('[WS] Connection request accepted');
$this->manager->openConnection($conn);
}
/**
* {@inheritdoc}
*/
public function onClose(Conn $conn)
{
$this->logger->debug('[WS] Connection closed');
$this->manager->closeConnection($conn);
}
/**
* {@inheritdoc}
*/
public function onError(Conn $conn, \Exception $e)
{
$this->logger->error('[WS] Connection error', ['exception' => $e]);
}
}

View File

@@ -1,88 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Websocket\Subscriber;
use Alchemy\Phrasea\Websocket\Topics\TopicsManager;
use Alchemy\TaskManager\Event\StateFormater;
use Alchemy\TaskManager\Event\TaskManagerEvent;
use Alchemy\TaskManager\Event\TaskManagerRequestEvent;
use Alchemy\TaskManager\Event\TaskManagerEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Alchemy\TaskManager\ZMQSocket;
class TaskManagerBroadcasterSubscriber implements EventSubscriberInterface
{
private $broadcaster;
private $formater;
public function __construct(ZMQSocket $broadcaster)
{
$this->formater = new StateFormater();
$this->broadcaster = $broadcaster;
$this->broadcaster->bind();
usleep(300000);
}
public function onManagerStart(TaskManagerEvent $event)
{
$this->broadcaster->send(json_encode([
'topic' => TopicsManager::TOPIC_TASK_MANAGER,
'event' => TaskManagerEvents::MANAGER_START,
]));
}
public function onManagerStop(TaskManagerEvent $event)
{
$this->broadcaster->send(json_encode([
'topic' => TopicsManager::TOPIC_TASK_MANAGER,
'event' => TaskManagerEvents::MANAGER_STOP,
]));
}
public function onManagerRequest(TaskManagerRequestEvent $event)
{
$this->broadcaster->send(json_encode([
'topic' => TopicsManager::TOPIC_TASK_MANAGER,
'event' => TaskManagerEvents::MANAGER_REQUEST,
'request' => $event->getRequest(),
'response' => $event->getResponse(),
]));
}
public function onManagerTick(TaskManagerEvent $event)
{
$this->broadcaster->send(json_encode([
'topic' => TopicsManager::TOPIC_TASK_MANAGER,
'event' => TaskManagerEvents::MANAGER_TICK,
'message' => $this->formater->toArray(
$event->getManager()->getProcessManager()->getManagedProcesses()
),
]));
}
public static function getSubscribedEvents()
{
return [
TaskManagerEvents::MANAGER_START => 'onManagerStart',
TaskManagerEvents::MANAGER_STOP => 'onManagerStop',
TaskManagerEvents::MANAGER_REQUEST => 'onManagerRequest',
TaskManagerEvents::MANAGER_TICK => 'onManagerTick',
];
}
public static function create(array $options)
{
return new static(ZMQSocket::create(new \ZMQContext(), \ZMQ::SOCKET_PUB, $options['protocol'], $options['host'], $options['port']));
}
}

View File

@@ -1,75 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Websocket\Topics;
use Alchemy\Phrasea\Websocket\Consumer\ConsumerInterface;
/**
* Stores consumer required settings for a topic
*/
class Directive
{
private $topic;
private $requireAuthentication;
private $requiredRights;
public function __construct($topic, $requireAuthentication, array $requiredRights)
{
$this->topic = $topic;
$this->requireAuthentication = (Boolean) $requireAuthentication;
$this->requiredRights = $requiredRights;
}
/**
* @return string
*/
public function getTopic()
{
return $this->topic;
}
/**
* Returns true if the topic requires an authenticated consumer
*
* @return Boolean
*/
public function requireAuthentication()
{
return $this->requireAuthentication;
}
/**
* Returns an array of required rights for the authenticated consumer
*
* @return array
*/
public function getRequiredRights()
{
return $this->requiredRights;
}
/**
* Returns true if the consumer satisfies the directive
*
* @param ConsumerInterface $consumer
*
* @return Boolean
*/
public function isStatisfiedBy(ConsumerInterface $consumer)
{
if ($this->requireAuthentication() && !$consumer->isAuthenticated()) {
return false;
}
return $consumer->hasRights($this->getRequiredRights());
}
}

View File

@@ -1,61 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Websocket\Topics;
use Alchemy\Phrasea\Websocket\Consumer\ConsumerInterface;
use Ratchet\Wamp\Topic;
class DirectivesManager
{
private $directives;
public function __construct(array $directives)
{
array_walk($directives, function ($directive) {
if (!$directive instanceof Directive) {
throw new \InvalidArgumentException('Websocket configuration only accepts configuration directives.');
}
});
$this->directives = $directives;
}
/**
* Returns true if the consumer has access to the given topic
*
* @param ConsumerInterface $consumer
* @param Topic $topic
*
* @return Boolean
*/
public function hasAccess(ConsumerInterface $consumer, Topic $topic)
{
foreach ($this->getDirectives($topic) as $directive) {
if (!$directive->isStatisfiedBy($consumer)) {
return false;
}
}
return true;
}
/**
* @param Topic $topic
*
* @return Directive[]
*/
private function getDirectives(Topic $topic)
{
return array_filter($this->directives, function (Directive $directive) use ($topic) {
return $directive->getTopic() === $topic->getId();
});
}
}

View File

@@ -1,24 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Websocket\Topics\Plugin;
use Alchemy\Phrasea\Websocket\Topics\TopicsManager;
interface PluginInterface
{
/**
* Attaches a Plugin to the TopicsManager
*
* @param TopicsManager $manager
*/
public function attach(TopicsManager $manager);
}

View File

@@ -1,63 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Websocket\Topics\Plugin;
use Alchemy\Phrasea\Websocket\Topics\TopicsManager;
use Psr\Log\LoggerInterface;
use React\EventLoop\LoopInterface;
use React\ZMQ\Context;
class TaskManagerSubscriberPlugin implements PluginInterface
{
private $logger;
private $pull;
public function __construct($options, LoopInterface $loop, LoggerInterface $logger)
{
$this->logger = $logger;
$context = new Context($loop);
$this->pull = $context->getSocket(\ZMQ::SOCKET_SUB);
$this->pull->setSockOpt(\ZMQ::SOCKOPT_SUBSCRIBE, "");
$this->pull->connect(sprintf('%s://%s:%s', $options['protocol'], $options['host'], $options['port']));
$this->pull->on('error', function ($e) use ($logger) {
$logger->error('TaskManager Subscriber received an error.', ['exception' => $e]);
});
}
/**
* {@inheritdoc}
*/
public function attach(TopicsManager $manager)
{
$this->pull->on('message', function ($msg) use ($manager) {
$data = @json_decode($msg, true);
if (json_last_error() !== JSON_ERROR_NONE) {
$this->logger->error(sprintf('[WS] Received invalid message %s : invalid json', $msg));
return;
}
if (!isset($data['topic'])) {
$this->logger->error(sprintf('[WS] Received invalid message %s : no topic', $msg));
return;
}
$this->logger->debug(sprintf('[WS] Received message %s', $msg));
$manager->broadcast($data['topic'], json_encode($msg));
});
}
}

View File

@@ -1,163 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Websocket\Topics;
use Alchemy\Phrasea\Websocket\Consumer\Consumer;
use Alchemy\Phrasea\Websocket\Consumer\ConsumerManager;
use Alchemy\Phrasea\Websocket\Topics\Plugin\PluginInterface;
use Ratchet\ConnectionInterface as Conn;
use Ratchet\Wamp\Topic;
class TopicsManager
{
const TOPIC_TASK_MANAGER = 'http://phraseanet.com/topics/admin/task-manager';
private $topics = [];
private $directives;
private $consumerManager;
public function __construct(DirectivesManager $directives, ConsumerManager $consumerManagaer)
{
$this->directives = $directives;
$this->consumerManager = $consumerManagaer;
}
/**
* Attaches a plugin to the TopicsManager
*
* @param PluginInterface $plugin
*
* @return TopicsManager
*/
public function attach(PluginInterface $plugin)
{
$plugin->attach($this);
return $this;
}
/**
* Checks if the consumer related to the connection has access to the topic,
* removes the connection from topic if the consumer is not granted.
*
* @param Conn $conn
* @param Topic $topic
*
* @return Boolean Return true if the consumer is granted, false otherwise
*/
public function subscribe(Conn $conn, Topic $topic)
{
if (!$this->directives->hasAccess($conn->User, $topic)) {
$topic->remove($conn);
return false;
}
$this->topics[$topic->getId()] = $topic;
return true;
}
/**
* Triggered on unsubscription.
*
* Removes internal references to the topic if no more consumers are listening.
*
* @param Conn $conn
* @param Topic $topic
*
* @return TopicsManager
*/
public function unsubscribe(Conn $conn, Topic $topic)
{
$this->cleanupReferences($conn, $topic);
return $this;
}
/**
* Triggered on connection, populates the connection with a consumer.
*
* @param Conn $conn
*
* @return TopicsManager
*/
public function openConnection(Conn $conn)
{
try {
$conn->User = $this->consumerManager->create($conn->Session);
} catch (\RuntimeException $e) {
$conn->close();
}
return $this;
}
/**
* Triggered on deconnexion.
*
* Removes internal references to topics if no more consumers are listening.
*
* @param Conn $conn
*
* @return TopicsManager
*/
public function closeConnection(Conn $conn)
{
$this->cleanupReferences($conn);
return $this;
}
/**
* Brodcasts a message to a topic, if it exists
*
* @param $topicId string
* @param $message string
*
* @return TopicsManager
*/
public function broadcast($topicId, $message)
{
if (isset($this->topics[$topicId])) {
$this->topics[$topicId]->broadcast($message);
}
return $this;
}
/**
* Removes internal references to topics if they do not contains any reference to an active connection.
*
* @param Conn $conn
* @param null|Topic $topic Restrict to this topic, if provided
*/
private function cleanupReferences(Conn $conn, Topic $topic = null)
{
$storage = $this->topics;
$updated = [];
foreach ($storage as $id => $storedTopic) {
if (null !== $topic && $id !== $topic->getId()) {
continue;
}
if ($storedTopic->has($conn)) {
$storedTopic->remove($conn);
}
if (count($storedTopic) > 0) {
$updated[] = $storedTopic;
}
}
$this->topics = $updated;
}
}

View File

@@ -193,7 +193,7 @@ class caption_record implements caption_interface, cache_cacheableInterface
$fields[$field->get_name()] = [ $fields[$field->get_name()] = [
'values' => $values, 'values' => $values,
'name' => $field->get_name(), 'name' => $field->get_name(),
'label' => $field->get_databox_field()->get_label($this->app['locale']), 'label_name' => $field->get_databox_field()->get_label($this->app['locale']),
'separator' => $field->get_databox_field()->get_separator(), 'separator' => $field->get_databox_field()->get_separator(),
'sbas_id' => $field->get_databox_field()->get_databox()->get_sbas_id() 'sbas_id' => $field->get_databox_field()->get_databox()->get_sbas_id()
]; ];

View File

@@ -1009,12 +1009,12 @@ class databox_field implements cache_cacheableInterface
} }
$sql = "INSERT INTO metadatas_structure $sql = "INSERT INTO metadatas_structure
(`id`, `name`, `src`, `readonly`, `indexable`, `type`, `tbranch`, (`id`, `name`, `src`, `readonly`, `required`, `indexable`, `type`, `tbranch`,
`thumbtitle`, `multi`, `business`, `aggregable`, `thumbtitle`, `multi`, `business`, `aggregable`,
`report`, `sorter`) `report`, `sorter`, `separator`)
VALUES (null, :name, '', 0, 1, 'string', '', VALUES (null, :name, '', 0, 0, 1, 'string', '',
null, :multi, null, :multi,
0, 0, 1, :sorter)"; 0, 0, 1, :sorter, '')";
$name = self::generateName($name); $name = self::generateName($name);

View File

@@ -58,21 +58,12 @@ class patch_390alpha11a extends patchAbstract
public function apply(base $appbox, Application $app) public function apply(base $appbox, Application $app)
{ {
$app['conf']->set(['main', 'task-manager', 'status'], 'started'); $app['conf']->set(['main', 'task-manager', 'status'], 'started');
$app['conf']->set(['main', 'websocket-server'], [
'host' => parse_url($app['conf']->get('servername'), PHP_URL_HOST), $app['conf']->set(['main', 'task-manager', 'options'], [
'port' => 9090,
'ip' => '0.0.0.0',
]);
$app['conf']->set(['main', 'task-manager', 'listener'], [
'protocol' => 'tcp', 'protocol' => 'tcp',
'host' => '127.0.0.1', 'host' => '127.0.0.1',
'port' => 6660, 'port' => 6660,
'linger' => 500, 'linger' => 500,
]); ]);
$app['conf']->set(['main', 'websocket-server', 'subscriber'], [
'protocol' => 'tcp',
'host' => '127.0.0.1',
'port' => 13598,
]);
} }
} }

View File

@@ -1974,18 +1974,15 @@
<name>pwd</name> <name>pwd</name>
<type>char(64)</type> <type>char(64)</type>
<null>YES</null> <null>YES</null>
<extra></extra> <extra></extra>
<default></default> <default></default>
<comment></comment> <comment></comment>
</field> </field>
<field> <field>
<name>viewname</name> <name>viewname</name>
<type>char(128)</type> <type>char(128)</type>
<null></null> <null>YES</null>
<extra></extra> <extra></extra>
<default></default> <default></default>
<comment></comment> <comment></comment>
</field> </field>

View File

@@ -34,23 +34,15 @@ main:
task-manager: task-manager:
status: started status: started
enabled: true enabled: true
logger: options:
max-files: 10
enabled: true
level: INFO
listener:
protocol: tcp protocol: tcp
host: 127.0.0.1 host: 127.0.0.1
port: 6660 port: 6660
linger: 500 linger: 500
websocket-server: logger:
host: local.phrasea max-files: 10
port: 9090 enabled: true
ip: 0.0.0.0 level: INFO
subscriber:
protocol: tcp
host: 127.0.0.1
port: 13598
session: session:
type: 'file' type: 'file'
options: [] options: []

View File

@@ -56,7 +56,6 @@ $groups = [
, '//assets/blueimp-load-image/load-image.js' , '//assets/blueimp-load-image/load-image.js'
, '//assets/jquery-file-upload/jquery.iframe-transport.js' , '//assets/jquery-file-upload/jquery.iframe-transport.js'
, '//assets/jquery-file-upload/jquery.fileupload.js' , '//assets/jquery-file-upload/jquery.fileupload.js'
, '//assets/autobahn/autobahn.js'
], ],
'report' => [ 'report' => [
'//assets/jquery.ui/i18n/jquery-ui-i18n.js' '//assets/jquery.ui/i18n/jquery-ui-i18n.js'

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2"> <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
<file date="2014-02-11T14:21:21Z" source-language="en" target-language="de" datatype="plaintext" original="not.available"> <file date="2015-03-09T18:08:03Z" source-language="en" target-language="de" datatype="plaintext" original="not.available">
<header> <header>
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/> <tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/>
<note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note> <note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note>
</header> </header>
<body> <body>
<trans-unit id="96f0767cb7ea65a7f86c8c9432e80d16cf9d8680" resname="Please provide the same passwords."> <trans-unit id="96f0767cb7ea65a7f86c8c9432e80d16cf9d8680" resname="Please provide the same passwords.">
<jms:reference-file line="44">Form/Login/PhraseaRecoverPasswordForm.php</jms:reference-file>
<jms:reference-file line="50">Form/Login/PhraseaRegisterForm.php</jms:reference-file>
<jms:reference-file line="36">Form/Login/PhraseaRenewPasswordForm.php</jms:reference-file>
<source>Please provide the same passwords.</source> <source>Please provide the same passwords.</source>
<target state="new">Please provide the same passwords.</target> <target state="new">Please provide the same passwords.</target>
<jms:reference-file line="44">Form/Login/PhraseaRecoverPasswordForm.php</jms:reference-file>
<jms:reference-file line="51">Form/Login/PhraseaRegisterForm.php</jms:reference-file>
<jms:reference-file line="36">Form/Login/PhraseaRenewPasswordForm.php</jms:reference-file>
</trans-unit> </trans-unit>
<trans-unit id="90b8c9717bb7ed061dbf20fe1986c8b8593d43d4" resname="The token provided is not valid anymore"> <trans-unit id="90b8c9717bb7ed061dbf20fe1986c8b8593d43d4" resname="The token provided is not valid anymore">
<source>The token provided is not valid anymore</source> <source>The token provided is not valid anymore</source>

View File

@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2"> <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
<file date="2014-02-11T14:23:06Z" source-language="en" target-language="en" datatype="plaintext" original="not.available"> <file date="2015-03-09T18:10:31Z" source-language="en" target-language="en" datatype="plaintext" original="not.available">
<header> <header>
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/> <tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/>
<note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note> <note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note>
</header> </header>
<body> <body>
<trans-unit id="96f0767cb7ea65a7f86c8c9432e80d16cf9d8680" resname="Please provide the same passwords."> <trans-unit id="96f0767cb7ea65a7f86c8c9432e80d16cf9d8680" resname="Please provide the same passwords.">
<jms:reference-file line="44">Form/Login/PhraseaRecoverPasswordForm.php</jms:reference-file>
<jms:reference-file line="50">Form/Login/PhraseaRegisterForm.php</jms:reference-file>
<jms:reference-file line="36">Form/Login/PhraseaRenewPasswordForm.php</jms:reference-file>
<source>Please provide the same passwords.</source> <source>Please provide the same passwords.</source>
<target state="new">Please provide the same passwords.</target> <target state="new">Please provide the same passwords.</target>
<jms:reference-file line="44">Form/Login/PhraseaRecoverPasswordForm.php</jms:reference-file>
<jms:reference-file line="51">Form/Login/PhraseaRegisterForm.php</jms:reference-file>
<jms:reference-file line="36">Form/Login/PhraseaRenewPasswordForm.php</jms:reference-file>
</trans-unit> </trans-unit>
<trans-unit id="90b8c9717bb7ed061dbf20fe1986c8b8593d43d4" resname="The token provided is not valid anymore"> <trans-unit id="90b8c9717bb7ed061dbf20fe1986c8b8593d43d4" resname="The token provided is not valid anymore">
<source>The token provided is not valid anymore</source> <source>The token provided is not valid anymore</source>

View File

@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2"> <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
<file date="2014-02-11T14:25:05Z" source-language="en" target-language="fr" datatype="plaintext" original="not.available"> <file date="2015-03-09T18:13:15Z" source-language="en" target-language="fr" datatype="plaintext" original="not.available">
<header> <header>
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/> <tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/>
<note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note> <note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note>
</header> </header>
<body> <body>
<trans-unit id="96f0767cb7ea65a7f86c8c9432e80d16cf9d8680" resname="Please provide the same passwords."> <trans-unit id="96f0767cb7ea65a7f86c8c9432e80d16cf9d8680" resname="Please provide the same passwords.">
<jms:reference-file line="44">Form/Login/PhraseaRecoverPasswordForm.php</jms:reference-file>
<jms:reference-file line="50">Form/Login/PhraseaRegisterForm.php</jms:reference-file>
<jms:reference-file line="36">Form/Login/PhraseaRenewPasswordForm.php</jms:reference-file>
<source>Please provide the same passwords.</source> <source>Please provide the same passwords.</source>
<target state="new">Please provide the same passwords.</target> <target state="new">Please provide the same passwords.</target>
<jms:reference-file line="44">Form/Login/PhraseaRecoverPasswordForm.php</jms:reference-file>
<jms:reference-file line="51">Form/Login/PhraseaRegisterForm.php</jms:reference-file>
<jms:reference-file line="36">Form/Login/PhraseaRenewPasswordForm.php</jms:reference-file>
</trans-unit> </trans-unit>
<trans-unit id="90b8c9717bb7ed061dbf20fe1986c8b8593d43d4" resname="The token provided is not valid anymore"> <trans-unit id="90b8c9717bb7ed061dbf20fe1986c8b8593d43d4" resname="The token provided is not valid anymore">
<source>The token provided is not valid anymore</source> <source>The token provided is not valid anymore</source>

View File

@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2"> <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
<file date="2014-02-11T14:27:16Z" source-language="en" target-language="nl" datatype="plaintext" original="not.available"> <file date="2015-03-09T18:16:13Z" source-language="en" target-language="nl" datatype="plaintext" original="not.available">
<header> <header>
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/> <tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/>
<note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note> <note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note>
</header> </header>
<body> <body>
<trans-unit id="96f0767cb7ea65a7f86c8c9432e80d16cf9d8680" resname="Please provide the same passwords."> <trans-unit id="96f0767cb7ea65a7f86c8c9432e80d16cf9d8680" resname="Please provide the same passwords.">
<jms:reference-file line="44">Form/Login/PhraseaRecoverPasswordForm.php</jms:reference-file>
<jms:reference-file line="50">Form/Login/PhraseaRegisterForm.php</jms:reference-file>
<jms:reference-file line="36">Form/Login/PhraseaRenewPasswordForm.php</jms:reference-file>
<source>Please provide the same passwords.</source> <source>Please provide the same passwords.</source>
<target state="new">Please provide the same passwords.</target> <target state="new">Please provide the same passwords.</target>
<jms:reference-file line="44">Form/Login/PhraseaRecoverPasswordForm.php</jms:reference-file>
<jms:reference-file line="51">Form/Login/PhraseaRegisterForm.php</jms:reference-file>
<jms:reference-file line="36">Form/Login/PhraseaRenewPasswordForm.php</jms:reference-file>
</trans-unit> </trans-unit>
<trans-unit id="90b8c9717bb7ed061dbf20fe1986c8b8593d43d4" resname="The token provided is not valid anymore"> <trans-unit id="90b8c9717bb7ed061dbf20fe1986c8b8593d43d4" resname="The token provided is not valid anymore">
<source>The token provided is not valid anymore</source> <source>The token provided is not valid anymore</source>

View File

@@ -62,7 +62,7 @@
{% if app['acl'].get(app['authentication'].getUser()).has_right('taskmanager') %} {% if app['acl'].get(app['authentication'].getUser()).has_right('taskmanager') %}
<li class="{% if feature == 'taskmanager' %}selected{% endif %}"> <li class="{% if feature == 'taskmanager' %}selected{% endif %}">
<a target="right" href="{{ path('admin_tasks_list') }}" class="ajax" data-ws-topic="http://phraseanet.com/topics/admin/task-manager"> <a target="right" href="{{ path('admin_tasks_list') }}" class="ajax">
<img src="/skins/admin/TaskManager.png" /> <img src="/skins/admin/TaskManager.png" />
<span>{{ 'admin::utilisateurs: gestionnaire de taches' | trans }}</span> <span>{{ 'admin::utilisateurs: gestionnaire de taches' | trans }}</span>
</a> </a>

View File

@@ -97,7 +97,7 @@
{% macro caption_field(field, bounceable, extra_classes) %} {% macro caption_field(field, bounceable, extra_classes) %}
<div class="desc {{ extra_classes|join(' ') }}"> <div class="desc {{ extra_classes|join(' ') }}">
<b>{{ field.label }}</b> : <b>{{ field.label_name }}</b> :
{{ _self.caption_value(field, bounceable|default(true))|highlight|linkify }} {{ _self.caption_value(field, bounceable|default(true))|highlight|linkify }}
</div> </div>
{% endmacro %} {% endmacro %}

View File

@@ -30,7 +30,7 @@
/> />
</td> </td>
<td> <td>
<a style="cursor:pointer;display:inline;padding:0;margin:0;" class="contextMenuTrigger">&#9660;</a> <a class="contextMenuTrigger"></a>
</td> </td>
</tr> </tr>
</table> </table>
@@ -112,10 +112,7 @@
</td> </td>
{% endif %} {% endif %}
<td> <td>
<a <a class="contextMenuTrigger"></a>
style="cursor:pointer;display:inline;padding:0;margin:0;"
class="contextMenuTrigger">&#9660;
</a>
</td> </td>
</tr> </tr>
</table> </table>

View File

@@ -186,11 +186,6 @@
<div class="PNB wrapper"> <div class="PNB wrapper">
<div class="tabs ui-tabs"> <div class="tabs ui-tabs">
<ul class="icon-menu ui-tabs-nav ui-helper-reset"> <ul class="icon-menu ui-tabs-nav ui-helper-reset">
<li class="ui-tabs-selected ui-corner-top">
<a href="#baskets" class="WZbasketTab">
<div id="basket_menu_trigger">&#9660;</div>
</a>
</li>
{% if GV_thesaurus %} {% if GV_thesaurus %}
<li class="proposals_WZ"> <li class="proposals_WZ">
<a href="#proposals" class="WZtabs"> <a href="#proposals" class="WZtabs">
@@ -209,13 +204,18 @@
<img src="/skins/icons/workzoneEscamote.png" title="{{ 'Close the WorkZone' | trans }}"/> <img src="/skins/icons/workzoneEscamote.png" title="{{ 'Close the WorkZone' | trans }}"/>
</a> </a>
</li> </li>
<li class="ui-tabs-selected ui-corner-top">
<a href="#baskets" class="WZbasketTab">
<div id="basket_menu_trigger">&#9660;</div>
</a>
</li>
</ul> </ul>
<div id="baskets" class="PNB"> <div id="baskets" class="PNB">
{% import 'prod/WorkZone/Macros.html.twig' as WorkZoneMacros %} {% import 'prod/WorkZone/Macros.html.twig' as WorkZoneMacros %}
{{WorkZoneMacros.make_bloc(app, WorkZone)}} {{WorkZoneMacros.make_bloc(app, WorkZone)}}
</div> </div>
{% if GV_thesaurus %} {% if GV_thesaurus %}
<div id="proposals" class="PNB" style="top:52px;" <div id="proposals" class="PNB" style="top:85px;"
ondblclick="return(thesau_dblclickThesaurus(event));" onclick="return(thesau_clickThesaurus(event));"> ondblclick="return(thesau_dblclickThesaurus(event));" onclick="return(thesau_clickThesaurus(event));">
</div> </div>
<div id="thesaurus_tab" class="PNB" style="top:52px;"> <div id="thesaurus_tab" class="PNB" style="top:52px;">
@@ -513,9 +513,6 @@
</span> </span>
</div> </div>
<!--td class="navigation">
<div id="tool_navigate"></div>
</td-->
</div> </div>
</div> </div>
@@ -760,6 +757,11 @@
}); });
</script> </script>
</div> </div>
<div id="paginate">
<div class="navigation">
<div id="tool_navigate"></div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -3,7 +3,7 @@
{% if app['acl'].get(app['authentication'].getUser()).has_right_on_base(record.get_base_id, 'canmodifrecord') %} {% if app['acl'].get(app['authentication'].getUser()).has_right_on_base(record.get_base_id, 'canmodifrecord') %}
<div class="edit_button" style="text-align:right"> <div class="edit_button" style="text-align:right">
<a href="#" onclick="editThis('IMGT','{{record.get_serialize_key()}}');"> <a href="#" onclick="editThis('IMGT','{{record.get_serialize_key()}}');">
<img style="vertical-align:middle" src="/skins/prod/000000/images/ppen_history.png" /> <img style="vertical-align:middle" src="/skins/prod/000000/images/ppen_history.png" width="16"/>
{{ 'action : editer' | trans }} {{ 'action : editer' | trans }}
</a> </a>
</div> </div>

View File

@@ -471,7 +471,7 @@ function T_search(menuItem, menu, cmenu, e, label)
var sbid = tcids.shift(); var sbid = tcids.shift();
var term = menu._li.find("span span").html(); var term = menu._li.find("span span").html();
v = '*:"' + term.replace("(", "[").replace(")", "]") + '"'; v = '[' + term + ']';
var nck = 0; var nck = 0;
$('#searchForm .adv_options :checkbox[name="bases[]"]').each(function(a) $('#searchForm .adv_options :checkbox[name="bases[]"]').each(function(a)
@@ -804,7 +804,7 @@ function doThesSearch(type, sbid, term, field)
} }
} }
if(type=='T') if(type=='T')
v = '*:"' + term.replace("(", "[").replace(")", "]") + '"'; v = '[' + term + ']';
else else
v = '"' + term + '" IN ' + field; v = '"' + term + '" IN ' + field;
$('form[name="phrasea_query"] input[name="qry"]').val(v); $('form[name="phrasea_query"] input[name="qry"]').val(v);

View File

@@ -1,29 +0,0 @@
<?php
namespace Alchemy\Tests\Phrasea\Command;
use Alchemy\Phrasea\Command\WebsocketServer;
class WebsocketServerTest extends \PhraseanetTestCase
{
public function testRunWithoutProblems()
{
$input = $this->getMock('Symfony\Component\Console\Input\InputInterface');
$output = $this->getMock('Symfony\Component\Console\Output\OutputInterface');
$sessionType = self::$DI['cli']['conf']->get(['main', 'session', 'type'], 'file');
self::$DI['cli']['conf']->set(['main', 'session', 'type'], 'memcached');
self::$DI['cli']['ws.server'] = $this->getMockBuilder('Ratchet\App')
->disableOriginalConstructor()
->getMock();
self::$DI['cli']['ws.server']->expects($this->once())
->method('run');
$command = new WebsocketServer('websocketserver');
$command->setContainer(self::$DI['cli']);
$command->execute($input, $output);
self::$DI['cli']['conf']->set(['main', 'session', 'type'], $sessionType);
}
}

View File

@@ -1,57 +0,0 @@
<?php
namespace Alchemy\Tests\Phrasea\Core\CLIProvider;
class WebsocketServerServiceProviderTest extends ServiceProviderTestCase
{
public function provideServiceDescription()
{
return [
[
'Alchemy\Phrasea\Core\CLIProvider\WebsocketServerServiceProvider',
'ws.task-manager.broadcaster',
'Alchemy\Phrasea\Websocket\Subscriber\TaskManagerBroadcasterSubscriber',
],
[
'Alchemy\Phrasea\Core\CLIProvider\WebsocketServerServiceProvider',
'ws.event-loop',
'React\EventLoop\LoopInterface',
],
[
'Alchemy\Phrasea\Core\CLIProvider\WebsocketServerServiceProvider',
'ws.server.subscriber',
'Alchemy\Phrasea\Websocket\Topics\Plugin\TaskManagerSubscriberPlugin',
],
[
'Alchemy\Phrasea\Core\CLIProvider\WebsocketServerServiceProvider',
'ws.server.application',
'Ratchet\WebSocket\WsServerInterface',
],
[
'Alchemy\Phrasea\Core\CLIProvider\WebsocketServerServiceProvider',
'ws.server',
'Ratchet\App',
],
[
'Alchemy\Phrasea\Core\CLIProvider\WebsocketServerServiceProvider',
'ws.server.phraseanet-server',
'Alchemy\Phrasea\Websocket\PhraseanetWampServer',
],
[
'Alchemy\Phrasea\Core\CLIProvider\WebsocketServerServiceProvider',
'ws.server.logger',
'Psr\Log\LoggerInterface',
],
[
'Alchemy\Phrasea\Core\CLIProvider\WebsocketServerServiceProvider',
'ws.server.topics-manager.directives',
'Alchemy\Phrasea\Websocket\Topics\DirectivesManager',
],
[
'Alchemy\Phrasea\Core\CLIProvider\WebsocketServerServiceProvider',
'ws.server.consumer-manager',
'Alchemy\Phrasea\Websocket\Consumer\ConsumerManager',
],
];
}
}

View File

@@ -1,58 +0,0 @@
<?php
namespace Alchemy\Tests\Phrasea\Websocket\Consumer;
use Alchemy\Phrasea\Websocket\Consumer\ConsumerManager;
class ConsumerManagerTest extends \PhraseanetTestCase
{
/**
* @dataProvider provideConsumerManagerData
*/
public function testCreate($usrId, $rights, $authenticated, $checkedRights, $hasRights)
{
$manager = new ConsumerManager();
$consumer = $manager->create($this->createSessionMock($usrId, $rights));
$this->assertSame($authenticated, $consumer->isAuthenticated());
$this->assertSame($hasRights, $consumer->hasRights($checkedRights));
}
public function provideConsumerManagerData()
{
return [
[25, ['task-manager'], true, [], true],
[25, ['task-manager'], true, ['task-manager'], true],
[null, ['task-manager'], false, ['task-manager', 'neutron'], false],
[null, ['neutron', 'task-manager'], false, ['task-manager', 'neutron'], true],
[42, ['neutron', 'task-manager', 'romain'], true, ['task-manager', 'neutron'], true],
];
}
private function createSessionMock($usrId, $rights)
{
$session = $this->getMock('Symfony\Component\HttpFoundation\Session\SessionInterface');
$session->expects($this->any())
->method('has')
->will($this->returnCallback(function ($prop) use ($usrId, $rights) {
switch ($prop) {
case 'usr_id':
return $usrId !== null;
case 'websockets_rights':
return $rights !== null;
}
}));
$session->expects($this->any())
->method('get')
->will($this->returnCallback(function ($prop) use ($usrId, $rights) {
switch ($prop) {
case 'usr_id':
return $usrId;
case 'websockets_rights':
return $rights;
}
}));
return $session;
}
}

View File

@@ -1,32 +0,0 @@
<?php
namespace Alchemy\Tests\Phrasea\Websocket\Consumer;
use Alchemy\Phrasea\Websocket\Consumer\Consumer;
class ConsumerTest extends \PhraseanetTestCase
{
public function testIsAuthenticated()
{
$consumer = new Consumer(42, []);
$this->assertTrue($consumer->isAuthenticated());
$consumer = new Consumer(null, []);
$this->assertFalse($consumer->isAuthenticated());
}
public function testHasRights()
{
$consumer = new Consumer(42, ['neutron']);
$this->assertTrue($consumer->hasRights('neutron'));
$consumer = new Consumer(42, ['neutron']);
$this->assertTrue($consumer->hasRights(['neutron']));
$consumer = new Consumer(42, ['romainneutron']);
$this->assertFalse($consumer->hasRights('neutron'));
$consumer = new Consumer(42, ['romainneutron']);
$this->assertFalse($consumer->hasRights(['neutron']));
$consumer = new Consumer(42, ['neutron']);
$this->assertFalse($consumer->hasRights(['neutron', 'romain']));
$consumer = new Consumer(42, ['romain', 'neutron', 'bouteille']);
$this->assertTrue($consumer->hasRights(['neutron', 'romain']));
}
}

View File

@@ -1,27 +0,0 @@
<?php
namespace Alchemy\Tests\Phrasea\Websocket;
use Alchemy\Phrasea\Websocket\PhraseanetWampServer;
class PhraseanetWampServerTest extends \PhraseanetTestCase
{
public function testOpenConnectionConnected()
{
$topicsManager = $this->createTopicsManagerMock();
$conn = $this->getMock('Ratchet\ConnectionInterface');
$topicsManager->expects($this->once())
->method('openConnection')
->with($conn);
$server = new PhraseanetWampServer($topicsManager, $this->createLoggerMock());
$server->onOpen($conn);
}
private function createTopicsManagerMock()
{
return $this->getMockBuilder('Alchemy\Phrasea\Websocket\Topics\TopicsManager')
->disableOriginalConstructor()
->getMock();
}
}

View File

@@ -1,127 +0,0 @@
<?php
namespace Alchemy\Tests\Phrasea\Websocket\Subscriber;
use Alchemy\Phrasea\Websocket\Subscriber\TaskManagerBroadcasterSubscriber;
use Alchemy\Phrasea\Websocket\Topics\TopicsManager;
use Alchemy\TaskManager\Event\TaskManagerEvent;
use Alchemy\TaskManager\Event\TaskManagerEvents;
use Alchemy\TaskManager\Event\TaskManagerRequestEvent;
class TaskManagerBroadcasterSubscriberTest extends \PhraseanetTestCase
{
public function testOnManagerStart()
{
$socket = $this->createZMQSocketMock();
$socket->expects($this->once())
->method('send')
->will($this->jsonCapture($json));
$subscriber = new TaskManagerBroadcasterSubscriber($socket);
$subscriber->onManagerStart($this->createTaskManagerEvent());
$this->assertValidJson($json, TopicsManager::TOPIC_TASK_MANAGER, TaskManagerEvents::MANAGER_START);
}
public function testOnManagerStop()
{
$socket = $this->createZMQSocketMock();
$socket->expects($this->once())
->method('send')
->will($this->jsonCapture($json));
$subscriber = new TaskManagerBroadcasterSubscriber($socket);
$subscriber->onManagerStop($this->createTaskManagerEvent());
$this->assertValidJson($json, TopicsManager::TOPIC_TASK_MANAGER, TaskManagerEvents::MANAGER_STOP);
}
public function testOnManagerRequest()
{
$socket = $this->createZMQSocketMock();
$socket->expects($this->once())
->method('send')
->will($this->jsonCapture($json));
$subscriber = new TaskManagerBroadcasterSubscriber($socket);
$subscriber->onManagerRequest(new TaskManagerRequestEvent($this->createTaskManagerMock(), 'PING', 'PONG'));
$data = $this->assertValidJson($json, TopicsManager::TOPIC_TASK_MANAGER, TaskManagerEvents::MANAGER_REQUEST);
$this->assertEquals('PING', $data['request']);
$this->assertEquals('PONG', $data['response']);
}
public function testOnManagerTick()
{
$socket = $this->createZMQSocketMock();
$socket->expects($this->once())
->method('send')
->will($this->jsonCapture($json));
$subscriber = new TaskManagerBroadcasterSubscriber($socket);
$subscriber->onManagerTick($this->createTaskManagerEvent());
$data = $this->assertValidJson($json, TopicsManager::TOPIC_TASK_MANAGER, TaskManagerEvents::MANAGER_TICK);
$this->assertArrayHasKey('message', $data);
$this->assertInternalType('array', $data['message']);
}
private function assertValidJson($json, $topic, $event)
{
$data = json_decode($json, true);
$this->assertTrue(json_last_error() === JSON_ERROR_NONE);
$this->assertArrayHasKey('event', $data);
$this->assertArrayHasKey('topic', $data);
$this->assertEquals($event, $data['event']);
$this->assertEquals($topic, $data['topic']);
return $data;
}
private function jsonCapture(&$json)
{
return $this->returnCallback(function ($arg) use (&$json) { $json = $arg; return 'lala'; });
}
private function createZMQSocketMock()
{
$socket = $this->getMockBuilder('Alchemy\TaskManager\ZMQSocket')
->setMethods(['send', 'bind'])
->disableOriginalConstructor()
->getMock();
$socket->expects($this->once())
->method('bind');
return $socket;
}
private function createTaskManagerMock()
{
$manager = $this->getMockBuilder('Alchemy\TaskManager\TaskManager')
->disableOriginalConstructor()
->getMock();
$processManager = $this->getMockBuilder('Neutron\ProcessManager\ProcessManager')
->disableOriginalConstructor()
->getMock();
$processManager->expects($this->any())
->method('getManagedProcesses')
->will($this->returnValue([]));
$manager->expects($this->any())
->method('getProcessManager')
->will($this->returnValue($processManager));
return $manager;
}
private function createTaskManagerEvent()
{
return new TaskManagerEvent($this->createTaskManagerMock());
}
}

View File

@@ -1,50 +0,0 @@
<?php
namespace Alchemy\Tests\Phrasea\Websocket\Topics;
use Alchemy\Phrasea\Websocket\Topics\Directive;
class DirectiveTest extends \PhraseanetTestCase
{
public function testGetters()
{
$directive = new Directive('http://topic', true, ['neutron']);
$this->assertSame('http://topic', $directive->getTopic());
$this->assertTrue($directive->requireAuthentication());
$this->assertSame(['neutron'], $directive->getRequiredRights());
}
/**
* @dataProvider provideStatisfiedByCombinaisons
*/
public function testIsSatisfiedBy($authenticationRequired, $requiredRights, $authenticated, $hasRights, $satisfied)
{
$consumer = $this->createConsumerMock($authenticated, $hasRights, $requiredRights);
$directive = new Directive('http://topic', $authenticationRequired, $requiredRights);
$this->assertEquals($satisfied, $directive->isStatisfiedBy($consumer));
}
public function provideStatisfiedByCombinaisons()
{
return [
[true, ['neutron'], true, true, true],
[true, [], false, true, false],
[false, ['neutron'], true, false, false],
[false, ['neutron'], false, false, false],
];
}
private function createConsumerMock($authenticated, $hasRights, $requiredRights)
{
$consumer = $this->getMock('Alchemy\Phrasea\Websocket\Consumer\ConsumerInterface');
$consumer->expects($this->any())
->method('isAuthenticated')
->will($this->returnValue($authenticated));
$consumer->expects($this->any())
->method('hasRights')
->with($requiredRights)
->will($this->returnValue($hasRights));
return $consumer;
}
}

View File

@@ -1,46 +0,0 @@
<?php
namespace Alchemy\Tests\Phrasea\Websocket\Topics;
use Alchemy\Phrasea\Websocket\Consumer\Consumer;
use Alchemy\Phrasea\Websocket\Topics\Directive;
use Alchemy\Phrasea\Websocket\Topics\DirectivesManager;
use Ratchet\Wamp\Topic;
class DirectivesManagerTest extends \PhraseanetTestCase
{
public function testHasAccess()
{
$manager = new DirectivesManager([
new Directive('http://topic', false, []),
new Directive('http://topic2', true, []),
new Directive('http://topic3', true, ['neutron']),
new Directive('http://topic4', true, ['bouteille']),
new Directive('http://topic4', true, ['neutron', 'romain']),
]);
$consumer = new Consumer(42, []);
$this->assertTrue($manager->hasAccess($consumer, new Topic('http://topic')));
$this->assertTrue($manager->hasAccess($consumer, new Topic('http://topic2')));
$this->assertFalse($manager->hasAccess($consumer, new Topic('http://topic3')));
$this->assertFalse($manager->hasAccess($consumer, new Topic('http://topic4')));
$consumer = new Consumer(null, []);
$this->assertTrue($manager->hasAccess($consumer, new Topic('http://topic')));
$this->assertFalse($manager->hasAccess($consumer, new Topic('http://topic2')));
$this->assertFalse($manager->hasAccess($consumer, new Topic('http://topic3')));
$this->assertFalse($manager->hasAccess($consumer, new Topic('http://topic4')));
$consumer = new Consumer(42, ['neutron']);
$this->assertTrue($manager->hasAccess($consumer, new Topic('http://topic')));
$this->assertTrue($manager->hasAccess($consumer, new Topic('http://topic2')));
$this->assertTrue($manager->hasAccess($consumer, new Topic('http://topic3')));
$this->assertFalse($manager->hasAccess($consumer, new Topic('http://topic4')));
$consumer = new Consumer(42, ['neutron', 'bouteille', 'romain']);
$this->assertTrue($manager->hasAccess($consumer, new Topic('http://topic')));
$this->assertTrue($manager->hasAccess($consumer, new Topic('http://topic2')));
$this->assertTrue($manager->hasAccess($consumer, new Topic('http://topic3')));
$this->assertTrue($manager->hasAccess($consumer, new Topic('http://topic4')));
}
}

View File

@@ -1,187 +0,0 @@
<?php
namespace Alchemy\Tests\Phrasea\Websocket\Topics;
use Alchemy\Phrasea\Websocket\Topics\TopicsManager;
use Ratchet\Wamp\Topic;
class TopicsManagerTest extends \PhraseanetTestCase
{
public function testAttach()
{
$directivesManager = $this->createDirectivesManagerMock();
$consumerManager = $this->createConsumerManagerMock();
$manager = new TopicsManager($directivesManager, $consumerManager);
$plugin = $this->getMock('Alchemy\Phrasea\Websocket\Topics\Plugin\PluginInterface');
$plugin->expects($this->once())
->method('attach')
->with($manager);
$this->assertSame($manager, $manager->attach($plugin));
}
public function testSubscribeWithAccess()
{
$directivesManager = $this->createDirectivesManagerMock();
$consumerManager = $this->createConsumerManagerMock();
$manager = new TopicsManager($directivesManager, $consumerManager);
$conn = $this->getMock('Ratchet\ConnectionInterface');
$conn->User = $this->getMock('Alchemy\Phrasea\Websocket\Consumer\ConsumerInterface');
$topic = $this->getMockBuilder('Ratchet\Wamp\Topic')
->disableOriginalConstructor()
->getMock();
$topic->expects($this->never())
->method('remove');
$directivesManager->expects($this->once())
->method('hasAccess')
->will($this->returnValue(true));
$manager->subscribe($conn, $topic);
}
public function testSubscribeWithoutAccess()
{
$directivesManager = $this->createDirectivesManagerMock();
$consumerManager = $this->createConsumerManagerMock();
$manager = new TopicsManager($directivesManager, $consumerManager);
$conn = $this->getMock('Ratchet\ConnectionInterface');
$conn->User = $this->getMock('Alchemy\Phrasea\Websocket\Consumer\ConsumerInterface');
$topic = $this->getMockBuilder('Ratchet\Wamp\Topic')
->disableOriginalConstructor()
->getMock();
$topic->expects($this->once())
->method('remove')
->with($conn);
$directivesManager->expects($this->once())
->method('hasAccess')
->will($this->returnValue(false));
$manager->subscribe($conn, $topic);
}
public function testUnsubscribe()
{
$directivesManager = $this->createDirectivesManagerMock();
$consumerManager = $this->createConsumerManagerMock();
$directivesManager->expects($this->once())
->method('hasAccess')
->will($this->returnValue(true));
$manager = new TopicsManager($directivesManager, $consumerManager);
$conn = $this->getMock('Ratchet\ConnectionInterface');
$conn->User = $this->getMock('Alchemy\Phrasea\Websocket\Consumer\ConsumerInterface');
$topic = new Topic('http://topic');
$topic->add($conn);
// should be subscribed to be unsubscribed
$manager->subscribe($conn, $topic);
$manager->unsubscribe($conn, $topic);
$this->assertFalse($topic->has($conn));
}
public function testOpenConnection()
{
$consumer = $this->getMock('Alchemy\Phrasea\Websocket\Consumer\ConsumerInterface');
$session = $this->getMock('Symfony\Component\HttpFoundation\Session\SessionInterface');
$directivesManager = $this->createDirectivesManagerMock();
$consumerManager = $this->createConsumerManagerMock();
$consumerManager->expects($this->once())
->method('create')
->with($session)
->will($this->returnValue($consumer));
$manager = new TopicsManager($directivesManager, $consumerManager);
$conn = $this->getMock('Ratchet\ConnectionInterface');
$conn->Session = $session;
$manager->openConnection($conn);
$this->assertSame($consumer, $conn->User);
}
public function testCloseConnection()
{
$directivesManager = $this->createDirectivesManagerMock();
$consumerManager = $this->createConsumerManagerMock();
$directivesManager->expects($this->once())
->method('hasAccess')
->will($this->returnValue(true));
$manager = new TopicsManager($directivesManager, $consumerManager);
$conn = $this->getMock('Ratchet\ConnectionInterface');
$conn->User = $this->getMock('Alchemy\Phrasea\Websocket\Consumer\ConsumerInterface');
$topic = new Topic('http://topic');
$topic->add($conn);
// should be subscribed to be unsubscribed
$manager->subscribe($conn, $topic);
$manager->closeConnection($conn);
$this->assertFalse($topic->has($conn));
}
public function testBroadcast()
{
$directivesManager = $this->createDirectivesManagerMock();
$consumerManager = $this->createConsumerManagerMock();
$directivesManager->expects($this->once())
->method('hasAccess')
->will($this->returnValue(true));
$manager = new TopicsManager($directivesManager, $consumerManager);
$conn = $this->getMock('Ratchet\ConnectionInterface');
$conn->User = $this->getMock('Alchemy\Phrasea\Websocket\Consumer\ConsumerInterface');
$topic = $this->getMockBuilder('Ratchet\Wamp\Topic')
->disableOriginalConstructor()
->getMock();
$topic->expects($this->any())
->method('getId')
->will($this->returnValue('http://topic'));
$topic->expects($this->once())
->method('broadcast')
->with('hello world !');
// should be subscribed to be unsubscribed
$manager->subscribe($conn, $topic);
$manager->broadcast('http://topic', 'hello world !');
$manager->broadcast('http://topic2', 'nothing');
}
private function createDirectivesManagerMock()
{
return $this->getMockBuilder('Alchemy\Phrasea\Websocket\Topics\DirectivesManager')
->disableOriginalConstructor()
->getMock();
}
private function createConsumerManagerMock()
{
return $this->getMockBuilder('Alchemy\Phrasea\Websocket\Consumer\ConsumerManager')
->disableOriginalConstructor()
->getMock();
}
}

View File

@@ -6,8 +6,8 @@ if ! ./bin/developer system:uninstall > /dev/null 2>&1
then then
rm -f config/configuration.yml config/configuration-compiled.php rm -f config/configuration.yml config/configuration-compiled.php
fi fi
./bin/setup system:install --email=test@phraseanet.com --password=test --db-user=root --db-template=fr --db-password=toor --databox=db_test --appbox=ab_test --server-name=http://127.0.0.1 -y ./bin/setup system:install --email=test@phraseanet.com --password=test --db-user=root --db-template=fr --db-password=toor --databox=db_test --appbox=ab_test --server-name=http://127.0.0.1 -y -vvv
./bin/developer ini:reset --email=test@phraseanet.com --password=test --run-patches --no-setup-dbs ./bin/developer ini:reset --email=test@phraseanet.com --password=test --run-patches --no-setup-dbs -vvv
php resources/hudson/cleanupSubdefs.php php resources/hudson/cleanupSubdefs.php
./bin/developer ini:setup-tests-dbs ./bin/developer ini:setup-tests-dbs -vvv
./bin/developer phraseanet:regenerate-sqlite ./bin/developer phraseanet:regenerate-sqlite -vvv

View File

@@ -11,10 +11,9 @@ define([
"jquery", "jquery",
"underscore", "underscore",
"backbone", "backbone",
"common/websockets/connection",
"apps/admin/main/views/leftPanel", "apps/admin/main/views/leftPanel",
"apps/admin/main/views/rightPanel" "apps/admin/main/views/rightPanel"
], function ($, _, Backbone, WSConnection, LeftPanel, RightPanel) { ], function ($, _, Backbone, LeftPanel, RightPanel) {
window.AdminApp = { window.AdminApp = {
$scope: $("#admin-app"), $scope: $("#admin-app"),
$leftView : $(".left-view", this.$scope), $leftView : $(".left-view", this.$scope),
@@ -68,10 +67,6 @@ define([
throw "You must define a websocket url"; throw "You must define a websocket url";
} }
if (false === WSConnection.isConnected()) {
// WSConnection.connect(options.wsurl);
}
create(); create();
AdminApp.LeftView.activeTree(); AdminApp.LeftView.activeTree();

View File

@@ -11,9 +11,8 @@ define([
"jquery", "jquery",
"underscore", "underscore",
"backbone", "backbone",
"common/websockets/subscriberManager",
"jquery.treeview" "jquery.treeview"
], function ($, _, Backbone, SubscriberManager) { ], function ($, _, Backbone) {
var LeftPanelView = Backbone.View.extend({ var LeftPanelView = Backbone.View.extend({
initialize: function (options) { initialize: function (options) {
options = options || {}; options = options || {};

View File

@@ -12,14 +12,12 @@ define([
"underscore", "underscore",
"backbone", "backbone",
"models/scheduler", "models/scheduler",
"common/websockets/connection",
"common/websockets/subscriberManager",
"apps/admin/tasks-manager/views/scheduler", "apps/admin/tasks-manager/views/scheduler",
"apps/admin/tasks-manager/views/tasks", "apps/admin/tasks-manager/views/tasks",
"apps/admin/tasks-manager/views/ping", "apps/admin/tasks-manager/views/ping",
"apps/admin/tasks-manager/views/refresh", "apps/admin/tasks-manager/views/refresh",
"apps/admin/tasks-manager/collections/tasks" "apps/admin/tasks-manager/collections/tasks"
], function ($, _, Backbone, Scheduler, WSConnection, SubscriberManager, SchedulerView, TasksView, PingView, RefreshView, TasksCollection) { ], function ($, _, Backbone, Scheduler, SchedulerView, TasksView, PingView, RefreshView, TasksCollection) {
var create = function() { var create = function() {
window.TaskManagerApp = { window.TaskManagerApp = {
$scope: $("#task-manager-app"), $scope: $("#task-manager-app"),
@@ -55,23 +53,6 @@ define([
TaskManagerApp.tasksView.render(); TaskManagerApp.tasksView.render();
TaskManagerApp.schedulerView.render(); TaskManagerApp.schedulerView.render();
SubscriberManager.pushCallback(function(topic, msg) {
// double encoded string
var msg = JSON.parse(JSON.parse(msg));
WSConnection.trigger("ws:"+msg.event, msg);
});
// On ticks re-render ping view, update tasks & scheduler model
WSConnection.on("ws:manager-tick", function(response) {
TaskManagerApp.pingView.render();
TaskManagerApp.Scheduler.set({"actual": "started", "process-id": response.message.manager["process-id"]});
_.each(response.message.jobs, function(data, id) {
var jobModel = TaskManagerApp.tasksCollection.get(id);
if ("undefined" !== typeof jobModel) {
jobModel.set({"actual": data["status"], "process-id": data["process-id"]});
}
});
});
} }
); );
}; };

View File

@@ -1,53 +0,0 @@
define([
"underscore",
"backbone"
], function (_, Backbone) {
var activeSession = null;
return _.extend({
connect: function(url) {
if (this.isConnected()) {
throw "Connection is already active";
}
var that = this;
// autobahn js is defined as a global object there is no way to load
// it as a UMD module
ab.connect(url, function (session) {
activeSession = session;
that.trigger("ws:connect", activeSession);
},
function (code, reason) {
that.trigger("ws:session-gone", code, reason);
});
},
close: function() {
if (false === this.isConnected()) {
throw "Not connected to websocket";
}
activeSession.close();
activeSession = null;
this.trigger("ws:session-close");
},
isConnected: function() {
return activeSession !== null;
},
subscribe: function(topic, callback) {
if (false === this.isConnected()) {
this.on("ws:connect", function(session) {
session.subscribe(topic, callback);
this.trigger("ws:session-subscribe", topic);
});
return;
}
activeSession.subscribe(topic, callback);
this.trigger("ws:session-subscribe", topic);
},
unsubscribe: function(topic, callback) {
if (false === this.isConnected()) {
return;
}
activeSession.unsubscribe(topic, callback);
this.trigger("ws:session-unsubscribe", topic);
}
}, Backbone.Events);
});

View File

@@ -1,39 +0,0 @@
define([
"underscore",
"backbone",
"common/websockets/connection"
], function (_, Backbone, WSConnection) {
var currentTopic = null;
var callbackStack = [];
var callbackHandler = function (topic, msg) {
_.each(callbackStack, function(cb) {
cb(topic, msg);
});
};
var reset = function () {
callbackStack = [];
currentTopic = null;
};
return {
'register': function (topic) {
this.unregister();
WSConnection.subscribe(topic, callbackHandler);
currentTopic = topic;
},
'unregister': function () {
if (currentTopic !== null) {
WSConnection.unsubscribe(currentTopic);
reset();
}
},
'pushCallback': function (callback) {
callbackStack.push(callback);
},
'hasCallbacks' : function() {
return callbackStack.length > 0;
}
}
});

View File

@@ -1,86 +0,0 @@
define([
'chai',
'sinonchai',
'underscore',
'common/websockets/connection'
], function (chai, sinonchai, _, connection) {
var expect = chai.expect;
var assert = chai.assert;
var should = chai.should();
chai.use(sinonchai);
describe("Connection", function () {
describe("Functionnal", function () {
beforeEach(function () {
this.session = {"hello":"session"};
this.session.close = sinon.spy();
this.session.subscribe = sinon.spy();
this.session.unsubscribe = sinon.spy();
this.wsConnection = connection;
var $this = this;
var cbSuccess = function (session) {
activeSession = $this.session;
};
window.ab = {
connect: function(url, cbSuccess, cbError) {
cbSuccess($this.session);
}
}
});
afterEach(function () {
if (this.wsConnection.isConnected()) {
this.wsConnection.close();
}
});
it("should have a session", function () {
this.wsConnection.connect();
assert.ok(this.wsConnection.isConnected());
});
it("should close the session", function () {
this.wsConnection.connect();
assert.ok(this.wsConnection.isConnected());
this.wsConnection.close();
assert.ok(!this.wsConnection.isConnected());
});
it("should warn if you close the session and you are not connected", function () {
var throws = false;
try {
this.wsConnection.close();
} catch (e) {
throws = true;
}
assert.ok(throws);
});
it("should not connect anymore after first connect", function () {
var throws = false;
this.wsConnection.connect();
try {
this.wsConnection.connect();
} catch (e) {
throws = true;
}
assert.ok(throws);
});
it("should call session subscribe once", function () {
this.wsConnection.connect();
this.wsConnection.subscribe();
expect(this.session.subscribe.should.have.callCount(1)).to.be.ok;
});
it("should call session unsubscribe once", function () {
this.wsConnection.connect();
this.wsConnection.unsubscribe();
expect(this.session.unsubscribe.should.have.callCount(1)).to.be.ok;
});
});
});
});

View File

@@ -1,73 +0,0 @@
define([
'chai',
'sinonchai',
'underscore',
'squire'
], function(chai, sinonchai, _, Squire) {
var expect = chai.expect;
var assert = chai.assert;
var should = chai.should();
chai.use(sinonchai);
(function () {
describe("SubscriberManager", function () {
beforeEach(function () {
var $this = this;
$this.connection = {};
$this.connection.subscribe = sinon.spy();
$this.connection.unsubscribe = sinon.spy();
});
it("should call subscribe", function () {
var $this = this;
var injector = new Squire();
injector.mock(
["common/websockets/connection"], $this.connection
).require(['common/websockets/subscriberManager'], function(manager) {
manager.register('topic');
expect($this.connection.subscribe.should.have.callCount(1)).to.be.ok;
assert.ok(manager.hasCallbacks());
});
try{
injector.remove();
} catch(e) {
}
});
it("should call unsubscribe", function () {
var $this = this;
var injector = new Squire();
injector.mock(
["common/websockets/connection"], $this.connection
).require(['common/websockets/subscriberManager'], function(manager) {
manager.register('topic');
manager.unregister();
expect($this.connection.unsubscribe.should.have.callCount(1)).to.be.ok;
assert.ok(!manager.hasCallbacks());
});
try{
injector.remove();
} catch(e) {
}
});
it("should add callbacks", function () {
var $this = this;
var injector = new Squire();
injector.mock(
["common/websockets/connection"], $this.connection
).require(['common/websockets/subscriberManager'], function(manager) {
assert.ok(!manager.hasCallbacks());
manager.pushCallback(function(){return null;});
assert.ok(manager.hasCallbacks());
});
try{
injector.remove();
} catch(e) {
}
});
});
})();
});

View File

@@ -1,33 +0,0 @@
<!doctype html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Mocha Spec Runner</title>
<link rel="stylesheet" href="../../assets/mocha/mocha.css">
</head>
<body>
<div id="mocha"></div>
<script src="../../assets/mocha/mocha.js"></script>
<script src="../../assets/sinonjs/sinon.js"></script>
<script src="../../assets/requirejs/require.js"></script>
<script src="common.js"></script>
<script>
mocha.setup({
ui: "bdd",
ignoreLeaks: false,
globals: ['ab']
});
require([
'tests/specs/websockets/connection',
'tests/specs/websockets/subscriberManager'
], function () {
if (window.mochaPhantomJS) {
mochaPhantomJS.run();
} else {
mocha.run();
}
});
</script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 942 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 548 B

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -276,7 +276,8 @@ span.ww_winTitle {
} }
#idFrameC .ui-tabs #thesaurus_tab li.th_tab { #idFrameC .ui-tabs #thesaurus_tab li.th_tab {
height: 34px; height: 23px;
margin-left: 10px;
} }
#THPD_T, #THPD_C { #THPD_T, #THPD_C {
@@ -957,6 +958,7 @@ div.diapo {
top: 0px; top: 0px;
left: 10px; left: 10px;
right: 10px; right: 10px;
margin-top: 21px;
} }
#idFrameC .ui-tabs .ui-tabs-panel,#idFrameE .ui-tabs .ui-tabs-panel { #idFrameC .ui-tabs .ui-tabs-panel,#idFrameE .ui-tabs .ui-tabs-panel {
@@ -1115,6 +1117,16 @@ div.diapo {
display: block; display: block;
} }
#baskets .menu .contextMenuTrigger {
cursor: pointer;
display: block;
padding: 0;
margin: 0;
background: url('../../icons/contextMenuTrigger.png') 0 13px no-repeat;
height: 45px;
width: 13px;
}
/** hack IE7 only */ /** hack IE7 only */
*:first-child+html .workzone-menu-title { *:first-child+html .workzone-menu-title {
margin-right:65px; margin-right:65px;
@@ -4405,7 +4417,47 @@ ui-dialog-titlebar {
max-heigh: 16px; max-heigh: 16px;
} }
#answers .status img { #paginate {
max-width: 16px; position: absolute;
max-heigh: 16px; bottom: 30px;
right: 65px;
}
#paginate #tool_navigate {
background-color: #000;
/*border: 1px solid #3b3b3b;*/
}
#paginate #tool_navigate input,
#paginate #tool_navigate a {
border: none;
border-top: 1px solid #3b3b3b;
border-bottom: 1px solid #3b3b3b;
padding: 0;
margin: 0;
border-radius: 0;
height: 50px;
line-height: 50px;
vertical-align: middle;
width: 30px;
background: none;
font-weight: normal;
text-shadow: none;
box-shadow: none;
color: #3b3b3b;
}
#paginate #tool_navigate:first-child {
border-left: 1px solid #3b3b3b;
}
#paginate #tool_navigate:last-child {
border-right: 1px solid #3b3b3b;
}
#paginate #tool_navigate input,
#paginate #tool_navigate a:hover {
color: #fff;
background: #076882;
} }