Commit 98ef4b11 authored by Henning Leutz's avatar Henning Leutz 🥋

Merge branch 'master' into 1.5

parents 02c1360c 759e8d6a
......@@ -3,4 +3,5 @@ etc/
media/
var/
.htaccess
!ajax/media/
\ No newline at end of file
!ajax/media/
!bin/QUI/controls/projects/project/media
1.5.0 ()
1.5.1 ()
Fix
- Sort Error fixed; Sorting consider inactive Sites
- quiqqer/quiqqer#1033 No Vhosts and only one language -> Links with language flag
- quiqqer/quiqqer#728 removed robloach/component-installer
1.5.0 (11.09.2020)
Features
......
......@@ -6,9 +6,7 @@
QUI::$Ajax->registerFunction(
'ajax_desktop_workspace_load',
function () {
$list = QUI\Workspace\Manager::getWorkspacesByUser(
QUI::getUserBySession()
);
$list = QUI\Workspace\Manager::getWorkspacesByUser(QUI::getUserBySession());
if (!QUI::conf('mail', 'admin_mail') || QUI::conf('mail', 'admin_mail') === '') {
QUI::getMessagesHandler()->addError(
......
<?php
use QUI\System\License;
/**
* Activate this QUIQQER system for the currently registered license
*
* @return array - Request response
*/
QUI::$Ajax->registerFunction(
'ajax_licenseKey_activate',
function () {
try {
return License::activateSystem();
} catch (\Exception $Exception) {
QUI\System\Log::writeException($Exception);
throw $Exception;
}
},
[],
'Permission::checkAdminUser'
);
<?php
use QUI\System\License;
/**
* Check license status
*
* @return array
* @throws QUI\Exception
*/
QUI::$Ajax->registerFunction(
'ajax_licenseKey_checkStatus',
function () {
try {
return License::getStatus();
} catch (\Exception $Exception) {
QUI\System\Log::writeException($Exception);
throw $Exception;
}
},
[],
'Permission::checkAdminUser'
);
<?php
use QUI\Security\Encryption;
use QUI\Utils\System\File;
use QUI\System\License;
use QUI\Config;
/**
......@@ -13,11 +12,16 @@ QUI::$Ajax->registerFunction(
'ajax_licenseKey_get',
function () {
$licenseConfigFile = CMS_DIR.'etc/license.ini.php';
$default = [
'id' => '-',
'created' => '-',
'validUntil' => '-',
'name' => '-',
$systemId = License::getSystemId();
$systemDataHash = License::getSystemDataHash();
$default = [
'systemId' => $systemId,
'systemDataHash' => $systemDataHash,
'id' => '-',
'created' => '-',
'validUntil' => '-',
'name' => '-',
];
if (!\file_exists($licenseConfigFile)) {
......@@ -41,6 +45,9 @@ QUI::$Ajax->registerFunction(
unset($data['keyHash']);
$data['systemId'] = $systemId;
$data['systemDataHash'] = $systemDataHash;
return $data;
},
[],
......
<?php
use QUI\Security\Encryption;
use QUI\Utils\System\File;
use QUI\Config;
use QUI\System\License;
/**
* Upload a license key file
......@@ -15,67 +13,8 @@ QUI::$Ajax->registerFunction(
'ajax_licenseKey_upload',
function ($File) {
try {
$content = \file_get_contents($File->getAttribute('filepath'));
$content = \json_decode(hex2bin($content), true);
if (\json_last_error() !== JSON_ERROR_NONE) {
throw new QUI\Exception('JSON Error in license data: '.\json_last_error_msg());
}
$keys = [
'id',
'created',
'licenseHash',
'licenseServer',
'validUntil',
'name'
];
foreach ($keys as $key) {
if (!isset($content[$key])) {
throw new QUI\Exception('Missing key "'.$key.'" in license data.');
}
if (empty($content[$key])) {
throw new QUI\Exception('Empty key "'.$key.'" in license data.');
}
if (!is_string($content[$key])) {
throw new QUI\Exception('Non-string key "'.$key.'" in license data.');
}
}
// put license data in config
$licenseConfigFile = CMS_DIR.'etc/license.ini.php';
File::mkfile($licenseConfigFile);
if (!\file_exists($licenseConfigFile)) {
throw new QUI\Exception('Could not create license config file "'.$licenseConfigFile.'"');
}
$LicenseConfig = new Config($licenseConfigFile);
$LicenseConfig->set('license', 'id', $content['id']);
$LicenseConfig->set('license', 'created', $content['created']);
$LicenseConfig->set('license', 'name', $content['name']);
$LicenseConfig->set('license', 'validUntil', $content['validUntil']);
$LicenseConfig->set(
'license',
'licenseHash',
\bin2hex(Encryption::encrypt(\hex2bin($content['licenseHash'])))
);
$LicenseConfig->save($licenseConfigFile);
// set license server
$Config = new QUI\Config(ETC_DIR.'conf.ini.php');
$Config->set('license', 'url', $content['licenseServer']);
$Config->save();
// re-create composer.json
QUI::getPackageManager()->refreshServerList();
License::registerLicenseFile($File);
} catch (\Exception $Exception) {
QUI\System\Log::addError('AJAX :: ajax_licenseKey_upload');
QUI\System\Log::writeException($Exception);
QUI::getMessagesHandler()->addError(
......
<?php
use QUI\Config;
/**
* Checks if this QUIQQER system has the license to use $package
*
* @param string $package
* @return bool
*/
QUI::$Ajax->registerFunction(
'ajax_packages_hasLicense',
function ($licensePackage) {
return QUI::getPackageManager()->hasLicense(\QUI\Utils\Security\Orthos::clear($licensePackage));
},
['licensePackage'],
'Permission::checkAdminUser'
);
......@@ -10,27 +10,23 @@
QUI::$Ajax->registerFunction(
'ajax_project_create',
function ($params) {
$params = \json_decode($params, true);
$Project = QUI\Projects\Manager::createProject(
$params['project'],
$params['lang']
);
$params = \json_decode($params, true);
$template = '';
// @todo check if template is allowed
if (isset($params['template']) && !empty($params['template'])) {
$Config = QUI::getProjectManager()->getConfig();
$installedTemplates = QUI::getPackageManager()->searchInstalledPackages([
'type' => 'quiqqer-template'
]);
$template = $params['template'];
$template = QUI\Utils\Security\Orthos::removeHTML($template);
$template = QUI\Utils\Security\Orthos::clearPath($template);
$Config->set($Project->getName(), 'template', $template);
$Config->save();
}
$Project = QUI\Projects\Manager::createProject(
$params['project'],
$params['lang'],
[],
$template
);
if (isset($params['demodata']) && $params['demodata'] && isset($template)) {
QUI\Utils\Project::applyDemoDataToProject($Project, $template);
}
......
......@@ -8,7 +8,11 @@
*/
QUI::$Ajax->registerFunction(
'ajax_settings_window',
function ($file) {
function ($file, $windowName) {
if (!isset($windowName) || \strpos($windowName, '.xml') !== false) {
$windowName = false;
}
if (\file_exists($file)) {
$files = [$file];
} else {
......@@ -18,13 +22,16 @@ QUI::$Ajax->registerFunction(
$cacheName = 'quiqqer/package/quiqqer/quiqqer/menu/windows/'.\md5(\json_encode($files));
$Settings = QUI\Utils\XML\Settings::getInstance();
if ($windowName) {
$cacheName .= \md5($windowName);
}
try {
$result = QUI\Cache\Manager::get($cacheName);
} catch (QUI\Exception $Exception) {
$windowName = false;
if (\is_array($files) &&
\in_array('packages/quiqqer/quiqqer/admin/settings/cache.xml', $files)) {
if (!$windowName
&& \is_array($files)
&& \in_array('packages/quiqqer/quiqqer/admin/settings/cache.xml', $files)) {
$windowName = 'quiqqer-cache';
}
......@@ -73,6 +80,6 @@ QUI::$Ajax->registerFunction(
return $result;
},
['file'],
['file', 'windowName'],
'Permission::checkAdminUser'
);
......@@ -23,7 +23,9 @@ QUI::$Ajax->registerFunction(
$Parent->save();
}
$childrenIds = $Parent->getChildrenIds();
$childrenIds = $Parent->getChildrenIds([
'active' => '0&1'
]);
foreach ($ids as $id) {
$from = $from + 1;
......
......@@ -69,6 +69,11 @@ QUI::$Ajax->registerFunction(
$Address->setAttributes($data);
$Address->save();
if (isset($data['standard']) && $data['standard'] === 1) {
$User->setAttribute('address', $Address->getId());
$User->save();
}
return $Address->getId();
},
['uid', 'aid', 'data'],
......
......@@ -151,6 +151,9 @@ if ($Avatar) {
var QUIQQER_HASH = "<?php echo QUI::getPackageManager()->getHash(); ?>";
var QUIQQER_CONFIG = <?php echo \json_encode($config); ?>;
// Exceptions
var QUIQQER_EXCEPTION_CODE_PACKAGE_NOT_LICENSED = <?php echo QUI::getPackageManager()::EXCEPTION_CODE_PACKAGE_NOT_LICENSED; ?>;
// standard project
var QUIQQER_PROJECT = <?php echo \json_encode([
'name' => $Project ? $Project->getName() : '',
......@@ -248,7 +251,7 @@ if ($Avatar) {
</div>
</noscript>
<script src="<?php echo URL_OPT_DIR; ?>bin/require.js"></script>
<script src="<?php echo URL_OPT_DIR; ?>bin/requirejs/require.js"></script>
<script src="<?php echo URL_OPT_DIR; ?>bin/qui/qui/lib/mootools-core.js"></script>
<script src="<?php echo URL_OPT_DIR; ?>bin/qui/qui/lib/mootools-more.js"></script>
<script src="<?php echo URL_OPT_DIR; ?>bin/qui/qui/lib/moofx.js"></script>
......
......@@ -328,7 +328,7 @@ foreach ($packages as $package) {
?>
<script src="<?php echo URL_OPT_DIR; ?>bin/require.js"></script>
<script src="<?php echo URL_OPT_DIR; ?>bin/r.js"></script>
<script src="<?php echo URL_OPT_DIR; ?>bin/qui/qui/lib/mootools-core.js"></script>
<script src="<?php echo URL_OPT_DIR; ?>bin/qui/qui/lib/mootools-more.js"></script>
<script src="<?php echo URL_OPT_DIR; ?>bin/qui/qui/lib/moofx.js"></script>
......@@ -376,13 +376,10 @@ foreach ($packages as $package) {
if ("language" in navigator) {
lang = navigator.language;
} else if ("browserLanguage" in navigator) {
lang = navigator.browserLanguage;
} else if ("systemLanguage" in navigator) {
lang = navigator.systemLanguage;
} else if ("userLanguage" in navigator) {
lang = navigator.userLanguage;
}
......@@ -405,7 +402,9 @@ foreach ($packages as $package) {
'locale/quiqqer/quiqqer/' + lang
], function (QUI, Session, QUILocale) {
QUILocale.setCurrent(lang);
Session.set('quiqqer-user-language', lang);
Session.set('quiqqer-user-language', lang).catch(function (err) {
// doesn't matter
});
var LoginElement = document.getElement('.quiqqer-login');
......
......@@ -610,6 +610,22 @@ define('classes/packages/Manager', [
onError : reject
});
});
},
/**
* Checks if this QUIQQER system has a specific package license
*
* @param {String} pkg
* @returns {Promise}
*/
hasPackageLicense: function (pkg) {
return new Promise(function (resolve, reject) {
Ajax.post('ajax_packages_hasLicense', resolve, {
'package' : pkg,
licensePackage: pkg,
onError : reject
});
});
}
});
});
......@@ -55,6 +55,36 @@ define('classes/projects/Manager', [
}
},
/**
* constructor
*
* @param {Object} options
*/
initialize: function (options) {
this.parent(options);
this.addEvents({
onProjectSave: function (Project) {
this.$getList = null;
var name = Project.getName(),
projects = {};
for (var key in this.$projects) {
if (!this.$projects.hasOwnProperty(key)) {
continue;
}
if (key.indexOf(name + '-') !== 0) {
projects[key] = this.$projects[key];
}
}
this.$projects = projects;
}.bind(this)
});
},
/**
* Return the wanted project
* If no name and lang given, the current project will be return
......
......@@ -163,16 +163,10 @@ define('classes/projects/Project', [
}
resolve(self.$config);
require(['Projects'], function (Projects) {
Projects.fireEvent('projectSave', [self]);
});
}, {
project: this.getName(),
onError: reject
});
}.bind(this));
},
......@@ -183,14 +177,12 @@ define('classes/projects/Project', [
getDefaults: function () {
var self = this;
return new Promise(function (resolve, reject) {
Ajax.get('ajax_project_get_defaults', function (result) {
resolve(result);
}, {
project: self.encode(),
onError: reject
});
});
},
......@@ -238,6 +230,10 @@ define('classes/projects/Project', [
resolve(result);
self.fireEvent('save');
require(['Projects'], function (Projects) {
Projects.fireEvent('projectSave', [self]);
});
}, {
project: self.getName(),
params : JSON.encode(params || false),
......@@ -284,6 +280,19 @@ define('classes/projects/Project', [
return this.getAttribute('lang');
},
/**
* Return all languages
*
* @return {Array}
*/
getLanguages: function () {
if (!this.getAttribute('langs')) {
return [this.getLang()];
}
return this.getAttribute('langs').split(',');
},
/**
* Return the project title
*
......
......@@ -463,6 +463,26 @@ define('classes/projects/project/Media', [
onError: reject
});
});
},
//region search
/**
* Search files into the media
*
* @return {Promise}
*/
search: function (search, params) {
var self = this;
return new Promise(function (resolve, reject) {
Ajax.get('ajax_media_search', resolve, {
project: self.getProject().getName(),
search : search,
params : JSON.encode(params),
onError: reject
});
});
}
});
});
......@@ -195,6 +195,15 @@ define('classes/request/Bundler', [
onCancel: function () {
this.fireEvent('requestCancel', [this]);
}.bind(this),
onFailure: function (xhr) {
if (xhr.responseText !== '') {
this.$parseResponse(xhr.responseText, Params, requestData);
}
this.fireEvent('requestFailure', [this]);
this.fireEvent('requestCancel', [this]);
}.bind(this)
});
......@@ -280,6 +289,8 @@ define('classes/request/Bundler', [
return false;
};
var maintenance = false;