Commit 0b923227 authored by Henning Leutz's avatar Henning Leutz 🥋

Merge branch 'dev'

parents ba249863 12960541
......@@ -57,7 +57,8 @@ QUI::$Ajax->registerFunction(
'apc',
'filesystem',
'redis',
'memcache'
'memcache',
'mongo'
], 0);
if (isset($params['handlers'][$cacheType])) {
......
<?php
/**
* cache purging
*/
QUI::$Ajax->registerFunction(
'ajax_system_cache_mongoAvailable',
function () {
try {
QUI::getPackage('mongodb/mongodb');
} catch (QUI\Exception $Exception) {
return false;
}
return \class_exists('\MongoDB\Client');
},
false,
'Permission::checkSU'
);
<?php
/**
* mongoDB data check
*/
use QUI\Cache\QuiqqerMongoDriver;
QUI::$Ajax->registerFunction(
'ajax_system_cache_mongoCheck',
function ($host, $database, $collection, $username, $password) {
try {
QUI::getPackage('mongodb/mongodb');
} catch (QUI\Exception $Exception) {
throw new QUI\Exception('MongoDB Client not installed');
}
if (!\class_exists('\MongoDB\Client')) {
throw new QUI\Exception('MongoDB Client not installed');
}
// database server
if (empty($host)) {
$host = 'localhost';
}
if (empty($database)) {
$database = 'local';
}
if (empty($collection)) {
$collection = 'quiqqer.longterm';
}
if (\strpos($host, 'mongodb://') === false) {
$host = 'mongodb://'.$host;
}
if (!empty($username) && !empty($password)) {
$Client = new \MongoDB\Client($host, [
"username" => $username,
"password" => $password
]);
} else {
$Client = new \MongoDB\Client($host);
}
$CacheDriver = new QuiqqerMongoDriver([
'mongo' => $Client,
'database' => $database,
'collection' => $collection
]);
$CacheDriver->storeData(['db-test'], 1, false);
$result = $CacheDriver->getData(['db-test']);
if ($result['data'] === 1) {
QUI::getMessagesHandler()->addSuccess(
QUI::getLocale()->get('quiqqer/quiqqer', 'message.quiqqer.mongo.success')
);
} else {
QUI::getMessagesHandler()->addError(
QUI::getLocale()->get('quiqqer/quiqqer', 'message.quiqqer.mongo.error')
);
}
},
['host', 'database', 'collection', 'username', 'password'],
'Permission::checkSU'
);
......@@ -27,6 +27,9 @@
<conf name="redis">
<type><![CDATA[bool]]></type>
</conf>
<conf name="mongo">
<type><![CDATA[bool]]></type>
</conf>
</section>
<section name="apc">
......@@ -74,12 +77,21 @@
<conf name="type">
<type><![CDATA[string]]></type>
</conf>
<conf name="mongo_host">
<type><![CDATA[string]]></type>
</conf>
<conf name="mongo_database">
<type><![CDATA[string]]></type>
</conf>
<conf name="mongo_collection">
<type><![CDATA[string]]></type>
</conf>
<conf name="mongo_username">
<type><![CDATA[string]]></type>
</conf>
<conf name="mongo_password">
<type><![CDATA[string]]></type>
</conf>
<conf name="file_path">
<type><![CDATA[string]]></type>
</conf>
......@@ -139,6 +151,9 @@
<option value="redis">
<locale group="quiqqer/quiqqer" var="quiqqer.settings.cache.handler.redis"/>
</option>
<option value="mongo">
<locale group="quiqqer/quiqqer" var="quiqqer.settings.cache.handler.mongo"/>
</option>
</select>
</settings>
......@@ -224,6 +239,38 @@
</description>
</input>
</settings>
<settings title="mongo" name="mongo">
<title>
<locale group="quiqqer/quiqqer" var="quiqqer.settings.mongo.title"/>
</title>
<input conf="mongo.host" type="text" placeholder="localhost">
<text>
<locale group="quiqqer/quiqqer" var="quiqqer.settings.mongo.server"/>
</text>
</input>
<input conf="mongo.database" type="text" placeholder="local">
<text>
<locale group="quiqqer/quiqqer" var="quiqqer.settings.mongo.database"/>
</text>
</input>
<input conf="mongo.collection" type="text" placeholder="quiqqer.cache">
<text>
<locale group="quiqqer/quiqqer" var="quiqqer.settings.mongo.collection"/>
</text>
</input>
<input conf="mongo.username" type="text">
<text>
<locale group="quiqqer/quiqqer" var="quiqqer.settings.mongo.username"/>
</text>
</input>
<input conf="mongo.password" type="text">
<text>
<locale group="quiqqer/quiqqer" var="quiqqer.settings.mongo.password"/>
</text>
</input>
</settings>
</category>
<category name="longtime" require="controls/cache/LongTime">
......@@ -297,11 +344,16 @@
<locale group="quiqqer/quiqqer" var="quiqqer.settings.longTimeCache.mongo.title"/>
</title>
<input conf="longtime.mongo_database" type="text" placeholder="local">
<input conf="longtime.mongo_host" type="text" placeholder="localhost">
<text>
<locale group="quiqqer/quiqqer" var="quiqqer.settings.longTimeCache.mongo.server"/>
</text>
</input>
<input conf="longtime.mongo_database" type="text" placeholder="local">
<text>
<locale group="quiqqer/quiqqer" var="quiqqer.settings.longTimeCache.mongo.database"/>
</text>
</input>
<input conf="longtime.mongo_collection" type="text" placeholder="quiqqer.store">
<text>
......@@ -309,6 +361,20 @@
var="quiqqer.settings.longTimeCache.mongo_collection.server"/>
</text>
</input>
<input conf="longtime.mongo_username" type="text">
<text>
<locale group="quiqqer/quiqqer"
var="quiqqer.settings.longTimeCache.mongo.username"/>
</text>
</input>
<input conf="longtime.mongo_password" type="text">
<text>
<locale group="quiqqer/quiqqer"
var="quiqqer.settings.longTimeCache.mongo.password"/>
</text>
</input>
</settings>
</category>
......
......@@ -348,6 +348,18 @@ define('classes/projects/project/media/panel/ContextMenu', [
return;
}
var id, ids;
// check if its the same id
if (typeOf(Element) === 'element') {
ids = Element.get('data-ids').split(',');
id = Droppable.get('data-id');
if (ids.length === 1 && ids[0] === id) {
return;
}
}
var self = this,
Menu = this.getPanel().getContextMenu(),
title = Droppable.get('title'),
......@@ -449,8 +461,8 @@ define('classes/projects/project/media/panel/ContextMenu', [
}
var ids = Element.get('data-ids').split(','),
id = Droppable.get('data-id');
ids = Element.get('data-ids').split(',');
id = Droppable.get('data-id');
// show choices
Menu.appendChild(
......
......@@ -94,17 +94,20 @@ define('controls/cache/General', [
* event: on type change
*/
$onTypeChange: function () {
var Elm = this.getElm(),
var self = this,
Elm = this.getElm(),
CacheType = Elm.querySelector('[name="general.cacheType"]'),
RedisTable = Elm.querySelector('[name="general.redis"]').getParent('table'),
APCTable = Elm.querySelector('[name="apc.namespace"]').getParent('table'),
MemTable = Elm.querySelector('[name="memcache.servers"]').getParent('table'),
MongoTable = Elm.querySelector('[name="mongo.host"]').getParent('table'),
FileTable = Elm.querySelector('[name="filesystem.path"]').getParent('table');
RedisTable.setStyle('display', 'none');
APCTable.setStyle('display', 'none');
MemTable.setStyle('display', 'none');
FileTable.setStyle('display', 'none');
MongoTable.setStyle('display', 'none');
switch (CacheType.value) {
case 'apc':
......@@ -119,6 +122,58 @@ define('controls/cache/General', [
RedisTable.setStyle('display', null);
break;
case 'mongo':
MongoTable.setStyle('display', null);
CacheType.disabled = true;
// availability check
this.checkMongoAvailability().then(function (availability) {
CacheType.disabled = false;
MongoTable.getElements('.mongo-error-message').destroy();
MongoTable.getElements('.mongo-check-button').destroy();
if (!availability) {
var RowMessage = new Element('tr', {
'class': 'mongo-error-message',
html : '<td>' +
'<div class="messages-message message-error">' +
QUILocale.get('quiqqer/quiqqer', 'message.quiqqer.mongo.missing') +
'</div>' +
'</td>'
});
RowMessage.inject(
MongoTable.getElement('tbody'),
'top'
);
return;
}
new Element('tr', {
'class': 'mongo-check-button',
html : '<td>' +
'<button class="qui-button" style="float: right">' +
QUILocale.get('quiqqer/quiqqer', 'message.quiqqer.mongo.button') +
'</button>' +
'</td>'
}).inject(MongoTable.getElement('tbody'));
var Button = MongoTable.getElement('button');
Button.addEvent('click', function () {
Button.disabled = true;
Button.set('html', '<span class="fa fa-spinner fa-spin"></span>');
self.checkMongoDB().then(function () {
Button.disabled = false;
Button.set('html', QUILocale.get('quiqqer/quiqqer', 'message.quiqqer.mongo.button'));
});
});
});
break;
default:
case 'filesystem':
FileTable.setStyle('display', null);
......@@ -159,6 +214,37 @@ define('controls/cache/General', [
}, {
server: this.getElm().querySelector('[name="general.redis"]').value
});
},
/**
* Checks, if mongoDB can be used
*
* @return {Promise}
*/
checkMongoAvailability: function () {
return new Promise(function (resolve) {
QUIAjax.get('ajax_system_cache_mongoAvailable', resolve);
});
},
/**
* Checks, if mongoDB can be used
*
* @return {Promise}
*/
checkMongoDB: function () {
var Elm = this.getElm(),
Form = Elm.querySelector('[name="mongo.host"]').getParent('form');
return new Promise(function (resolve) {
QUIAjax.get('ajax_system_cache_mongoCheck', resolve, {
'host' : Form.elements['mongo.host'].value,
'database' : Form.elements['mongo.database'].value,
'collection': Form.elements['mongo.collection'].value,
'username' : Form.elements['mongo.username'].value,
'password' : Form.elements['mongo.password'].value
});
});
}
});
});
......@@ -93,7 +93,8 @@ define('controls/cache/LongTime', [
* event: on type change
*/
$onTypeChange: function () {
var Elm = this.getElm(),
var self = this,
Elm = this.getElm(),
CacheType = Elm.querySelector('[name="longtime.type"]'),
RedisTable = Elm.querySelector('[name="longtime.redis_server"]').getParent('table'),
FileTable = Elm.querySelector('[name="longtime.file_path"]').getParent('table'),
......@@ -106,6 +107,54 @@ define('controls/cache/LongTime', [
switch (CacheType.value) {
case 'mongo':
MongoTable.setStyle('display', null);
CacheType.disabled = true;
// availability check
this.checkMongoAvailability().then(function (availability) {
CacheType.disabled = false;
MongoTable.getElements('.mongo-error-message').destroy();
MongoTable.getElements('.mongo-check-button').destroy();
if (!availability) {
var RowMessage = new Element('tr', {
'class': 'mongo-error-message',
html : '<td>' +
'<div class="messages-message message-error">' +
QUILocale.get('quiqqer/quiqqer', 'message.quiqqer.mongo.missing') +
'</div>' +
'</td>'
});
RowMessage.inject(
MongoTable.getElement('tbody'),
'top'
);
return;
}
new Element('tr', {
'class': 'mongo-check-button',
html : '<td>' +
'<button class="qui-button" style="float: right">' +
QUILocale.get('quiqqer/quiqqer', 'message.quiqqer.mongo.button') +
'</button>' +
'</td>'
}).inject(MongoTable.getElement('tbody'));
var Button = MongoTable.getElement('button');
Button.addEvent('click', function () {
Button.disabled = true;
Button.set('html', '<span class="fa fa-spinner fa-spin"></span>');
self.checkMongoDB().then(function () {
Button.disabled = false;
Button.set('html', QUILocale.get('quiqqer/quiqqer', 'message.quiqqer.mongo.button'));
});
});
});
break;
case 'redis':
......@@ -185,6 +234,43 @@ define('controls/cache/LongTime', [
}
}
}).open();
},
/**
* Checks, if mongoDB can be used
*
* @return {Promise}
*/
checkMongoAvailability: function () {
return new Promise(function (resolve) {
QUIAjax.get('ajax_system_cache_mongoAvailable', resolve);
});
},
/**
* Checks, if mongoDB can be used
*
* @return {Promise}
*/
checkMongoDB: function () {
var Elm = this.getElm(),
Form = Elm.querySelector('[name="longtime.mongo_host"]').getParent('form');
var collection = 'quiqqer.store';
if (Form.elements['longtime.mongo_collection'].value !== '') {
collection = Form.elements['longtime.mongo_collection'].value;
}
return new Promise(function (resolve) {
QUIAjax.get('ajax_system_cache_mongoCheck', resolve, {
'host' : Form.elements['longtime.mongo_host'].value,
'database' : Form.elements['longtime.mongo_database'].value,
'collection': collection,
'username' : Form.elements['longtime.mongo_username'].value,
'password' : Form.elements['longtime.mongo_password'].value
});
});
}
});
});
......@@ -110,6 +110,10 @@ define('controls/menu/Manager', [
Menu = document.getElement('.qui-menu-container'),
letter = USER.name.substr(0, 1);
if (!self.$Profile) {
return;
}
var ContextMenu = self.$Profile.getContextMenu();
ContextMenu.addEvent('blur', function () {
......
......@@ -1171,7 +1171,7 @@ define('controls/projects/project/media/Panel', [
if (!files.length) {
return;
}
console.log('$viewOnDrop');
if (Elm.hasClass('qui-media-content')) {
this.$PanelContextMenu.showDragDropMenu(files, Elm, event);
return;
......
......@@ -36,7 +36,7 @@ define('controls/upload/Manager', [
return new Class({
Extends: QUIPanel,
Type : 'controls/upload/Manager',
Type: 'controls/upload/Manager',
Binds: [
'$onCreate',
......@@ -47,19 +47,19 @@ define('controls/upload/Manager', [
],
options: {
icon : 'fa fa-upload',
icon: 'fa fa-upload',
pauseAllowed: true,
contextMenu : true
contextMenu: true
},
initialize: function (options) {
this.parent(options);
this.$files = [];
this.$files = [];
this.$container = null;
this.$uploads = {};
this.$uploads = {};
this.$maxPercent = 0;
this.$maxPercent = 0;
this.$uploadPerCents = {};
this.$Container = null;
......@@ -79,8 +79,8 @@ define('controls/upload/Manager', [
}).inject(this.getContent());
this.addButton({
icon : 'fa fa-trash',
title : Locale.get(lg, 'upload.manager.clear'),
icon: 'fa fa-trash',
title: Locale.get(lg, 'upload.manager.clear'),
styles: {
'float': 'right'
},
......@@ -219,10 +219,10 @@ define('controls/upload/Manager', [
// ask for extraction
new QUIAlert({
title : Locale.get(lg, 'upload.manager.message.archivfile.title'),
content : Locale.get(lg, 'upload.manager.message.archivfile.text') + '<br />' + list,
title: Locale.get(lg, 'upload.manager.message.archivfile.title'),
content: Locale.get(lg, 'upload.manager.message.archivfile.text') + '<br />' + list,
closeButtonText: Locale.get(lg, 'upload.manager.message.archivfile.btn.start'),
events : {
events: {
onClose: function (Win) {
var i, len;
......@@ -276,7 +276,17 @@ define('controls/upload/Manager', [
self.$onFileUploadRefresh();
};
var onError = function (Exception) {
var onError = function (Exception, File) {
var newFileList = [];
for (var i = 0, len = self.$files.length; i < len; i++) {
if (self.$files[i].$File !== File.$File) {
newFileList.push(self.$files);
}
}
self.$files = newFileList;
if ('error' in self.$events) {
self.fireEvent('error', [Exception]);
return;
......@@ -288,11 +298,20 @@ define('controls/upload/Manager', [
};
var onCancel = function (File) {
var newFileList = [];
for (var i = 0, len = self.$files.length; i < len; i++) {
if (self.$files[i].$File !== File.$File) {
newFileList.push(self.$files);
}
}
self.$files = newFileList;
self.fireEvent('fileCancel', [self, File]);
};
for (i = 0, len = files.length; i < len; i++) {
file_params = Object.clone(params);
file_params = Object.clone(params);
file_params.extract = false;
if (extract && extract[files[i].name]) {
......@@ -306,18 +325,18 @@ define('controls/upload/Manager', [
}
var QUIFile = new UploadFile(files[i], {
phpfunc : rf,
params : file_params,
events : events,
phpfunc: rf,
params: file_params,
events: events,
pauseAllowed: this.getAttribute('pauseAllowed'),
contextMenu : this.getAttribute('contextMenu')
contextMenu: this.getAttribute('contextMenu')
});
QUIFile.addEvents({
onComplete: onComplete,
onRefresh : onRefresh,
onError : onError,
onCancel : onCancel
onRefresh: onRefresh,
onError: onError,
onCancel: onCancel
});
if (file_params.phponstart) {
......@@ -340,13 +359,13 @@ define('controls/upload/Manager', [
Node.setStyles({
background: '#fff',
border : '1px solid #f1f1f1',
bottom : 10,
boxShadow : '0 0 10px rgba(0, 0, 0, 0.3)',
position : 'absolute',
right : 10,
width : 300,
zIndex : 1000
border: '1px solid #f1f1f1',
bottom: 10,
boxShadow: '0 0 10px rgba(0, 0, 0, 0.3)',
position: 'absolute',
right: 10,
width: 300,
zIndex: 1000
});
Node.inject(document.body);
......@@ -425,10 +444,10 @@ define('controls/upload/Manager', [
QUIFile = new UploadFile(params.file, {
phpfunc: params.phpfunc,
params : params,
events : {
params: params,
events: {
onComplete: func_oncomplete,
onCancel : func_oncancel
onCancel: func_oncancel
}
});
......
......@@ -696,7 +696,7 @@ define('controls/users/Panel', [
return;
}
if (Switch.getStatus() === false) {
if (!Switch.getStatus()) {
new QUIConfirm({
title : QUILocale.get(lg, 'users.panel.deactivate.window.title'),
text : QUILocale.get(lg, 'users.panel.deactivate.window.text', {
......
......@@ -202,28 +202,51 @@ class LongTermCache
break;
case 'mongo':
$conf = $Config->get('longtime');
$database = 'localhost';
$collection = \md5(__FILE__);
if (!class_exists('\MongoDB\Client')) {
QUI\System\Log::write(
'Mongo DB Driver not found.
Please install MongoDB\Client (php MongoDB extension) and the mongodb/mongodb package.
Otherwise don\'t use MongoDB as long term cache',
QUI\System\Log::LEVEL_ALERT
);
} else {
$conf = $Config->get('longtime');
$host = 'localhost';
$database = 'local';
$collection = 'quiqqer.longterm';
// database server
if (!empty($conf['mongo_host'])) {
$host = $conf['mongo_host'];
}
// database server
if (!empty($conf['mongo_database'])) {
$database = $conf['mongo_database'];
}
if (!empty($conf['mongo_database'])) {
$database = $conf['mongo_database'];
}