mirror of
https://github.com/humhub/humhub.git
synced 2025-01-17 14:18:27 +01:00
Merge branch 'v1.2-dev' of https://github.com/humhub/humhub into v1.2-dev
This commit is contained in:
commit
08fea57851
@ -23,6 +23,7 @@
|
|||||||
"cebe/markdown": "1.0.2",
|
"cebe/markdown": "1.0.2",
|
||||||
"yiisoft/yii2-jui": "^2.0",
|
"yiisoft/yii2-jui": "^2.0",
|
||||||
"zendframework/zend-http": "*",
|
"zendframework/zend-http": "*",
|
||||||
|
"jbroadway/urlify": "^1.0",
|
||||||
"nqxcode/zendsearch": "^2.0",
|
"nqxcode/zendsearch": "^2.0",
|
||||||
"xj/yii2-jplayer-widget": "*",
|
"xj/yii2-jplayer-widget": "*",
|
||||||
"zendframework/zend-ldap": "^2.5",
|
"zendframework/zend-ldap": "^2.5",
|
||||||
|
63
js/app.js
63
js/app.js
@ -125,11 +125,23 @@ function HashTable(obj) {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* setModalLoader
|
* To allow other frameworks to overlay focusable nodes over an active modal we have
|
||||||
*
|
* to explicitly allow ith within this overwritten function.
|
||||||
* Change buttons with loader
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
$.fn.modal.Constructor.prototype.enforceFocus = function () {
|
||||||
|
var that = this;
|
||||||
|
$(document).on('focusin.modal', function (e) {
|
||||||
|
if ($(e.target).hasClass('select2-input') || $(e.target).hasClass('hexInput')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (that.$element[0] !== e.target && !that.$element.has(e.target).length) {
|
||||||
|
that.$element.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
function setModalLoader() {
|
function setModalLoader() {
|
||||||
$(".modal-footer .btn").hide();
|
$(".modal-footer .btn").hide();
|
||||||
$(".modal-footer .loader").removeClass("hidden");
|
$(".modal-footer .loader").removeClass("hidden");
|
||||||
@ -143,14 +155,53 @@ $(document).ready(function () {
|
|||||||
$(this).removeData('bs.modal');
|
$(this).removeData('bs.modal');
|
||||||
|
|
||||||
// just close modal and reset modal content to default (shows the loader)
|
// just close modal and reset modal content to default (shows the loader)
|
||||||
$(this).html('<div class="modal-dialog"><div class="modal-content"><div class="modal-body"><div class="loader"><div class="sk-spinner sk-spinner-three-bounce"><div class="sk-bounce1"></div><div class="sk-bounce2"></div><div class="sk-bounce3"></div></div></div></div></div></div>');
|
$(this).html('<div class="modal-dialog"><div class="modal-content"><div class="modal-body">\n\
|
||||||
})
|
<div class="loader"><div class="sk-spinner sk-spinner-three-bounce"><div class="sk-bounce1"></div><div class="sk-bounce2"></div><div class="sk-bounce3"></div></div></div></div></div></div>');
|
||||||
|
});
|
||||||
|
|
||||||
// set Modal handler to all modal links
|
// set Modal handler to all modal links
|
||||||
setModalHandler();
|
setModalHandler();
|
||||||
|
|
||||||
initPlugins();
|
initPlugins();
|
||||||
|
|
||||||
|
$('a[data-ui-loader], button[data-ui-loader]').on('click', function () {
|
||||||
|
var $this = $(this);
|
||||||
|
|
||||||
|
if($this.find('.loader').length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Adopt current color for the loader animation
|
||||||
|
var color = $this.css('color') || '#ffffff';
|
||||||
|
var $loader = $('<span class="loader"><span class="sk-spinner sk-spinner-three-bounce"><span class="sk-bounce1"></span><span class="sk-bounce2"></span><span class="sk-bounce3"></span></span></span>');
|
||||||
|
|
||||||
|
//Align bouncer animation color and size
|
||||||
|
$loader.find('.sk-bounce1, .sk-bounce2, .sk-bounce3')
|
||||||
|
.addClass('disabled')
|
||||||
|
.css( {'background-color': color, 'width': '10px', 'height': '10px'});
|
||||||
|
|
||||||
|
//The loader does have some margin we have to hide
|
||||||
|
$this.css('overflow', 'hidden');
|
||||||
|
$this.addClass('disabled');
|
||||||
|
|
||||||
|
//Prevent the container from resizing
|
||||||
|
$this.css('min-width', this.getBoundingClientRect().width);
|
||||||
|
$this.data('text', $this.text());
|
||||||
|
$this.html($loader);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('afterValidate', function(evt, messages, errors) {
|
||||||
|
if(errors.length) {
|
||||||
|
$('[data-ui-loader]').each(function() {
|
||||||
|
var $this = $(this);
|
||||||
|
if($this.find('.loader').length) {
|
||||||
|
$this.html($this.data('text'));
|
||||||
|
$this.removeClass('disabled');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function setModalHandler() {
|
function setModalHandler() {
|
||||||
@ -162,7 +213,7 @@ function setModalHandler() {
|
|||||||
$(document).on('click.humhub', "a[data-target='#globalModal']", function (ev) {
|
$(document).on('click.humhub', "a[data-target='#globalModal']", function (ev) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
var options = {
|
var options = {
|
||||||
'show' : true,
|
'show': true,
|
||||||
'backdrop': $(this).data('backdrop')
|
'backdrop': $(this).data('backdrop')
|
||||||
}
|
}
|
||||||
$("#globalModal").modal(options);
|
$("#globalModal").modal(options);
|
||||||
|
36
js/select2-extension.js
Normal file
36
js/select2-extension.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
//This file contains style alignments for the select2 multi dropdown js framework.
|
||||||
|
$(document).ready(function () {
|
||||||
|
$.fn.select2.defaults = {};
|
||||||
|
|
||||||
|
//We have to overwrite the the result gui after every change
|
||||||
|
$('.multiselect_dropdown').select2({}).on('change', function () {
|
||||||
|
$(this).trigger('update');
|
||||||
|
}).on('select2:open', function () {
|
||||||
|
$(this).data('isOpen', true);
|
||||||
|
}).on('select2:close', function () {
|
||||||
|
$(this).data('isOpen', false);
|
||||||
|
}).on('update', function () {
|
||||||
|
var $container = $(this).next('.select2-container');
|
||||||
|
var $choices = $container.find('.select2-selection__choice');
|
||||||
|
$choices.addClass('userInput');
|
||||||
|
var $closeButton = $('<i class="fa fa-times-circle"></i>');
|
||||||
|
$closeButton.on('click', function () {
|
||||||
|
$(this).siblings('span[role="presentation"]').trigger('click');
|
||||||
|
});
|
||||||
|
$choices.append($closeButton);
|
||||||
|
});
|
||||||
|
|
||||||
|
//For highlighting the input
|
||||||
|
$(".select2-container").on("focusin", function () {
|
||||||
|
$(this).find('.select2-selection').addClass('select2-selection--focus');
|
||||||
|
});
|
||||||
|
|
||||||
|
//Since the focusout of the ontainer is called when the dropdown is opened we have to use this focusout
|
||||||
|
$(document).on('focusout', '.select2-search__field', function () {
|
||||||
|
if (!$(this).closest('.select2-container').prev('.multiselect_dropdown').data('isOpen')) {
|
||||||
|
$(this).closest('.select2-selection').removeClass('select2-selection--focus');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.multiselect_dropdown').trigger('update');
|
||||||
|
});
|
95
js/tabbedForm.js
Normal file
95
js/tabbedForm.js
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
$(document).ready(function () {
|
||||||
|
/**
|
||||||
|
* Searches a
|
||||||
|
* @param {type} $form
|
||||||
|
* @returns {$lastFieldSet$fieldSet}
|
||||||
|
*/
|
||||||
|
var getPreparedFieldSets = function ($form) {
|
||||||
|
var result = {};
|
||||||
|
var $lastFieldSet;
|
||||||
|
|
||||||
|
// Assamble all fieldsets with label
|
||||||
|
$form.find('fieldset').each(function () {
|
||||||
|
var $fieldSet = $(this);
|
||||||
|
$fieldSet.hide();
|
||||||
|
|
||||||
|
var legend = $fieldSet.children('legend').text();
|
||||||
|
if (legend && legend.length) {
|
||||||
|
// Make sure all fieldsets are direct children
|
||||||
|
result[legend] = $lastFieldSet = $fieldSet;
|
||||||
|
} else if($lastFieldSet) {
|
||||||
|
// We append form groups to the previous fieldset if no label is defined
|
||||||
|
$lastFieldSet.append($fieldSet.children(".form-group"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check for errors in a specific category
|
||||||
|
* @param _object
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
var hasErrors = function($fieldSet) {
|
||||||
|
var hasError = false;
|
||||||
|
|
||||||
|
$fieldSet.children(".form-group").each(function (index, value) {
|
||||||
|
|
||||||
|
// if an input have the class "error"
|
||||||
|
if ($(this).children('.form-control').hasClass("error")) {
|
||||||
|
hasError = true;
|
||||||
|
return false; // stop loop/function
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return hasError;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
$('[data-ui-tabbed-form]').each(function () {
|
||||||
|
var activeTab = 0;
|
||||||
|
|
||||||
|
var $form = $(this);
|
||||||
|
var $tabContent = $('<div class="tab-content"></div>');
|
||||||
|
var $tabs = $('<ul id="profile-tabs" class="nav nav-tabs" data-tabs="tabs"></ul>');
|
||||||
|
$form.prepend($tabContent);
|
||||||
|
$form.prepend($tabs);
|
||||||
|
|
||||||
|
var index = 0;
|
||||||
|
$.each(getPreparedFieldSets($form), function(label, $fieldSet) {
|
||||||
|
// activate this tab if there are any errors
|
||||||
|
if (hasErrors($fieldSet)) {
|
||||||
|
activeTab = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
// build tab structure
|
||||||
|
$tabs.append('<li><a href="#tab-' + index + '" data-toggle="tab">' + label + '</a></li>');
|
||||||
|
$tabContent.append('<div class="tab-pane" data-tab-index="'+index+'" id="tab-' + index + '"></div>');
|
||||||
|
|
||||||
|
// clone inputs from fieldSet into our tab structure
|
||||||
|
var $inputs = $fieldSet.children(".form-group");
|
||||||
|
$('#tab-' + index).html($inputs.clone());
|
||||||
|
|
||||||
|
// Remove old fieldset
|
||||||
|
$fieldSet.remove();
|
||||||
|
|
||||||
|
index++;
|
||||||
|
});
|
||||||
|
|
||||||
|
// prepend error summary to form if present
|
||||||
|
if ($('.errorSummary').length != null) {
|
||||||
|
var _errorSummary = $('.errorSummary').clone();
|
||||||
|
$('.errorSummary').remove();
|
||||||
|
$form.prepend(_errorSummary);
|
||||||
|
}
|
||||||
|
|
||||||
|
// activate the first tab or the tab with errors
|
||||||
|
$tabs.find('a[href="#tab-' + activeTab + '"]').tab('show');
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('afterValidate', function(evt, messages, errors) {
|
||||||
|
if(errors.length) {
|
||||||
|
var index = $(errors[0].container).closest('.tab-pane').data('tab-index');
|
||||||
|
$('a[href="#tab-' + index + '"]').tab('show');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
34
protected/humhub/assets/Select2ExtensionAsset.php
Normal file
34
protected/humhub/assets/Select2ExtensionAsset.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2015 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\assets;
|
||||||
|
|
||||||
|
use yii\web\AssetBundle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* jquery-knob
|
||||||
|
*
|
||||||
|
* @author luke
|
||||||
|
*/
|
||||||
|
class Select2ExtensionAsset extends AssetBundle
|
||||||
|
{
|
||||||
|
|
||||||
|
public $jsOptions = ['position' => \yii\web\View::POS_BEGIN];
|
||||||
|
|
||||||
|
public $basePath = '@webroot';
|
||||||
|
public $baseUrl = '@web';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public $js = ['js/select2-extension.js'];
|
||||||
|
|
||||||
|
public $depends = [
|
||||||
|
'humhub\assets\Select2Asset'
|
||||||
|
];
|
||||||
|
}
|
28
protected/humhub/assets/TabbedFormAsset.php
Normal file
28
protected/humhub/assets/TabbedFormAsset.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2015 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\assets;
|
||||||
|
|
||||||
|
use yii\web\AssetBundle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* jquery-knob
|
||||||
|
*
|
||||||
|
* @author luke
|
||||||
|
*/
|
||||||
|
class TabbedFormAsset extends AssetBundle
|
||||||
|
{
|
||||||
|
public $basePath = '@webroot';
|
||||||
|
public $baseUrl = '@web';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public $js = ['js/tabbedForm.js'];
|
||||||
|
|
||||||
|
}
|
@ -15,7 +15,7 @@ use humhub\models\Setting;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Cronjobs
|
* Cronjobs
|
||||||
*
|
*
|
||||||
* @author Luke
|
* @author Luke
|
||||||
*/
|
*/
|
||||||
class CronController extends Controller
|
class CronController extends Controller
|
||||||
@ -41,7 +41,7 @@ class CronController extends Controller
|
|||||||
$this->trigger(self::EVENT_ON_HOURLY_RUN);
|
$this->trigger(self::EVENT_ON_HOURLY_RUN);
|
||||||
|
|
||||||
$this->stdout("\n\nAll cron tasks finished.\n\n", Console::FG_GREEN);
|
$this->stdout("\n\nAll cron tasks finished.\n\n", Console::FG_GREEN);
|
||||||
Setting::Set('cronLastHourlyRun', time());
|
Yii::$app->settings->set('cronLastHourlyRun', time());
|
||||||
|
|
||||||
return self::EXIT_CODE_NORMAL;
|
return self::EXIT_CODE_NORMAL;
|
||||||
}
|
}
|
||||||
@ -56,7 +56,7 @@ class CronController extends Controller
|
|||||||
$this->trigger(self::EVENT_ON_DAILY_RUN);
|
$this->trigger(self::EVENT_ON_DAILY_RUN);
|
||||||
|
|
||||||
$this->stdout("\n\nAll cron tasks finished.\n\n", Console::FG_GREEN);
|
$this->stdout("\n\nAll cron tasks finished.\n\n", Console::FG_GREEN);
|
||||||
Setting::Set('cronLastDailyRun', time());
|
Yii::$app->settings->set('cronLastDailyRun', time());
|
||||||
|
|
||||||
return self::EXIT_CODE_NORMAL;
|
return self::EXIT_CODE_NORMAL;
|
||||||
}
|
}
|
||||||
|
@ -162,7 +162,7 @@ class HForm extends \yii\base\Component
|
|||||||
$output = "";
|
$output = "";
|
||||||
foreach ($buttons as $buttonName => $definition) {
|
foreach ($buttons as $buttonName => $definition) {
|
||||||
if ($definition['type'] == 'submit') {
|
if ($definition['type'] == 'submit') {
|
||||||
$output .= \yii\helpers\Html::submitButton($definition['label'], ['name' => $buttonName, 'class' => $definition['class']]);
|
$output .= \yii\helpers\Html::submitButton($definition['label'], ['name' => $buttonName, 'class' => $definition['class'], 'data-ui-loader' => '']);
|
||||||
$output .= " ";
|
$output .= " ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -193,6 +193,7 @@ class HForm extends \yii\base\Component
|
|||||||
|
|
||||||
if (isset($definition['readonly']) && $definition['readonly']) {
|
if (isset($definition['readonly']) && $definition['readonly']) {
|
||||||
$options['readOnly'] = true;
|
$options['readOnly'] = true;
|
||||||
|
$options['disabled'] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($definition['value'])) {
|
if (isset($definition['value'])) {
|
||||||
|
@ -31,7 +31,7 @@ class Application extends \yii\web\Application
|
|||||||
* Check if it's already installed - if not force controller module
|
* Check if it's already installed - if not force controller module
|
||||||
*/
|
*/
|
||||||
if (!$this->params['installed'] && $this->controller->module != null && $this->controller->module->id != 'installer') {
|
if (!$this->params['installed'] && $this->controller->module != null && $this->controller->module->id != 'installer') {
|
||||||
$this->controller->redirect(\yii\helpers\Url::to(['/installer/index']));
|
$this->controller->redirect(['/installer/index']);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,20 @@ class Module extends \yii\base\Module
|
|||||||
*/
|
*/
|
||||||
public $resourcesPath = 'assets';
|
public $resourcesPath = 'assets';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function init()
|
||||||
|
{
|
||||||
|
parent::init();
|
||||||
|
|
||||||
|
// Set settings component
|
||||||
|
$this->set('settings', [
|
||||||
|
'class' => SettingsManager::className(),
|
||||||
|
'moduleId' => $this->id
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns modules name provided by module.json file
|
* Returns modules name provided by module.json file
|
||||||
*
|
*
|
||||||
@ -82,7 +96,7 @@ class Module extends \yii\base\Module
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns image url for this module
|
* Returns image url for this module
|
||||||
* Place your modules image in assets/module_image.png
|
* Place your modules image in <resourcesPath>/module_image.png
|
||||||
*
|
*
|
||||||
* @return String Image Url
|
* @return String Image Url
|
||||||
*/
|
*/
|
||||||
@ -91,7 +105,8 @@ class Module extends \yii\base\Module
|
|||||||
$moduleImageFile = $this->getBasePath() . '/' . $this->resourcesPath . '/module_image.png';
|
$moduleImageFile = $this->getBasePath() . '/' . $this->resourcesPath . '/module_image.png';
|
||||||
|
|
||||||
if (is_file($moduleImageFile)) {
|
if (is_file($moduleImageFile)) {
|
||||||
return $this->getAssetsUrl() . '/module_image.png';
|
list($path, $url) = Yii::$app->assetManager->publish($moduleImageFile);
|
||||||
|
return $url;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Yii::getAlias("@web/img/default_module.jpg");
|
return Yii::getAlias("@web/img/default_module.jpg");
|
||||||
@ -110,20 +125,14 @@ class Module extends \yii\base\Module
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables this module
|
* Enables this module
|
||||||
* It will be available on the next request.
|
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function enable()
|
public function enable()
|
||||||
{
|
{
|
||||||
$moduleEnabled = ModuleEnabled::findOne(['module_id' => $this->id]);
|
Yii::$app->moduleManager->enable($this);
|
||||||
if ($moduleEnabled == null) {
|
|
||||||
$moduleEnabled = new ModuleEnabled();
|
|
||||||
$moduleEnabled->module_id = $this->id;
|
|
||||||
$moduleEnabled->save();
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->migrate();
|
$this->migrate();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,11 +144,7 @@ class Module extends \yii\base\Module
|
|||||||
*/
|
*/
|
||||||
public function disable()
|
public function disable()
|
||||||
{
|
{
|
||||||
// Disable module in database
|
|
||||||
$moduleEnabled = ModuleEnabled::findOne(['module_id' => $this->id]);
|
|
||||||
if ($moduleEnabled != null) {
|
|
||||||
$moduleEnabled->delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove database tables
|
* Remove database tables
|
||||||
@ -173,24 +178,23 @@ class Module extends \yii\base\Module
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (\humhub\modules\content\models\ContentContainerSetting::findAll(['module_id' => $this->id]) as $containerSetting) {
|
||||||
|
$containerSetting->delete();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
foreach (\humhub\models\Setting::findAll(['module_id' => $this->id]) as $containerSetting) {
|
||||||
HSetting::model()->deleteAllByAttributes(array('module_id' => $this->getId()));
|
$containerSetting->delete();
|
||||||
SpaceSetting::model()->deleteAllByAttributes(array('module_id' => $this->getId()));
|
}
|
||||||
UserSetting::model()->deleteAllByAttributes(array('module_id' => $this->getId()));
|
|
||||||
|
|
||||||
// Delete also records with disabled state from SpaceApplicationModule Table
|
foreach (\humhub\modules\user\models\Module::findAll(['module_id' => $this->id]) as $userModule) {
|
||||||
foreach (SpaceApplicationModule::model()->findAllByAttributes(array('module_id' => $this->getId())) as $sam) {
|
$userModule->delete();
|
||||||
$sam->delete();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Delete also records with disabled state from UserApplicationModule Table
|
foreach (\humhub\modules\space\models\Module::findAll(['module_id' => $this->id]) as $spaceModule) {
|
||||||
foreach (UserApplicationModule::model()->findAllByAttributes(array('module_id' => $this->getId())) as $uam) {
|
$spaceModule->delete();
|
||||||
$uam->delete();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ModuleManager::flushCache();
|
Yii::$app->moduleManager->disable($this);
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -251,7 +255,7 @@ class Module extends \yii\base\Module
|
|||||||
{
|
{
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of notification classes this module provides.
|
* Returns a list of notification classes this module provides.
|
||||||
*
|
*
|
||||||
|
@ -13,6 +13,7 @@ use yii\base\Exception;
|
|||||||
use yii\base\Event;
|
use yii\base\Event;
|
||||||
use yii\base\InvalidConfigException;
|
use yii\base\InvalidConfigException;
|
||||||
use humhub\components\bootstrap\ModuleAutoLoader;
|
use humhub\components\bootstrap\ModuleAutoLoader;
|
||||||
|
use humhub\models\ModuleEnabled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ModuleManager handles all installed modules.
|
* ModuleManager handles all installed modules.
|
||||||
@ -114,6 +115,8 @@ class ModuleManager extends \yii\base\Component
|
|||||||
if (isset($config['namespace'])) {
|
if (isset($config['namespace'])) {
|
||||||
Yii::setAlias('@' . str_replace('\\', '/', $config['namespace']), $basePath);
|
Yii::setAlias('@' . str_replace('\\', '/', $config['namespace']), $basePath);
|
||||||
}
|
}
|
||||||
|
Yii::setAlias('@' . $config['id'], $basePath);
|
||||||
|
|
||||||
|
|
||||||
if (!Yii::$app->params['installed'] && $isInstallerModule) {
|
if (!Yii::$app->params['installed'] && $isInstallerModule) {
|
||||||
$this->enabledModules[] = $config['id'];
|
$this->enabledModules[] = $config['id'];
|
||||||
@ -145,14 +148,12 @@ class ModuleManager extends \yii\base\Component
|
|||||||
|
|
||||||
// Add config file values to module
|
// Add config file values to module
|
||||||
if (isset(Yii::$app->modules[$config['id']]) && is_array(Yii::$app->modules[$config['id']])) {
|
if (isset(Yii::$app->modules[$config['id']]) && is_array(Yii::$app->modules[$config['id']])) {
|
||||||
$moduleConfig = yii\helpers\ArrayHelper::merge($moduleConfig, Yii::$app->modules[$config['id']]);
|
$moduleConfig = \yii\helpers\ArrayHelper::merge($moduleConfig, Yii::$app->modules[$config['id']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register Yii Module
|
// Register Yii Module
|
||||||
Yii::$app->setModule($config['id'], $moduleConfig);
|
Yii::$app->setModule($config['id'], $moduleConfig);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Register Event Handlers
|
// Register Event Handlers
|
||||||
if (isset($config['events'])) {
|
if (isset($config['events'])) {
|
||||||
foreach ($config['events'] as $event) {
|
foreach ($config['events'] as $event) {
|
||||||
@ -295,13 +296,52 @@ class ModuleManager extends \yii\base\Component
|
|||||||
|
|
||||||
$backupFolderName = $moduleBackupFolder . DIRECTORY_SEPARATOR . $moduleId . "_" . time();
|
$backupFolderName = $moduleBackupFolder . DIRECTORY_SEPARATOR . $moduleId . "_" . time();
|
||||||
if (!@rename($module->getBasePath(), $backupFolderName)) {
|
if (!@rename($module->getBasePath(), $backupFolderName)) {
|
||||||
throw new Exception("Could not remove module folder!" . $backupFolderName);
|
throw new Exception("Could not move module to backup folder!" . $backupFolderName);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//TODO: Delete directory
|
//TODO: Delete directory
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->flushCache();
|
$this->flushCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables a module
|
||||||
|
*
|
||||||
|
* @since 1.1
|
||||||
|
* @param \humhub\components\Module $module
|
||||||
|
*/
|
||||||
|
public function enable(Module $module)
|
||||||
|
{
|
||||||
|
$moduleEnabled = ModuleEnabled::findOne(['module_id' => $module->id]);
|
||||||
|
if ($moduleEnabled == null) {
|
||||||
|
$moduleEnabled = new ModuleEnabled();
|
||||||
|
$moduleEnabled->module_id = $module->id;
|
||||||
|
$moduleEnabled->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->enabledModules[] = $module->id;
|
||||||
|
$this->register($module->getBasePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables a module
|
||||||
|
*
|
||||||
|
* @since 1.1
|
||||||
|
* @param \humhub\components\Module $module
|
||||||
|
*/
|
||||||
|
public function disable(Module $module)
|
||||||
|
{
|
||||||
|
$moduleEnabled = ModuleEnabled::findOne(['module_id' => $module->id]);
|
||||||
|
if ($moduleEnabled != null) {
|
||||||
|
$moduleEnabled->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($key = array_search($module->id, $this->enabledModules)) !== false) {
|
||||||
|
unset($this->enabledModules[$key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Yii::$app->setModule($module->id, 'null');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,8 @@ use Yii;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @author luke
|
* @author luke
|
||||||
*/
|
*/
|
||||||
class Request extends \yii\web\Request
|
class Request extends \yii\web\Request
|
||||||
@ -25,10 +25,10 @@ class Request extends \yii\web\Request
|
|||||||
public function init()
|
public function init()
|
||||||
{
|
{
|
||||||
if (\humhub\models\Setting::isInstalled()) {
|
if (\humhub\models\Setting::isInstalled()) {
|
||||||
$secret = \humhub\models\Setting::Get('secret');
|
$secret = Yii::$app->settings->get('secret');
|
||||||
if ($secret != "") {
|
if ($secret != "") {
|
||||||
$this->cookieValidationKey = \humhub\models\Setting::Get('secret');
|
$this->cookieValidationKey = $secret;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$this->cookieValidationKey = 'installer';
|
$this->cookieValidationKey = 'installer';
|
||||||
}
|
}
|
||||||
|
100
protected/humhub/components/SettingsManager.php
Normal file
100
protected/humhub/components/SettingsManager.php
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2016 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\components;
|
||||||
|
|
||||||
|
use Yii;
|
||||||
|
use humhub\libs\BaseSettingsManager;
|
||||||
|
use humhub\modules\content\components\ContentContainerActiveRecord;
|
||||||
|
use humhub\modules\content\components\ContentContainerSettingsManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SettingsManager application component
|
||||||
|
*
|
||||||
|
* @since 1.1
|
||||||
|
* @author Luke
|
||||||
|
*/
|
||||||
|
class SettingsManager extends BaseSettingsManager
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ContentContainerSettingsManager[] already loaded content container settings managers
|
||||||
|
*/
|
||||||
|
protected $contentContainers = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns content container
|
||||||
|
*
|
||||||
|
* @param ContentContainerActiveRecord $container
|
||||||
|
* @return ContentContainerSettingsManager
|
||||||
|
*/
|
||||||
|
public function contentContainer(ContentContainerActiveRecord $container)
|
||||||
|
{
|
||||||
|
if (isset($this->contentContainers[$container->id])) {
|
||||||
|
return $this->contentContainers[$container->id];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->contentContainers[$container->id] = new ContentContainerSettingsManager([
|
||||||
|
'moduleId' => $this->moduleId,
|
||||||
|
'contentContainer' => $container,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $this->contentContainers[$container->id];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns ContentContainerSettingsManager for current logged in user
|
||||||
|
* @return ContentContainerSettingsManager
|
||||||
|
*/
|
||||||
|
public function user()
|
||||||
|
{
|
||||||
|
return $this->contentContainer(Yii::$app->user->getIdentity());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns ContentContainerSettingsManager for current logged in user
|
||||||
|
* @return ContentContainerSettingsManager
|
||||||
|
*/
|
||||||
|
public function space()
|
||||||
|
{
|
||||||
|
if (Yii::$app->controller instanceof \humhub\modules\content\components\ContentContainerController) {
|
||||||
|
if (Yii::$app->controller->contentContainer instanceof \humhub\modules\space\models\Space) {
|
||||||
|
return $this->contentContainer(Yii::$app->controller->contentContainer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates this setting is fixed in configuration file and cannot be
|
||||||
|
* changed at runtime.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function isFixed($name)
|
||||||
|
{
|
||||||
|
if (isset(Yii::$app->params['fixed-settings'][$this->moduleId][$name])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function get($name)
|
||||||
|
{
|
||||||
|
if ($this->isFixed($name)) {
|
||||||
|
return Yii::$app->params['fixed-settings'][$this->moduleId][$name];
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::get($name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
124
protected/humhub/components/SocialActivity.php
Normal file
124
protected/humhub/components/SocialActivity.php
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2016 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\components;
|
||||||
|
|
||||||
|
use humhub\modules\notification\models\Notification;
|
||||||
|
use humhub\modules\content\components\ContentActiveRecord;
|
||||||
|
use humhub\modules\content\components\ContentContainerActiveRecord;
|
||||||
|
use humhub\modules\content\components\ContentAddonActiveRecord;
|
||||||
|
use humhub\libs\Viewable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name (SocialEvent/NetworkEvent/SocialActivity/BaseEvent)
|
||||||
|
*
|
||||||
|
* This class represents an social activity triggered within the network.
|
||||||
|
* An activity instance can be linked to an $originator user, which performed the activity.
|
||||||
|
*
|
||||||
|
* The activity mainly provides functions for rendering the output for different channels as
|
||||||
|
* web, mail or plain-text.
|
||||||
|
*
|
||||||
|
* @since 1.1
|
||||||
|
* @author buddha
|
||||||
|
*/
|
||||||
|
abstract class SocialActivity extends Viewable
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User which performed the activity.
|
||||||
|
*
|
||||||
|
* @var \humhub\modules\user\models\User
|
||||||
|
*/
|
||||||
|
public $originator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The source instance which created this activity
|
||||||
|
*
|
||||||
|
* @var \yii\db\ActiveRecord
|
||||||
|
*/
|
||||||
|
public $source;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The content container this activity belongs to.
|
||||||
|
*
|
||||||
|
* If the source object is a type of Content/ContentAddon or ContentContainer the container
|
||||||
|
* will be automatically set.
|
||||||
|
*
|
||||||
|
* @var ContentContainerActiveRecord
|
||||||
|
*/
|
||||||
|
public $container = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string the module id which this activity belongs to (required)
|
||||||
|
*/
|
||||||
|
public $moduleId = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The notification record this notification belongs to
|
||||||
|
*
|
||||||
|
* @var Notification
|
||||||
|
*/
|
||||||
|
public $record;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
protected function getViewParams($params = [])
|
||||||
|
{
|
||||||
|
$params['originator'] = $this->originator;
|
||||||
|
$params['source'] = $this->source;
|
||||||
|
$params['contentContainer'] = $this->container;
|
||||||
|
$params['record'] = $this->record;
|
||||||
|
if (!isset($params['url'])) {
|
||||||
|
$params['url'] = $this->getUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $params;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Url of the origin of this notification
|
||||||
|
* If source is a Content / ContentAddon / ContentContainer this will automatically generated.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getUrl()
|
||||||
|
{
|
||||||
|
$url = '#';
|
||||||
|
|
||||||
|
if ($this->source instanceof ContentActiveRecord || $this->source instanceof ContentAddonActiveRecord) {
|
||||||
|
$url = $this->source->content->getUrl();
|
||||||
|
} elseif ($this->source instanceof ContentContainerActiveRecord) {
|
||||||
|
$url = $this->source->getUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create absolute URL, for E-Mails
|
||||||
|
if (substr($url, 0, 4) !== 'http') {
|
||||||
|
$url = \yii\helpers\Url::to($url, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build info text about a content
|
||||||
|
*
|
||||||
|
* This is a combination a the type of the content with a short preview
|
||||||
|
* of it.
|
||||||
|
*
|
||||||
|
* @param Content $content
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getContentInfo(\humhub\modules\content\interfaces\ContentTitlePreview $content)
|
||||||
|
{
|
||||||
|
return \yii\helpers\Html::encode($content->getContentName()) .
|
||||||
|
' "' .
|
||||||
|
\humhub\widgets\RichText::widget(['text' => $content->getContentDescription(), 'minimal' => true, 'maxLength' => 60]) . '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -10,6 +10,7 @@ namespace humhub\components;
|
|||||||
|
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\helpers\FileHelper;
|
use yii\helpers\FileHelper;
|
||||||
|
use humhub\libs\ThemeHelper;
|
||||||
use humhub\models\Setting;
|
use humhub\models\Setting;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -20,7 +21,7 @@ class Theme extends \yii\base\Theme
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Name of the Theme
|
* Name of the Theme
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public $name;
|
public $name;
|
||||||
@ -30,6 +31,11 @@ class Theme extends \yii\base\Theme
|
|||||||
*/
|
*/
|
||||||
private $_baseUrl = null;
|
private $_baseUrl = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that resources should be published via assetManager
|
||||||
|
*/
|
||||||
|
public $publishResources = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
@ -46,26 +52,36 @@ class Theme extends \yii\base\Theme
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string the base URL (without ending slash) for this theme. All resources of this theme are considered
|
* @inheritdoc
|
||||||
* to be under this base URL.
|
|
||||||
*/
|
*/
|
||||||
public function getBaseUrl()
|
public function getBaseUrl()
|
||||||
{
|
{
|
||||||
|
|
||||||
if ($this->_baseUrl !== null) {
|
if ($this->_baseUrl !== null) {
|
||||||
return $this->_baseUrl;
|
return $this->_baseUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->_baseUrl = rtrim(Yii::getAlias('@web/themes/' . $this->name), '/');
|
$this->_baseUrl = ($this->publishResources) ? $this->publishResources() : rtrim(Yii::getAlias('@web/themes/' . $this->name), '/');
|
||||||
return $this->_baseUrl;
|
return $this->_baseUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will be called before when this theme is written to the
|
||||||
|
* dynamic configuration file.
|
||||||
|
*/
|
||||||
|
public function beforeActivate()
|
||||||
|
{
|
||||||
|
// Force republish theme files
|
||||||
|
$this->publishResources(true);
|
||||||
|
|
||||||
|
// Store color variables to configuration
|
||||||
|
$this->storeColorsToConfig();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
public function applyTo($path)
|
public function applyTo($path)
|
||||||
{
|
{
|
||||||
|
|
||||||
$autoPath = $this->autoFindModuleView($path);
|
$autoPath = $this->autoFindModuleView($path);
|
||||||
if ($autoPath !== null && file_exists($autoPath)) {
|
if ($autoPath !== null && file_exists($autoPath)) {
|
||||||
return $autoPath;
|
return $autoPath;
|
||||||
@ -84,9 +100,28 @@ class Theme extends \yii\base\Theme
|
|||||||
return parent::applyTo($path);
|
return parent::applyTo($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publishs theme assets (e.g. images or css)
|
||||||
|
*
|
||||||
|
* @param boolean|null $force
|
||||||
|
* @return string url of published resources
|
||||||
|
*/
|
||||||
|
public function publishResources($force = null)
|
||||||
|
{
|
||||||
|
if ($force === null) {
|
||||||
|
$force = (YII_DEBUG);
|
||||||
|
}
|
||||||
|
|
||||||
|
$published = Yii::$app->assetManager->publish(
|
||||||
|
$this->getBasePath(), ['forceCopy' => $force, 'except' => ['views/']]
|
||||||
|
);
|
||||||
|
|
||||||
|
return $published[1];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to automatically maps the view file of a module to a themed one.
|
* Tries to automatically maps the view file of a module to a themed one.
|
||||||
*
|
*
|
||||||
* Formats:
|
* Formats:
|
||||||
|
|
||||||
* .../moduleId/views/controllerId/viewName.php
|
* .../moduleId/views/controllerId/viewName.php
|
||||||
@ -96,7 +131,7 @@ class Theme extends \yii\base\Theme
|
|||||||
* .../moduleId/[widgets|activities|notifications]/views/viewName.php
|
* .../moduleId/[widgets|activities|notifications]/views/viewName.php
|
||||||
* to:
|
* to:
|
||||||
* .../views/moduleId/[widgets|activities|notifications]/viewName.php
|
* .../views/moduleId/[widgets|activities|notifications]/viewName.php
|
||||||
*
|
*
|
||||||
* @return string theme view path or null
|
* @return string theme view path or null
|
||||||
*/
|
*/
|
||||||
protected function autoFindModuleView($path)
|
protected function autoFindModuleView($path)
|
||||||
@ -122,113 +157,13 @@ class Theme extends \yii\base\Theme
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of all installed themes.
|
* Stores color informations to configuration for use in modules.
|
||||||
*
|
|
||||||
* @return Array Theme instances
|
|
||||||
*/
|
*/
|
||||||
public static function getThemes()
|
public function storeColorsToConfig()
|
||||||
{
|
{
|
||||||
$themes = array();
|
$lessFileName = $this->getBasePath() . '/css/theme.less';
|
||||||
$themePaths = [];
|
|
||||||
$themePaths[] = \Yii::getAlias('@webroot/themes');
|
|
||||||
|
|
||||||
// Collect enabled module theme paths
|
|
||||||
foreach (Yii::$app->getModules() as $module) {
|
|
||||||
$basePath = "";
|
|
||||||
if (is_array($module)) {
|
|
||||||
if (isset($module['class'])) {
|
|
||||||
$reflector = new \ReflectionClass($module['class']);
|
|
||||||
$basePath = dirname($reflector->getFileName());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$basePath = $module->getBasePath();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_dir($basePath . DIRECTORY_SEPARATOR . 'themes')) {
|
|
||||||
$themePaths[] = $basePath . DIRECTORY_SEPARATOR . 'themes';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($themePaths as $themePath) {
|
|
||||||
foreach (scandir($themePath) as $file) {
|
|
||||||
if ($file == "." || $file == ".." || !is_dir($themePath . DIRECTORY_SEPARATOR . $file)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$themes[] = Yii::createObject([
|
|
||||||
'class' => 'humhub\components\Theme',
|
|
||||||
'basePath' => $themePath . DIRECTORY_SEPARATOR . $file,
|
|
||||||
'name' => $file
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $themes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a Theme by given name
|
|
||||||
*
|
|
||||||
* @param string $name of the theme
|
|
||||||
* @return Theme
|
|
||||||
*/
|
|
||||||
public static function getThemeByName($name)
|
|
||||||
{
|
|
||||||
foreach (self::getThemes() as $theme) {
|
|
||||||
if ($theme->name === $name) {
|
|
||||||
return $theme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns configuration array of given theme
|
|
||||||
*
|
|
||||||
* @param Theme|string $theme name or theme instance
|
|
||||||
* @return array Configuration
|
|
||||||
*/
|
|
||||||
public static function getThemeConfig($theme)
|
|
||||||
{
|
|
||||||
if (is_string($theme)) {
|
|
||||||
$theme = self::getThemeByName($theme);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($theme === null) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
|
||||||
'components' => [
|
|
||||||
'view' => [
|
|
||||||
'theme' => [
|
|
||||||
'name' => $theme->name,
|
|
||||||
'basePath' => $theme->getBasePath()
|
|
||||||
],
|
|
||||||
],
|
|
||||||
'mailer' => [
|
|
||||||
'view' => [
|
|
||||||
'theme' => [
|
|
||||||
'name' => $theme->name,
|
|
||||||
'basePath' => $theme->getBasePath()
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function setColorVariables($themeName)
|
|
||||||
{
|
|
||||||
$theme = self::getThemeByName($themeName);
|
|
||||||
|
|
||||||
if ($theme === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$lessFileName = Yii::getAlias($theme->getBasePath() . '/css/theme.less');
|
|
||||||
if (file_exists($lessFileName)) {
|
if (file_exists($lessFileName)) {
|
||||||
$file = fopen($lessFileName, "r") or die("Unable to open file!");
|
$less = file_get_contents($lessFileName);
|
||||||
$less = fread($file, filesize($lessFileName));
|
|
||||||
fclose($file);
|
|
||||||
|
|
||||||
$startDefault = strpos($less, '@default') + 10;
|
$startDefault = strpos($less, '@default') + 10;
|
||||||
$startPrimary = strpos($less, '@primary') + 10;
|
$startPrimary = strpos($less, '@primary') + 10;
|
||||||
@ -238,12 +173,27 @@ class Theme extends \yii\base\Theme
|
|||||||
$startDanger = strpos($less, '@danger') + 9;
|
$startDanger = strpos($less, '@danger') + 9;
|
||||||
$length = 7;
|
$length = 7;
|
||||||
|
|
||||||
Setting::Set('colorDefault', substr($less, $startDefault, $length));
|
Yii::$app->settings->set('colorDefault', substr($less, $startDefault, $length));
|
||||||
Setting::Set('colorPrimary', substr($less, $startPrimary, $length));
|
Yii::$app->settings->set('colorPrimary', substr($less, $startPrimary, $length));
|
||||||
Setting::Set('colorInfo', substr($less, $startInfo, $length));
|
Yii::$app->settings->set('colorInfo', substr($less, $startInfo, $length));
|
||||||
Setting::Set('colorSuccess', substr($less, $startSuccess, $length));
|
Yii::$app->settings->set('colorSuccess', substr($less, $startSuccess, $length));
|
||||||
Setting::Set('colorWarning', substr($less, $startWarning, $length));
|
Yii::$app->settings->set('colorWarning', substr($less, $startWarning, $length));
|
||||||
Setting::Set('colorDanger', substr($less, $startDanger, $length));
|
Yii::$app->settings->set('colorDanger', substr($less, $startDanger, $length));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store colors to configuration.
|
||||||
|
*
|
||||||
|
* @deprecated since version 1.1
|
||||||
|
* @param type $themeName
|
||||||
|
*/
|
||||||
|
public static function setColorVariables($themeName)
|
||||||
|
{
|
||||||
|
$theme = ThemeHelper::getThemeByName($themeName);
|
||||||
|
|
||||||
|
if ($theme !== null) {
|
||||||
|
$theme->storeColorsToConfig();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,25 +44,26 @@ class AccessControl extends \yii\base\ActionFilter
|
|||||||
*/
|
*/
|
||||||
public function beforeAction($action)
|
public function beforeAction($action)
|
||||||
{
|
{
|
||||||
|
|
||||||
$identity = Yii::$app->user->getIdentity();
|
$identity = Yii::$app->user->getIdentity();
|
||||||
if($identity != null && !$identity->isActive()) {
|
if($identity != null && !$identity->isActive()) {
|
||||||
Yii::$app->user->logout();
|
Yii::$app->user->logout();
|
||||||
Yii::$app->response->redirect(Yii::$app->urlManager->createUrl('user/auth/login'));
|
Yii::$app->response->redirect(['/user/auth/login']);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Yii::$app->user->isGuest) {
|
if (Yii::$app->user->isGuest) {
|
||||||
if (!$this->loggedInOnly && !$this->adminOnly) {
|
if (!$this->loggedInOnly && !$this->adminOnly) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (in_array($action->id, $this->guestAllowedActions) && Setting::Get('allowGuestAccess', 'authentication_internal') == 1) {
|
if (in_array($action->id, $this->guestAllowedActions) && Yii::$app->getModule('user')->settings->get('auth.allowGuestAccess') == 1) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Yii::$app->user->loginRequired();
|
Yii::$app->user->loginRequired();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->adminOnly && !Yii::$app->user->isAdmin()) {
|
if ($this->adminOnly && !Yii::$app->user->isAdmin()) {
|
||||||
$this->forbidden();
|
$this->forbidden();
|
||||||
}
|
}
|
||||||
|
@ -38,8 +38,8 @@ class ModuleAutoLoader implements BootstrapInterface
|
|||||||
if (is_dir($moduleDir) && is_file($moduleDir . DIRECTORY_SEPARATOR . 'config.php')) {
|
if (is_dir($moduleDir) && is_file($moduleDir . DIRECTORY_SEPARATOR . 'config.php')) {
|
||||||
try {
|
try {
|
||||||
$modules[$moduleDir] = require($moduleDir . DIRECTORY_SEPARATOR . 'config.php');
|
$modules[$moduleDir] = require($moduleDir . DIRECTORY_SEPARATOR . 'config.php');
|
||||||
} catch (Exception $ex) {
|
} catch (\Exception $ex) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @link https://www.humhub.org/
|
* @link https://www.humhub.org/
|
||||||
* @copyright Copyright (c) 2015 HumHub GmbH & Co. KG
|
* @copyright Copyright (c) 2016 HumHub GmbH & Co. KG
|
||||||
* @license https://www.humhub.com/licences
|
* @license https://www.humhub.com/licences
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -33,14 +33,20 @@ class Application extends \yii\console\Application
|
|||||||
$this->trigger(self::EVENT_ON_INIT);
|
$this->trigger(self::EVENT_ON_INIT);
|
||||||
|
|
||||||
if ($this->isDatabaseInstalled()) {
|
if ($this->isDatabaseInstalled()) {
|
||||||
$baseUrl = Setting::get('baseUrl');
|
$baseUrl = Yii::$app->settings->get('baseUrl');
|
||||||
|
if ($baseUrl !== null) {
|
||||||
if($baseUrl != null) {
|
|
||||||
Yii::setAlias(("@web"), $baseUrl);
|
Yii::setAlias(("@web"), $baseUrl);
|
||||||
$this->urlManager->scriptUrl = $baseUrl;
|
$this->urlManager->scriptUrl = $baseUrl;
|
||||||
$this->urlManager->baseUrl = $baseUrl;
|
$this->urlManager->baseUrl = $baseUrl;
|
||||||
|
|
||||||
|
// Set hostInfo based on given baseUrl
|
||||||
|
$urlParts = parse_url($baseUrl);
|
||||||
|
$hostInfo = $urlParts['scheme'] . '://' . $urlParts['host'];
|
||||||
|
if (isset($urlParts['port'])) {
|
||||||
|
$hostInfo .= ':' . $urlParts['port'];
|
||||||
|
}
|
||||||
|
$this->urlManager->hostInfo = $hostInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +66,7 @@ class Application extends \yii\console\Application
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if database is installed
|
* Checks if database is installed
|
||||||
*
|
*
|
||||||
* @return boolean is database installed/migrated
|
* @return boolean is database installed/migrated
|
||||||
*/
|
*/
|
||||||
public function isDatabaseInstalled()
|
public function isDatabaseInstalled()
|
||||||
@ -68,7 +74,7 @@ class Application extends \yii\console\Application
|
|||||||
if (in_array('setting', Yii::$app->db->schema->getTableNames())) {
|
if (in_array('setting', Yii::$app->db->schema->getTableNames())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
namespace humhub\components\i18n;
|
namespace humhub\components\i18n;
|
||||||
|
|
||||||
|
use Yii;
|
||||||
use humhub\models\Setting;
|
use humhub\models\Setting;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -20,7 +21,7 @@ class Formatter extends \yii\i18n\Formatter
|
|||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
public $sizeFormatBase = 1000;
|
public $sizeFormatBase = 1000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string the default format string to be used to format a input field [[asDate()|date]].
|
* @var string the default format string to be used to format a input field [[asDate()|date]].
|
||||||
* This mostly used in forms (DatePicker).
|
* This mostly used in forms (DatePicker).
|
||||||
@ -35,8 +36,8 @@ class Formatter extends \yii\i18n\Formatter
|
|||||||
{
|
{
|
||||||
parent::init();
|
parent::init();
|
||||||
|
|
||||||
if (Setting::Get('defaultDateInputFormat', 'admin') != '') {
|
if (Yii::$app->getModule('admin')->settings->get('defaultDateInputFormat') != '') {
|
||||||
$this->dateInputFormat = Setting::Get('defaultDateInputFormat', 'admin');
|
$this->dateInputFormat = Yii::$app->getModule('admin')->settings->get('defaultDateInputFormat');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ Yii::setAlias('@config', '@app/config');
|
|||||||
|
|
||||||
$config = [
|
$config = [
|
||||||
'name' => 'HumHub',
|
'name' => 'HumHub',
|
||||||
'version' => '1.1.0-dev',
|
'version' => '1.2.0-dev',
|
||||||
'basePath' => dirname(__DIR__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR,
|
'basePath' => dirname(__DIR__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR,
|
||||||
'bootstrap' => ['log', 'humhub\components\bootstrap\ModuleAutoLoader'],
|
'bootstrap' => ['log', 'humhub\components\bootstrap\ModuleAutoLoader'],
|
||||||
'sourceLanguage' => 'en',
|
'sourceLanguage' => 'en',
|
||||||
@ -27,6 +27,7 @@ $config = [
|
|||||||
[
|
[
|
||||||
'class' => 'yii\log\DbTarget',
|
'class' => 'yii\log\DbTarget',
|
||||||
'levels' => ['error', 'warning'],
|
'levels' => ['error', 'warning'],
|
||||||
|
'except' => ['yii\web\HttpException:404'],
|
||||||
'logVars' => ['_GET', '_SERVER'],
|
'logVars' => ['_GET', '_SERVER'],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
@ -34,6 +35,10 @@ $config = [
|
|||||||
'search' => array(
|
'search' => array(
|
||||||
'class' => 'humhub\modules\search\engine\ZendLuceneSearch',
|
'class' => 'humhub\modules\search\engine\ZendLuceneSearch',
|
||||||
),
|
),
|
||||||
|
'settings' => array(
|
||||||
|
'class' => 'humhub\components\SettingsManager',
|
||||||
|
'moduleId' => 'base',
|
||||||
|
),
|
||||||
'i18n' => [
|
'i18n' => [
|
||||||
'class' => 'humhub\components\i18n\I18N',
|
'class' => 'humhub\components\i18n\I18N',
|
||||||
'translations' => [
|
'translations' => [
|
||||||
@ -53,10 +58,6 @@ $config = [
|
|||||||
'class' => 'yii\i18n\PhpMessageSource',
|
'class' => 'yii\i18n\PhpMessageSource',
|
||||||
'basePath' => '@humhub/messages'
|
'basePath' => '@humhub/messages'
|
||||||
],
|
],
|
||||||
'iso3166Codes' => [
|
|
||||||
'class' => 'yii\i18n\PhpMessageSource',
|
|
||||||
'basePath' => '@humhub/messages'
|
|
||||||
],
|
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'formatter' => [
|
'formatter' => [
|
||||||
|
@ -5,7 +5,7 @@ return [
|
|||||||
'sourcePath' => __DIR__ . DIRECTORY_SEPARATOR . '..',
|
'sourcePath' => __DIR__ . DIRECTORY_SEPARATOR . '..',
|
||||||
// array, required, list of language codes that the extracted messages
|
// array, required, list of language codes that the extracted messages
|
||||||
// should be translated to. For example, ['zh-CN', 'de'].
|
// should be translated to. For example, ['zh-CN', 'de'].
|
||||||
'languages' => array('de', 'fr', 'nl', 'pt', 'pl', 'pt_br', 'es', 'it', 'tr', 'ru', 'th', 'uk', 'el', 'hu', 'ja', 'nb_no', 'zh_cn', 'ca', 'an', 'cs', 'vi', 'sv', 'da', 'uz', 'fa_ir', 'bg', 'sk', 'en_uk', 'zh_tw', 'ro', 'ar', 'id', 'ko', 'lt', 'hr'),
|
'languages' => array('de', 'fr', 'nl', 'pt', 'pl', 'pt_br', 'es', 'it', 'tr', 'ru', 'th', 'uk', 'el', 'hu', 'ja', 'nb_no', 'zh_cn', 'ca', 'an', 'cs', 'vi', 'sv', 'da', 'uz', 'fa_ir', 'bg', 'sk', 'zh_tw', 'ro', 'ar', 'id', 'ko', 'lt', 'hr'),
|
||||||
// string, the name of the function for translating messages.
|
// string, the name of the function for translating messages.
|
||||||
// Defaults to 'Yii::t'. This is used as a mark to find the messages to be
|
// Defaults to 'Yii::t'. This is used as a mark to find the messages to be
|
||||||
// translated. You may use a string for single function name or an array for
|
// translated. You may use a string for single function name or an array for
|
||||||
|
@ -49,7 +49,7 @@ class ErrorController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Show special login required view for guests
|
* Show special login required view for guests
|
||||||
*/
|
*/
|
||||||
if (Yii::$app->user->isGuest && $exception instanceof HttpException && $exception->statusCode == "401" && Setting::Get('allowGuestAccess', 'authentication_internal')) {
|
if (Yii::$app->user->isGuest && $exception instanceof HttpException && $exception->statusCode == "401" && Yii::$app->getModule('user')->settings->get('auth.allowGuestAccess')) {
|
||||||
return $this->render('@humhub/views/error/401_guests', ['message' => $message]);
|
return $this->render('@humhub/views/error/401_guests', ['message' => $message]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,18 +5,20 @@ Introduction
|
|||||||
------------
|
------------
|
||||||
* [About HumHub](intro-index.md)
|
* [About HumHub](intro-index.md)
|
||||||
* [Licence](intro-licence.md)
|
* [Licence](intro-licence.md)
|
||||||
|
* [Bundled Software](intro-bundled_software.md)
|
||||||
|
|
||||||
Administration
|
Getting Started
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
* [Requirements](admin-requirements.md)
|
* [Requirements](admin-requirements.md)
|
||||||
* [Installation](admin-installation.md)
|
* [Installation](admin-installation.md)
|
||||||
* [Updating](admin-updating.md)
|
* [Updating](admin-updating.md)
|
||||||
|
|
||||||
|
Administration
|
||||||
|
---------------------
|
||||||
* [User](admin-user.md)
|
* [User](admin-user.md)
|
||||||
* [Spaces](admin-spaces.md)
|
* [Spaces](admin-spaces.md)
|
||||||
|
* [Authentication](admin-authentication.md)
|
||||||
Administration - Topics
|
|
||||||
-------------------------
|
|
||||||
* [Advanced Configuration](admin-adv-config.md)
|
* [Advanced Configuration](admin-adv-config.md)
|
||||||
* [Console](admin-adv-console.md)
|
* [Console](admin-adv-console.md)
|
||||||
* [Search](admin-adv-search.md)
|
* [Search](admin-adv-search.md)
|
||||||
@ -27,34 +29,22 @@ Development
|
|||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
* [Getting Started](dev-index.md)
|
* [Getting Started](dev-index.md)
|
||||||
* [Updating / Migrate](dev-migrate.md)
|
* [Update / Migration](dev-migrate.md)
|
||||||
* [Application Overview](dev-overview.md)
|
|
||||||
* [Content](dev-content.md)
|
* [Content](dev-content.md)
|
||||||
* [Notification](dev-notifications.md)
|
* [Permissions](dev-permissions.md)
|
||||||
* [Activities](dev-environment.md)
|
* [Notifications](dev-notifications.md)
|
||||||
* [Search](dev-environment.md)
|
* [Activities](dev-activities.md)
|
||||||
* [User](dev-environment.md)
|
* [Streams](dev-stream.md)
|
||||||
* [Build](dev-environment.md)
|
* [Events](dev-events.md)
|
||||||
* [Frontend](dev-javascript.md)
|
* [Widgets](dev-widgets.md)
|
||||||
* [Contributions](dev-contributing.md)
|
* [Internationalization](dev-i18n.md)
|
||||||
|
* [Authentication](dev-authentication.md)
|
||||||
|
* [Models / Database](dev-db.md)
|
||||||
Development - Modules
|
* [Search](dev-search.md)
|
||||||
---------------------
|
* [CronJobs](dev-cron.md)
|
||||||
|
* [Settings and Configuration](dev-settings.md)
|
||||||
* [Getting Started](dev-module-index.md)
|
* [Console Application](dev-console.md)
|
||||||
* [Events](dev-module-events.md)
|
* [Module Development](dev-module.md)
|
||||||
* [Database](dev-module-db.md)
|
|
||||||
* [Space/User](dev-module-spaceuser.md)
|
|
||||||
* [Navigations](dev-module-menus.md)
|
|
||||||
* [Widget Stacks](dev-module-stack.md)
|
|
||||||
* [Activities](dev-module-activities.md)
|
|
||||||
* [Streams / Walls](dev-module-stream.md)
|
|
||||||
* [Search](dev-module-search.md)
|
|
||||||
* [Translations](dev-module-i18n.md)
|
|
||||||
* [CronJobs](dev-module-cron.md)
|
|
||||||
* [Console](dev-module-console.md)
|
|
||||||
* [Special Topics](dev-module-special-topics.md)
|
|
||||||
|
|
||||||
Theming
|
Theming
|
||||||
-------
|
-------
|
||||||
@ -62,10 +52,3 @@ Theming
|
|||||||
* [Getting Started](theming-index.md)
|
* [Getting Started](theming-index.md)
|
||||||
* [Update / Migrate](theming-migrate.md)
|
* [Update / Migrate](theming-migrate.md)
|
||||||
|
|
||||||
|
|
||||||
Special Topics
|
|
||||||
--------------
|
|
||||||
|
|
||||||
* [Translations](special-translations.md)
|
|
||||||
* [Bundled Software](special-bundled_software.md)
|
|
||||||
|
|
||||||
|
@ -1,72 +0,0 @@
|
|||||||
Authentication
|
|
||||||
==============
|
|
||||||
|
|
||||||
## Example: GitHub Authentication
|
|
||||||
|
|
||||||
- Obtain Application ID and Secret from GitHub
|
|
||||||
- Add following block to protected/config/common.php
|
|
||||||
|
|
||||||
```
|
|
||||||
// ...
|
|
||||||
'components' => [
|
|
||||||
// ...
|
|
||||||
'authClientCollection' => [
|
|
||||||
'class' => 'yii\authclient\Collection',
|
|
||||||
'clients' => [
|
|
||||||
'github' => [
|
|
||||||
'class' => 'yii\authclient\clients\GitHub',
|
|
||||||
'clientId' => '--->your-client-id<---',
|
|
||||||
'clientSecret' => '--->your-client-secret<---',
|
|
||||||
'normalizeUserAttributeMap' => [
|
|
||||||
'username' => 'login',
|
|
||||||
'firstname' => function ($attributes) {
|
|
||||||
list($f, $l) = mb_split(' ', $attributes['name'], 2);
|
|
||||||
return $f;
|
|
||||||
},
|
|
||||||
'lastname' => function ($attributes) {
|
|
||||||
list($f, $l) = mb_split(' ', $attributes['name'], 2);
|
|
||||||
return $l;
|
|
||||||
},
|
|
||||||
],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
// ..
|
|
||||||
],
|
|
||||||
// ...
|
|
||||||
```
|
|
||||||
|
|
||||||
## Example: Facebook
|
|
||||||
|
|
||||||
- Obtain Application ID and Secret from Facebook
|
|
||||||
- Add following block to protected/config/common.php
|
|
||||||
|
|
||||||
```
|
|
||||||
// ...
|
|
||||||
'components' => [
|
|
||||||
// ...
|
|
||||||
'authClientCollection' => [
|
|
||||||
'class' => 'yii\authclient\Collection',
|
|
||||||
'clients' => [
|
|
||||||
'facebook' => [
|
|
||||||
'class' => 'yii\authclient\clients\Facebook',
|
|
||||||
'clientId' => '1662633133992750',
|
|
||||||
'clientSecret' => '3c786f625a26f7f3649bd5cc8d8c6a61',
|
|
||||||
'normalizeUserAttributeMap' => [
|
|
||||||
'username' => 'name',
|
|
||||||
'firstname' => function ($attributes) {
|
|
||||||
list($f, $l) = mb_split(' ', $attributes['name'], 2);
|
|
||||||
return $f;
|
|
||||||
},
|
|
||||||
'lastname' => function ($attributes) {
|
|
||||||
list($f, $l) = mb_split(' ', $attributes['name'], 2);
|
|
||||||
return $l;
|
|
||||||
},
|
|
||||||
],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
// ..
|
|
||||||
],
|
|
||||||
// ...
|
|
||||||
```
|
|
@ -66,7 +66,7 @@ config/messages/de/PostModule.widgets_views_postForm.php
|
|||||||
|
|
||||||
with the content:
|
with the content:
|
||||||
|
|
||||||
``` php
|
```php
|
||||||
<?php
|
<?php
|
||||||
return array (
|
return array (
|
||||||
'What\'s on your mind?' => 'Wie geht es dir heute?',
|
'What\'s on your mind?' => 'Wie geht es dir heute?',
|
||||||
|
140
protected/humhub/docs/guide/admin-authentication.md
Normal file
140
protected/humhub/docs/guide/admin-authentication.md
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
Authentication
|
||||||
|
==============
|
||||||
|
|
||||||
|
LDAP
|
||||||
|
----
|
||||||
|
|
||||||
|
You can enable authentication against LDAP (e.g. against Active Directory or OpenLDAP) via
|
||||||
|
`Administration -> Settings -> User -> LDAP`.
|
||||||
|
|
||||||
|
Facebook
|
||||||
|
--------
|
||||||
|
|
||||||
|
In order to use Facebook OAuth you must register your application at <https://developers.facebook.com/apps>.
|
||||||
|
|
||||||
|
Add following block to your configuration (protected/config/common.php):
|
||||||
|
|
||||||
|
```php
|
||||||
|
return [
|
||||||
|
// ...
|
||||||
|
'components' => [
|
||||||
|
// ...
|
||||||
|
'authClientCollection' => [
|
||||||
|
'clients' => [
|
||||||
|
// ...
|
||||||
|
'facebook' => [
|
||||||
|
'class' => 'humhub\modules\user\authclient\Facebook',
|
||||||
|
'clientId' => 'Your Facebook App ID here',
|
||||||
|
'clientSecret' => 'Your Facebook App Secret here',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
// ...
|
||||||
|
],
|
||||||
|
// ...
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
Google
|
||||||
|
------
|
||||||
|
|
||||||
|
In order to use Google OAuth you must create a project at <https://console.developers.google.com/project>
|
||||||
|
and setup its credentials at <https://console.developers.google.com/project/[yourProjectId]/apiui/credential>.
|
||||||
|
|
||||||
|
In order to enable using scopes for retrieving user attributes, you should also enable Google+ API at
|
||||||
|
<https://console.developers.google.com/project/[yourProjectId]/apiui/api/plus>.
|
||||||
|
|
||||||
|
Add following block to your configuration (protected/config/common.php):
|
||||||
|
|
||||||
|
```php
|
||||||
|
return [
|
||||||
|
// ...
|
||||||
|
'components' => [
|
||||||
|
// ...
|
||||||
|
'authClientCollection' => [
|
||||||
|
'clients' => [
|
||||||
|
// ...
|
||||||
|
'google' => [
|
||||||
|
'class' => 'humhub\modules\user\authclient\Google',
|
||||||
|
'clientId' => 'Your Client ID here',
|
||||||
|
'clientSecret' => 'Your Client Secret here',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
// ...
|
||||||
|
],
|
||||||
|
// ...
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
GitHub
|
||||||
|
------
|
||||||
|
|
||||||
|
In order to use GitHub OAuth you must register your application at <https://github.com/settings/applications/new>.
|
||||||
|
|
||||||
|
Authorization callback URLs:
|
||||||
|
- http://domain/path-to-humhub/user/auth/external (With clean urls enabled)
|
||||||
|
- http://domain/path-to-humhub/index.php?r=user%2Fauth%2Fexternal (Without clean urls)
|
||||||
|
|
||||||
|
Add following block to your configuration (protected/config/common.php):
|
||||||
|
|
||||||
|
```php
|
||||||
|
return [
|
||||||
|
// ...
|
||||||
|
'components' => [
|
||||||
|
// ...
|
||||||
|
'authClientCollection' => [
|
||||||
|
'clients' => [
|
||||||
|
// ...
|
||||||
|
'github' => [
|
||||||
|
'class' => 'humhub\modules\user\authclient\GitHub',
|
||||||
|
'clientId' => 'Your GitHub Client ID here',
|
||||||
|
'clientSecret' => 'Your GitHub Client Secret here',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
// ...
|
||||||
|
],
|
||||||
|
// ...
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Microsoft Live
|
||||||
|
--------------
|
||||||
|
|
||||||
|
In order to use Microsoft Live OAuth you must register your application at <https://account.live.com/developers/applications>.
|
||||||
|
|
||||||
|
Also add a new Platform and allow following Redirect URI.
|
||||||
|
|
||||||
|
- https://domain/path-to-humhub/user/auth/external (With clean urls enabled)
|
||||||
|
- https://domain/path-to-humhub/index.php (Without clean urls)
|
||||||
|
|
||||||
|
Add following block to your configuration (protected/config/common.php):
|
||||||
|
|
||||||
|
```php
|
||||||
|
return [
|
||||||
|
// ...
|
||||||
|
'components' => [
|
||||||
|
// ...
|
||||||
|
'authClientCollection' => [
|
||||||
|
'clients' => [
|
||||||
|
// ...
|
||||||
|
'live' => [
|
||||||
|
'class' => 'humhub\modules\user\authclient\Live',
|
||||||
|
'clientId' => 'Your Microsoft application ID here',
|
||||||
|
'clientSecret' => 'Your Microsoft application password here',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
// ...
|
||||||
|
],
|
||||||
|
// ...
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
Other providers
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Please see [Development - Authentication](dev-authentication.md) for more information
|
||||||
|
about additional authentication providers.
|
@ -1,7 +1,7 @@
|
|||||||
Installation
|
Installation
|
||||||
============
|
============
|
||||||
|
|
||||||
## 1. Preparation
|
## Preparation
|
||||||
|
|
||||||
Create an MySQL Database, e.g.:
|
Create an MySQL Database, e.g.:
|
||||||
|
|
||||||
@ -11,16 +11,31 @@ GRANT ALL ON `humhub`.* TO `humhub_dbuser`@localhost IDENTIFIED BY 'password_cha
|
|||||||
FLUSH PRIVILEGES;
|
FLUSH PRIVILEGES;
|
||||||
```
|
```
|
||||||
|
|
||||||
## 2. Get HumHub
|
> Note: Do not forget to change the `humhub_dbuser` and `password_changeme`!
|
||||||
|
|
||||||
|
## Get HumHub
|
||||||
|
|
||||||
|
### Via: Download Package
|
||||||
|
|
||||||
|
The easiest way to get HumHub is the direct download of the complete package under [http://www.humhub.org/downloads](http://www.humhub.org/downloads).
|
||||||
|
After the download is completed, just extract the package into the htdocs folder of your webserver.
|
||||||
|
|
||||||
### Via: Git/Composer
|
### Via: Git/Composer
|
||||||
|
|
||||||
|
To be able to install a branch retrieved by git you'll have to run a composer update to download all external dependencies.
|
||||||
|
|
||||||
- Clone Git Repository
|
- Clone Git Repository
|
||||||
|
|
||||||
```
|
```
|
||||||
git clone https://github.com/humhub/humhub.git
|
git clone https://github.com/humhub/humhub.git
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- Switch to stable branch (recommended)
|
||||||
|
|
||||||
|
```
|
||||||
|
git checkout stable
|
||||||
|
```
|
||||||
|
|
||||||
- Install composer ([https://getcomposer.org/doc/00-intro.md](https://getcomposer.org/doc/00-intro.md))
|
- Install composer ([https://getcomposer.org/doc/00-intro.md](https://getcomposer.org/doc/00-intro.md))
|
||||||
- Navigate to your HumHub webroot and fetch dependencies
|
- Navigate to your HumHub webroot and fetch dependencies
|
||||||
|
|
||||||
@ -29,11 +44,9 @@ php composer.phar global require "fxp/composer-asset-plugin:~1.1.1"
|
|||||||
composer update
|
composer update
|
||||||
```
|
```
|
||||||
|
|
||||||
### Via: Download Package
|
> Note: The composer update may have to be executed again after an update of your local repository by a git pull. Read more about updating ([Update Guide](http://localhost/codebase/doku/guide-admin-updating.html#gitcomposer-based-installations))
|
||||||
|
|
||||||
Download package at [http://www.humhub.org/downloads](http://www.humhub.org/downloads) and extract it somewhere into your htdocs folder.
|
## Setting up
|
||||||
|
|
||||||
## 3. Setting up
|
|
||||||
|
|
||||||
### File Modes / Permissions
|
### File Modes / Permissions
|
||||||
|
|
||||||
@ -48,19 +61,26 @@ Make the following files executable:
|
|||||||
- /protected/yii
|
- /protected/yii
|
||||||
- /protected/yii.bat
|
- /protected/yii.bat
|
||||||
|
|
||||||
|
**Make sure following directories are not accessible throu webserver!**
|
||||||
|
|
||||||
|
(These folders are protected by default with ".htaccess")
|
||||||
|
|
||||||
|
- protected
|
||||||
|
- uploads/file
|
||||||
|
|
||||||
### Start Installer
|
### Start Installer
|
||||||
|
|
||||||
Open installation in your browser (e.g. [http://localhost/humhub](http://localhost/humhub))
|
Open installation in your browser (e.g. [http://localhost/humhub](http://localhost/humhub))
|
||||||
|
|
||||||
|
|
||||||
## 4. Fine Tuning
|
## Fine Tuning
|
||||||
|
|
||||||
### E-Mail Configuration
|
### E-Mail Configuration
|
||||||
|
|
||||||
Depending on your environment which you are using you may want specify a local or remote SMTP Server.
|
Depending on your environment you are using, you may want to specify a local or remote SMTP Server.
|
||||||
You can change this settings at `Administration -> Mailing -> Server Settings`.
|
You can change the mail-server settings under `Administration -> Mailing -> Server Settings`.
|
||||||
|
|
||||||
By default PHP Mail Transport is used. <http://php.net/manual/en/mail.setup.php>
|
By default the PHP Mail Transport is used. <http://php.net/manual/en/mail.setup.php>
|
||||||
|
|
||||||
|
|
||||||
### Enable Url Rewriting (Optional)
|
### Enable Url Rewriting (Optional)
|
||||||
@ -84,11 +104,8 @@ return [
|
|||||||
|
|
||||||
### Enable Cron Jobs
|
### Enable Cron Jobs
|
||||||
|
|
||||||
Daily cron command:
|
- Daily cron command: `> yii cron/daily`
|
||||||
> yii cron/daily
|
- Hourly cron command: `> yii cron/hourly`
|
||||||
|
|
||||||
Hourly cron command:
|
|
||||||
> yii cron/hourly
|
|
||||||
|
|
||||||
Example Tab:
|
Example Tab:
|
||||||
|
|
||||||
@ -97,15 +114,6 @@ Example Tab:
|
|||||||
00 18 * * * /path/to/humhub/protected/yii cron/daily >/dev/null 2>&1
|
00 18 * * * /path/to/humhub/protected/yii cron/daily >/dev/null 2>&1
|
||||||
```
|
```
|
||||||
|
|
||||||
### Check Directory Protection
|
|
||||||
|
|
||||||
**Make sure following directories are not accessible throu webserver!**
|
|
||||||
|
|
||||||
(These folders are protected by default with ".htaccess")
|
|
||||||
|
|
||||||
- protected
|
|
||||||
- uploads/file
|
|
||||||
|
|
||||||
### Disable Errors / Debugging
|
### Disable Errors / Debugging
|
||||||
|
|
||||||
- Modify *index.php* in humhub root directory
|
- Modify *index.php* in humhub root directory
|
||||||
|
@ -7,7 +7,7 @@ A space can be used by space members to share content with other users.
|
|||||||
|
|
||||||
## Add Spaces
|
## Add Spaces
|
||||||
|
|
||||||
Administrators can configure which groups are allowed to create new spaces under _Administration->Groups->Permissions_.
|
Administrators can configure which groups are allowed to create new spaces under **Administration->Groups->Permissions**.
|
||||||
Please read the [Group Section](admin-groups.md) for more information about goups.
|
Please read the [Group Section](admin-groups.md) for more information about goups.
|
||||||
Spaces can be added by clicking _Add Space_ within the _Space Navigation_.
|
Spaces can be added by clicking _Add Space_ within the _Space Navigation_.
|
||||||
A new space will require at least a space name. Futhermore you are able to define a space color, a description and advanced access settings.
|
A new space will require at least a space name. Futhermore you are able to define a space color, a description and advanced access settings.
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
Updating
|
Updating
|
||||||
========
|
========
|
||||||
|
|
||||||
|
> Warning: Before you run an update please check, if your installed modules and themes are compatible with your target version. If not, you can follow the migration guides.
|
||||||
|
- [Theme Migration Guide](theming-migrate.md)
|
||||||
|
- [Module Migration Guide](dev-migrate.md)
|
||||||
|
|
||||||
> NOTE: Only use this guide if you want to update from HumHub 0.20 or higher!
|
> NOTE: Only use this guide if you want to update from HumHub 0.20 or higher!
|
||||||
> If you want to update from an older version (e.g. 0.11.2 or lower) to HumHub 0.20+, you have to use this guide: **[Upgrade to 0.20 and above](admin-updating-020.md "Guide: Upgrade to 0.20 and above")**
|
> If you want to update from an older version (e.g. 0.11.2 or lower) to HumHub 0.20+, you have to use this guide: **[Upgrade to 0.20 and above](admin-updating-020.md "Guide: Upgrade to 0.20 and above")**
|
||||||
|
|
||||||
1. Before you run an update please check, if your installed modules and themes are compatible with your target version. If not, you can follow the [Theme Migration Guide](theming-migrate.md) and [Module Migration Guide](dev-migrate.md) to make everything ready for the new version.
|
> NOTE: Backup your data:
|
||||||
|
- Backup the whole HumHub installation folder from your webroot
|
||||||
2. Backup your data:
|
- Make a complete MySQL Backup from your HumHub database
|
||||||
- Backup the whole HumHub installation folder from your webroot
|
|
||||||
- Make a complete MySQL Backup from your HumHub database
|
|
||||||
|
|
||||||
|
|
||||||
## Download Package installations
|
## Download Package installations
|
||||||
|
@ -2,7 +2,7 @@ User
|
|||||||
=======
|
=======
|
||||||
##User Management
|
##User Management
|
||||||
|
|
||||||
Users can be managed under _Administration -> Users_.
|
Users are managed under **Administration -> Users**.
|
||||||
|
|
||||||
###Overview:
|
###Overview:
|
||||||
|
|
||||||
@ -12,54 +12,43 @@ The _Overview_ lists all registrated users with actions to
|
|||||||
- _Edit User_
|
- _Edit User_
|
||||||
- _Delete User_
|
- _Delete User_
|
||||||
|
|
||||||
###Add new user:
|
> Note: You can only delete users which are not owner of a space. You'll have to assign a new space-owner in the space-settings before beeing able to delte the user account.
|
||||||
|
|
||||||
Beside the registration of new users, users can be added by system administrators under _Administration -> Add new user_.
|
###Add new users:
|
||||||
|
|
||||||
###Login As User:
|
Beside the registration of a new user, users can be added by system administrators under _Administration -> Users -> Add new user_.
|
||||||
|
|
||||||
Administrators are able to login as another user by clicking on _Become this user_ on the bottom of the user edit form.
|
###Login as a specific User:
|
||||||
|
|
||||||
|
Administrators are able to login as other users by clicking on **Become this user** within the user edit view.
|
||||||
|
|
||||||
## Authentication
|
## Authentication
|
||||||
|
|
||||||
The way users can register to the system can be configured under _Administration -> Authentication_.
|
The way users can be registered to your HumHub instance is configurable under **Administration -> Authentication**.
|
||||||
The following configurations are available:
|
The following configurations are available:
|
||||||
|
|
||||||
**Allow limited access for non-authenticated user (guests):**
|
- **Allow limited access for non-authenticated user (guests)**:
|
||||||
|
|
||||||
Guest users are non-authenticated users and are able to view public accessible content if this option is enabled.
|
Guest users are non-authenticated users and are able to view public accessible content if this option is enabled.
|
||||||
Instead of showing an initial Login modal, non-authenticated users are able to access the directory and dashboard and view public content of spaces.
|
Instead of showing an initial Login modal, non-authenticated users are able to access the directory and dashboard and view public content of spaces.
|
||||||
|
- **Anonymous users can register:**
|
||||||
**Anonymous users can register:**
|
|
||||||
|
|
||||||
If this checkbox is enabled anonymous users will be able to send registration requests to the system.
|
If this checkbox is enabled anonymous users will be able to send registration requests to the system.
|
||||||
|
- **Members can invite external users by email**:
|
||||||
**Members can invite external users by email:**
|
|
||||||
|
|
||||||
If this checkbox is enabled all members will be able to invite new users by email.
|
If this checkbox is enabled all members will be able to invite new users by email.
|
||||||
|
- **Require group admin approval after registration**:
|
||||||
**Require group admin approval after registration:**
|
|
||||||
|
|
||||||
This checkbox will either add an additional group dropdown selection to the registration form,
|
This checkbox will either add an additional group dropdown selection to the registration form,
|
||||||
or automatically add the user to a default group. After the registration, all admins of the given group will be informed about a new pending user request
|
or automatically add the user to a default group. After the registration, all admins of the given group will be informed about a new pending user request
|
||||||
and have the possibility to accept or decline the registration request.
|
and have the possibility to accept or decline the registration request.
|
||||||
|
- **Default user group for new users**:
|
||||||
**Default user group for new users:**
|
|
||||||
|
|
||||||
With this selection you can set the default group for all new users. If 'None' is selected the user will be able to
|
With this selection you can set the default group for all new users. If 'None' is selected the user will be able to
|
||||||
select an group while registration (If the group admin approval is activated).
|
select an group while registration (If the group admin approval is activated).
|
||||||
|
- **Default user idle timeout, auto-logout (in seconds, optional):**
|
||||||
**Default user idle timeout, auto-logout (in seconds, optional)**
|
|
||||||
|
|
||||||
Sets the time in seconds before inactive users session is closed, min value 20 seconds, default 1400seconds/24minutes.
|
Sets the time in seconds before inactive users session is closed, min value 20 seconds, default 1400seconds/24minutes.
|
||||||
|
- **Default user profile visiblity**:
|
||||||
**Default user profile visiblity**
|
|
||||||
|
|
||||||
Sets the default visibility of user profiles. This is only applicable when limited access for non-authenticated users is enabled.
|
Sets the default visibility of user profiles. This is only applicable when limited access for non-authenticated users is enabled.
|
||||||
Changes of this selection will only affect new users. It can either be set to _members only_ or _members and guests_.
|
Changes of this selection will only affect new users. It can either be set to _members only_ or _members and guests_.
|
||||||
|
|
||||||
##User Approval
|
##User Approval
|
||||||
|
|
||||||
Pending users can either be approved by group admins over the _Dashboard_ and _Account Dropdown -> User Approval_ or by System Admins under _Administration -> User Approval_.
|
Pending users can either be approved by group managers under the **Dashboard/Account Dropdown -> User Approval** or by Administrators under **Administration -> User Approval**.
|
||||||
|
|
||||||
|
|
||||||
|
> Note: The approval process is only needed if the **Require group admin approval after registration** checkbox within the user authentication settings is enabled.
|
||||||
|
72
protected/humhub/docs/guide/dev-activities.md
Normal file
72
protected/humhub/docs/guide/dev-activities.md
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
Activities
|
||||||
|
==========
|
||||||
|
|
||||||
|
An activity is instance is created for special events in the context of a [[humhub\modules\content\models\ContentContainer|ContentContainer]] as the creation of new content.
|
||||||
|
|
||||||
|
Contrary to notifications - activities are always bound to a [[humhub\modules\content\models\ContentContainer|ContentContainer]], so they are not especially linked against a user or a given set of them.
|
||||||
|
Besides the link to the [[humhub\modules\content\models\ContentContainer|ContentContainer]] - an activity can also be assigned with a Content or ContentAddon. So it will automatically inherit some content attributes such as visiblity.
|
||||||
|
|
||||||
|
> Note: Internally activities are handled as content.
|
||||||
|
|
||||||
|
## Implement a Custom Activity
|
||||||
|
|
||||||
|
### Create Class & View
|
||||||
|
|
||||||
|
Create a folder ** activities ** in your module and a new class ** SomethingHappend **
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace johndoe\example\activities;
|
||||||
|
|
||||||
|
use humhub\core\activity\components\BaseActivity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifies a user about something happend
|
||||||
|
*/
|
||||||
|
class SomethingHappend extends BaseActivity
|
||||||
|
{
|
||||||
|
// View Name for activity
|
||||||
|
public $viewName = "somethingHappend";
|
||||||
|
|
||||||
|
// Module Id (required)
|
||||||
|
public $moduleId = "example";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
```
|
||||||
|
|
||||||
|
By default activity views should be located inside a subfolder named ** views ** where your activity class is located. (e.g. /modules/examples/activities/views/)
|
||||||
|
|
||||||
|
Example view file ** somethingHappend.php **:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use yii\helpers\Html;
|
||||||
|
|
||||||
|
echo Yii::t('ExampleModule.views_notifications_newLike', "%someUser% did something cool.", array(
|
||||||
|
'%someUser%' => '<strong>' . Html::encode($originator->displayName) . '</strong>'
|
||||||
|
));
|
||||||
|
?>
|
||||||
|
```
|
||||||
|
|
||||||
|
If you require a different view for mails. You can create a ** mail ** folder in your views directory.
|
||||||
|
|
||||||
|
### Persist an Activity
|
||||||
|
|
||||||
|
```php
|
||||||
|
$activity = new \johndoe\example\activities\NewLike();
|
||||||
|
|
||||||
|
// Link to a ContentContainer, Content or ContentAddon
|
||||||
|
$activity->source = $this;
|
||||||
|
|
||||||
|
// User which trigged this Activity - in case of Content/ContentAddon the Creator will be automatically set.
|
||||||
|
$activity->originator = $user;
|
||||||
|
|
||||||
|
$activity->create();
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Delete
|
||||||
|
|
||||||
|
TBD
|
41
protected/humhub/docs/guide/dev-authentication.md
Normal file
41
protected/humhub/docs/guide/dev-authentication.md
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
Authentication
|
||||||
|
===============
|
||||||
|
|
||||||
|
HumHub is using <http://www.yiiframework.com/doc-2.0/ext-authclient-index.html> to provide an interface to pluggable authentication providers.
|
||||||
|
|
||||||
|
|
||||||
|
Implementing own AuthClients
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Please see <https://github.com/yiisoft/yii2-authclient/blob/master/docs/guide/README.md> for more details.
|
||||||
|
|
||||||
|
|
||||||
|
HumHub Specific Extensions
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
Optionally your custom client can implement following interfaces to provide additional HumHub features.
|
||||||
|
|
||||||
|
### ApprovalBypass
|
||||||
|
|
||||||
|
Use interface ([[humhub\modules\user\authclient\interfaces\ApprovalBypass]]) to skip user approval for new users.
|
||||||
|
|
||||||
|
### AutoSyncUsers
|
||||||
|
|
||||||
|
The interface ([[humhub\modules\user\authclient\interfaces\AutoSyncUsers]]) the HumHub cronjob will execute
|
||||||
|
the AuthClients syncUsers method hourly to create, update or delete existing users.
|
||||||
|
|
||||||
|
### SyncAttributes
|
||||||
|
|
||||||
|
By using the interface ([[humhub\modules\user\authclient\interfaces\SyncAttributes]]) interface - you can define user attribute (e.g. profile fields) to
|
||||||
|
be automatically updated by the AuthClient and cannot be changed by the user.
|
||||||
|
|
||||||
|
### PrimaryClient
|
||||||
|
|
||||||
|
A user can only belongs to one ([[humhub\modules\user\authclient\interfaces\PrimaryClient]]) AuthClient.
|
||||||
|
|
||||||
|
Example for PrimaryClients:
|
||||||
|
|
||||||
|
- Standard Password Authentication
|
||||||
|
- LDAP
|
||||||
|
|
||||||
|
|
3
protected/humhub/docs/guide/dev-build.md
Normal file
3
protected/humhub/docs/guide/dev-build.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Build
|
||||||
|
========
|
||||||
|
(TBD)
|
61
protected/humhub/docs/guide/dev-console.md
Normal file
61
protected/humhub/docs/guide/dev-console.md
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
Console Application
|
||||||
|
=====================
|
||||||
|
|
||||||
|
## Add controller to the console application
|
||||||
|
|
||||||
|
To add a custom controller to the console application, you need to catch the [[humhub\components\console\Application::EVENT_ON_INIT]].
|
||||||
|
|
||||||
|
|
||||||
|
Example event:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use humhub\components\console\Application;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'id' => 'translation',
|
||||||
|
'class' => 'humhub\modules\translation\Module',
|
||||||
|
'namespace' => 'humhub\modules\translation',
|
||||||
|
'events' => array(
|
||||||
|
//...
|
||||||
|
array('class' => Application::className(), 'event' => Application::EVENT_ON_INIT, 'callback' => array('humhub\modules\translation\Module', 'onConsoleApplicationInit')),
|
||||||
|
//...
|
||||||
|
),
|
||||||
|
];
|
||||||
|
?>
|
||||||
|
```
|
||||||
|
|
||||||
|
Example callback:
|
||||||
|
|
||||||
|
```php
|
||||||
|
public static function onConsoleApplicationInit($event) {
|
||||||
|
$application = $event->sender;
|
||||||
|
$application->controllerMap['translation'] = commands\TranslationController::className();
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Integrity Checker
|
||||||
|
|
||||||
|
The integrity checker is a command which validates and if necessary repairs the application database.
|
||||||
|
|
||||||
|
If you want to add own checking methods for your module to it, you can intercept the [[humhub\controllers\IntegrityController::EVENT_ON_RUN]] event.
|
||||||
|
|
||||||
|
Example callback implementation:
|
||||||
|
|
||||||
|
```php
|
||||||
|
public static function onIntegrityCheck($event)
|
||||||
|
{
|
||||||
|
$integrityController = $event->sender;
|
||||||
|
$integrityController->showTestHeadline("Polls Module - Answers (" . PollAnswer::find()->count() . " entries)");
|
||||||
|
|
||||||
|
foreach (PollAnswer::find()->joinWith('poll')->all() as $answer) {
|
||||||
|
if ($answer->poll === null) {
|
||||||
|
if ($integrityController->showFix("Deleting poll answer id " . $answer->id . " without existing poll!")) {
|
||||||
|
$answer->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
@ -3,8 +3,9 @@ Content
|
|||||||
|
|
||||||
## ContentContainer
|
## ContentContainer
|
||||||
|
|
||||||
A [[humhub\modules\content\models\ContentContainer|ContentContainer]] in HumHub is the base concept for assigning content to a specific container instance.
|
A [[humhub\modules\content\models\ContentContainer|ContentContainer]] in HumHub is the base concept for assigning content entries to a specific container instance (user or space).
|
||||||
A [[humhub\modules\content\models\ContentContainer|ContentContainer]] is assigned with a unique guid, which is used in controllers to identify the context of its actions.
|
Each [[humhub\modules\content\models\ContentContainer|ContentContainer]] is assigned with an unique guid, which is used in controllers to identify the context of its actions.
|
||||||
|
|
||||||
Currently there are two types of ContentContainer:
|
Currently there are two types of ContentContainer:
|
||||||
|
|
||||||
- [[humhub\modules\user\models\User|User]]
|
- [[humhub\modules\user\models\User|User]]
|
||||||
@ -16,8 +17,8 @@ Currently there are two types of ContentContainer:
|
|||||||
|
|
||||||
### ContentContainerController
|
### ContentContainerController
|
||||||
|
|
||||||
The [[humhub\modules\content\components\ContentContainerController|ContentContainerController]] class should be extended by controllers, which are working in the context of a [[humhub\modules\content\models\ContentContainer|ContentContainer]].
|
The [[humhub\modules\content\components\ContentContainerController|ContentContainerController]] class is extended by controllers working in the context of a specific [[humhub\modules\content\models\ContentContainer|ContentContainer]].
|
||||||
A [[humhub\modules\content\components\ContentContainerController|ContentContainerController]] will automatically search a **sguid** (Space) or **uguid** (User) request parameter for every request and will instantiate the associated [[humhub\modules\content\models\ContentContainer|ContentContainer]].
|
A [[humhub\modules\content\components\ContentContainerController|ContentContainerController]] will automatically search a **sguid** (Space) or **uguid** (User) request parameter for every request and will instantiate and provide the associated [[humhub\modules\content\models\ContentContainer|ContentContainer]].
|
||||||
|
|
||||||
The [[humhub\modules\content\components\ContentContainerController|ContentContainerController]] provides common tasks like:
|
The [[humhub\modules\content\components\ContentContainerController|ContentContainerController]] provides common tasks like:
|
||||||
|
|
||||||
@ -26,7 +27,7 @@ The [[humhub\modules\content\components\ContentContainerController|ContentContai
|
|||||||
- Layout selection based on container type (User or Space)
|
- Layout selection based on container type (User or Space)
|
||||||
- Create URL's for the given ContentContainer
|
- Create URL's for the given ContentContainer
|
||||||
|
|
||||||
For example,
|
For example:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
class ExampleController extends \humhub\modules\content\components\ContentContainerController
|
class ExampleController extends \humhub\modules\content\components\ContentContainerController
|
||||||
@ -57,19 +58,26 @@ Links to a [[humhub\modules\content\components\ContentContainerController|Conten
|
|||||||
Each ContentContainer class is derived from [[\humhub\modules\content\components\ContentContainerActiveRecord]].
|
Each ContentContainer class is derived from [[\humhub\modules\content\components\ContentContainerActiveRecord]].
|
||||||
Beside others, this abstract class provides the following functionality:
|
Beside others, this abstract class provides the following functionality:
|
||||||
|
|
||||||
- Permission Management
|
- [Permission Management](dev-permissions.md) `getPermissionManager()`
|
||||||
- Getter for Profile-/BannerImage
|
- Profile-/Banner-image access `getProfileImage()`, `getProfileBannerImage()`
|
||||||
|
- Rendering the container stream `getWallOut()` (see [Permission Management](dev-stream.md))
|
||||||
|
|
||||||
TBD (URL, AccessChecking, ProfileImage)
|
Profile image example:
|
||||||
|
|
||||||
|
```php
|
||||||
|
//Get Profile Image Url
|
||||||
|
$profileImage = $space->getProfileImage();
|
||||||
|
if($profileImage->hasImage()) {
|
||||||
|
$url = $profileImage->getUrl();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### ContentContainerModule
|
### ContentContainerModule
|
||||||
|
|
||||||
If a module should be shown in the content containers module section, the module class must extend [[humhub\modules\content\components\ContentContainerModule]].
|
If a module should appear in the content containers module section, the module class must extend [[humhub\modules\content\components\ContentContainerModule]].
|
||||||
A ContentContainerModule can be enabled or disabled for a specific ContentContainer. The calendar module, for example, can be enabled for a specific space or a specific user account.
|
A ContentContainerModule can be enabled or disabled for a specific ContentContainer. The calendar module, for example, can be enabled for a specific space or a specific user account.
|
||||||
|
|
||||||
If you're working with content or other persistent data, make also sure to delete it when the module is disabled on a content container. Do this by overwriting the method [[humhub\modules\content\components\ContentContainerModule::disableContentContainer]].
|
See the [[humhub\modules\content\components\ContentContainerModule]] class for a full list of options.
|
||||||
|
|
||||||
See [[humhub\modules\content\components\ContentContainerModule]] class for a full list of options.
|
|
||||||
|
|
||||||
Example of a modules `Module.php` file:
|
Example of a modules `Module.php` file:
|
||||||
|
|
||||||
@ -77,27 +85,31 @@ Example of a modules `Module.php` file:
|
|||||||
class Module extends \humhub\modules\content\components\ContentContainerModule
|
class Module extends \humhub\modules\content\components\ContentContainerModule
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// Defines for which content container type this module is appropriate
|
||||||
public function getContentContainerTypes()
|
public function getContentContainerTypes()
|
||||||
{
|
{
|
||||||
//This content container can be assigned to Spaces and User
|
// This content container can be assigned to Spaces and User
|
||||||
return [
|
return [
|
||||||
Space::className(),
|
Space::className(),
|
||||||
User::className(),
|
User::className(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Is called when the whole module is disabled
|
||||||
public function disable()
|
public function disable()
|
||||||
{
|
{
|
||||||
// Clear all Module data and call parent disable
|
// Clear all Module data and call parent disable
|
||||||
parent::disable();
|
parent::disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Is called when the module is disabled on a specific container
|
||||||
public function disableContentContainer(ContentContainerActiveRecord $container)
|
public function disableContentContainer(ContentContainerActiveRecord $container)
|
||||||
{
|
{
|
||||||
parent::disableContentContainer($container);
|
parent::disableContentContainer($container);
|
||||||
//Here you can clear all data related to the given container
|
//Here you can clear all data related to the given container
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Can be used to define a specific description text for different container types
|
||||||
public function getContentContainerDescription(ContentContainerActiveRecord $container)
|
public function getContentContainerDescription(ContentContainerActiveRecord $container)
|
||||||
{
|
{
|
||||||
if ($container instanceof Space) {
|
if ($container instanceof Space) {
|
||||||
@ -107,20 +119,8 @@ class Module extends \humhub\modules\content\components\ContentContainerModule
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
> Note: If you're working with content or other persistent data, make sure to delete the container related data, when the module is disabled on a content container. This can be archieved by overwriting the [[humhub\modules\content\components\ContentContainerModule::disableContentContainer]] method.
|
||||||
|
|
||||||
### ContentContainerPermissionManager
|
|
||||||
|
|
||||||
Beside permissions for groups, you can assign permissions to a ContentContainer.
|
|
||||||
|
|
||||||
(TBD link to permissions docs)
|
|
||||||
|
|
||||||
### ContentContainerPermission
|
|
||||||
|
|
||||||
(TBD)
|
|
||||||
|
|
||||||
### ContentContainerStream
|
|
||||||
|
|
||||||
(TBD)
|
|
||||||
|
|
||||||
## Content
|
## Content
|
||||||
|
|
||||||
@ -138,10 +138,10 @@ This Content record holds all neccessary informations and provides common method
|
|||||||
- Archiving / Sticking
|
- Archiving / Sticking
|
||||||
- And more...
|
- And more...
|
||||||
|
|
||||||
If you're implementing an ActiveRecord based on [[humhub\modules\content\components\ContentContainerActiveRecord]] you need to implement following abstract methods:
|
If you're implementing an ActiveRecord based on [[humhub\modules\content\components\ContentContainerActiveRecord]] you need to implement the following abstract methods:
|
||||||
|
|
||||||
- getContentName() - Returns the displayed name of the Content (e.g. Post or Poll)
|
- `getContentName()` - Returns the displayed name of the Content (e.g. Post or Poll)
|
||||||
- getContentDescription() - Returns a preview of the Content - which is used in Notifications for example.
|
- `getContentDescription()` - Returns a preview of the Content - which is used in Notifications for example.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@ -150,22 +150,17 @@ Example:
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
#### Wall/Stream Output
|
#### Wall/Stream Output
|
||||||
|
(TBD)
|
||||||
|
|
||||||
#### Querying Content
|
#### Querying Content
|
||||||
|
|
||||||
If you're calling find() on a [[\humhub\modules\content\components\ContentActiveRecord]] instance you'll get an special [[\humhub\modules\content\components\ActiveQueryContent]] which provides additional method to select content.
|
If you're calling find() on a [[\humhub\modules\content\components\ContentActiveRecord]] instance you'll get an special [[\humhub\modules\content\components\ActiveQueryContent]] which provides additional methods to select content.
|
||||||
|
|
||||||
- contentContainer($container) - Find content only inside a given container
|
- contentContainer($container) - Find content only inside a given container
|
||||||
- readable($user) - Return only user readable content
|
- readable($user) - Return only user readable content
|
||||||
- ...
|
- ...
|
||||||
|
|
||||||
#### Permissions
|
|
||||||
|
|
||||||
TBD (Read Permissions not enhanceable)
|
|
||||||
|
|
||||||
|
|
||||||
### Controller
|
### Controller
|
||||||
|
|
||||||
|
87
protected/humhub/docs/guide/dev-db.md
Normal file
87
protected/humhub/docs/guide/dev-db.md
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
Database and Models
|
||||||
|
====================
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
|
||||||
|
- prefix your tables with the module id. e.g. example_foo
|
||||||
|
- singular table names
|
||||||
|
- use underscorce in fieldnames/attributes e.g. user_id
|
||||||
|
|
||||||
|
## ActiveRecord (Model)
|
||||||
|
|
||||||
|
To be able to provide persistent data a module has to implement model class derived from [[humhub\components\ActiveRecord]].
|
||||||
|
Yii follows the concept of rich models, which means a model class can contain content in form of attributes as well as domain logic.
|
||||||
|
More information about the use of ActiveRecords is available in the [Yii2 guide](http://www.yiiframework.com/doc-2.0/guide-db-active-record.html).
|
||||||
|
|
||||||
|
> Info: [[humhub\components\ActiveRecord]] is derived from [[yii\db\ActiveRecord]] and provides some automatic attribute settings as `created_by` and `crated_at` if the underlying table contains these fields.
|
||||||
|
|
||||||
|
## Migrations
|
||||||
|
|
||||||
|
See Yii 2.0 guide for more details about migrations [http://www.yiiframework.com/doc-2.0/guide-db-migrations.html](http://www.yiiframework.com/doc-2.0/guide-db-migrations.html).
|
||||||
|
|
||||||
|
HumHub provides an enhanced Migration class [[humhub\components\Migration]] which provides the ability to rename class files. This is required because HumHub also stores some class names in database for Polymorphic relations.
|
||||||
|
|
||||||
|
#### Usage
|
||||||
|
|
||||||
|
- Create a module migration
|
||||||
|
`> php yii migrate/create example --migrationPath='@app/modules/polls/migrations'`
|
||||||
|
- Execute module migration
|
||||||
|
`> php yii migrate/up --migrationPath='@app/modules/polls/migrations'`
|
||||||
|
- Execute all migrations (including enabled modules)
|
||||||
|
`> php yii migrate/up --includeModuleMigrations=1`
|
||||||
|
|
||||||
|
#### Uninstall
|
||||||
|
|
||||||
|
There is a special migration file called 'uninstall.php' - which is executed after the module is uninstalled.
|
||||||
|
Use this drop created tables & columns.
|
||||||
|
|
||||||
|
Example file: *migrations/uninstall.php*
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use yii\db\Migration;
|
||||||
|
|
||||||
|
class uninstall extends Migration
|
||||||
|
{
|
||||||
|
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
|
||||||
|
$this->dropTable('poll');
|
||||||
|
$this->dropTable('poll_answer');
|
||||||
|
$this->dropTable('poll_answer_user');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
echo "uninstall does not support migration down.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Integrity Checker
|
||||||
|
|
||||||
|
The integrity checker is a command which validates and if necessary repairs the application database.
|
||||||
|
|
||||||
|
If you want to add own checking methods for your module to it, you can intercept the [[humhub\controllers\IntegrityController::EVENT_ON_RUN]] event.
|
||||||
|
|
||||||
|
Example callback implementation:
|
||||||
|
|
||||||
|
```php
|
||||||
|
public static function onIntegrityCheck($event)
|
||||||
|
{
|
||||||
|
$integrityController = $event->sender;
|
||||||
|
$integrityController->showTestHeadline("Polls Module - Answers (" . PollAnswer::find()->count() . " entries)");
|
||||||
|
|
||||||
|
foreach (PollAnswer::find()->joinWith('poll')->all() as $answer) {
|
||||||
|
if ($answer->poll === null) {
|
||||||
|
if ($integrityController->showFix("Deleting poll answer id " . $answer->id . " without existing poll!")) {
|
||||||
|
$answer->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
@ -1,63 +0,0 @@
|
|||||||
# Enviroment
|
|
||||||
|
|
||||||
## Enable Yii Debug Module
|
|
||||||
|
|
||||||
Add following block to your local web configuration (/protected/config/web.php)
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php
|
|
||||||
return [
|
|
||||||
// ...
|
|
||||||
'bootstrap' => ['debug'],
|
|
||||||
'modules' => [
|
|
||||||
// ...
|
|
||||||
|
|
||||||
'debug' => [
|
|
||||||
'class' => 'yii\debug\Module',
|
|
||||||
'allowedIPs' => ['127.0.0.1', '::1'],
|
|
||||||
],
|
|
||||||
|
|
||||||
// ...
|
|
||||||
]
|
|
||||||
];
|
|
||||||
?>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Enable Gii
|
|
||||||
|
|
||||||
### Web
|
|
||||||
|
|
||||||
Add following block to your local web configuration (/protected/config/web.php)
|
|
||||||
|
|
||||||
```php
|
|
||||||
return [
|
|
||||||
// ...
|
|
||||||
'modules' => [
|
|
||||||
// ...
|
|
||||||
|
|
||||||
'gii' => [
|
|
||||||
'class' => 'yii\gii\Module',
|
|
||||||
'allowedIPs' => ['127.0.0.1', '::1'],
|
|
||||||
],
|
|
||||||
|
|
||||||
// ...
|
|
||||||
]
|
|
||||||
];
|
|
||||||
?>
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### Console
|
|
||||||
|
|
||||||
Add following block to your local console configuration (/protected/config/console.php)
|
|
||||||
|
|
||||||
```php
|
|
||||||
return [
|
|
||||||
// ...
|
|
||||||
'bootstrap' => ['gii'],
|
|
||||||
'modules' => [
|
|
||||||
'gii' => 'yii\gii\Module',
|
|
||||||
],
|
|
||||||
// ...
|
|
||||||
];
|
|
||||||
```
|
|
@ -6,9 +6,112 @@ Overview
|
|||||||
- HumHub is based on Yii 2.0 PHP Framework (http://www.yiiframework.com/)
|
- HumHub is based on Yii 2.0 PHP Framework (http://www.yiiframework.com/)
|
||||||
- [The Definitive Guide to Yii 2.0](http://www.yiiframework.com/doc-2.0/guide-index.html)
|
- [The Definitive Guide to Yii 2.0](http://www.yiiframework.com/doc-2.0/guide-index.html)
|
||||||
|
|
||||||
|
## Application Overview
|
||||||
|
|
||||||
|
Humhub is based on _PHP5_ and _Yii2_ and leverages the highly modular and flexible nature of _Yii_.
|
||||||
|
Before learning about the internals of HumHub, you should be familiar with the basic concepts of
|
||||||
|
[Yii](http://www.yiiframework.com/doc-2.0/guide-README.html "Yii Guide").
|
||||||
|
|
||||||
|
![Application Layers](images/appLayer.svg)
|
||||||
|
|
||||||
|
The HumHub core contains several core modules as well as extended Yii components:
|
||||||
|
|
||||||
|
**Core Components:**
|
||||||
|
|
||||||
|
- [[humhub\components\ActiveRecord]]
|
||||||
|
- [[humhub\components\Application]]
|
||||||
|
- [[humhub\components\Controller]]
|
||||||
|
- [[humhub\components\Migration]]
|
||||||
|
- [[humhub\components\Module]]
|
||||||
|
- [[humhub\components\ModuleManager]]
|
||||||
|
- [[humhub\components\Request]]
|
||||||
|
- [[humhub\components\Theme]]
|
||||||
|
- [[humhub\components\View]]
|
||||||
|
- [[humhub\components\Widget]]
|
||||||
|
|
||||||
|
**Core Modules:**
|
||||||
|
|
||||||
|
- **activity:** User/Space activities
|
||||||
|
- **admin:** Responsible for admin/configuration related issues
|
||||||
|
- **comment:** Content addon for commenting
|
||||||
|
- **content:** Base module for all content types (Post,Wiki,...)
|
||||||
|
- **dashboard:** Dashboard related functionality
|
||||||
|
- **directory:** Directory related functionality
|
||||||
|
- **file:** Basic file module for accessing the filesystem
|
||||||
|
- **installer:** HumHub installer module
|
||||||
|
- **like:** Content addon for likes
|
||||||
|
- **notification:** User Notifications
|
||||||
|
- **post:** Simple user-post related functionality
|
||||||
|
- **search:** Luceene Search Module
|
||||||
|
- **space:** Space related functionality
|
||||||
|
- **tour:** HumHub user-guide
|
||||||
|
- **user:** Basic user module
|
||||||
|
|
||||||
## Development Environment Notes
|
## Development Environment Notes
|
||||||
|
|
||||||
- Use Composer Installation include dev requirements
|
- Use Composer Installation as described in the [Installation Guide](admin-installation.md#via-gitcomposer)
|
||||||
- Switch to development mode in ``index.php`` (see inline documentation)
|
- Switch to development mode in ``index.php`` (described [here](admin-installation.md#disable-errors-debugging))
|
||||||
- Disable Caching (Administration -> Settings -> Caching -> None)
|
- Disable Caching under **Administration -> Settings -> Caching -> None**
|
||||||
|
|
||||||
|
## Enable Yii Debug Module
|
||||||
|
|
||||||
|
Add following block to your local web configuration (/protected/config/web.php)
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
return [
|
||||||
|
// ...
|
||||||
|
'bootstrap' => ['debug'],
|
||||||
|
'modules' => [
|
||||||
|
// ...
|
||||||
|
|
||||||
|
'debug' => [
|
||||||
|
'class' => 'yii\debug\Module',
|
||||||
|
'allowedIPs' => ['127.0.0.1', '::1'],
|
||||||
|
],
|
||||||
|
|
||||||
|
// ...
|
||||||
|
]
|
||||||
|
];
|
||||||
|
?>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Enable Gii
|
||||||
|
|
||||||
|
### Web
|
||||||
|
|
||||||
|
Add following block to your local web configuration (/protected/config/web.php)
|
||||||
|
|
||||||
|
```php
|
||||||
|
return [
|
||||||
|
// ...
|
||||||
|
'modules' => [
|
||||||
|
// ...
|
||||||
|
|
||||||
|
'gii' => [
|
||||||
|
'class' => 'yii\gii\Module',
|
||||||
|
'allowedIPs' => ['127.0.0.1', '::1'],
|
||||||
|
],
|
||||||
|
|
||||||
|
// ...
|
||||||
|
]
|
||||||
|
];
|
||||||
|
?>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Console
|
||||||
|
|
||||||
|
Add following block to your local console configuration (/protected/config/console.php)
|
||||||
|
|
||||||
|
```php
|
||||||
|
return [
|
||||||
|
// ...
|
||||||
|
'bootstrap' => ['gii'],
|
||||||
|
'modules' => [
|
||||||
|
'gii' => 'yii\gii\Module',
|
||||||
|
],
|
||||||
|
// ...
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Here you will learn how you can adapt existing modules to working fine with actually versions.
|
Here you will learn how you can adapt existing modules to working fine with actually versions.
|
||||||
|
|
||||||
## to 1.1
|
## Migrate from 1.0 to 1.1
|
||||||
|
|
||||||
- Dropped unused space attribute "website"
|
- Dropped unused space attribute "website"
|
||||||
|
|
||||||
@ -14,27 +14,36 @@ Here you will learn how you can adapt existing modules to working fine with actu
|
|||||||
- Not longer validates content visibility (private/public) permissions
|
- Not longer validates content visibility (private/public) permissions
|
||||||
|
|
||||||
- system_admin attribute in user table was removed
|
- system_admin attribute in user table was removed
|
||||||
|
see [[humhub\modules\user\models\User::isSystemAdmin]]
|
||||||
|
|
||||||
|
- Renamed space header settings menu dropdown class
|
||||||
|
from [[humhub\modules\space\modules\manage\widgets\Menu]] to [[humhub\modules\space\widgets\HeaderControlsMenu]]
|
||||||
|
|
||||||
|
- Refactored settings system. see [Settings Documentation](dev-settings.md) for more details.
|
||||||
|
Old settings api is still available in 1.1.x
|
||||||
|
|
||||||
|
- Refactored user group system
|
||||||
|
|
||||||
|
- New administration menu structure
|
||||||
|
|
||||||
|
## Migrate from 0.20 to 1.0
|
||||||
|
|
||||||
|
|
||||||
## to 0.20
|
## Migrate from 0.12 to 0.20
|
||||||
|
|
||||||
**Important: This release upgrades from Yii1 to Yii2 Framework!**
|
**Important: This release upgrades from Yii1 to Yii2 Framework!**
|
||||||
|
|
||||||
This requires an extensive migration of all custom modules/themes.
|
This requires an extensive migration of all custom modules/themes.
|
||||||
Find more details here: [HumHub 0.20 Migration](dev-migrate-0.20.md)
|
Find more details here: [HumHub 0.20 Migration](dev-migrate-0.20.md)
|
||||||
|
|
||||||
## to 0.12
|
## Migrate from 0.11 to 0.12
|
||||||
|
|
||||||
- Rewritten Search
|
- Rewritten Search
|
||||||
|
|
||||||
## to 0.11
|
## Migrate from 0.10 to 0.11
|
||||||
|
|
||||||
No breaking changes.
|
No breaking changes.
|
||||||
|
|
||||||
- Now handle ContentContainerController layouts, new option showSidebar
|
- Now handle ContentContainerController layouts, new option showSidebar
|
||||||
- New ContentAddonController Class
|
- New ContentAddonController Class
|
||||||
- New Wiki Parser / Editor Widget
|
- New Wiki Parser / Editor Widget
|
||||||
|
|
||||||
## to 0.10
|
|
||||||
|
|
||||||
No breaking changes
|
|
@ -1,77 +0,0 @@
|
|||||||
Activities
|
|
||||||
==========
|
|
||||||
|
|
||||||
Contrary to Notifications - Activities are bound to a ContentContainer, so they are not especially linked against a user or a given set of them.
|
|
||||||
|
|
||||||
Besides the link to the ContentContainer - an Activity can be also assigned to a Content or ContentAddon. So it will automatically inherits some Content Attributes such as Visiblity.
|
|
||||||
|
|
||||||
Note: Internally Activities will be handled as Content.
|
|
||||||
|
|
||||||
## Steps to create an Activity
|
|
||||||
|
|
||||||
### Create Class & View
|
|
||||||
|
|
||||||
Create a folder ** activities ** in your module and a new class ** SomethingHappend **
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace johndoe\example\activities;
|
|
||||||
|
|
||||||
use humhub\core\activity\components\BaseActivity;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notifies a user about something happend
|
|
||||||
*/
|
|
||||||
class SomethingHappend extends BaseActivity
|
|
||||||
{
|
|
||||||
// View Name for activity
|
|
||||||
public $viewName = "somethingHappend";
|
|
||||||
|
|
||||||
// Module Id (required)
|
|
||||||
public $moduleId = "example";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
By default activity views should be located inside a subfolder named ** views ** where your activity class is located. (e.g. /modules/examples/activities/views/)
|
|
||||||
|
|
||||||
Example view file ** somethingHappend.php **:
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php
|
|
||||||
|
|
||||||
use yii\helpers\Html;
|
|
||||||
|
|
||||||
echo Yii::t('ExampleModule.views_notifications_newLike', "%someUser% did something cool.", array(
|
|
||||||
'%someUser%' => '<strong>' . Html::encode($originator->displayName) . '</strong>'
|
|
||||||
));
|
|
||||||
?>
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
If you require a diffrent view in mails. You can create a subfolder inside the subfolder called ** mail ** in your views directory.
|
|
||||||
|
|
||||||
|
|
||||||
### Create it
|
|
||||||
|
|
||||||
```php
|
|
||||||
$activity = new \johndoe\example\activities\NewLike();
|
|
||||||
|
|
||||||
// Link to a ContentContainer, Content or ContentAddon
|
|
||||||
$activity->source = $this;
|
|
||||||
|
|
||||||
// User which trigged this Activity - in case of Content/ContentAddon the Creator will be automatically set.
|
|
||||||
$activity->originator = $user;
|
|
||||||
|
|
||||||
$activity->create();
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### Delete
|
|
||||||
|
|
||||||
TBD
|
|
@ -1,35 +0,0 @@
|
|||||||
Console
|
|
||||||
=======
|
|
||||||
|
|
||||||
To add a custom controller to the console application, you need to catch the [[humhub\components\console\Application::EVENT_ON_INIT]].
|
|
||||||
|
|
||||||
|
|
||||||
### Example: Event
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php
|
|
||||||
|
|
||||||
use humhub\components\console\Application;
|
|
||||||
|
|
||||||
return [
|
|
||||||
'id' => 'translation',
|
|
||||||
'class' => 'humhub\modules\translation\Module',
|
|
||||||
'namespace' => 'humhub\modules\translation',
|
|
||||||
'events' => array(
|
|
||||||
//...
|
|
||||||
array('class' => Application::className(), 'event' => Application::EVENT_ON_INIT, 'callback' => array('humhub\modules\translation\Module', 'onConsoleApplicationInit')),
|
|
||||||
//...
|
|
||||||
),
|
|
||||||
];
|
|
||||||
?>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Example: Callback
|
|
||||||
|
|
||||||
```php
|
|
||||||
public static function onConsoleApplicationInit($event) {
|
|
||||||
$application = $event->sender;
|
|
||||||
$application->controllerMap['translation'] = commands\TranslationController::className();
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
@ -1,66 +0,0 @@
|
|||||||
Database
|
|
||||||
========
|
|
||||||
|
|
||||||
### Conventions
|
|
||||||
|
|
||||||
- prefix your tables with the module id. e.g. example_foo
|
|
||||||
- singular table names
|
|
||||||
- use underscorce in fieldnames/attributes e.g. user_id
|
|
||||||
|
|
||||||
### ActiveRecord
|
|
||||||
|
|
||||||
TBD
|
|
||||||
|
|
||||||
[[humhub\components\ActiveRecord]]
|
|
||||||
|
|
||||||
|
|
||||||
### Migrations
|
|
||||||
|
|
||||||
See Yii 2.0 guide for more details about migrations [http://www.yiiframework.com/doc-2.0/guide-db-migrations.html](http://www.yiiframework.com/doc-2.0/guide-db-migrations.html).
|
|
||||||
|
|
||||||
HumHub provides an enhanced Migration class [[humhub\components\Migration]] which provides the ability to rename class files. This is required because HumHub also stores some class names in database for Polymorphic relations.
|
|
||||||
|
|
||||||
|
|
||||||
** Examples: **
|
|
||||||
|
|
||||||
|
|
||||||
- Create a module migration
|
|
||||||
> php yii migrate/create example --migrationPath='@app/modules/polls/migrations'
|
|
||||||
|
|
||||||
- Execute module migrations
|
|
||||||
> php yii migrate/up --migrationPath='@app/modules/polls/migrations'
|
|
||||||
|
|
||||||
- Execute all migrations (including enabled modules)
|
|
||||||
> php yii migrate/up --includeModuleMigrations=1
|
|
||||||
|
|
||||||
#### Uninstall
|
|
||||||
|
|
||||||
There is a special migration file called 'uninstall.php' - which is executed after the module is uninstalled.
|
|
||||||
Use this drop created tables & columns.
|
|
||||||
|
|
||||||
Example file: *migrations/uninstall.php*
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php
|
|
||||||
|
|
||||||
use yii\db\Migration;
|
|
||||||
|
|
||||||
class uninstall extends Migration
|
|
||||||
{
|
|
||||||
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
|
|
||||||
$this->dropTable('poll');
|
|
||||||
$this->dropTable('poll_answer');
|
|
||||||
$this->dropTable('poll_answer_user');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
echo "uninstall does not support migration down.\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
```
|
|
@ -1,66 +0,0 @@
|
|||||||
Modules - General
|
|
||||||
=================
|
|
||||||
|
|
||||||
Basically modules in HumHub are identical to Yii2 modules [http://www.yiiframework.com/doc-2.0/guide-structure-modules.html](http://www.yiiframework.com/doc-2.0/guide-structure-modules.html).
|
|
||||||
|
|
||||||
You can use either the Yii's module base class [[yii\base\Module]] or the enhanced HumHub module base class [[humhub\components\Module]].
|
|
||||||
|
|
||||||
The enhanced HumHub module class provides additional features like:
|
|
||||||
- Dynamic module management (enable / disable / install / uninstall) via administration interface
|
|
||||||
- Usable as Space or User Profile module
|
|
||||||
|
|
||||||
|
|
||||||
config.php
|
|
||||||
-------------
|
|
||||||
|
|
||||||
If the module is placed inside the */protected/modules* folder, you can create a *config.php* in the module directory which provides automatic loading without manually modifing the application config.
|
|
||||||
|
|
||||||
The config.php should return an array including following fields:
|
|
||||||
|
|
||||||
- **id** - Unqiue ID of the module (required)
|
|
||||||
- **class** - Namespaced classname of the module (required)
|
|
||||||
- **events** - Array of Events (optional)
|
|
||||||
- **namespace** - Namespace of your module
|
|
||||||
- **urlManagerRules** - Array of URL Manager Rules [http://www.yiiframework.com/doc-2.0/yii-web-urlmanager.html#addRules()-detail](http://www.yiiframework.com/doc-2.0/yii-web-urlmanager.html#addRules()-detail)
|
|
||||||
- **modules** - Submodules (optional)
|
|
||||||
|
|
||||||
Example of a config.php file:
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php
|
|
||||||
|
|
||||||
use johndoe\example\Module;
|
|
||||||
use humhub\widgets\TopMenu;
|
|
||||||
|
|
||||||
return [
|
|
||||||
'id' => 'example',
|
|
||||||
'class' => 'johndoe\example\Module',
|
|
||||||
'namespace' => 'johndoe\example',
|
|
||||||
'events' => [
|
|
||||||
array('class' => TopMenu::className(), 'event' => TopMenu::EVENT_INIT, 'callback' => array('johndoe\example\Module', 'onTopMenuInit')),
|
|
||||||
]
|
|
||||||
];
|
|
||||||
?>
|
|
||||||
```
|
|
||||||
|
|
||||||
**Note: ** Do not execute any code in the config.php - the result will be cached!
|
|
||||||
|
|
||||||
|
|
||||||
module.json
|
|
||||||
-----------
|
|
||||||
|
|
||||||
This file holds basic information about the module like name, description or current version. Locate this file in the root directory of the module.
|
|
||||||
|
|
||||||
Example of a ´´module.json file:
|
|
||||||
```
|
|
||||||
{
|
|
||||||
"id": "example",
|
|
||||||
"name": "My Example Module",
|
|
||||||
"description": "My testing module.",
|
|
||||||
"keywords": ["my", "cool", "module"],
|
|
||||||
"version": "1.0",
|
|
||||||
"humhub": {
|
|
||||||
"minVersion": "0.20"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
@ -1,44 +0,0 @@
|
|||||||
Menus
|
|
||||||
=====
|
|
||||||
|
|
||||||
All navigations widget classes inherits the base class [[humhub\widgets\BaseMenu]] which allows modules
|
|
||||||
to inject own items into navigation menu.
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
__config.php__ - Catching Event
|
|
||||||
|
|
||||||
```php
|
|
||||||
//...
|
|
||||||
use humhub\widgets\TopMenu;
|
|
||||||
//...
|
|
||||||
'events' => array(
|
|
||||||
array('class' => TopMenu::className(), 'event' => TopMenu::EVENT_INIT, 'callback' => array('humhub\modules\calendar\Events', 'onTopMenuInit')),
|
|
||||||
),
|
|
||||||
//...
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
__Events.php__ - Handling the Event
|
|
||||||
|
|
||||||
```php
|
|
||||||
//...
|
|
||||||
public static function onTopMenuInit($event)
|
|
||||||
{
|
|
||||||
if (Yii::$app->user->isGuest) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = Yii::$app->user->getIdentity();
|
|
||||||
if ($user->isModuleEnabled('calendar')) {
|
|
||||||
$event->sender->addItem(array(
|
|
||||||
'label' => Yii::t('CalendarModule.base', 'Calendar'),
|
|
||||||
'url' => Url::to(['/calendar/global/index']),
|
|
||||||
'icon' => '<i class="fa fa-calendar"></i>',
|
|
||||||
'isActive' => (Yii::$app->controller->module && Yii::$app->controller->module->id == 'calendar' && Yii::$app->controller->id == 'global'),
|
|
||||||
'sortOrder' => 300,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//...
|
|
||||||
```
|
|
@ -1,37 +0,0 @@
|
|||||||
Settings
|
|
||||||
========
|
|
||||||
|
|
||||||
|
|
||||||
Global Settings
|
|
||||||
---------------
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```php
|
|
||||||
HSetting::Set('someName', 'someValue' ,'exampleModuleId');
|
|
||||||
$mySetting = HSetting::Get('someName', 'exampleModuleId');
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
User Settings
|
|
||||||
-------------
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```php
|
|
||||||
$user->setSetting("someName", "someValue", "exampleModuleId");
|
|
||||||
$mySetting = $user->getSetting("someName", "exampleModuleId");
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Space Settings
|
|
||||||
--------------
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```php
|
|
||||||
$space->setSetting("someName", "someValue", "exampleModuleId");
|
|
||||||
$mySetting = $space->getSetting("someName", "exampleModuleId");
|
|
||||||
```
|
|
@ -1,44 +0,0 @@
|
|||||||
Space/User Modules
|
|
||||||
==================
|
|
||||||
|
|
||||||
TBD
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Enabled/Disable per Space/User
|
|
||||||
|
|
||||||
|
|
||||||
Tasks:
|
|
||||||
- Inherit your modules base class from [[\humhub\modules\content\components\ContentContainerModule]]
|
|
||||||
- Define valid container types (e.g. Space or/and User)
|
|
||||||
|
|
||||||
Example
|
|
||||||
|
|
||||||
```php
|
|
||||||
|
|
||||||
// ...
|
|
||||||
use humhub\modules\space\models\Space;
|
|
||||||
use humhub\modules\user\models\User;
|
|
||||||
// ...
|
|
||||||
|
|
||||||
class Module extends \humhub\modules\content\components\ContentContainerModule
|
|
||||||
{
|
|
||||||
|
|
||||||
// ...
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
public function getContentContainerTypes()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
Space::className(),
|
|
||||||
User::className(),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ...
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
@ -1,27 +0,0 @@
|
|||||||
Special Topics
|
|
||||||
==============
|
|
||||||
|
|
||||||
## Integrity Checker
|
|
||||||
|
|
||||||
The integrity checker is a command which validates and if necessary repairs the application database.
|
|
||||||
|
|
||||||
If you want to add own checking methods for your module to it, you can intercept the [[humhub\controllers\IntegrityController::EVENT_ON_RUN]] event.
|
|
||||||
|
|
||||||
Example callback implementation:
|
|
||||||
|
|
||||||
```php
|
|
||||||
public static function onIntegrityCheck($event)
|
|
||||||
{
|
|
||||||
$integrityController = $event->sender;
|
|
||||||
$integrityController->showTestHeadline("Polls Module - Answers (" . PollAnswer::find()->count() . " entries)");
|
|
||||||
|
|
||||||
foreach (PollAnswer::find()->joinWith('poll')->all() as $answer) {
|
|
||||||
if ($answer->poll === null) {
|
|
||||||
if ($integrityController->showFix("Deleting poll answer id " . $answer->id . " without existing poll!")) {
|
|
||||||
$answer->delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
|||||||
Widget Stack
|
|
||||||
============
|
|
||||||
|
|
||||||
- Base class: [[humhub\widgets\BaseStack]]
|
|
||||||
- Use Cases: Sidebars, ...
|
|
||||||
|
|
||||||
TBD
|
|
||||||
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Example of stack used as sidebar.
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php
|
|
||||||
echo \humhub\core\space\widgets\Sidebar::widget(['widgets' => [
|
|
||||||
[\humhub\core\activity\widgets\Stream::className(), ['streamAction' => '/space/space/stream', 'contentContainer' => $space], ['sortOrder' => 10]],
|
|
||||||
[\humhub\core\space\widgets\Members::className(), ['space' => $space], ['sortOrder' => 20]]
|
|
||||||
]]);
|
|
||||||
?>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Events
|
|
||||||
|
|
||||||
### Example
|
|
||||||
|
|
||||||
__config.php__
|
|
||||||
|
|
||||||
```php
|
|
||||||
//...
|
|
||||||
'events' => array(
|
|
||||||
// Wait for TopMenu Initalization Event
|
|
||||||
array('class' => 'DashboardSidebarWidget', 'event' => 'onInit', 'callback' => array('ExampleModule', 'onDashboardSidebarInit')),
|
|
||||||
),
|
|
||||||
//...
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
__Events.php__
|
|
||||||
|
|
||||||
```php
|
|
||||||
public static function onDashboardSidebarInit($event) {
|
|
||||||
$event->sender->addWidget('application.modules.example.widgets.MyCoolWidget', array(), array('sortOrder' => 1));
|
|
||||||
}
|
|
||||||
```
|
|
@ -1,161 +0,0 @@
|
|||||||
# Streams / Walls
|
|
||||||
|
|
||||||
TBD
|
|
||||||
|
|
||||||
- Define Streaming/Wall
|
|
||||||
|
|
||||||
You can also implement Creanown Stream/Wall output for your module content only.
|
|
||||||
|
|
||||||
Example Implementations:
|
|
||||||
|
|
||||||
- Tasks
|
|
||||||
- Polls
|
|
||||||
|
|
||||||
Of course your modules Content implementation needs to provides a WallEntry widget. See Content Section for more details.
|
|
||||||
|
|
||||||
|
|
||||||
## Create own Module Content Stream
|
|
||||||
|
|
||||||
### Implement StreamAction
|
|
||||||
|
|
||||||
Derived from [[humhub\modules\content\components\actions\ContentContainerStream]]
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace humhub\modules\polls\components;
|
|
||||||
|
|
||||||
use humhub\modules\content\components\actions\ContentContainerStream;
|
|
||||||
use humhub\modules\polls\models\Poll;
|
|
||||||
|
|
||||||
class StreamAction extends ContentContainerStream
|
|
||||||
{
|
|
||||||
|
|
||||||
public function setupFilters()
|
|
||||||
{
|
|
||||||
// Limit output to specific content type
|
|
||||||
$this->activeQuery->andWhere(['content.object_model' => Poll::className()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
Specify Action in Controller
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```php
|
|
||||||
class PollController extends ContentContainerController
|
|
||||||
{
|
|
||||||
|
|
||||||
public function actions()
|
|
||||||
{
|
|
||||||
return array(
|
|
||||||
'stream' => array(
|
|
||||||
'class' => \humhub\modules\polls\components\StreamAction::className(),
|
|
||||||
'mode' => \humhub\modules\polls\components\StreamAction::MODE_NORMAL,
|
|
||||||
'contentContainer' => $this->contentContainer
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Display Stream
|
|
||||||
|
|
||||||
You can use the Stream Widget to display the Stream in your View.
|
|
||||||
|
|
||||||
```php
|
|
||||||
|
|
||||||
echo \humhub\modules\content\widgets\Stream::widget(array(
|
|
||||||
'contentContainer' => $contentContainer,
|
|
||||||
'streamAction' => '//polls/poll/stream',
|
|
||||||
'messageStreamEmpty' => ($contentContainer->canWrite()) ?
|
|
||||||
Yii::t('PollsModule.widgets_views_stream', '<b>There are no polls yet!</b><br>Be the first and create one...') :
|
|
||||||
Yii::t('PollsModule.widgets_views_stream', '<b>There are no polls yet!</b>'),
|
|
||||||
'messageStreamEmptyCss' => ($contentContainer->canWrite()) ?
|
|
||||||
'placeholder-empty-stream' :
|
|
||||||
'',
|
|
||||||
));
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
## Create Content Form
|
|
||||||
|
|
||||||
### Create Form Widget
|
|
||||||
|
|
||||||
Create a Form Widget derived from [[humhub\modules\content\widgets\WallCreateContentForm]]
|
|
||||||
|
|
||||||
```php
|
|
||||||
|
|
||||||
namespace humhub\modules\polls\widgets;
|
|
||||||
|
|
||||||
class WallCreateForm extends \humhub\modules\content\widgets\WallCreateContentForm
|
|
||||||
{
|
|
||||||
|
|
||||||
public $submitUrl = '/polls/poll/create';
|
|
||||||
|
|
||||||
public function renderForm()
|
|
||||||
{
|
|
||||||
// Render your custom form here
|
|
||||||
return $this->render('form', array());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
Create a view file for widget which contains module specific fields. All standard fields (e.g. visibility) are added automatically.
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php echo Html::textArea("question", "", array('id' => 'contentForm_question', 'class' => 'form-control autosize contentForm', 'rows' => '1', "tabindex" => "1", "placeholder" => Yii::t('PollsModule.widgets_views_pollForm', "Ask something..."))); ?>
|
|
||||||
|
|
||||||
<div class="contentForm_options">
|
|
||||||
<?php echo Html::textArea("answersText", "", array('id' => "contentForm_answersText", 'rows' => '5', 'style' => 'height: auto !important;', "class" => "form-control contentForm", "tabindex" => "2", "placeholder" => Yii::t('PollsModule.widgets_views_pollForm', "Possible answers (one per line)"))); ?>
|
|
||||||
<div class="checkbox">
|
|
||||||
<label>
|
|
||||||
<?php echo Html::checkbox("allowMultiple", "", array('id' => "contentForm_allowMultiple", 'class' => 'checkbox contentForm', "tabindex" => "4")); ?> <?php echo Yii::t('PollsModule.widgets_views_pollForm', 'Allow multiple answers per user?'); ?>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Create Create Action
|
|
||||||
|
|
||||||
Create an action in your modules controller to receive form inputs.
|
|
||||||
|
|
||||||
All default tasks (e.g. access validation, ContentContainer assignment) are handled by [[humhub\modules\content\widgets\WallCreateContentForm::create]]
|
|
||||||
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```php
|
|
||||||
|
|
||||||
public function actionCreate()
|
|
||||||
{
|
|
||||||
$poll = new Poll();
|
|
||||||
$poll->question = Yii::$app->request->post('question');
|
|
||||||
$poll->answersText = Yii::$app->request->post('answersText');
|
|
||||||
$poll->allow_multiple = Yii::$app->request->post('allowMultiple', 0);
|
|
||||||
|
|
||||||
return \humhub\modules\polls\widgets\WallCreateForm::create($poll);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### Display Form
|
|
||||||
|
|
||||||
Place the Form widget above the Stream widget in your view.
|
|
||||||
|
|
||||||
e.g.
|
|
||||||
|
|
||||||
```php
|
|
||||||
|
|
||||||
<?php echo \humhub\modules\polls\widgets\WallCreateForm::widget(array('contentContainer' => $contentContainer)); ?>
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
64
protected/humhub/docs/guide/dev-module.md
Normal file
64
protected/humhub/docs/guide/dev-module.md
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
Modules - Getting Started
|
||||||
|
=================
|
||||||
|
|
||||||
|
Basically modules in HumHub are identical to Yii2 modules [http://www.yiiframework.com/doc-2.0/guide-structure-modules.html](http://www.yiiframework.com/doc-2.0/guide-structure-modules.html).
|
||||||
|
|
||||||
|
You can use either the Yii's module base class [[yii\base\Module]] or the enhanced HumHub module base class [[humhub\components\Module]].
|
||||||
|
|
||||||
|
The enhanced HumHub module class provides additional features like:
|
||||||
|
- Dynamic module management (enable / disable / install / uninstall) via administration interface
|
||||||
|
- Usable as Space or User Profile module
|
||||||
|
|
||||||
|
|
||||||
|
## config.php
|
||||||
|
|
||||||
|
|
||||||
|
If the module is placed inside the */protected/modules* folder, you can create a *config.php* in the module directory which provides automatic loading without manually modifing the application config.
|
||||||
|
|
||||||
|
The config.php should return an array including following fields:
|
||||||
|
|
||||||
|
- **id** - Unqiue ID of the module (required)
|
||||||
|
- **class** - Namespaced classname of the module (required)
|
||||||
|
- **events** - Array of Events (optional)
|
||||||
|
- **namespace** - Namespace of your module
|
||||||
|
- **urlManagerRules** - Array of URL Manager Rules [http://www.yiiframework.com/doc-2.0/yii-web-urlmanager.html#addRules()-detail](http://www.yiiframework.com/doc-2.0/yii-web-urlmanager.html#addRules()-detail)
|
||||||
|
- **modules** - Submodules (optional)
|
||||||
|
|
||||||
|
Example of a config.php file:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use johndoe\example\Module;
|
||||||
|
use humhub\widgets\TopMenu;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'id' => 'example',
|
||||||
|
'class' => 'johndoe\example\Module',
|
||||||
|
'namespace' => 'johndoe\example',
|
||||||
|
'events' => [
|
||||||
|
array('class' => TopMenu::className(), 'event' => TopMenu::EVENT_INIT, 'callback' => array('johndoe\example\Module', 'onTopMenuInit')),
|
||||||
|
]
|
||||||
|
];
|
||||||
|
?>
|
||||||
|
```
|
||||||
|
|
||||||
|
> Note: Do not execute any code in the __config.php__ - the result will be cached!
|
||||||
|
|
||||||
|
|
||||||
|
## module.json
|
||||||
|
|
||||||
|
This file holds basic information about the module like name, description or current version. Locate this file in the root directory of the module.
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"id": "example",
|
||||||
|
"name": "My Example Module",
|
||||||
|
"description": "My testing module.",
|
||||||
|
"keywords": ["my", "cool", "module"],
|
||||||
|
"version": "1.0",
|
||||||
|
"humhub": {
|
||||||
|
"minVersion": "0.20"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
@ -1,15 +1,32 @@
|
|||||||
Notifications
|
Notifications
|
||||||
=============
|
=============
|
||||||
|
|
||||||
Notifications are derived from [[humhub\modules\notification\components\BaseNotification]] and are used to inform one or a given set of users about a specific event.
|
Notifications are used to inform one or a given set of users about a specific event as the liking of a post or mentioning of a user, over multiple channels (e.g. web and mail).
|
||||||
|
|
||||||
|
Custom notification types are derived from [[humhub\modules\notification\components\BaseNotification]] and can be assigned with an optional `$originator` user instance, which links
|
||||||
|
the notification with the user who triggered the event. Furthermore the [[humhub\modules\notification\components\BaseNotification|BaseNotification]] can be assigned with a `$source` of type [[yii\db\ActiveRecord]],
|
||||||
|
which links the notification to a source instance like a Content or ContentAddon (e.g. a Post or Like).
|
||||||
|
|
||||||
|
The BaseNotification is responsible for:
|
||||||
|
|
||||||
|
- **instantiating** and **persisting** [[humhub\modules\notification\models\Notification]] model instances.
|
||||||
|
- **rendering** the notification output for the differen output channels.
|
||||||
|
|
||||||
![Notification Class Diagram](images/notificationClassDiag.jpg)
|
![Notification Class Diagram](images/notificationClassDiag.jpg)
|
||||||
|
|
||||||
### Create Notifications
|
Examples for core notifications are:
|
||||||
|
|
||||||
Notifications should reside in the `notifications` directory of a module. (e.g. `/modules/examples/notifications/`)
|
- [[humhub\modules\like\notifications\NewLike]]: is sent if an user likes a post or comment.
|
||||||
|
- [[humhub\modules\user\notifications\Followed]]: is sent if an user follows another user.
|
||||||
|
- [[humhub\modules\user\notifications\Mentioned]]: is sent if an user is mentioned within an post or comment.
|
||||||
|
- [[humhub\modules\content\notifications\ContentCreated]]: is sent when content (e.g. a post) was created.
|
||||||
|
|
||||||
Example notification:
|
## Custom Notifications
|
||||||
|
|
||||||
|
#### Notification Class
|
||||||
|
|
||||||
|
Custom Notifications are derived from [[humhub\modules\notification\components\BaseNotification|BaseNotification]] and should reside in the a subfolder `notifications` of your module directory.
|
||||||
|
The notification class at least has to overwrite the `$moduleId` variable with the id of your module and the `$viewName` with the name of the view which is used to render the notification.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
<?php
|
<?php
|
||||||
@ -23,37 +40,45 @@ use humhub\modules\notification\components\BaseNotification;
|
|||||||
*/
|
*/
|
||||||
class SomethingHappend extends BaseNotification
|
class SomethingHappend extends BaseNotification
|
||||||
{
|
{
|
||||||
// Module Id (required)
|
// Module Id (required)
|
||||||
public $moduleId = "example";
|
public $moduleId = "example";
|
||||||
|
|
||||||
|
// Viewname (required)
|
||||||
public $viewName = "somethingHappend";
|
public $viewName = "somethingHappend";
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
```
|
```
|
||||||
|
|
||||||
By default, the view of a notification should be located inside a subfolder `notifications/views`. (e.g. `/modules/examples/notifications/views/`)
|
#### Notification View
|
||||||
|
|
||||||
Example view file _somethingHappend.php_:
|
By default, the view of a notification should be located inside the subfolder `notifications/views`.
|
||||||
|
The view of our example is therefore located in `/modules/examples/notifications/views/somethingHappened.php`.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use yii\helpers\Html;
|
use yii\helpers\Html;
|
||||||
|
|
||||||
echo Yii::t('LikeModule.views_notifications_newLike', "%someUser% did something cool.", array(
|
echo Yii::t('SomethingHappend.views_notifications_somethingHappened', "%someUser% did something cool.", [
|
||||||
'%someUser%' => '<strong>' . Html::encode($originator->displayName) . '</strong>'
|
'%someUser%' => '<strong>' . Html::encode($originator->displayName) . '</strong>'
|
||||||
));
|
]);
|
||||||
?>
|
?>
|
||||||
```
|
```
|
||||||
|
|
||||||
> Info: If you require a different notification view for mails. You have to add a view file to a subfolder `notifications/views/mail`.
|
> Info: If you require a different notification view for mails, you have to add an extra view file to a subfolder `notifications/views/mail`.
|
||||||
|
|
||||||
### Send Notifications
|
## Send Notifications
|
||||||
|
|
||||||
|
After an event was triggered you'll have to instantiate your custom [[humhub\modules\notification\components\BaseNotification|BaseNotification]] and call its
|
||||||
|
`send` or `sendBulk` which will instantiate and persist a [[humhub\modules\notification\models\Notification]] instance for every user you want to notify.
|
||||||
|
|
||||||
|
A notification can optionally be assigned with a `$source` model instance (e.g. a post or comment related to the notification) which has to be derived from [[yii\db\ActiveRecord]].
|
||||||
|
If the notification was created in the context of a space (e.g. `$source` is a Content, ContentAddon or ContentContainer) the `$space` variable is set with the related space instance automatically.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
$notification = new \johndoe\example\notifications\SomethingHappend();
|
$notification = new \johndoe\example\notifications\SomethingHappend();
|
||||||
|
|
||||||
// Link to the object which fired the notification (optional)
|
// Link to the object which fired the notification e.g. a SomethingHappened content-addon (optional)
|
||||||
$notification->source = $this;
|
$notification->source = $this;
|
||||||
|
|
||||||
// The user which triggered the notification (optional)
|
// The user which triggered the notification (optional)
|
||||||
@ -65,9 +90,14 @@ $notification->sendBulk(User::find()->where([...]));
|
|||||||
// or: a single user
|
// or: a single user
|
||||||
$notification->send($user);
|
$notification->send($user);
|
||||||
```
|
```
|
||||||
> Info: The `send` and `sendBulk` will create and persist an own [[humhub\modules\notification\models\Notification]] for each user.
|
|
||||||
|
> Info: The `send` and `sendBulk` will create and persist a [[humhub\modules\notification\models\Notification]] instance for each user.
|
||||||
|
|
||||||
### Delete Notifications
|
> Tip: Notifications are often created and sent within the `afterSave` hook of the related `source` instance. This should be prefered over the instantiation within a controller.
|
||||||
|
|
||||||
|
> Note: Notifications are only sent by mail depending on the users account settings.
|
||||||
|
|
||||||
|
## Delete Notifications
|
||||||
|
|
||||||
By default notifications will automatically be deleted after a given period of time or if the originator(user) object is removed.
|
By default notifications will automatically be deleted after a given period of time or if the originator(user) object is removed.
|
||||||
|
|
||||||
@ -77,4 +107,4 @@ Example for manual notification deletion:
|
|||||||
$notification = new johndoe\example\notifications\SomethingHappend();
|
$notification = new johndoe\example\notifications\SomethingHappend();
|
||||||
$notification->source = $this;
|
$notification->source = $this;
|
||||||
$notification->delete(User::findOne(['id' => $userId]));
|
$notification->delete(User::findOne(['id' => $userId]));
|
||||||
```
|
```
|
@ -1,40 +0,0 @@
|
|||||||
Application Overview
|
|
||||||
=======
|
|
||||||
|
|
||||||
Humhub is based on **PHP5** and **Yii2** and leverages the highly modular and flexible nature of *Yii*.
|
|
||||||
Before learning about the internals of HumHub, you should be familiar with the basic concepts of the
|
|
||||||
[Yii Framework](http://www.yiiframework.com/doc-2.0/guide-README.html "Yii Framework").
|
|
||||||
The HumHub core contains of several core modules as well as extended Yii components:
|
|
||||||
|
|
||||||
**Core Components:**
|
|
||||||
|
|
||||||
- [[humhub\components\ActiveRecord]]:
|
|
||||||
- [[humhub\components\Application]]
|
|
||||||
- [[humhub\components\Controller]]
|
|
||||||
- [[humhub\components\Migration]]
|
|
||||||
- [[humhub\components\Module]]
|
|
||||||
- [[humhub\components\ModuleManager]]
|
|
||||||
- [[humhub\components\Request]]
|
|
||||||
- [[humhub\components\Theme]]
|
|
||||||
- [[humhub\components\View]]
|
|
||||||
- [[humhub\components\Widget]]
|
|
||||||
|
|
||||||
**Core Modules:**
|
|
||||||
|
|
||||||
- **activity:** User/Space activities
|
|
||||||
- **admin:** Responsible for admin/configuration related issues
|
|
||||||
- **comment:** Content addon for commenting
|
|
||||||
- **content:** Base module for all content types (Post,Wiki,...)
|
|
||||||
- **dashboard:** Dashboard related functionality
|
|
||||||
- **directory:** Directory related functionality
|
|
||||||
- **file:** Basic file module for accessing the filesystem
|
|
||||||
- **installer:** HumHub installer module
|
|
||||||
- **like:** Content addon for likes
|
|
||||||
- **notification:** User Notifications
|
|
||||||
- **post:** Simple user-post related functionality
|
|
||||||
- **search:** Luceene Search Module
|
|
||||||
- **space:** Space related functionality
|
|
||||||
- **tour:** HumHub user-guide
|
|
||||||
- **user:** Basic user module
|
|
||||||
|
|
||||||
![Application Layers](images/appLayer.svg)
|
|
3
protected/humhub/docs/guide/dev-permissions.md
Normal file
3
protected/humhub/docs/guide/dev-permissions.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Permissions
|
||||||
|
========
|
||||||
|
(TBD)
|
75
protected/humhub/docs/guide/dev-settings.md
Normal file
75
protected/humhub/docs/guide/dev-settings.md
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
Settings Manager
|
||||||
|
================
|
||||||
|
|
||||||
|
The SettingsManager allows you to easily store key/value based configuration settings
|
||||||
|
based on module components and also optionally bound to a contentcontainer (e.g. users or spaces).
|
||||||
|
|
||||||
|
If you need to categorize key names, use this syntax: category.subcategory.camelCaseKeyName
|
||||||
|
|
||||||
|
The SettingsManager component is automatically added all to humhub\components\Module classes.
|
||||||
|
|
||||||
|
Module settings
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Get desired module / application instance:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$module = Yii::$app;
|
||||||
|
// or
|
||||||
|
$module = Yii::$app->getModule('polls');
|
||||||
|
// or
|
||||||
|
$module = $controller->module;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Create or update existing setting in settings manager:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$module->settings->set('key', $value);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Get value of setting manager:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$value = $module->settings->get('key');
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Delete setting:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$module->settings->delete('key');
|
||||||
|
// or
|
||||||
|
$module->settings->set('key', null);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
ContentContainer related settings
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
If you want to store settings related to an user or space - use the ContentContainerSettingsManager:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$module->settings->contentContainer($user)->get('key');
|
||||||
|
$module->settings->contentContainer($user)->set('key', $value);
|
||||||
|
$module->settings->contentContainer($user)->delete('key');
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Shortcuts for currently logged in user settings:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$module->settings->user()->get('key');
|
||||||
|
$module->settings->user()->set('key', $value);
|
||||||
|
$module->settings->user()->delete('key');
|
||||||
|
```
|
||||||
|
|
||||||
|
Shortcuts for current space settings:
|
||||||
|
Note: This is only available if current controller is instance of ContentContainerController.
|
||||||
|
|
||||||
|
```php
|
||||||
|
$module->settings->space()->get('key');
|
||||||
|
$module->settings->space()->set('key', $value);
|
||||||
|
$module->settings->space()->delete('key');
|
||||||
|
```
|
161
protected/humhub/docs/guide/dev-stream.md
Normal file
161
protected/humhub/docs/guide/dev-stream.md
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
# Streams / Walls
|
||||||
|
|
||||||
|
TBD
|
||||||
|
|
||||||
|
- Define Streaming/Wall
|
||||||
|
|
||||||
|
You can also implement Creanown Stream/Wall output for your module content only.
|
||||||
|
|
||||||
|
Example Implementations:
|
||||||
|
|
||||||
|
- Tasks
|
||||||
|
- Polls
|
||||||
|
|
||||||
|
Of course your modules Content implementation needs to provides a WallEntry widget. See Content Section for more details.
|
||||||
|
|
||||||
|
|
||||||
|
## Create own Module Content Stream
|
||||||
|
|
||||||
|
### Implement StreamAction
|
||||||
|
|
||||||
|
Derived from [[humhub\modules\content\components\actions\ContentContainerStream]]
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace humhub\modules\polls\components;
|
||||||
|
|
||||||
|
use humhub\modules\content\components\actions\ContentContainerStream;
|
||||||
|
use humhub\modules\polls\models\Poll;
|
||||||
|
|
||||||
|
class StreamAction extends ContentContainerStream
|
||||||
|
{
|
||||||
|
|
||||||
|
public function setupFilters()
|
||||||
|
{
|
||||||
|
// Limit output to specific content type
|
||||||
|
$this->activeQuery->andWhere(['content.object_model' => Poll::className()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Specify Action in Controller
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```php
|
||||||
|
class PollController extends ContentContainerController
|
||||||
|
{
|
||||||
|
|
||||||
|
public function actions()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'stream' => array(
|
||||||
|
'class' => \humhub\modules\polls\components\StreamAction::className(),
|
||||||
|
'mode' => \humhub\modules\polls\components\StreamAction::MODE_NORMAL,
|
||||||
|
'contentContainer' => $this->contentContainer
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Display Stream
|
||||||
|
|
||||||
|
You can use the Stream Widget to display the Stream in your View.
|
||||||
|
|
||||||
|
```php
|
||||||
|
|
||||||
|
echo \humhub\modules\content\widgets\Stream::widget(array(
|
||||||
|
'contentContainer' => $contentContainer,
|
||||||
|
'streamAction' => '//polls/poll/stream',
|
||||||
|
'messageStreamEmpty' => ($contentContainer->canWrite()) ?
|
||||||
|
Yii::t('PollsModule.widgets_views_stream', '<b>There are no polls yet!</b><br>Be the first and create one...') :
|
||||||
|
Yii::t('PollsModule.widgets_views_stream', '<b>There are no polls yet!</b>'),
|
||||||
|
'messageStreamEmptyCss' => ($contentContainer->canWrite()) ?
|
||||||
|
'placeholder-empty-stream' :
|
||||||
|
'',
|
||||||
|
));
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Create Content Form
|
||||||
|
|
||||||
|
### Create Form Widget
|
||||||
|
|
||||||
|
Create a Form Widget derived from [[humhub\modules\content\widgets\WallCreateContentForm]]
|
||||||
|
|
||||||
|
```php
|
||||||
|
|
||||||
|
namespace humhub\modules\polls\widgets;
|
||||||
|
|
||||||
|
class WallCreateForm extends \humhub\modules\content\widgets\WallCreateContentForm
|
||||||
|
{
|
||||||
|
|
||||||
|
public $submitUrl = '/polls/poll/create';
|
||||||
|
|
||||||
|
public function renderForm()
|
||||||
|
{
|
||||||
|
// Render your custom form here
|
||||||
|
return $this->render('form', array());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Create a view file for widget which contains module specific fields. All standard fields (e.g. visibility) are added automatically.
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php echo Html::textArea("question", "", array('id' => 'contentForm_question', 'class' => 'form-control autosize contentForm', 'rows' => '1', "tabindex" => "1", "placeholder" => Yii::t('PollsModule.widgets_views_pollForm', "Ask something..."))); ?>
|
||||||
|
|
||||||
|
<div class="contentForm_options">
|
||||||
|
<?php echo Html::textArea("answersText", "", array('id' => "contentForm_answersText", 'rows' => '5', 'style' => 'height: auto !important;', "class" => "form-control contentForm", "tabindex" => "2", "placeholder" => Yii::t('PollsModule.widgets_views_pollForm', "Possible answers (one per line)"))); ?>
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<?php echo Html::checkbox("allowMultiple", "", array('id' => "contentForm_allowMultiple", 'class' => 'checkbox contentForm', "tabindex" => "4")); ?> <?php echo Yii::t('PollsModule.widgets_views_pollForm', 'Allow multiple answers per user?'); ?>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Create Action
|
||||||
|
|
||||||
|
Create an action in your modules controller to receive form inputs.
|
||||||
|
|
||||||
|
All default tasks (e.g. access validation, ContentContainer assignment) are handled by [[humhub\modules\content\widgets\WallCreateContentForm::create]]
|
||||||
|
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```php
|
||||||
|
|
||||||
|
public function actionCreate()
|
||||||
|
{
|
||||||
|
$poll = new Poll();
|
||||||
|
$poll->question = Yii::$app->request->post('question');
|
||||||
|
$poll->answersText = Yii::$app->request->post('answersText');
|
||||||
|
$poll->allow_multiple = Yii::$app->request->post('allowMultiple', 0);
|
||||||
|
|
||||||
|
return \humhub\modules\polls\widgets\WallCreateForm::create($poll);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Display Form
|
||||||
|
|
||||||
|
Place the Form widget above the Stream widget in your view.
|
||||||
|
|
||||||
|
e.g.
|
||||||
|
|
||||||
|
```php
|
||||||
|
|
||||||
|
<?php echo \humhub\modules\polls\widgets\WallCreateForm::widget(array('contentContainer' => $contentContainer)); ?>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
21
protected/humhub/docs/guide/dev-testing.md
Normal file
21
protected/humhub/docs/guide/dev-testing.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
Testing
|
||||||
|
====================
|
||||||
|
|
||||||
|
1. Install codeception
|
||||||
|
composer global require "codeception/codeception=2.0.*" "codeception/specify=*" "codeception/verify=*"
|
||||||
|
|
||||||
|
2. Create test Database:
|
||||||
|
CREATE DATABASE `humhub_test` CHARACTER SET utf8 COLLATE utf8_general_ci;
|
||||||
|
|
||||||
|
3. Migrate Up:
|
||||||
|
cd protected/humhub/tests/codeception/bin
|
||||||
|
php yii migrate/up --includeModuleMigrations=1 --interactive=0
|
||||||
|
php yii installer/auto
|
||||||
|
|
||||||
|
4. Build Tests:
|
||||||
|
cd protected/humhub/tests
|
||||||
|
codecept build
|
||||||
|
|
||||||
|
5. Run Tests:
|
||||||
|
cd protected/humhub/tests/
|
||||||
|
codecept run
|
88
protected/humhub/docs/guide/dev-widgets.md
Normal file
88
protected/humhub/docs/guide/dev-widgets.md
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
Widgets
|
||||||
|
============
|
||||||
|
|
||||||
|
Widgets are used to provide reusable view parts by means of a view class. Please refer to the [Yii-Guide](http://www.yiiframework.com/doc-2.0/guide-structure-widgets.html)
|
||||||
|
for more information about widgets.
|
||||||
|
|
||||||
|
## Widget Stacks
|
||||||
|
|
||||||
|
HumHub uses Widget-Stacks to assamble multiple entries of a base widget as a naviagation or list.
|
||||||
|
Stacked widget are derived from [[humhub\widgets\BaseStack]] and will fire an `onInit` and `onRun` event by default,
|
||||||
|
which can be subscribed by other modules to inject widget items. This mechanism can be used for example for sidebars.
|
||||||
|
|
||||||
|
Example of stack used as sidebar:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
// Render the sidebar with two default item
|
||||||
|
echo \humhub\core\space\widgets\Sidebar::widget(['widgets' => [
|
||||||
|
[\humhub\core\activity\widgets\Stream::className(), ['streamAction' => '/space/space/stream', 'contentContainer' => $space], ['sortOrder' => 10]],
|
||||||
|
[\humhub\core\space\widgets\Members::className(), ['space' => $space], ['sortOrder' => 20]]
|
||||||
|
]]);
|
||||||
|
?>
|
||||||
|
```
|
||||||
|
|
||||||
|
__config.php__
|
||||||
|
|
||||||
|
```php
|
||||||
|
// Subscribe to the onInit event of the sidebar
|
||||||
|
'events' => array(
|
||||||
|
// Wait for TopMenu Initalization Event
|
||||||
|
array('class' => 'DashboardSidebarWidget', 'event' => 'onInit', 'callback' => array('ExampleModule', 'onDashboardSidebarInit')),
|
||||||
|
),
|
||||||
|
//...
|
||||||
|
```
|
||||||
|
|
||||||
|
__Events.php__
|
||||||
|
|
||||||
|
```php
|
||||||
|
// This handler function will inject a custom widget to the stack
|
||||||
|
public static function onDashboardSidebarInit($event) {
|
||||||
|
$event->sender->addWidget('application.modules.example.widgets.MyCoolWidget', array(), array('sortOrder' => 1));
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Menus
|
||||||
|
|
||||||
|
All navigations widget classes inherit from the class [[humhub\widgets\BaseMenu]], which allows modules
|
||||||
|
to inject own items into navigation menu.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
__config.php__ - Catching Event
|
||||||
|
|
||||||
|
```php
|
||||||
|
use humhub\widgets\TopMenu;
|
||||||
|
|
||||||
|
return [
|
||||||
|
//...
|
||||||
|
'events' => [
|
||||||
|
['class' => TopMenu::className(), 'event' => TopMenu::EVENT_INIT, 'callback' => ['humhub\modules\calendar\Events', 'onTopMenuInit']],
|
||||||
|
],
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
__Events.php__ - Handling the Event
|
||||||
|
|
||||||
|
```php
|
||||||
|
//...
|
||||||
|
public static function onTopMenuInit($event)
|
||||||
|
{
|
||||||
|
if (Yii::$app->user->isGuest) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = Yii::$app->user->getIdentity();
|
||||||
|
if ($user->isModuleEnabled('calendar')) {
|
||||||
|
$event->sender->addItem([
|
||||||
|
'label' => Yii::t('CalendarModule.base', 'Calendar'),
|
||||||
|
'url' => Url::to(['/calendar/global/index']),
|
||||||
|
'icon' => '<i class="fa fa-calendar"></i>',
|
||||||
|
'isActive' => (Yii::$app->controller->module && Yii::$app->controller->module->id == 'calendar' && Yii::$app->controller->id == 'global'),
|
||||||
|
'sortOrder' => 300,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//...
|
||||||
|
```
|
@ -1,110 +0,0 @@
|
|||||||
Space
|
|
||||||
=====
|
|
||||||
|
|
||||||
When your module should also appear in space module section you need to add the
|
|
||||||
SpaceModuleBehavior to your Module Class.
|
|
||||||
|
|
||||||
```php
|
|
||||||
|
|
||||||
class SomeModule extends HWebModule
|
|
||||||
{
|
|
||||||
|
|
||||||
public function behaviors()
|
|
||||||
{
|
|
||||||
|
|
||||||
return array(
|
|
||||||
'SpaceModuleBehavior' => array(
|
|
||||||
'class' => 'application.modules_core.space.behaviors.SpaceModuleBehavior',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//...
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
See SpaceModuleBehavior Class for further details.
|
|
||||||
|
|
||||||
## Example: Add item to space navigation
|
|
||||||
|
|
||||||
Catch Space Navigation Init Event in your modules autostart.php.
|
|
||||||
|
|
||||||
```autostart.php
|
|
||||||
|
|
||||||
Yii::app()->moduleManager->register(array(
|
|
||||||
//...
|
|
||||||
|
|
||||||
'events' => array(
|
|
||||||
array('class' => 'SpaceMenuWidget', 'event' => 'onInit', 'callback' => array('ExampleModule', 'onSpaceMenuInit')),
|
|
||||||
)
|
|
||||||
|
|
||||||
));
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
Define callback in your module to add item.
|
|
||||||
|
|
||||||
```php
|
|
||||||
/**
|
|
||||||
* On build of a Space Navigation, check if this module is enabled.
|
|
||||||
* When enabled add a menu item
|
|
||||||
*
|
|
||||||
* @param type $event
|
|
||||||
*/
|
|
||||||
public static function onSpaceMenuInit($event) {
|
|
||||||
|
|
||||||
$space = Yii::app()->getController()->getSpace();
|
|
||||||
|
|
||||||
// Is Module enabled on this workspace?
|
|
||||||
if ($space->isModuleEnabled('example')) {
|
|
||||||
|
|
||||||
$event->sender->addItem(array(
|
|
||||||
'label' => 'Some space navigation entry',
|
|
||||||
'url' => '#',
|
|
||||||
'icon' => 'icon',
|
|
||||||
'isActive' => (Yii::app()->controller->module && Yii::app()->controller->module->id == 'example'),
|
|
||||||
));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Access space by by module controller
|
|
||||||
|
|
||||||
By adding the SpaceControllerBehavior you are able to access current space in your controllers.
|
|
||||||
Make sure you always pass the current space guid (sguid) in your urls.
|
|
||||||
|
|
||||||
When using the method createContainerUrl (provided by SpaceControllerBehavior or UserControllerBehavior) the
|
|
||||||
current space or user guid is automatically added to urls.
|
|
||||||
|
|
||||||
```php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add mix-ins to this model
|
|
||||||
*
|
|
||||||
* @return type
|
|
||||||
*/
|
|
||||||
public function behaviors()
|
|
||||||
{
|
|
||||||
return array(
|
|
||||||
'SpaceControllerBehavior' => array(
|
|
||||||
'class' => 'application.modules_core.space.behaviors.SpaceControllerBehavior',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function actionTest() {
|
|
||||||
$currentSpace = $this->getSpace();
|
|
||||||
|
|
||||||
$this->redirect($this->createContainerUrl('test2'));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function actionTest2() {
|
|
||||||
$currentSpace = $this->getSpace();
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
@ -1,4 +0,0 @@
|
|||||||
User
|
|
||||||
====
|
|
||||||
|
|
||||||
TBD
|
|
Binary file not shown.
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 46 KiB |
91
protected/humhub/docs/guide/images/notificationClassDiag.svg
Normal file
91
protected/humhub/docs/guide/images/notificationClassDiag.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 53 KiB |
@ -2,12 +2,26 @@
|
|||||||
|
|
||||||
Here you will learn how you can adapt existing themes to working fine with actually versions.
|
Here you will learn how you can adapt existing themes to working fine with actually versions.
|
||||||
|
|
||||||
## Migrate to 1.0.0-beta.4
|
## Migrate to 1.1
|
||||||
|
|
||||||
|
- Make sure to update your themed less file with the latest version.
|
||||||
|
In the upcoming 1.2.x releases we'll split the 'theme' less file into multiple files, to simplify this process.
|
||||||
|
|
||||||
|
- There were also many view file updates this release, please check changes (e.g. diff) of your themed versions.
|
||||||
|
We are constantly reducing view complexity to ease this process.
|
||||||
|
|
||||||
|
**Important changed views:**
|
||||||
|
|
||||||
|
- Logins (Standalone / Modal)
|
||||||
|
- Registration
|
||||||
|
- Main Layout
|
||||||
|
|
||||||
|
## Migrate from 0.20 to 1.0
|
||||||
|
|
||||||
The following line was added to the HumHub Base Theme Less/Css file due to a Bootstrap update:
|
The following line was added to the HumHub Base Theme Less/Css file due to a Bootstrap update:
|
||||||
https://github.com/humhub/humhub/blob/0a388d225a53fd873773cf0989d6e10aaf66996a/themes/HumHub/css/theme.less#L648
|
https://github.com/humhub/humhub/blob/0a388d225a53fd873773cf0989d6e10aaf66996a/themes/HumHub/css/theme.less#L648
|
||||||
|
|
||||||
## Migrate from 0.11.x to 0.20
|
## Migrate from 0.11 to 0.20
|
||||||
|
|
||||||
As you know, HumHub based on the Yii Framework. In the new 0.20 release, the Framework was changed from Yii 1.1 to Yii 2. With this change the style.css in **webroot/css/** was removed and from now all styles are merged in the theme.css under **webroot/themes/humhub/css/**.
|
As you know, HumHub based on the Yii Framework. In the new 0.20 release, the Framework was changed from Yii 1.1 to Yii 2. With this change the style.css in **webroot/css/** was removed and from now all styles are merged in the theme.css under **webroot/themes/humhub/css/**.
|
||||||
|
|
||||||
@ -32,10 +46,7 @@ Follow this steps to migrate an older theme ot 0.20:
|
|||||||
|
|
||||||
6. Check if everything works well, and fix optical issues at your theme file, if necessery.
|
6. Check if everything works well, and fix optical issues at your theme file, if necessery.
|
||||||
|
|
||||||
|
## Migrate from 0.9 to 10.0
|
||||||
---
|
|
||||||
|
|
||||||
## Migrate from 0.9 and earlier to 10.0
|
|
||||||
|
|
||||||
In 0.10 release, all refer links from **head.php** (to js, css and icon files) moved back to the ``<head>`` section in **main.php**, to keep them independet from themes.
|
In 0.10 release, all refer links from **head.php** (to js, css and icon files) moved back to the ``<head>`` section in **main.php**, to keep them independet from themes.
|
||||||
|
|
||||||
|
169
protected/humhub/libs/BaseSettingsManager.php
Normal file
169
protected/humhub/libs/BaseSettingsManager.php
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2016 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\libs;
|
||||||
|
|
||||||
|
use Yii;
|
||||||
|
use yii\base\Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of SettingManager
|
||||||
|
*
|
||||||
|
* @since 1.1
|
||||||
|
* @author Luke
|
||||||
|
*/
|
||||||
|
abstract class BaseSettingsManager extends Component
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string module id this settings manager belongs to.
|
||||||
|
*/
|
||||||
|
public $moduleId = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array|null of loaded settings
|
||||||
|
*/
|
||||||
|
protected $_loaded = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string settings model class name
|
||||||
|
*/
|
||||||
|
public $modelClass = 'humhub\models\Setting';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function init()
|
||||||
|
{
|
||||||
|
if ($this->moduleId === null) {
|
||||||
|
throw new \Exception('Could not determine module id');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->loadValues();
|
||||||
|
|
||||||
|
parent::init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a settings value
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @param string $value
|
||||||
|
*/
|
||||||
|
public function set($name, $value)
|
||||||
|
{
|
||||||
|
if ($value === null) {
|
||||||
|
return $this->delete($name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update database setting record
|
||||||
|
$record = $this->find()->andWhere(['name' => $name])->one();
|
||||||
|
if ($record === null) {
|
||||||
|
$record = $this->createRecord();
|
||||||
|
$record->name = $name;
|
||||||
|
}
|
||||||
|
$record->value = (string) $value;
|
||||||
|
if (!$record->save()) {
|
||||||
|
throw new \yii\base\Exception("Could not store setting! (" . print_r($record->getErrors(), 1) . ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store to runtime
|
||||||
|
$this->_loaded[$name] = $value;
|
||||||
|
|
||||||
|
$this->invalidateCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns value of setting
|
||||||
|
*
|
||||||
|
* @param string $name the name of setting
|
||||||
|
* @return string the setting value or null when not exists
|
||||||
|
*/
|
||||||
|
public function get($name)
|
||||||
|
{
|
||||||
|
return isset($this->_loaded[$name]) ? $this->_loaded[$name] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes setting
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
*/
|
||||||
|
public function delete($name)
|
||||||
|
{
|
||||||
|
$record = $this->find()->andWhere(['name' => $name])->one();
|
||||||
|
if ($record !== null) {
|
||||||
|
$record->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($this->_loaded[$name])) {
|
||||||
|
unset($this->_loaded[$name]);
|
||||||
|
}
|
||||||
|
$this->invalidateCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads values from database
|
||||||
|
*/
|
||||||
|
protected function loadValues()
|
||||||
|
{
|
||||||
|
$cached = Yii::$app->cache->get($this->getCacheKey());
|
||||||
|
if ($cached === false) {
|
||||||
|
$this->_loaded = [];
|
||||||
|
$settings = &$this->_loaded;
|
||||||
|
|
||||||
|
array_map(function ($record) use(&$settings ) {
|
||||||
|
$settings[$record->name] = $record->value;
|
||||||
|
}, $this->find()->all());
|
||||||
|
|
||||||
|
Yii::$app->cache->set($this->getCacheKey(), $this->_loaded);
|
||||||
|
} else {
|
||||||
|
$this->_loaded = $cached;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidates settings cache
|
||||||
|
*/
|
||||||
|
protected function invalidateCache()
|
||||||
|
{
|
||||||
|
Yii::$app->cache->delete($this->getCacheKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns settings managers cache key
|
||||||
|
*
|
||||||
|
* @return string the cache key
|
||||||
|
*/
|
||||||
|
protected function getCacheKey()
|
||||||
|
{
|
||||||
|
return 'settings-' . $this->moduleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns settings active record instance
|
||||||
|
*/
|
||||||
|
protected function createRecord()
|
||||||
|
{
|
||||||
|
$model = new $this->modelClass;
|
||||||
|
$model->module_id = $this->moduleId;
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns ActiveQuery to find settings
|
||||||
|
*
|
||||||
|
* @return \yii\db\ActiveQuery
|
||||||
|
*/
|
||||||
|
protected function find()
|
||||||
|
{
|
||||||
|
$modelClass = $this->modelClass;
|
||||||
|
return $modelClass::find()->andWhere(['module_id' => $this->moduleId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -21,7 +21,7 @@ class CURLHelper
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns CURL Default Options
|
* Returns CURL Default Options
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public static function getOptions()
|
public static function getOptions()
|
||||||
@ -34,17 +34,17 @@ class CURLHelper
|
|||||||
CURLOPT_CAINFO => Yii::getAlias('@humhub/config/cacert.pem')
|
CURLOPT_CAINFO => Yii::getAlias('@humhub/config/cacert.pem')
|
||||||
);
|
);
|
||||||
|
|
||||||
if (Setting::Get('enabled', 'proxy')) {
|
if (Yii::$app->settings->get('proxy.enabled')) {
|
||||||
$options[CURLOPT_PROXY] = Setting::Get('server', 'proxy');
|
$options[CURLOPT_PROXY] = Yii::$app->settings->get('proxy.server');
|
||||||
$options[CURLOPT_PROXYPORT] = Setting::Get('port', 'proxy');
|
$options[CURLOPT_PROXYPORT] = Yii::$app->settings->get('proxy.port');
|
||||||
if (defined('CURLOPT_PROXYUSERNAME')) {
|
if (defined('CURLOPT_PROXYUSERNAME')) {
|
||||||
$options[CURLOPT_PROXYUSERNAME] = Setting::Get('user', 'proxy');
|
$options[CURLOPT_PROXYUSERNAME] = Yii::$app->settings->get('proxy.user');
|
||||||
}
|
}
|
||||||
if (defined('CURLOPT_PROXYPASSWORD')) {
|
if (defined('CURLOPT_PROXYPASSWORD')) {
|
||||||
$options[CURLOPT_PROXYPASSWORD] = Setting::Get('password', 'proxy');
|
$options[CURLOPT_PROXYPASSWORD] = Yii::$app->settings->get('proxy.password');
|
||||||
}
|
}
|
||||||
if (defined('CURLOPT_NOPROXY')) {
|
if (defined('CURLOPT_NOPROXY')) {
|
||||||
$options[CURLOPT_NOPROXY] = Setting::Get('noproxy', 'proxy');
|
$options[CURLOPT_NOPROXY] = Yii::$app->settings->get('proxy.noproxy');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ namespace humhub\libs;
|
|||||||
|
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\helpers\ArrayHelper;
|
use yii\helpers\ArrayHelper;
|
||||||
use humhub\components\Theme;
|
use humhub\libs\ThemeHelper;
|
||||||
use humhub\models\Setting;
|
use humhub\models\Setting;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -23,7 +23,7 @@ class DynamicConfig extends \yii\base\Object
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an array to the dynamic configuration
|
* Add an array to the dynamic configuration
|
||||||
*
|
*
|
||||||
* @param array $new
|
* @param array $new
|
||||||
*/
|
*/
|
||||||
public static function merge($new)
|
public static function merge($new)
|
||||||
@ -32,54 +32,9 @@ class DynamicConfig extends \yii\base\Object
|
|||||||
self::save($config);
|
self::save($config);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is called when a a setting is changed.
|
|
||||||
*
|
|
||||||
* @see Setting
|
|
||||||
* @param Setting $setting
|
|
||||||
*/
|
|
||||||
public static function onSettingChange($setting)
|
|
||||||
{
|
|
||||||
$config = self::load();
|
|
||||||
self::setSettingValue($config['params'], $setting);
|
|
||||||
self::save($config);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function setSettingValue(&$config, $setting)
|
|
||||||
{
|
|
||||||
|
|
||||||
$moduleId = $setting->module_id;
|
|
||||||
if ($moduleId == '') {
|
|
||||||
$moduleId = 'core';
|
|
||||||
}
|
|
||||||
|
|
||||||
$value = '';
|
|
||||||
if ($setting->value_text != '') {
|
|
||||||
$value = (string) $setting->value_text;
|
|
||||||
} else {
|
|
||||||
$value = (string) $setting->value;
|
|
||||||
}
|
|
||||||
|
|
||||||
$config['settings'][$moduleId][$setting->name] = $value;
|
|
||||||
Yii::$app->params['settings'][$moduleId][$setting->name] = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getSettingValue($name, $moduleId)
|
|
||||||
{
|
|
||||||
if ($moduleId == '') {
|
|
||||||
$moduleId = 'core';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset(Yii::$app->params['settings'][$moduleId][$name])) {
|
|
||||||
return Yii::$app->params['settings'][$moduleId][$name];
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the dynamic configuration
|
* Returns the dynamic configuration
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public static function load()
|
public static function load()
|
||||||
@ -103,7 +58,7 @@ class DynamicConfig extends \yii\base\Object
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a new dynamic configuration
|
* Sets a new dynamic configuration
|
||||||
*
|
*
|
||||||
* @param array $config
|
* @param array $config
|
||||||
*/
|
*/
|
||||||
public static function save($config)
|
public static function save($config)
|
||||||
@ -135,17 +90,17 @@ class DynamicConfig extends \yii\base\Object
|
|||||||
$config = self::load();
|
$config = self::load();
|
||||||
|
|
||||||
// Add Application Name to Configuration
|
// Add Application Name to Configuration
|
||||||
$config['name'] = Setting::Get('name');
|
$config['name'] = Yii::$app->settings->get('name');
|
||||||
|
|
||||||
// Add Default language
|
// Add Default language
|
||||||
$defaultLanguage = Setting::Get('defaultLanguage');
|
$defaultLanguage = Yii::$app->settings->get('defaultLanguage');
|
||||||
if ($defaultLanguage !== null && $defaultLanguage != "") {
|
if ($defaultLanguage !== null && $defaultLanguage != "") {
|
||||||
$config['language'] = Setting::Get('defaultLanguage');
|
$config['language'] = Yii::$app->settings->get('defaultLanguage');
|
||||||
} else {
|
} else {
|
||||||
$config['language'] = Yii::$app->language;
|
$config['language'] = Yii::$app->language;
|
||||||
}
|
}
|
||||||
|
|
||||||
$timeZone = Setting::Get('timeZone');
|
$timeZone = Yii::$app->settings->get('timeZone');
|
||||||
if ($timeZone != "") {
|
if ($timeZone != "") {
|
||||||
$config['timeZone'] = $timeZone;
|
$config['timeZone'] = $timeZone;
|
||||||
$config['components']['formatter']['defaultTimeZone'] = $timeZone;
|
$config['components']['formatter']['defaultTimeZone'] = $timeZone;
|
||||||
@ -154,66 +109,55 @@ class DynamicConfig extends \yii\base\Object
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add Caching
|
// Add Caching
|
||||||
$cacheClass = Setting::Get('type', 'cache');
|
$cacheClass = Yii::$app->settings->get('cache.class');
|
||||||
if (in_array($cacheClass, ['yii\caching\DummyCache', 'yii\caching\ApcCache', 'yii\caching\FileCache'])) {
|
if (in_array($cacheClass, ['yii\caching\DummyCache', 'yii\caching\ApcCache', 'yii\caching\FileCache'])) {
|
||||||
$config['components']['cache'] = [
|
$config['components']['cache'] = [
|
||||||
'class' => $cacheClass,
|
'class' => $cacheClass,
|
||||||
'keyPrefix' => Yii::$app->id
|
'keyPrefix' => Yii::$app->id
|
||||||
];
|
];
|
||||||
|
|
||||||
// Prefix APC Cache Keys
|
|
||||||
//if ($cacheClass == 'yii\caching\ApcCache') {
|
|
||||||
// $config['components']['cache'] = [
|
|
||||||
// 'keyPrefix' => Yii::$app->id
|
|
||||||
// ];
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
// Add User settings
|
// Add User settings
|
||||||
$config['components']['user'] = array();
|
$config['components']['user'] = array();
|
||||||
if (Setting::Get('defaultUserIdleTimeoutSec', 'authentication_internal')) {
|
if (Yii::$app->getModule('user')->settings->get('auth.defaultUserIdleTimeoutSec')) {
|
||||||
$config['components']['user']['authTimeout'] = Setting::Get('defaultUserIdleTimeoutSec', 'authentication_internal');
|
$config['components']['user']['authTimeout'] = Yii::$app->getModule('user')->settings->get('auth.defaultUserIdleTimeoutSec');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Install Mail Component
|
// Install Mail Component
|
||||||
$mail = [];
|
$mail = [];
|
||||||
$mail['transport'] = array();
|
$mail['transport'] = array();
|
||||||
if (Setting::Get('transportType', 'mailing') == 'smtp') {
|
if (Yii::$app->settings->get('mailer.transportType') == 'smtp') {
|
||||||
$mail['transport']['class'] = 'Swift_SmtpTransport';
|
$mail['transport']['class'] = 'Swift_SmtpTransport';
|
||||||
|
|
||||||
if (Setting::Get('hostname', 'mailing'))
|
if (Yii::$app->settings->get('mailer.hostname'))
|
||||||
$mail['transport']['host'] = Setting::Get('hostname', 'mailing');
|
$mail['transport']['host'] = Yii::$app->settings->get('mailer.hostname');
|
||||||
|
|
||||||
if (Setting::Get('username', 'mailing'))
|
if (Yii::$app->settings->get('mailer.username'))
|
||||||
$mail['transport']['username'] = Setting::Get('username', 'mailing');
|
$mail['transport']['username'] = Yii::$app->settings->get('mailer.username');
|
||||||
|
|
||||||
if (Setting::Get('password', 'mailing'))
|
if (Yii::$app->settings->get('mailer.password'))
|
||||||
$mail['transport']['password'] = Setting::Get('password', 'mailing');
|
$mail['transport']['password'] = Yii::$app->settings->get('mailer.password');
|
||||||
|
|
||||||
if (Setting::Get('encryption', 'mailing'))
|
if (Yii::$app->settings->get('mailer.encryption'))
|
||||||
$mail['transport']['encryption'] = Setting::Get('encryption', 'mailing');
|
$mail['transport']['encryption'] = Yii::$app->settings->get('mailer.encryption');
|
||||||
|
|
||||||
if (Setting::Get('port', 'mailing'))
|
if (Yii::$app->settings->get('mailer.port'))
|
||||||
$mail['transport']['port'] = Setting::Get('port', 'mailing');
|
$mail['transport']['port'] = Yii::$app->settings->get('mailer.port');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (Setting::Get('allowSelfSignedCerts', 'mailing')) {
|
if (Yii::$app->settings->get('mailer.allowSelfSignedCerts')) {
|
||||||
$mail['transport']['ssl']['allow_self_signed'] = true;
|
$mail['transport']['ssl']['allow_self_signed'] = true;
|
||||||
$mail['transport']['ssl']['verify_peer'] = false;
|
$mail['transport']['ssl']['verify_peer'] = false;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
} elseif (Setting::Get('transportType', 'mailing') == 'php') {
|
} elseif (Yii::$app->settings->get('mailer.transportType') == 'php') {
|
||||||
$mail['transport']['class'] = 'Swift_MailTransport';
|
$mail['transport']['class'] = 'Swift_MailTransport';
|
||||||
} else {
|
} else {
|
||||||
$mail['useFileTransport'] = true;
|
$mail['useFileTransport'] = true;
|
||||||
}
|
}
|
||||||
$config['components']['mailer'] = $mail;
|
$config['components']['mailer'] = $mail;
|
||||||
$config = ArrayHelper::merge($config, Theme::getThemeConfig(Setting::Get('theme')));
|
$config = ArrayHelper::merge($config, ThemeHelper::getThemeConfig(Yii::$app->settings->get('theme')));
|
||||||
$config['params']['config_created_at'] = time();
|
$config['params']['config_created_at'] = time();
|
||||||
|
|
||||||
foreach (Setting::find()->all() as $setting) {
|
|
||||||
self::setSettingValue($config['params'], $setting);
|
|
||||||
}
|
|
||||||
|
|
||||||
self::save($config);
|
self::save($config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,289 +513,9 @@ class iso3166Codes
|
|||||||
"ZW" => "263"
|
"ZW" => "263"
|
||||||
);
|
);
|
||||||
|
|
||||||
public static $continents = array(
|
|
||||||
"AF" => "Africa",
|
|
||||||
"AN" => "Antarctica",
|
|
||||||
"AS" => "Asia",
|
|
||||||
"EU" => "Europa",
|
|
||||||
"NA" => "North America",
|
|
||||||
"OC" => "Oceania",
|
|
||||||
"SA" => "South America"
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Trigger Yii translations.
|
|
||||||
* Only used for the message/create command from YII.
|
|
||||||
*/
|
|
||||||
public static function initTranslation()
|
|
||||||
{
|
|
||||||
static::$countriesTranslated = array(
|
|
||||||
'AF' => Yii::t('iso3166Codes', 'Afghanistan'),
|
|
||||||
'AX' => Yii::t('iso3166Codes', 'Aland Islands'),
|
|
||||||
'AL' => Yii::t('iso3166Codes', 'Albania'),
|
|
||||||
'DZ' => Yii::t('iso3166Codes', 'Algeria'),
|
|
||||||
'AS' => Yii::t('iso3166Codes', 'American Samoa'),
|
|
||||||
'AD' => Yii::t('iso3166Codes', 'Andorra'),
|
|
||||||
'AO' => Yii::t('iso3166Codes', 'Angola'),
|
|
||||||
'AI' => Yii::t('iso3166Codes', 'Anguilla'),
|
|
||||||
'AQ' => Yii::t('iso3166Codes', 'Antarctica'),
|
|
||||||
'AG' => Yii::t('iso3166Codes', 'Antigua and Barbuda'),
|
|
||||||
'AR' => Yii::t('iso3166Codes', 'Argentina'),
|
|
||||||
'AM' => Yii::t('iso3166Codes', 'Armenia'),
|
|
||||||
'AW' => Yii::t('iso3166Codes', 'Aruba'),
|
|
||||||
'AU' => Yii::t('iso3166Codes', 'Australia'),
|
|
||||||
'AT' => Yii::t('iso3166Codes', 'Austria'),
|
|
||||||
'AZ' => Yii::t('iso3166Codes', 'Azerbaijan'),
|
|
||||||
'BS' => Yii::t('iso3166Codes', 'Bahamas'),
|
|
||||||
'BH' => Yii::t('iso3166Codes', 'Bahrain'),
|
|
||||||
'BD' => Yii::t('iso3166Codes', 'Bangladesh'),
|
|
||||||
'BB' => Yii::t('iso3166Codes', 'Barbados'),
|
|
||||||
'BY' => Yii::t('iso3166Codes', 'Belarus'),
|
|
||||||
'BE' => Yii::t('iso3166Codes', 'Belgium'),
|
|
||||||
'BZ' => Yii::t('iso3166Codes', 'Belize'),
|
|
||||||
'BJ' => Yii::t('iso3166Codes', 'Benin'),
|
|
||||||
'BM' => Yii::t('iso3166Codes', 'Bermuda'),
|
|
||||||
'BT' => Yii::t('iso3166Codes', 'Bhutan'),
|
|
||||||
'BO' => Yii::t('iso3166Codes', 'Bolivia'),
|
|
||||||
'BQ' => Yii::t('iso3166Codes', 'Bonaire, Saint Eustatius and Saba'),
|
|
||||||
'BA' => Yii::t('iso3166Codes', 'Bosnia and Herzegovina'),
|
|
||||||
'BW' => Yii::t('iso3166Codes', 'Botswana'),
|
|
||||||
'BV' => Yii::t('iso3166Codes', 'Bouvet Island'),
|
|
||||||
'BR' => Yii::t('iso3166Codes', 'Brazil'),
|
|
||||||
'IO' => Yii::t('iso3166Codes', 'British Indian Ocean Territory'),
|
|
||||||
'VG' => Yii::t('iso3166Codes', 'British Virgin Islands'),
|
|
||||||
'BN' => Yii::t('iso3166Codes', 'Brunei'),
|
|
||||||
'BG' => Yii::t('iso3166Codes', 'Bulgaria'),
|
|
||||||
'BF' => Yii::t('iso3166Codes', 'Burkina Faso'),
|
|
||||||
'BI' => Yii::t('iso3166Codes', 'Burundi'),
|
|
||||||
'KH' => Yii::t('iso3166Codes', 'Cambodia'),
|
|
||||||
'CM' => Yii::t('iso3166Codes', 'Cameroon'),
|
|
||||||
'CA' => Yii::t('iso3166Codes', 'Canada'),
|
|
||||||
'CV' => Yii::t('iso3166Codes', 'Cape Verde'),
|
|
||||||
'KY' => Yii::t('iso3166Codes', 'Cayman Islands'),
|
|
||||||
'CF' => Yii::t('iso3166Codes', 'Central African Republic'),
|
|
||||||
'TD' => Yii::t('iso3166Codes', 'Chad'),
|
|
||||||
'CL' => Yii::t('iso3166Codes', 'Chile'),
|
|
||||||
'CN' => Yii::t('iso3166Codes', 'China'),
|
|
||||||
'CX' => Yii::t('iso3166Codes', 'Christmas Island'),
|
|
||||||
'CC' => Yii::t('iso3166Codes', 'Cocos Islands'),
|
|
||||||
'CO' => Yii::t('iso3166Codes', 'Colombia'),
|
|
||||||
'KM' => Yii::t('iso3166Codes', 'Comoros'),
|
|
||||||
'CK' => Yii::t('iso3166Codes', 'Cook Islands'),
|
|
||||||
'CR' => Yii::t('iso3166Codes', 'Costa Rica'),
|
|
||||||
'HR' => Yii::t('iso3166Codes', 'Croatia'),
|
|
||||||
'CU' => Yii::t('iso3166Codes', 'Cuba'),
|
|
||||||
'CW' => Yii::t('iso3166Codes', 'Curacao'),
|
|
||||||
'CY' => Yii::t('iso3166Codes', 'Cyprus'),
|
|
||||||
'CZ' => Yii::t('iso3166Codes', 'Czech Republic'),
|
|
||||||
'CD' => Yii::t('iso3166Codes', 'Democratic Republic of the Congo'),
|
|
||||||
'DK' => Yii::t('iso3166Codes', 'Denmark'),
|
|
||||||
'DJ' => Yii::t('iso3166Codes', 'Djibouti'),
|
|
||||||
'DM' => Yii::t('iso3166Codes', 'Dominica'),
|
|
||||||
'DO' => Yii::t('iso3166Codes', 'Dominican Republic'),
|
|
||||||
'EC' => Yii::t('iso3166Codes', 'Ecuador'),
|
|
||||||
'EG' => Yii::t('iso3166Codes', 'Egypt'),
|
|
||||||
'SV' => Yii::t('iso3166Codes', 'El Salvador'),
|
|
||||||
'GQ' => Yii::t('iso3166Codes', 'Equatorial Guinea'),
|
|
||||||
'ER' => Yii::t('iso3166Codes', 'Eritrea'),
|
|
||||||
'EE' => Yii::t('iso3166Codes', 'Estonia'),
|
|
||||||
'ET' => Yii::t('iso3166Codes', 'Ethiopia'),
|
|
||||||
'FK' => Yii::t('iso3166Codes', 'Falkland Islands'),
|
|
||||||
'FO' => Yii::t('iso3166Codes', 'Faroe Islands'),
|
|
||||||
'FJ' => Yii::t('iso3166Codes', 'Fiji'),
|
|
||||||
'FI' => Yii::t('iso3166Codes', 'Finland'),
|
|
||||||
'FR' => Yii::t('iso3166Codes', 'France'),
|
|
||||||
'GF' => Yii::t('iso3166Codes', 'French Guiana'),
|
|
||||||
'PF' => Yii::t('iso3166Codes', 'French Polynesia'),
|
|
||||||
'TF' => Yii::t('iso3166Codes', 'French Southern Territories'),
|
|
||||||
'GA' => Yii::t('iso3166Codes', 'Gabon'),
|
|
||||||
'GM' => Yii::t('iso3166Codes', 'Gambia'),
|
|
||||||
'GE' => Yii::t('iso3166Codes', 'Georgia'),
|
|
||||||
'DE' => Yii::t('iso3166Codes', 'Germany'),
|
|
||||||
'GH' => Yii::t('iso3166Codes', 'Ghana'),
|
|
||||||
'GI' => Yii::t('iso3166Codes', 'Gibraltar'),
|
|
||||||
'GR' => Yii::t('iso3166Codes', 'Greece'),
|
|
||||||
'GL' => Yii::t('iso3166Codes', 'Greenland'),
|
|
||||||
'GD' => Yii::t('iso3166Codes', 'Grenada'),
|
|
||||||
'GP' => Yii::t('iso3166Codes', 'Guadeloupe'),
|
|
||||||
'GU' => Yii::t('iso3166Codes', 'Guam'),
|
|
||||||
'GT' => Yii::t('iso3166Codes', 'Guatemala'),
|
|
||||||
'GG' => Yii::t('iso3166Codes', 'Guernsey'),
|
|
||||||
'GN' => Yii::t('iso3166Codes', 'Guinea'),
|
|
||||||
'GW' => Yii::t('iso3166Codes', 'Guinea-Bissau'),
|
|
||||||
'GY' => Yii::t('iso3166Codes', 'Guyana'),
|
|
||||||
'HT' => Yii::t('iso3166Codes', 'Haiti'),
|
|
||||||
'HM' => Yii::t('iso3166Codes', 'Heard Island and McDonald Islands'),
|
|
||||||
'HN' => Yii::t('iso3166Codes', 'Honduras'),
|
|
||||||
'HK' => Yii::t('iso3166Codes', 'Hong Kong'),
|
|
||||||
'HU' => Yii::t('iso3166Codes', 'Hungary'),
|
|
||||||
'IS' => Yii::t('iso3166Codes', 'Iceland'),
|
|
||||||
'IN' => Yii::t('iso3166Codes', 'India'),
|
|
||||||
'ID' => Yii::t('iso3166Codes', 'Indonesia'),
|
|
||||||
'IR' => Yii::t('iso3166Codes', 'Iran'),
|
|
||||||
'IQ' => Yii::t('iso3166Codes', 'Iraq'),
|
|
||||||
'IE' => Yii::t('iso3166Codes', 'Ireland'),
|
|
||||||
'IM' => Yii::t('iso3166Codes', 'Isle of Man'),
|
|
||||||
'IL' => Yii::t('iso3166Codes', 'Israel'),
|
|
||||||
'IT' => Yii::t('iso3166Codes', 'Italy'),
|
|
||||||
'CI' => Yii::t('iso3166Codes', 'Ivory Coast'),
|
|
||||||
'JM' => Yii::t('iso3166Codes', 'Jamaica'),
|
|
||||||
'JP' => Yii::t('iso3166Codes', 'Japan'),
|
|
||||||
'JE' => Yii::t('iso3166Codes', 'Jersey'),
|
|
||||||
'JO' => Yii::t('iso3166Codes', 'Jordan'),
|
|
||||||
'KZ' => Yii::t('iso3166Codes', 'Kazakhstan'),
|
|
||||||
'KE' => Yii::t('iso3166Codes', 'Kenya'),
|
|
||||||
'KI' => Yii::t('iso3166Codes', 'Kiribati'),
|
|
||||||
'XK' => Yii::t('iso3166Codes', 'Kosovo'),
|
|
||||||
'KW' => Yii::t('iso3166Codes', 'Kuwait'),
|
|
||||||
'KG' => Yii::t('iso3166Codes', 'Kyrgyzstan'),
|
|
||||||
'LA' => Yii::t('iso3166Codes', 'Laos'),
|
|
||||||
'LV' => Yii::t('iso3166Codes', 'Latvia'),
|
|
||||||
'LB' => Yii::t('iso3166Codes', 'Lebanon'),
|
|
||||||
'LS' => Yii::t('iso3166Codes', 'Lesotho'),
|
|
||||||
'LR' => Yii::t('iso3166Codes', 'Liberia'),
|
|
||||||
'LY' => Yii::t('iso3166Codes', 'Libya'),
|
|
||||||
'LI' => Yii::t('iso3166Codes', 'Liechtenstein'),
|
|
||||||
'LT' => Yii::t('iso3166Codes', 'Lithuania'),
|
|
||||||
'LU' => Yii::t('iso3166Codes', 'Luxembourg'),
|
|
||||||
'MO' => Yii::t('iso3166Codes', 'Macao'),
|
|
||||||
'MK' => Yii::t('iso3166Codes', 'Macedonia'),
|
|
||||||
'MG' => Yii::t('iso3166Codes', 'Madagascar'),
|
|
||||||
'MW' => Yii::t('iso3166Codes', 'Malawi'),
|
|
||||||
'MY' => Yii::t('iso3166Codes', 'Malaysia'),
|
|
||||||
'MV' => Yii::t('iso3166Codes', 'Maldives'),
|
|
||||||
'ML' => Yii::t('iso3166Codes', 'Mali'),
|
|
||||||
'MT' => Yii::t('iso3166Codes', 'Malta'),
|
|
||||||
'MH' => Yii::t('iso3166Codes', 'Marshall Islands'),
|
|
||||||
'MQ' => Yii::t('iso3166Codes', 'Martinique'),
|
|
||||||
'MR' => Yii::t('iso3166Codes', 'Mauritania'),
|
|
||||||
'MU' => Yii::t('iso3166Codes', 'Mauritius'),
|
|
||||||
'YT' => Yii::t('iso3166Codes', 'Mayotte'),
|
|
||||||
'MX' => Yii::t('iso3166Codes', 'Mexico'),
|
|
||||||
'FM' => Yii::t('iso3166Codes', 'Micronesia'),
|
|
||||||
'MD' => Yii::t('iso3166Codes', 'Moldova'),
|
|
||||||
'MC' => Yii::t('iso3166Codes', 'Monaco'),
|
|
||||||
'MN' => Yii::t('iso3166Codes', 'Mongolia'),
|
|
||||||
'ME' => Yii::t('iso3166Codes', 'Montenegro'),
|
|
||||||
'MS' => Yii::t('iso3166Codes', 'Montserrat'),
|
|
||||||
'MA' => Yii::t('iso3166Codes', 'Morocco'),
|
|
||||||
'MZ' => Yii::t('iso3166Codes', 'Mozambique'),
|
|
||||||
'MM' => Yii::t('iso3166Codes', 'Myanmar'),
|
|
||||||
'NA' => Yii::t('iso3166Codes', 'Namibia'),
|
|
||||||
'NR' => Yii::t('iso3166Codes', 'Nauru'),
|
|
||||||
'NP' => Yii::t('iso3166Codes', 'Nepal'),
|
|
||||||
'NL' => Yii::t('iso3166Codes', 'Netherlands'),
|
|
||||||
'AN' => Yii::t('iso3166Codes', 'Netherlands Antilles'),
|
|
||||||
'NC' => Yii::t('iso3166Codes', 'New Caledonia'),
|
|
||||||
'NZ' => Yii::t('iso3166Codes', 'New Zealand'),
|
|
||||||
'NI' => Yii::t('iso3166Codes', 'Nicaragua'),
|
|
||||||
'NE' => Yii::t('iso3166Codes', 'Niger'),
|
|
||||||
'NG' => Yii::t('iso3166Codes', 'Nigeria'),
|
|
||||||
'NU' => Yii::t('iso3166Codes', 'Niue'),
|
|
||||||
'NF' => Yii::t('iso3166Codes', 'Norfolk Island'),
|
|
||||||
'KP' => Yii::t('iso3166Codes', 'North Korea'),
|
|
||||||
'MP' => Yii::t('iso3166Codes', 'Northern Mariana Islands'),
|
|
||||||
'NO' => Yii::t('iso3166Codes', 'Norway'),
|
|
||||||
'OM' => Yii::t('iso3166Codes', 'Oman'),
|
|
||||||
'PK' => Yii::t('iso3166Codes', 'Pakistan'),
|
|
||||||
'PW' => Yii::t('iso3166Codes', 'Palau'),
|
|
||||||
'PS' => Yii::t('iso3166Codes', 'Palestinian Territory'),
|
|
||||||
'PA' => Yii::t('iso3166Codes', 'Panama'),
|
|
||||||
'PG' => Yii::t('iso3166Codes', 'Papua New Guinea'),
|
|
||||||
'PY' => Yii::t('iso3166Codes', 'Paraguay'),
|
|
||||||
'PE' => Yii::t('iso3166Codes', 'Peru'),
|
|
||||||
'PH' => Yii::t('iso3166Codes', 'Philippines'),
|
|
||||||
'PN' => Yii::t('iso3166Codes', 'Pitcairn'),
|
|
||||||
'PL' => Yii::t('iso3166Codes', 'Poland'),
|
|
||||||
'PT' => Yii::t('iso3166Codes', 'Portugal'),
|
|
||||||
'PR' => Yii::t('iso3166Codes', 'Puerto Rico'),
|
|
||||||
'QA' => Yii::t('iso3166Codes', 'Qatar'),
|
|
||||||
'CG' => Yii::t('iso3166Codes', 'Republic of the Congo'),
|
|
||||||
'RE' => Yii::t('iso3166Codes', 'Reunion'),
|
|
||||||
'RO' => Yii::t('iso3166Codes', 'Romania'),
|
|
||||||
'RU' => Yii::t('iso3166Codes', 'Russia'),
|
|
||||||
'RW' => Yii::t('iso3166Codes', 'Rwanda'),
|
|
||||||
'BL' => Yii::t('iso3166Codes', 'Saint Barthelemy'),
|
|
||||||
'SH' => Yii::t('iso3166Codes', 'Saint Helena'),
|
|
||||||
'KN' => Yii::t('iso3166Codes', 'Saint Kitts and Nevis'),
|
|
||||||
'LC' => Yii::t('iso3166Codes', 'Saint Lucia'),
|
|
||||||
'MF' => Yii::t('iso3166Codes', 'Saint Martin'),
|
|
||||||
'PM' => Yii::t('iso3166Codes', 'Saint Pierre and Miquelon'),
|
|
||||||
'VC' => Yii::t('iso3166Codes', 'Saint Vincent and the Grenadines'),
|
|
||||||
'WS' => Yii::t('iso3166Codes', 'Samoa'),
|
|
||||||
'SM' => Yii::t('iso3166Codes', 'San Marino'),
|
|
||||||
'ST' => Yii::t('iso3166Codes', 'Sao Tome and Principe'),
|
|
||||||
'SA' => Yii::t('iso3166Codes', 'Saudi Arabia'),
|
|
||||||
'SN' => Yii::t('iso3166Codes', 'Senegal'),
|
|
||||||
'RS' => Yii::t('iso3166Codes', 'Serbia'),
|
|
||||||
'SC' => Yii::t('iso3166Codes', 'Seychelles'),
|
|
||||||
'SL' => Yii::t('iso3166Codes', 'Sierra Leone'),
|
|
||||||
'SG' => Yii::t('iso3166Codes', 'Singapore'),
|
|
||||||
'SX' => Yii::t('iso3166Codes', 'Sint Maarten'),
|
|
||||||
'SK' => Yii::t('iso3166Codes', 'Slovakia'),
|
|
||||||
'SI' => Yii::t('iso3166Codes', 'Slovenia'),
|
|
||||||
'SB' => Yii::t('iso3166Codes', 'Solomon Islands'),
|
|
||||||
'SO' => Yii::t('iso3166Codes', 'Somalia'),
|
|
||||||
'ZA' => Yii::t('iso3166Codes', 'South Africa'),
|
|
||||||
'GS' => Yii::t('iso3166Codes', 'South Georgia and the South Sandwich Islands'),
|
|
||||||
'KR' => Yii::t('iso3166Codes', 'South Korea'),
|
|
||||||
'SS' => Yii::t('iso3166Codes', 'South Sudan'),
|
|
||||||
'ES' => Yii::t('iso3166Codes', 'Spain'),
|
|
||||||
'LK' => Yii::t('iso3166Codes', 'Sri Lanka'),
|
|
||||||
'SD' => Yii::t('iso3166Codes', 'Sudan'),
|
|
||||||
'SR' => Yii::t('iso3166Codes', 'Suriname'),
|
|
||||||
'SJ' => Yii::t('iso3166Codes', 'Svalbard and Jan Mayen'),
|
|
||||||
'SZ' => Yii::t('iso3166Codes', 'Swaziland'),
|
|
||||||
'SE' => Yii::t('iso3166Codes', 'Sweden'),
|
|
||||||
'CH' => Yii::t('iso3166Codes', 'Switzerland'),
|
|
||||||
'SY' => Yii::t('iso3166Codes', 'Syria'),
|
|
||||||
'TW' => Yii::t('iso3166Codes', 'Taiwan'),
|
|
||||||
'TJ' => Yii::t('iso3166Codes', 'Tajikistan'),
|
|
||||||
'TZ' => Yii::t('iso3166Codes', 'Tanzania'),
|
|
||||||
'TH' => Yii::t('iso3166Codes', 'Thailand'),
|
|
||||||
'TL' => Yii::t('iso3166Codes', 'Timor-Leste'),
|
|
||||||
'TG' => Yii::t('iso3166Codes', 'Togo'),
|
|
||||||
'TK' => Yii::t('iso3166Codes', 'Tokelau'),
|
|
||||||
'TO' => Yii::t('iso3166Codes', 'Tonga'),
|
|
||||||
'TT' => Yii::t('iso3166Codes', 'Trinidad and Tobago'),
|
|
||||||
'TN' => Yii::t('iso3166Codes', 'Tunisia'),
|
|
||||||
'TR' => Yii::t('iso3166Codes', 'Turkey'),
|
|
||||||
'TM' => Yii::t('iso3166Codes', 'Turkmenistan'),
|
|
||||||
'TC' => Yii::t('iso3166Codes', 'Turks and Caicos Islands'),
|
|
||||||
'TV' => Yii::t('iso3166Codes', 'Tuvalu'),
|
|
||||||
'VI' => Yii::t('iso3166Codes', 'U.S. Virgin Islands'),
|
|
||||||
'UG' => Yii::t('iso3166Codes', 'Uganda'),
|
|
||||||
'UA' => Yii::t('iso3166Codes', 'Ukraine'),
|
|
||||||
'AE' => Yii::t('iso3166Codes', 'United Arab Emirates'),
|
|
||||||
'GB' => Yii::t('iso3166Codes', 'United Kingdom'),
|
|
||||||
'US' => Yii::t('iso3166Codes', 'United States'),
|
|
||||||
'UM' => Yii::t('iso3166Codes', 'United States Minor Outlying Islands'),
|
|
||||||
'UY' => Yii::t('iso3166Codes', 'Uruguay'),
|
|
||||||
'UZ' => Yii::t('iso3166Codes', 'Uzbekistan'),
|
|
||||||
'VU' => Yii::t('iso3166Codes', 'Vanuatu'),
|
|
||||||
'VA' => Yii::t('iso3166Codes', 'Vatican'),
|
|
||||||
'VE' => Yii::t('iso3166Codes', 'Venezuela'),
|
|
||||||
'VN' => Yii::t('iso3166Codes', 'Vietnam'),
|
|
||||||
'WF' => Yii::t('iso3166Codes', 'Wallis and Futuna'),
|
|
||||||
'EH' => Yii::t('iso3166Codes', 'Western Sahara'),
|
|
||||||
'YE' => Yii::t('iso3166Codes', 'Yemen'),
|
|
||||||
'ZM' => Yii::t('iso3166Codes', 'Zambia'),
|
|
||||||
'ZW' => Yii::t('iso3166Codes', 'Zimbabwe')
|
|
||||||
);
|
|
||||||
static::$continentsTranslated = array(
|
|
||||||
"AF" => Yii::t('iso3166Codes', 'Africa'),
|
|
||||||
"AN" => Yii::t('iso3166Codes', 'Antarctica'),
|
|
||||||
"AS" => Yii::t('iso3166Codes', 'Asia'),
|
|
||||||
"EU" => Yii::t('iso3166Codes', 'Europa'),
|
|
||||||
"NA" => Yii::t('iso3166Codes', 'North America'),
|
|
||||||
"OC" => Yii::t('iso3166Codes', 'Oceania'),
|
|
||||||
"SA" => Yii::t('iso3166Codes', 'South America')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function country($code, $translate = true)
|
public static function country($code, $translate = true)
|
||||||
{
|
{
|
||||||
return (isset(static::$countries[strtoupper($code)])) ? ($translate ? Yii::t('iso3166Codes', static::$countries[strtoupper($code)]) : static::$countries[strtoupper($code)]) : $code;
|
return \Locale::getDisplayRegion("_$code", $translate ? Yii::$app->language : 'en');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function phoneCode($code)
|
public static function phoneCode($code)
|
||||||
@ -803,11 +523,6 @@ class iso3166Codes
|
|||||||
return (isset(static::$phoneCodes[strtoupper($code)])) ? static::$phoneCodes[strtoupper($code)] : 'N/A';
|
return (isset(static::$phoneCodes[strtoupper($code)])) ? static::$phoneCodes[strtoupper($code)] : 'N/A';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function continent($code, $translate = true)
|
|
||||||
{
|
|
||||||
return (isset(static::$continents[strtoupper($code)])) ? ($translate ? Yii::t('iso3166Codes', static::$continents[strtoupper($code)]) : static::$continents[strtoupper($code)]) : Yii::t('iso3166Codes', 'Invalid Code');
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function isValid($code)
|
public static function isValid($code)
|
||||||
{
|
{
|
||||||
return isset(static::$countries[strtoupper($code)]);
|
return isset(static::$countries[strtoupper($code)]);
|
||||||
|
@ -1,342 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HumHub
|
|
||||||
* Copyright © 2014 The HumHub Project
|
|
||||||
*
|
|
||||||
* The texts of the GNU Affero General Public License with an additional
|
|
||||||
* permission and of our proprietary license can be found at and
|
|
||||||
* in the LICENSE file you have received along with this program.
|
|
||||||
*
|
|
||||||
* According to our dual licensing model, this program can be used either
|
|
||||||
* under the terms of the GNU Affero General Public License, version 3,
|
|
||||||
* or under a proprietary license.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace humhub\libs;
|
|
||||||
|
|
||||||
use humhub\models\Setting;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ImageConverter provides a simple interface for converting or resizing images.
|
|
||||||
*
|
|
||||||
* @package humhub.modules_core.file.libs
|
|
||||||
* @since 0.5
|
|
||||||
*/
|
|
||||||
class ImageConverter
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transforms given File to Jpeg
|
|
||||||
*
|
|
||||||
* @param String $sourceFile
|
|
||||||
* @param String $targetFile
|
|
||||||
* @param String $originalFileName (provide this when sourceFile has no extension e.g. tempfile)
|
|
||||||
*/
|
|
||||||
public static function TransformToJpeg($sourceFile, $targetFile)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (Setting::Get('imageMagickPath', 'file')) {
|
|
||||||
$convertCommand = Setting::Get('imageMagickPath', 'file');
|
|
||||||
$command = $convertCommand . " \"{$sourceFile}\" \"{$targetFile}\"";
|
|
||||||
$ret = passthru($command);
|
|
||||||
} else {
|
|
||||||
$gdImage = self::getGDImageByFile($sourceFile);
|
|
||||||
$gdImage = self::fixOrientation($gdImage, $sourceFile);
|
|
||||||
imagejpeg($gdImage, $targetFile, 100);
|
|
||||||
imagedestroy($gdImage);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resizes an given Image to an given Size
|
|
||||||
*
|
|
||||||
* Options Array:
|
|
||||||
* width - in px
|
|
||||||
* height - in px
|
|
||||||
* mode:
|
|
||||||
* force - creates image with given dimensions (default)
|
|
||||||
* max - creates image with a maximum of given width / height
|
|
||||||
*
|
|
||||||
* @param String $sourceFile
|
|
||||||
* @param String $targetFile
|
|
||||||
* @param Array $options
|
|
||||||
*/
|
|
||||||
public static function Resize($sourceFile, $targetFile, $options = array())
|
|
||||||
{
|
|
||||||
|
|
||||||
if (!isset($options['width']))
|
|
||||||
$options['width'] = 0;
|
|
||||||
|
|
||||||
if (!isset($options['height']))
|
|
||||||
$options['height'] = 0;
|
|
||||||
|
|
||||||
if (!isset($options['mode']))
|
|
||||||
$options['mode'] = 'force';
|
|
||||||
|
|
||||||
if (Setting::Get('imageMagickPath', 'file')) {
|
|
||||||
self::ResizeImageMagick($sourceFile, $targetFile, $options);
|
|
||||||
} else {
|
|
||||||
self::ResizeGD($sourceFile, $targetFile, $options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resize GD Libary Implementation
|
|
||||||
*
|
|
||||||
* @param type $sourceFile
|
|
||||||
* @param type $targetFile
|
|
||||||
* @param type $options
|
|
||||||
*/
|
|
||||||
private static function ResizeGD($sourceFile, $targetFile, $options = array())
|
|
||||||
{
|
|
||||||
|
|
||||||
$width = $options['width'];
|
|
||||||
$height = $options['height'];
|
|
||||||
|
|
||||||
$gdImage = self::getGDImageByFile($sourceFile);
|
|
||||||
$gdImage = self::fixOrientation($gdImage, $sourceFile);
|
|
||||||
|
|
||||||
$sourceWidth = imagesx($gdImage);
|
|
||||||
$sourceHeight = imagesy($gdImage);
|
|
||||||
|
|
||||||
$dst_x = 0;
|
|
||||||
$dst_y = 0;
|
|
||||||
$src_x = 0;
|
|
||||||
$src_y = 0;
|
|
||||||
$dst_w = $width;
|
|
||||||
$dst_h = $height;
|
|
||||||
$src_w = $sourceWidth;
|
|
||||||
$src_h = $sourceHeight;
|
|
||||||
|
|
||||||
if ($options['mode'] == 'max') {
|
|
||||||
|
|
||||||
if ($sourceHeight > $height || $sourceWidth > $width) {
|
|
||||||
|
|
||||||
// http://snipplr.com/view/53183
|
|
||||||
|
|
||||||
if ($height == 0)
|
|
||||||
$height = $sourceHeight;
|
|
||||||
if ($width == 0)
|
|
||||||
$width = $sourceWidth;
|
|
||||||
|
|
||||||
$w = $sourceWidth;
|
|
||||||
$h = $sourceHeight;
|
|
||||||
$max_w = $width;
|
|
||||||
$max_h = $height;
|
|
||||||
|
|
||||||
// $w is the width of the current rectangle
|
|
||||||
// $h is the height of the current rectangle
|
|
||||||
// $max_w is the maximum width that an image can be sized
|
|
||||||
// $max_h is the maximum height that an image can be sized
|
|
||||||
// **** Here's where the magic is starts ****
|
|
||||||
// Switch the concept of horiz/vertical/square to long/short side
|
|
||||||
$short_side_len = ($w < $h ? $w : $h);
|
|
||||||
$long_side_len = ($w > $h ? $w : $h);
|
|
||||||
// Set a variable to the variable name of the output variable
|
|
||||||
$ssvar = ($w > $h ? 'h' : 'w');
|
|
||||||
$lsvar = ($w > $h ? 'w' : 'h');
|
|
||||||
$maxLSvar = "max_" . $lsvar;
|
|
||||||
$maxSSvar = "max_" . $ssvar;
|
|
||||||
|
|
||||||
// Do the first pass on the long side
|
|
||||||
$ratio = $$maxLSvar / $long_side_len;
|
|
||||||
$newSS = round($short_side_len * $ratio);
|
|
||||||
$newLS = round($long_side_len * $ratio);
|
|
||||||
|
|
||||||
// *** Note - the only coditional block!
|
|
||||||
// If short side is still out of limit, limit the short side and adjust
|
|
||||||
if ($newSS > $$maxSSvar) {
|
|
||||||
$ratio = $$maxSSvar / $newSS;
|
|
||||||
$newLS = round($ratio * $newLS);
|
|
||||||
$newSS = $$maxSSvar;
|
|
||||||
}
|
|
||||||
|
|
||||||
// **** Here's where the magic ends ****
|
|
||||||
// Re-couple the h/w (or w/h) with the long/shortside counterparts
|
|
||||||
// $$ means it's a variable variable (dynamic assignment)
|
|
||||||
$$ssvar = $newSS;
|
|
||||||
$$lsvar = $newLS;
|
|
||||||
|
|
||||||
// Prep the return array
|
|
||||||
#$dimensions['w'] = $w; // this is derived from either $ssvar or $lsvar
|
|
||||||
#$dimensions['h'] = $h;
|
|
||||||
|
|
||||||
$width = $w;
|
|
||||||
$height = $h;
|
|
||||||
$dst_h = $h;
|
|
||||||
$dst_w = $w;
|
|
||||||
} else {
|
|
||||||
$height = $sourceHeight;
|
|
||||||
$width = $sourceWidth;
|
|
||||||
$dst_h = $sourceHeight;
|
|
||||||
$dst_w = $sourceWidth;
|
|
||||||
}
|
|
||||||
} else if ($options['mode'] == 'force') {
|
|
||||||
|
|
||||||
// When ratio not fit, crop it - requires given width & height
|
|
||||||
if ($width != 0 && $height != 0) {
|
|
||||||
if (($sourceWidth / $sourceHeight) != ($width / $height)) {
|
|
||||||
|
|
||||||
$_scale = min((float) ($sourceWidth / $width), (float) ($sourceHeight / $height));
|
|
||||||
$cropX = (float) ($sourceWidth - ($_scale * $width));
|
|
||||||
$cropY = (float) ($sourceHeight - ($_scale * $height));
|
|
||||||
|
|
||||||
// cropped image size
|
|
||||||
$cropW = (float) ($sourceWidth - $cropX);
|
|
||||||
$cropH = (float) ($sourceHeight - $cropY);
|
|
||||||
|
|
||||||
// crop the middle part of the image to fit proportions
|
|
||||||
$crop = ImageCreateTrueColor($cropW, $cropH);
|
|
||||||
ImageCopy(
|
|
||||||
$crop, $gdImage, 0, 0, (int) ($cropX / 2), (int) ($cropY / 2), $cropW, $cropH
|
|
||||||
);
|
|
||||||
|
|
||||||
$src_w = $cropW;
|
|
||||||
$src_h = $cropH;
|
|
||||||
|
|
||||||
imagecopy($gdImage, $crop, 0, 0, 0, 0, $src_w, $src_h);
|
|
||||||
}
|
|
||||||
} elseif ($width == 0) {
|
|
||||||
$width = $sourceWidth;
|
|
||||||
} elseif ($height == 0) {
|
|
||||||
$height = $sourceHeight;
|
|
||||||
} else {
|
|
||||||
$width = $sourceWidth;
|
|
||||||
$height = $sourceHeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create new Image
|
|
||||||
$newGdImage = imagecreatetruecolor($width, $height);
|
|
||||||
|
|
||||||
if (isset($options['transparent']) && $options['transparent']) {
|
|
||||||
imagealphablending($newGdImage, false);
|
|
||||||
imagesavealpha($newGdImage, true);
|
|
||||||
$transparent = imagecolorallocatealpha($newGdImage, 255, 255, 255, 127);
|
|
||||||
imagefilledrectangle($newGdImage, 0, 0, $width, $height, $transparent);
|
|
||||||
}
|
|
||||||
|
|
||||||
imagecopyresampled($newGdImage, $gdImage, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
|
|
||||||
|
|
||||||
list($hw, $hx, $imageType) = getimagesize($sourceFile);
|
|
||||||
|
|
||||||
switch ($imageType) {
|
|
||||||
case IMAGETYPE_PNG:
|
|
||||||
imagepng($newGdImage, $targetFile);
|
|
||||||
break;
|
|
||||||
case IMAGETYPE_GIF:
|
|
||||||
imagegif($newGdImage, $targetFile);
|
|
||||||
break;
|
|
||||||
case IMAGETYPE_JPEG:
|
|
||||||
imagejpeg($newGdImage, $targetFile, 100);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
imagedestroy($gdImage);
|
|
||||||
imagedestroy($newGdImage);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resize Image Magick Implementation
|
|
||||||
*
|
|
||||||
* @param type $sourceFile
|
|
||||||
* @param type $targetFile
|
|
||||||
* @param type $options
|
|
||||||
*/
|
|
||||||
private static function ResizeImageMagick($sourceFile, $targetFile, $options = array())
|
|
||||||
{
|
|
||||||
$convertCommand = Setting::Get('imageMagickPath', 'file');
|
|
||||||
$width = (int) $options['width'];
|
|
||||||
$height = (int) $options['height'];
|
|
||||||
|
|
||||||
if ($options['mode'] == 'max') {
|
|
||||||
|
|
||||||
if ($width && $height)
|
|
||||||
$command = $convertCommand . " -quality 100 -density 300 \"{$sourceFile}\" -resize '{$width}x{$height}>' \"{$targetFile}\"";
|
|
||||||
elseif ($width)
|
|
||||||
$command = $convertCommand . " -quality 100 -density 300 \"{$sourceFile}\" -resize '{$width}x>' \"{$targetFile}\"";
|
|
||||||
elseif ($height)
|
|
||||||
$command = $convertCommand . " -quality 100 -density 300 \"{$sourceFile}\" -resize 'x{$height}>' \"{$targetFile}\"";
|
|
||||||
|
|
||||||
$ret = passthru($command);
|
|
||||||
} elseif ($options['mode'] == 'force') {
|
|
||||||
$command = $convertCommand . " \"{$sourceFile}\" -gravity center -quality 100 -resize {$width}x{$height}^ -extent {$width}x{$height} \"{$targetFile}\"";
|
|
||||||
$ret = passthru($command);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates GD Image Resource by given Filename
|
|
||||||
*
|
|
||||||
* @param String $fileName
|
|
||||||
* @return resource GD Image
|
|
||||||
*/
|
|
||||||
public static function getGDImageByFile($fileName)
|
|
||||||
{
|
|
||||||
|
|
||||||
list($width, $height, $imageType) = getimagesize($fileName);
|
|
||||||
|
|
||||||
switch ($imageType) {
|
|
||||||
case IMAGETYPE_PNG:
|
|
||||||
$gdImage = imagecreatefrompng($fileName);
|
|
||||||
break;
|
|
||||||
case IMAGETYPE_GIF:
|
|
||||||
$gdImage = imagecreatefromgif($fileName);
|
|
||||||
break;
|
|
||||||
case IMAGETYPE_JPEG:
|
|
||||||
$gdImage = imagecreatefromjpeg($fileName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $gdImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function fixOrientation($image, $filename)
|
|
||||||
{
|
|
||||||
$exif = @exif_read_data($filename);
|
|
||||||
if (is_array($exif) && !empty($exif['Orientation'])) {
|
|
||||||
switch ($exif['Orientation']) {
|
|
||||||
case 8:
|
|
||||||
$image = imagerotate($image, 90, 0);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
$image = imagerotate($image, 180, 0);
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
$image = imagerotate($image, -90, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $image;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function checkTransparent($im)
|
|
||||||
{
|
|
||||||
|
|
||||||
$im = self::getGDImageByFile($im);
|
|
||||||
|
|
||||||
$width = imagesx($im); // Get the width of the image
|
|
||||||
$height = imagesy($im); // Get the height of the image
|
|
||||||
// We run the image pixel by pixel and as soon as we find a transparent pixel we stop and return true.
|
|
||||||
for ($i = 0; $i < $width; $i++) {
|
|
||||||
for ($j = 0; $j < $height; $j++) {
|
|
||||||
$rgba = imagecolorat($im, $i, $j);
|
|
||||||
if (($rgba & 0x7F000000) >> 24) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we dont find any pixel the function will return false.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,11 +1,21 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2016 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
namespace humhub\libs;
|
namespace humhub\libs;
|
||||||
|
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\web\UploadedFile;
|
use yii\web\UploadedFile;
|
||||||
use yii\helpers\Url;
|
use yii\helpers\Url;
|
||||||
|
use humhub\modules\file\libs\ImageConverter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LogoImage
|
||||||
|
*/
|
||||||
class LogoImage
|
class LogoImage
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -19,11 +29,6 @@ class LogoImage
|
|||||||
*/
|
*/
|
||||||
protected $folder_images = "logo_image";
|
protected $folder_images = "logo_image";
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the URl of Logo Image
|
* Returns the URl of Logo Image
|
||||||
*
|
*
|
||||||
|
@ -1,26 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HumHub
|
* @link https://www.humhub.org/
|
||||||
* Copyright © 2014 The HumHub Project
|
* @copyright Copyright (c) 2016 HumHub GmbH & Co. KG
|
||||||
*
|
* @license https://www.humhub.com/licences
|
||||||
* The texts of the GNU Affero General Public License with an additional
|
|
||||||
* permission and of our proprietary license can be found at and
|
|
||||||
* in the LICENSE file you have received along with this program.
|
|
||||||
*
|
|
||||||
* According to our dual licensing model, this program can be used either
|
|
||||||
* under the terms of the GNU Affero General Public License, version 3,
|
|
||||||
* or under a proprietary license.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace humhub\libs;
|
namespace humhub\libs;
|
||||||
|
|
||||||
use humhub\libs\ImageConverter;
|
use humhub\modules\file\libs\ImageConverter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ProfileBannerImage is responsible for the profile banner images.
|
* ProfileBannerImage is responsible for the profile banner images.
|
||||||
@ -32,7 +20,6 @@ use humhub\libs\ImageConverter;
|
|||||||
* "" = Resized profile image
|
* "" = Resized profile image
|
||||||
* "_org" = Orginal uploaded file
|
* "_org" = Orginal uploaded file
|
||||||
*
|
*
|
||||||
* @package humhub.modules_core.file
|
|
||||||
* @since 0.5
|
* @since 0.5
|
||||||
* @author Luke
|
* @author Luke
|
||||||
*/
|
*/
|
||||||
|
@ -1,28 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HumHub
|
* @link https://www.humhub.org/
|
||||||
* Copyright © 2014 The HumHub Project
|
* @copyright Copyright (c) 2016 HumHub GmbH & Co. KG
|
||||||
*
|
* @license https://www.humhub.com/licences
|
||||||
* The texts of the GNU Affero General Public License with an additional
|
|
||||||
* permission and of our proprietary license can be found at and
|
|
||||||
* in the LICENSE file you have received along with this program.
|
|
||||||
*
|
|
||||||
* According to our dual licensing model, this program can be used either
|
|
||||||
* under the terms of the GNU Affero General Public License, version 3,
|
|
||||||
* or under a proprietary license.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace humhub\libs;
|
namespace humhub\libs;
|
||||||
|
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\helpers\Url;
|
use yii\helpers\Url;
|
||||||
use humhub\libs\ImageConverter;
|
use humhub\modules\file\libs\ImageConverter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ProfileImage is responsible for all profile images.
|
* ProfileImage is responsible for all profile images.
|
||||||
@ -34,7 +22,6 @@ use humhub\libs\ImageConverter;
|
|||||||
* "" = Resized profile image
|
* "" = Resized profile image
|
||||||
* "_org" = Orginal uploaded file
|
* "_org" = Orginal uploaded file
|
||||||
*
|
*
|
||||||
* @package humhub.modules_core.file
|
|
||||||
* @since 0.5
|
* @since 0.5
|
||||||
* @author Luke
|
* @author Luke
|
||||||
*/
|
*/
|
||||||
|
@ -85,7 +85,7 @@ class SelfTest
|
|||||||
|
|
||||||
$icuVersion = (defined('INTL_ICU_VERSION')) ? INTL_ICU_VERSION : 0;
|
$icuVersion = (defined('INTL_ICU_VERSION')) ? INTL_ICU_VERSION : 0;
|
||||||
$icuMinVersion = '4.8.1';
|
$icuMinVersion = '4.8.1';
|
||||||
$title = 'PHP - INTL Extension - ICU Version (' . INTL_ICU_VERSION . ')';
|
$title = 'PHP - INTL Extension - ICU Version (' . $icuVersion . ')';
|
||||||
if (version_compare($icuVersion, $icuMinVersion, '>=')) {
|
if (version_compare($icuVersion, $icuMinVersion, '>=')) {
|
||||||
$checks[] = array(
|
$checks[] = array(
|
||||||
'title' => Yii::t('base', $title),
|
'title' => Yii::t('base', $title),
|
||||||
@ -100,7 +100,7 @@ class SelfTest
|
|||||||
}
|
}
|
||||||
$icuDataVersion = (defined('INTL_ICU_DATA_VERSION')) ? INTL_ICU_DATA_VERSION : 0;
|
$icuDataVersion = (defined('INTL_ICU_DATA_VERSION')) ? INTL_ICU_DATA_VERSION : 0;
|
||||||
$icuMinDataVersion = '4.8.1';
|
$icuMinDataVersion = '4.8.1';
|
||||||
$title = 'PHP - INTL Extension - ICU Data Version (' . INTL_ICU_DATA_VERSION . ')';
|
$title = 'PHP - INTL Extension - ICU Data Version (' . $icuDataVersion . ')';
|
||||||
if (version_compare($icuDataVersion, $icuMinDataVersion, '>=')) {
|
if (version_compare($icuDataVersion, $icuMinDataVersion, '>=')) {
|
||||||
$checks[] = array(
|
$checks[] = array(
|
||||||
'title' => Yii::t('base', $title),
|
'title' => Yii::t('base', $title),
|
||||||
|
132
protected/humhub/libs/ThemeHelper.php
Normal file
132
protected/humhub/libs/ThemeHelper.php
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2016 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\libs;
|
||||||
|
|
||||||
|
use Yii;
|
||||||
|
use humhub\components\Theme;
|
||||||
|
use yii\helpers\ArrayHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ThemeHelper
|
||||||
|
*
|
||||||
|
* @since 1.1
|
||||||
|
* @author Luke
|
||||||
|
*/
|
||||||
|
class ThemeHelper
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of all available themes.
|
||||||
|
*
|
||||||
|
* @return Array Theme instances
|
||||||
|
*/
|
||||||
|
public static function getThemes()
|
||||||
|
{
|
||||||
|
$themes = self::getThemesByPath(Yii::getAlias('@webroot/themes'));
|
||||||
|
|
||||||
|
// Collect themes provided by modules
|
||||||
|
foreach (Yii::$app->getModules() as $id => $module) {
|
||||||
|
if (is_array($module)) {
|
||||||
|
$module = Yii::$app->getModule($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
$moduleThemePath = $module->getBasePath() . DIRECTORY_SEPARATOR . 'themes';
|
||||||
|
if (is_dir($moduleThemePath)) {
|
||||||
|
$themes = ArrayHelper::merge($themes, self::getThemesByPath($moduleThemePath, ['publishResources' => true]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $themes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of Theme instances of a given directory
|
||||||
|
*
|
||||||
|
* @param string $path the theme directory
|
||||||
|
* @param type $additionalOptions options for Theme instance
|
||||||
|
* @return Theme[]
|
||||||
|
*/
|
||||||
|
public static function getThemesByPath($path, $additionalOptions = [])
|
||||||
|
{
|
||||||
|
$themes = [];
|
||||||
|
if (is_dir($path)) {
|
||||||
|
foreach (scandir($path) as $file) {
|
||||||
|
|
||||||
|
// Skip dots and non directories
|
||||||
|
if ($file == "." || $file == ".." || !is_dir($path . DIRECTORY_SEPARATOR . $file)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$themes[] = Yii::createObject(ArrayHelper::merge([
|
||||||
|
'class' => 'humhub\components\Theme',
|
||||||
|
'basePath' => $path . DIRECTORY_SEPARATOR . $file,
|
||||||
|
'name' => $file
|
||||||
|
], $additionalOptions));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $themes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a Theme by given name
|
||||||
|
*
|
||||||
|
* @param string $name of the theme
|
||||||
|
* @return Theme
|
||||||
|
*/
|
||||||
|
public static function getThemeByName($name)
|
||||||
|
{
|
||||||
|
foreach (self::getThemes() as $theme) {
|
||||||
|
if ($theme->name === $name) {
|
||||||
|
return $theme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns configuration array of given theme
|
||||||
|
*
|
||||||
|
* @param Theme|string $theme name or theme instance
|
||||||
|
* @return array Configuration
|
||||||
|
*/
|
||||||
|
public static function getThemeConfig($theme)
|
||||||
|
{
|
||||||
|
if (is_string($theme)) {
|
||||||
|
$theme = self::getThemeByName($theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($theme === null) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$theme->beforeActivate();
|
||||||
|
|
||||||
|
return [
|
||||||
|
'components' => [
|
||||||
|
'view' => [
|
||||||
|
'theme' => [
|
||||||
|
'name' => $theme->name,
|
||||||
|
'basePath' => $theme->getBasePath(),
|
||||||
|
'publishResources' => $theme->publishResources,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'mailer' => [
|
||||||
|
'view' => [
|
||||||
|
'theme' => [
|
||||||
|
'name' => $theme->name,
|
||||||
|
'basePath' => $theme->getBasePath(),
|
||||||
|
'publishResources' => $theme->publishResources,
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
158
protected/humhub/libs/Viewable.php
Normal file
158
protected/humhub/libs/Viewable.php
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2016 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\libs;
|
||||||
|
|
||||||
|
use Yii;
|
||||||
|
use yii\base\Component;
|
||||||
|
use yii\base\ViewContextInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Viewable provides view rendering support including layout and different
|
||||||
|
* output formats (e.g. text, web or mail=.
|
||||||
|
*
|
||||||
|
* @since 1.1
|
||||||
|
* @author Luke
|
||||||
|
*/
|
||||||
|
abstract class Viewable extends Component implements ViewContextInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
const OUTPUT_WEB = 'web';
|
||||||
|
const OUTPUT_MAIL = 'mail';
|
||||||
|
const OUTPUT_MAIL_PLAINTEXT = 'mail_plaintext';
|
||||||
|
const OUTPUT_TEXT = 'text';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the view, used for rendering the event
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $viewName = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* View path
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $viewPath = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Layout file for web version
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $layoutWeb;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Layout file for mail version
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $layoutMail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Layout file for mail plaintext version
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $layoutMailPlaintext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assambles all parameter required for rendering the view.
|
||||||
|
*
|
||||||
|
* @return array all view parameter
|
||||||
|
*/
|
||||||
|
protected function getViewParams($params = [])
|
||||||
|
{
|
||||||
|
$params['originator'] = $this->originator;
|
||||||
|
$params['source'] = $this->source;
|
||||||
|
$params['contentContainer'] = $this->container;
|
||||||
|
$params['record'] = $this->record;
|
||||||
|
$params['url'] = $this->getUrl();
|
||||||
|
|
||||||
|
return $params;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the notification
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function render($mode = self::OUTPUT_WEB, $params = [])
|
||||||
|
{
|
||||||
|
$viewFile = $this->getViewFile($mode);
|
||||||
|
$viewParams = $this->getViewParams($params);
|
||||||
|
|
||||||
|
$result = Yii::$app->getView()->renderFile($viewFile, $viewParams, $this);
|
||||||
|
|
||||||
|
if ($mode == self::OUTPUT_TEXT) {
|
||||||
|
return strip_tags($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
$viewParams['content'] = $result;
|
||||||
|
return Yii::$app->getView()->renderFile($this->getLayoutFile($mode), $viewParams, $this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the correct view file
|
||||||
|
*
|
||||||
|
* @param string $mode the output mode
|
||||||
|
* @return string the view file
|
||||||
|
*/
|
||||||
|
protected function getViewFile($mode)
|
||||||
|
{
|
||||||
|
$viewFile = $this->getViewPath() . '/' . $this->viewName . '.php';
|
||||||
|
$alternativeViewFile = "";
|
||||||
|
|
||||||
|
// Lookup alternative view file based on view mode
|
||||||
|
if ($mode == self::OUTPUT_MAIL) {
|
||||||
|
$alternativeViewFile = $this->getViewPath() . '/mail/' . $this->viewName . '.php';
|
||||||
|
} elseif ($mode === self::OUTPUT_MAIL_PLAINTEXT) {
|
||||||
|
$alternativeViewFile = $this->getViewPath() . '/mail/plaintext/' . $this->viewName . '.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($alternativeViewFile != "" && file_exists($alternativeViewFile)) {
|
||||||
|
$viewFile = $alternativeViewFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $viewFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the layout file
|
||||||
|
*
|
||||||
|
* @param string $mode the output mode
|
||||||
|
* @return string the layout file
|
||||||
|
*/
|
||||||
|
protected function getLayoutFile($mode)
|
||||||
|
{
|
||||||
|
if ($mode == self::OUTPUT_MAIL_PLAINTEXT) {
|
||||||
|
return $this->layoutMailPlaintext;
|
||||||
|
} elseif ($mode == self::OUTPUT_MAIL) {
|
||||||
|
return $this->layoutMail;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->layoutWeb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the directory containing the view files for this event.
|
||||||
|
* The default implementation returns the 'views' subdirectory under the directory containing the notification class file.
|
||||||
|
* @return string the directory containing the view files for this notification.
|
||||||
|
*/
|
||||||
|
public function getViewPath()
|
||||||
|
{
|
||||||
|
if ($this->viewPath !== null) {
|
||||||
|
return Yii::getAlias($this->viewPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
$class = new \ReflectionClass($this);
|
||||||
|
return dirname($class->getFileName()) . DIRECTORY_SEPARATOR . 'views';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,56 +1,37 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
return array (
|
||||||
* Message translations.
|
'<strong>Latest</strong> updates' => '<strong>Zagueras</strong> actividatz',
|
||||||
*
|
'Account settings' => 'Achustes d\'a cuenta',
|
||||||
* This file is automatically generated by 'yii message' command.
|
'Administration' => 'Administración',
|
||||||
* It contains the localizable messages extracted from source code.
|
'Allow' => '',
|
||||||
* You may modify this file by translating the extracted messages.
|
'Back' => '',
|
||||||
*
|
'Back to dashboard' => 'Tornar a Encieto',
|
||||||
* Each array element represents the translation (value) of a message (key).
|
'Choose language:' => '',
|
||||||
* If the value is empty, the message is considered as not translated.
|
'Collapse' => 'Zarrar',
|
||||||
* Messages that no longer need translation will have their translations
|
'Content Addon source must be instance of HActiveRecordContent or HActiveRecordContentAddon!' => '',
|
||||||
* enclosed between a pair of '@@' marks.
|
'Could not determine content container!' => '',
|
||||||
*
|
'Could not find content of addon!' => '',
|
||||||
* Message string can be used with plural forms format. Check i18n section
|
'Default' => '',
|
||||||
* of the guide for details.
|
'Deny' => '',
|
||||||
*
|
'Error' => 'Error',
|
||||||
* NOTE: this file must be saved in UTF-8 encoding.
|
'Expand' => 'Esbandir',
|
||||||
*/
|
'It looks like you may have taken the wrong turn.' => 'Pareixe que has tomau o camín incorrecto.',
|
||||||
return [
|
'Language' => '',
|
||||||
'Allow' => '',
|
'Latest news' => 'Zagueras noticias',
|
||||||
'Back' => '',
|
'Login' => '',
|
||||||
'Choose language:' => '',
|
'Logout' => 'Zarrar sesión',
|
||||||
'Content Addon source must be instance of HActiveRecordContent or HActiveRecordContentAddon!' => '',
|
'Menu' => 'Menú',
|
||||||
'Could not determine content container!' => '',
|
'Module is not on this content container enabled!' => '',
|
||||||
'Could not find content of addon!' => '',
|
'My profile' => 'O mío perfil',
|
||||||
'Default' => '',
|
'New profile image' => 'Nueva imachen de perfil',
|
||||||
'Deny' => '',
|
'Next' => '',
|
||||||
'Language' => '',
|
'Ok' => '',
|
||||||
'Login' => '',
|
'Oooops...' => 'Oooops...',
|
||||||
'Module is not on this content container enabled!' => '',
|
'Please type at least 3 characters' => '',
|
||||||
'Next' => '',
|
'Save' => 'Uložit',
|
||||||
'Please type at least 3 characters' => '',
|
'Search' => 'Buscar',
|
||||||
'Save' => '',
|
'Search for users and spaces' => 'Buscar usuarios y espacios',
|
||||||
'<strong>Latest</strong> updates' => '<strong>Zagueras</strong> actividatz',
|
'Space not found!' => 'Espacio no trobau!',
|
||||||
'Account settings' => 'Achustes d\'a cuenta',
|
'User not found!' => 'Usuario no trobau!',
|
||||||
'Administration' => 'Administración',
|
'Your daily summary' => 'Resumen diario',
|
||||||
'Back to dashboard' => 'Tornar a Encieto',
|
);
|
||||||
'Collapse' => 'Zarrar',
|
|
||||||
'Error' => 'Error',
|
|
||||||
'Expand' => 'Esbandir',
|
|
||||||
'Insufficent permissions to create content!' => 'Premisos insuficients ta creyar una cuenta!',
|
|
||||||
'It looks like you may have taken the wrong turn.' => 'Pareixe que has tomau o camín incorrecto.',
|
|
||||||
'Latest news' => 'Zagueras noticias',
|
|
||||||
'Logout' => 'Zarrar sesión',
|
|
||||||
'Menu' => 'Menú',
|
|
||||||
'My profile' => 'O mío perfil',
|
|
||||||
'New profile image' => 'Nueva imachen de perfil',
|
|
||||||
'Oooops...' => 'Oooops...',
|
|
||||||
'Search' => 'Buscar',
|
|
||||||
'Search for users and spaces' => 'Buscar usuarios y espacios',
|
|
||||||
'Space not found!' => 'Espacio no trobau!',
|
|
||||||
'User Approvals' => 'Aprobacions d\'usuario',
|
|
||||||
'User not found!' => 'Usuario no trobau!',
|
|
||||||
'You cannot create public visible content!' => 'No puetz creyar conteniu publico visible!',
|
|
||||||
'Your daily summary' => 'Resumen diario',
|
|
||||||
];
|
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Message translations.
|
|
||||||
*
|
|
||||||
* This file is automatically generated by 'yiic message' command.
|
|
||||||
* It contains the localizable messages extracted from source code.
|
|
||||||
* You may modify this file by translating the extracted messages.
|
|
||||||
*
|
|
||||||
* Each array element represents the translation (value) of a message (key).
|
|
||||||
* If the value is empty, the message is considered as not translated.
|
|
||||||
* Messages that no longer need translation will have their translations
|
|
||||||
* enclosed between a pair of '@@' marks.
|
|
||||||
*
|
|
||||||
* Message string can be used with plural forms format. Check i18n section
|
|
||||||
* of the guide for details.
|
|
||||||
*
|
|
||||||
* NOTE, this file must be saved in UTF-8 encoding.
|
|
||||||
*/
|
|
||||||
return array (
|
|
||||||
'Global {global} array cleaned using {method} method.' => '',
|
|
||||||
);
|
|
File diff suppressed because one or more lines are too long
@ -1,56 +1,37 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
return array (
|
||||||
* Message translations.
|
'<strong>Latest</strong> updates' => '<strong>آخر</strong> التحديثات',
|
||||||
*
|
'Account settings' => 'إعدادات الحساب',
|
||||||
* This file is automatically generated by 'yii message' command.
|
'Administration' => 'الإدارة',
|
||||||
* It contains the localizable messages extracted from source code.
|
'Allow' => '',
|
||||||
* You may modify this file by translating the extracted messages.
|
'Back' => 'عودة',
|
||||||
*
|
'Back to dashboard' => 'عودة لسطح المكتب',
|
||||||
* Each array element represents the translation (value) of a message (key).
|
'Choose language:' => 'خيارات اللغه:',
|
||||||
* If the value is empty, the message is considered as not translated.
|
'Collapse' => 'إغلاق',
|
||||||
* Messages that no longer need translation will have their translations
|
'Content Addon source must be instance of HActiveRecordContent or HActiveRecordContentAddon!' => '@Content Addon source must be instance of HActiveRecordContent or HActiveRecordContentAddon!@',
|
||||||
* enclosed between a pair of '@@' marks.
|
'Could not determine content container!' => 'لم يمكن تحديد content container!',
|
||||||
*
|
'Could not find content of addon!' => 'لم يمكن ايجاد محتويات الإضافة',
|
||||||
* Message string can be used with plural forms format. Check i18n section
|
'Default' => '',
|
||||||
* of the guide for details.
|
'Deny' => '',
|
||||||
*
|
'Error' => 'خطأ',
|
||||||
* NOTE: this file must be saved in UTF-8 encoding.
|
'Expand' => 'توسعة',
|
||||||
*/
|
'It looks like you may have taken the wrong turn.' => 'يبدو انك أتيت للصفحة الخطأ',
|
||||||
return [
|
'Language' => 'اللغة',
|
||||||
'Allow' => '',
|
'Latest news' => 'آخر الأخبار',
|
||||||
'Default' => '',
|
'Login' => 'تسجيل الدخول',
|
||||||
'Deny' => '',
|
'Logout' => 'تسجيل الخروج',
|
||||||
'Next' => '',
|
'Menu' => 'القائمة',
|
||||||
'Please type at least 3 characters' => '',
|
'Module is not on this content container enabled!' => 'الموديل ليس متاحاً في هذه الخانة',
|
||||||
'Save' => '',
|
'My profile' => 'صفحتي الشخصية',
|
||||||
'<strong>Latest</strong> updates' => '<strong>آخر</strong> التحديثات',
|
'New profile image' => 'صورة شخصية جديدة',
|
||||||
'Account settings' => 'إعدادات الحساب',
|
'Next' => '',
|
||||||
'Administration' => 'الإدارة',
|
'Ok' => '',
|
||||||
'Back' => 'عودة',
|
'Oooops...' => 'يالهوي...',
|
||||||
'Back to dashboard' => 'عودة لسطح المكتب',
|
'Please type at least 3 characters' => '',
|
||||||
'Choose language:' => 'خيارات اللغه:',
|
'Save' => 'حفظ',
|
||||||
'Collapse' => 'إغلاق',
|
'Search' => 'بحث',
|
||||||
'Content Addon source must be instance of HActiveRecordContent or HActiveRecordContentAddon!' => '@Content Addon source must be instance of HActiveRecordContent or HActiveRecordContentAddon!@',
|
'Search for users and spaces' => 'البحث عن مستخدمين و باحات',
|
||||||
'Could not determine content container!' => 'لم يمكن تحديد content container!',
|
'Space not found!' => 'لم اتمكن من إيجاد الباحة!',
|
||||||
'Could not find content of addon!' => 'لم يمكن ايجاد محتويات الإضافة',
|
'User not found!' => 'لم يتم إيجاد العضو',
|
||||||
'Error' => 'خطأ',
|
'Your daily summary' => 'المختصر اليومي',
|
||||||
'Expand' => 'توسعة',
|
);
|
||||||
'Insufficent permissions to create content!' => 'لا توجد الصلاحية لكتابة محتويات',
|
|
||||||
'It looks like you may have taken the wrong turn.' => 'يبدو انك أتيت للصفحة الخطأ',
|
|
||||||
'Language' => 'اللغة',
|
|
||||||
'Latest news' => 'آخر الأخبار',
|
|
||||||
'Login' => 'تسجيل الدخول',
|
|
||||||
'Logout' => 'تسجيل الخروج',
|
|
||||||
'Menu' => 'القائمة',
|
|
||||||
'Module is not on this content container enabled!' => 'الموديل ليس متاحاً في هذه الخانة',
|
|
||||||
'My profile' => 'صفحتي الشخصية',
|
|
||||||
'New profile image' => 'صورة شخصية جديدة',
|
|
||||||
'Oooops...' => 'يالهوي...',
|
|
||||||
'Search' => 'بحث',
|
|
||||||
'Search for users and spaces' => 'البحث عن مستخدمين و باحات',
|
|
||||||
'Space not found!' => 'لم اتمكن من إيجاد الباحة!',
|
|
||||||
'User Approvals' => 'موافقات الأعضاء',
|
|
||||||
'User not found!' => 'لم يتم إيجاد العضو',
|
|
||||||
'You cannot create public visible content!' => 'ليس مسموحاً لك كتابة مواضيع للنشر العام!',
|
|
||||||
'Your daily summary' => 'المختصر اليومي',
|
|
||||||
];
|
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
<?php
|
|
||||||
return array (
|
|
||||||
'Global {global} array cleaned using {method} method.' => '@Global {global} array cleaned using {method} method.@',
|
|
||||||
);
|
|
@ -1 +1 @@
|
|||||||
{"Invalid request.":["Грешна заявка."],"Results":["Резултати"],"Show more results":["Покажи още резултати"],"Sorry, nothing found!":["Нищо не е намерено!"],"Welcome to %appName%":["Добре дошли в %appName%"],"<strong>Latest</strong> updates":["<strong>Последни</strong> ъпдейти"],"Account settings":["Настройки на акаунта"],"Administration":["Администрация"],"Back":["Назад"],"Back to dashboard":["Върни се в работното място"],"Choose language:":["Избери език:"],"Collapse":["Свий"],"Error":["Грешка"],"Expand":["Разшири"],"Language":["Език"],"Latest news":["Последни новини"],"Login":["Вход"],"Logout":["Изход"],"Menu":["Меню"],"My profile":["Моят Профил"],"New profile image":["Нова профилна картинка"],"Oooops...":["Опаля..."],"Search":["Търси"],"Search for users and spaces":["Търси хора и зони"],"Space not found!":["Зоната не е открита!"],"User not found!":["Потребителя не е намерен!","Потребителят не е намерен!"],"Access denied!":["Достъп отказан!"],"Visible for all":["Видима за всички"]," Invite and request":["Покани и заявки"],"Everyone can enter":["Всеки може да се присъедини"],"Invite and request":["Покани и заявки"],"Only by invite":["Само при покана"],"Private (Invisible)":["Лична зона (Невидима)"],"End guide":["Край на урока"],"Next »":["Напред »"],"« Prev":["« Назад"],"<strong>Hurray!</strong> That's all for now.":["<strong>¡Bien!</strong> Eso es todo por ahora."],"<strong>Dashboard</strong>":["<strong>Inicio</strong>"],"This is your dashboard.<br><br>Any new activities or posts that might interest you will be displayed here.":["Este es tu inicio.<br><br>Todas las nuevas actividades serán mostradas aquí."],"<strong>Edit</strong> account":["<strong>Editar</strong> cuenta"],"<strong>Hurray!</strong> The End.":["<strong>¡Bien!</strong> Has acabado."],"<strong>Hurray!</strong> You're done!":["<strong>¡Bien!</strong> ya está!"],"<strong>Profile</strong> menu":["Menú de <strong>perfil</strong>"],"<strong>Profile</strong> photo":["Fotos de <strong>perfil</strong>"],"<strong>Profile</strong> stream":["Actividad del <strong>perfil</strong> "],"<strong>User profile</strong>":["<strong>Perfil de usuario</strong>"],"Click on this button to update your profile and account settings. You can also add more information to your profile.":["Haz click en este botón para actualizar tu perfil y los ajustes de cuenta. También puedes añadir más información a tu perfil."],"Each profile has its own pin board. Your posts will also appear on the dashboards of those users who are following you.":["Cada perfil tiene su muro. Tus entradas también aparecerán en el Inicio de los usuarios que te sigan."],"Just like in the space, the user profile can be personalized with various modules.<br><br>You can see which modules are available for your profile by looking them in “Modules” in the account settings menu.":["Como en un espacio, los perfiles de usuarios pueden ser personalizados con varios módulos. <br><br>Puedes ver qué módulos están disponibles para tu perfil buscándolos en \"Módulos\" en el menú Ajustes de cuenta."],"This is your public user profile, which can be seen by any registered user.":["Este es tu perfil de usuario público, que será visible por cualquier usuario registrado."],"Upload a new profile photo by simply clicking here or by drag&drop. Do just the same for updating your cover photo.":["Sube una nueva foto haciendo click aquí o simplemente arrástrala. Haz lo mismo para actualizar tu imagen de cabecera."],"You've completed the user profile guide!":["¡Has completado la guía de los perfiles de usuario!"],"This user account is not approved yet!":["Потребителският профил не е потвърден!"],"You need to login to view this user profile!":["Трябва да си логнат за да гледаш този профил!"],"Back to modules":["Върни се при модулите"],"Cancel":["Отказ"],"Delete":["Изтрий"],"Delete category":["Изтрий категория"],"Delete link":["Изтрий линк"],"Link":["Линк"],"Linklist":["Линк списак"],"Save":["Запази"],"Messages":["Съобщения"],"No users.":["Няма потребители"],"Get a list":["Вземи списак"],"Notes":["Бележки"],"Polls":["Анкети"],"by :displayName":["от :displayName"],"Tasks":["Задачи"],"Translation Manager":["Мениджър за преводи"],"Translations":["Преводи"]}
|
{"Invalid request.":["Грешна заявка."],"Results":["Резултати"],"Show more results":["Покажи още резултати"],"Sorry, nothing found!":["Нищо не е намерено!"],"Welcome to %appName%":["Добре дошли в %appName%"],"<strong>Latest</strong> updates":["<strong>Последни</strong> ъпдейти"],"Account settings":["Настройки на акаунта"],"Administration":["Администрация"],"Back":["Назад"],"Back to dashboard":["Върни се в работното място"],"Choose language:":["Избери език:"],"Collapse":["Свий"],"Error":["Грешка"],"Expand":["Разшири"],"Language":["Език"],"Latest news":["Последни новини"],"Login":["Вход"],"Logout":["Изход"],"Menu":["Меню"],"My profile":["Моят Профил"],"New profile image":["Нова профилна картинка"],"Oooops...":["Опаля..."],"Search":["Търси"],"Search for users and spaces":["Търси хора и зони"],"Space not found!":["Зоната не е открита!"],"User not found!":["Потребителят не е намерен!"],"Access denied!":["Достъп отказан!"],"Visible for all":["Видима за всички"]," Invite and request":["Покани и заявки"],"Everyone can enter":["Всеки може да се присъедини"],"Invite and request":["Покани и заявки"],"Only by invite":["Само при покана"],"Private (Invisible)":["Лична зона (Невидима)"],"End guide":["Край на урока"],"Next »":["Напред »"],"« Prev":["« Назад"],"<strong>Hurray!</strong> That's all for now.":["<strong>¡Bien!</strong> Eso es todo por ahora."],"<strong>Dashboard</strong>":["<strong>Inicio</strong>"],"This is your dashboard.<br><br>Any new activities or posts that might interest you will be displayed here.":["Este es tu inicio.<br><br>Todas las nuevas actividades serán mostradas aquí."],"<strong>Edit</strong> account":["<strong>Editar</strong> cuenta"],"<strong>Hurray!</strong> The End.":["<strong>¡Bien!</strong> Has acabado."],"<strong>Hurray!</strong> You're done!":["<strong>¡Bien!</strong> ya está!"],"<strong>Profile</strong> menu":["Menú de <strong>perfil</strong>"],"<strong>Profile</strong> photo":["Fotos de <strong>perfil</strong>"],"<strong>Profile</strong> stream":["Actividad del <strong>perfil</strong> "],"<strong>User profile</strong>":["<strong>Perfil de usuario</strong>"],"Click on this button to update your profile and account settings. You can also add more information to your profile.":["Haz click en este botón para actualizar tu perfil y los ajustes de cuenta. También puedes añadir más información a tu perfil."],"Each profile has its own pin board. Your posts will also appear on the dashboards of those users who are following you.":["Cada perfil tiene su muro. Tus entradas también aparecerán en el Inicio de los usuarios que te sigan."],"Just like in the space, the user profile can be personalized with various modules.<br><br>You can see which modules are available for your profile by looking them in “Modules” in the account settings menu.":["Como en un espacio, los perfiles de usuarios pueden ser personalizados con varios módulos. <br><br>Puedes ver qué módulos están disponibles para tu perfil buscándolos en \"Módulos\" en el menú Ajustes de cuenta."],"This is your public user profile, which can be seen by any registered user.":["Este es tu perfil de usuario público, que será visible por cualquier usuario registrado."],"Upload a new profile photo by simply clicking here or by drag&drop. Do just the same for updating your cover photo.":["Sube una nueva foto haciendo click aquí o simplemente arrástrala. Haz lo mismo para actualizar tu imagen de cabecera."],"You've completed the user profile guide!":["¡Has completado la guía de los perfiles de usuario!"],"This user account is not approved yet!":["Потребителският профил не е потвърден!"],"You need to login to view this user profile!":["Трябва да си логнат за да гледаш този профил!"],"Back to modules":["Върни се при модулите"],"Cancel":["Отказ"],"Delete":["Изтрий"],"Delete category":["Изтрий категория"],"Delete link":["Изтрий линк"],"Link":["Линк"],"Linklist":["Линк списак"],"Save":["Запази"],"Messages":["Съобщения"],"No users.":["Няма потребители"],"Get a list":["Вземи списак"],"Notes":["Бележки"],"Polls":["Анкети"],"by :displayName":["от :displayName"],"Tasks":["Задачи"],"Translation Manager":["Мениджър за преводи"],"Translations":["Преводи"]}
|
@ -1,56 +1,37 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
return array (
|
||||||
* Message translations.
|
'<strong>Latest</strong> updates' => '<strong>Последни</strong> ъпдейти',
|
||||||
*
|
'Account settings' => 'Настройки на акаунта',
|
||||||
* This file is automatically generated by 'yii message' command.
|
'Administration' => 'Администрация',
|
||||||
* It contains the localizable messages extracted from source code.
|
'Allow' => '',
|
||||||
* You may modify this file by translating the extracted messages.
|
'Back' => 'Назад',
|
||||||
*
|
'Back to dashboard' => 'Върни се в работното място',
|
||||||
* Each array element represents the translation (value) of a message (key).
|
'Choose language:' => 'Избери език:',
|
||||||
* If the value is empty, the message is considered as not translated.
|
'Collapse' => 'Свий',
|
||||||
* Messages that no longer need translation will have their translations
|
'Content Addon source must be instance of HActiveRecordContent or HActiveRecordContentAddon!' => '',
|
||||||
* enclosed between a pair of '@@' marks.
|
'Could not determine content container!' => '',
|
||||||
*
|
'Could not find content of addon!' => '',
|
||||||
* Message string can be used with plural forms format. Check i18n section
|
'Default' => '',
|
||||||
* of the guide for details.
|
'Deny' => '',
|
||||||
*
|
'Error' => 'Грешка',
|
||||||
* NOTE: this file must be saved in UTF-8 encoding.
|
'Expand' => 'Разшири',
|
||||||
*/
|
'It looks like you may have taken the wrong turn.' => '',
|
||||||
return [
|
'Language' => 'Език',
|
||||||
'Allow' => '',
|
'Latest news' => 'Последни новини',
|
||||||
'Content Addon source must be instance of HActiveRecordContent or HActiveRecordContentAddon!' => '',
|
'Login' => 'Вход',
|
||||||
'Could not determine content container!' => '',
|
'Logout' => 'Изход',
|
||||||
'Could not find content of addon!' => '',
|
'Menu' => 'Меню',
|
||||||
'Default' => '',
|
'Module is not on this content container enabled!' => '',
|
||||||
'Deny' => '',
|
'My profile' => 'Моят Профил',
|
||||||
'Insufficent permissions to create content!' => '',
|
'New profile image' => 'Нова профилна картинка',
|
||||||
'It looks like you may have taken the wrong turn.' => '',
|
'Next' => '',
|
||||||
'Module is not on this content container enabled!' => '',
|
'Ok' => '',
|
||||||
'Next' => '',
|
'Oooops...' => 'Опаля...',
|
||||||
'Please type at least 3 characters' => '',
|
'Please type at least 3 characters' => '',
|
||||||
'Save' => '',
|
'Save' => 'Запази',
|
||||||
'User Approvals' => '',
|
'Search' => 'Търси',
|
||||||
'You cannot create public visible content!' => '',
|
'Search for users and spaces' => 'Търси хора и зони',
|
||||||
'Your daily summary' => '',
|
'Space not found!' => 'Зоната не е открита!',
|
||||||
'<strong>Latest</strong> updates' => '<strong>Последни</strong> ъпдейти',
|
'User not found!' => 'Потребителя не е намерен!',
|
||||||
'Account settings' => 'Настройки на акаунта',
|
'Your daily summary' => '',
|
||||||
'Administration' => 'Администрация',
|
);
|
||||||
'Back' => 'Назад',
|
|
||||||
'Back to dashboard' => 'Върни се в работното място',
|
|
||||||
'Choose language:' => 'Избери език:',
|
|
||||||
'Collapse' => 'Свий',
|
|
||||||
'Error' => 'Грешка',
|
|
||||||
'Expand' => 'Разшири',
|
|
||||||
'Language' => 'Език',
|
|
||||||
'Latest news' => 'Последни новини',
|
|
||||||
'Login' => 'Вход',
|
|
||||||
'Logout' => 'Изход',
|
|
||||||
'Menu' => 'Меню',
|
|
||||||
'My profile' => 'Моят Профил',
|
|
||||||
'New profile image' => 'Нова профилна картинка',
|
|
||||||
'Oooops...' => 'Опаля...',
|
|
||||||
'Search' => 'Търси',
|
|
||||||
'Search for users and spaces' => 'Търси хора и зони',
|
|
||||||
'Space not found!' => 'Зоната не е открита!',
|
|
||||||
'User not found!' => 'Потребителя не е намерен!',
|
|
||||||
];
|
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Message translations.
|
|
||||||
*
|
|
||||||
* This file is automatically generated by 'yiic message' command.
|
|
||||||
* It contains the localizable messages extracted from source code.
|
|
||||||
* You may modify this file by translating the extracted messages.
|
|
||||||
*
|
|
||||||
* Each array element represents the translation (value) of a message (key).
|
|
||||||
* If the value is empty, the message is considered as not translated.
|
|
||||||
* Messages that no longer need translation will have their translations
|
|
||||||
* enclosed between a pair of '@@' marks.
|
|
||||||
*
|
|
||||||
* Message string can be used with plural forms format. Check i18n section
|
|
||||||
* of the guide for details.
|
|
||||||
*
|
|
||||||
* NOTE, this file must be saved in UTF-8 encoding.
|
|
||||||
*/
|
|
||||||
return array (
|
|
||||||
'Global {global} array cleaned using {method} method.' => '',
|
|
||||||
);
|
|
File diff suppressed because one or more lines are too long
@ -1,56 +1,37 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
return array (
|
||||||
* Message translations.
|
'<strong>Latest</strong> updates' => '<strong>Últimes</strong> actualitzacions',
|
||||||
*
|
'Account settings' => 'Configuració del compte',
|
||||||
* This file is automatically generated by 'yii message' command.
|
'Administration' => 'Administració',
|
||||||
* It contains the localizable messages extracted from source code.
|
'Allow' => '',
|
||||||
* You may modify this file by translating the extracted messages.
|
'Back' => 'Enrere',
|
||||||
*
|
'Back to dashboard' => 'Torna a la portada',
|
||||||
* Each array element represents the translation (value) of a message (key).
|
'Choose language:' => 'Escull un idioma:',
|
||||||
* If the value is empty, the message is considered as not translated.
|
'Collapse' => 'Redueix',
|
||||||
* Messages that no longer need translation will have their translations
|
'Content Addon source must be instance of HActiveRecordContent or HActiveRecordContentAddon!' => '',
|
||||||
* enclosed between a pair of '@@' marks.
|
'Could not determine content container!' => '',
|
||||||
*
|
'Could not find content of addon!' => '',
|
||||||
* Message string can be used with plural forms format. Check i18n section
|
'Default' => '',
|
||||||
* of the guide for details.
|
'Deny' => '',
|
||||||
*
|
'Error' => 'Error',
|
||||||
* NOTE: this file must be saved in UTF-8 encoding.
|
'Expand' => 'Amplia',
|
||||||
*/
|
'It looks like you may have taken the wrong turn.' => '',
|
||||||
return [
|
'Language' => 'Llengua',
|
||||||
'Allow' => '',
|
'Latest news' => 'Últimes notícies',
|
||||||
'Content Addon source must be instance of HActiveRecordContent or HActiveRecordContentAddon!' => '',
|
'Login' => 'Inici de sessió',
|
||||||
'Could not determine content container!' => '',
|
'Logout' => 'Sortir',
|
||||||
'Could not find content of addon!' => '',
|
'Menu' => 'Menú',
|
||||||
'Default' => '',
|
'Module is not on this content container enabled!' => '',
|
||||||
'Deny' => '',
|
'My profile' => 'El meu perfil',
|
||||||
'It looks like you may have taken the wrong turn.' => '',
|
'New profile image' => 'Nova imatge de perfil',
|
||||||
'Module is not on this content container enabled!' => '',
|
'Next' => 'Següent',
|
||||||
'Next' => '',
|
'Ok' => 'D\'acord',
|
||||||
'Please type at least 3 characters' => '',
|
'Oooops...' => 'Oooops...',
|
||||||
'Save' => '',
|
'Please type at least 3 characters' => '',
|
||||||
'<strong>Latest</strong> updates' => '<strong>Últimes</strong> actualitzacions',
|
'Save' => 'Desa',
|
||||||
'Account settings' => 'Configuració del compte',
|
'Search' => 'Cerca',
|
||||||
'Administration' => 'Administració',
|
'Search for users and spaces' => 'Cerca per membres i espais',
|
||||||
'Back' => 'Enrere',
|
'Space not found!' => 'Espai no trobat!',
|
||||||
'Back to dashboard' => 'Torna a la portada',
|
'User not found!' => 'Membre no trobat!',
|
||||||
'Choose language:' => 'Escull un idioma:',
|
'Your daily summary' => 'El teu resum diari',
|
||||||
'Collapse' => 'Redueix',
|
);
|
||||||
'Error' => 'Error',
|
|
||||||
'Expand' => 'Amplia',
|
|
||||||
'Insufficent permissions to create content!' => 'Permisos insuficients per crear contingut!',
|
|
||||||
'Language' => 'Llengua',
|
|
||||||
'Latest news' => 'Últimes notícies',
|
|
||||||
'Login' => 'Inici de sessió',
|
|
||||||
'Logout' => 'Sortir',
|
|
||||||
'Menu' => 'Menú',
|
|
||||||
'My profile' => 'El meu perfil',
|
|
||||||
'New profile image' => 'Nova imatge de perfil',
|
|
||||||
'Oooops...' => 'Oooops...',
|
|
||||||
'Search' => 'Cerca',
|
|
||||||
'Search for users and spaces' => 'Cerca per membres i espais',
|
|
||||||
'Space not found!' => 'Espai no trobat!',
|
|
||||||
'User Approvals' => 'Aprovacions de membres',
|
|
||||||
'User not found!' => 'Membre no trobat!',
|
|
||||||
'You cannot create public visible content!' => 'No pots crear contingut públic visible!',
|
|
||||||
'Your daily summary' => 'El teu resum diari',
|
|
||||||
];
|
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
<?php
|
|
||||||
return array (
|
|
||||||
'Global {global} array cleaned using {method} method.' => 'S\'ha netejat la cadena {global} utilitzant el mètode {method}.',
|
|
||||||
);
|
|
File diff suppressed because one or more lines are too long
@ -1,56 +1,37 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
return array (
|
||||||
* Message translations.
|
'<strong>Latest</strong> updates' => '<strong>Poslední</strong> události',
|
||||||
*
|
'Account settings' => 'Nastavení účtu',
|
||||||
* This file is automatically generated by 'yii message' command.
|
'Administration' => 'Administrace',
|
||||||
* It contains the localizable messages extracted from source code.
|
'Allow' => 'Povolit',
|
||||||
* You may modify this file by translating the extracted messages.
|
'Back' => 'Zpět',
|
||||||
*
|
'Back to dashboard' => 'Zpět na nástěnku',
|
||||||
* Each array element represents the translation (value) of a message (key).
|
'Choose language:' => 'Vyberte jazyk:',
|
||||||
* If the value is empty, the message is considered as not translated.
|
'Collapse' => 'Sbalit',
|
||||||
* Messages that no longer need translation will have their translations
|
'Content Addon source must be instance of HActiveRecordContent or HActiveRecordContentAddon!' => 'Content Addon musí být buď instancí objektu HActiveRecordContent nebo HActiveRecordContentAddon!',
|
||||||
* enclosed between a pair of '@@' marks.
|
'Could not determine content container!' => 'Obsah nenalezen!',
|
||||||
*
|
'Could not find content of addon!' => 'Nebylo možné nalézt obsah dolpňku!',
|
||||||
* Message string can be used with plural forms format. Check i18n section
|
'Default' => 'Výchozí',
|
||||||
* of the guide for details.
|
'Deny' => 'Odmítnout',
|
||||||
*
|
'Error' => 'Chyba',
|
||||||
* NOTE: this file must be saved in UTF-8 encoding.
|
'Expand' => 'Rozbalit',
|
||||||
*/
|
'It looks like you may have taken the wrong turn.' => 'Zdá se, že jste někde špatně odbočili.',
|
||||||
return [
|
'Language' => 'Jazyk',
|
||||||
'<strong>Latest</strong> updates' => '<strong>Poslední</strong> události',
|
'Latest news' => 'Poslední události',
|
||||||
'Account settings' => 'Nastavení účtu',
|
'Login' => 'Přihlásit se',
|
||||||
'Administration' => 'Administrace',
|
'Logout' => 'Odhlásit',
|
||||||
'Allow' => 'Povolit',
|
'Menu' => 'Menu',
|
||||||
'Back' => 'Zpět',
|
'Module is not on this content container enabled!' => 'Modul nebyl nalezen nebo je vypnut!',
|
||||||
'Back to dashboard' => 'Zpět na nástěnku',
|
'My profile' => 'Můj profil',
|
||||||
'Choose language:' => 'Vyberte jazyk:',
|
'New profile image' => 'Nový profilový obrázek',
|
||||||
'Collapse' => 'Sbalit',
|
'Next' => 'Další',
|
||||||
'Content Addon source must be instance of HActiveRecordContent or HActiveRecordContentAddon!' => 'Content Addon musí být buď instancí objektu HActiveRecordContent nebo HActiveRecordContentAddon!',
|
'Ok' => 'Ok',
|
||||||
'Could not determine content container!' => 'Obsah nenalezen!',
|
'Oooops...' => 'Jejda...',
|
||||||
'Could not find content of addon!' => 'Nebylo možné nalézt obsah dolpňku!',
|
'Please type at least 3 characters' => 'Napište prosím alespoň 3 znaky',
|
||||||
'Default' => 'Výchozí',
|
'Save' => 'Uložit',
|
||||||
'Deny' => 'Odmítnout',
|
'Search' => 'Hledat',
|
||||||
'Error' => 'Chyba',
|
'Search for users and spaces' => 'Hledat mezi uživateli a prostory',
|
||||||
'Expand' => 'Rozbalit',
|
'Space not found!' => 'Prostor nebyl nalezen!',
|
||||||
'Insufficent permissions to create content!' => 'Nedostatečná práva pro vytvoření obsahu!',
|
'User not found!' => 'Uživatel nebyl nalezen!',
|
||||||
'It looks like you may have taken the wrong turn.' => 'Zdá se, že jste někde špatně odbočili.',
|
'Your daily summary' => 'Vaše denní shrnutí',
|
||||||
'Language' => 'Jazyk',
|
);
|
||||||
'Latest news' => 'Poslední události',
|
|
||||||
'Login' => 'Přihlásit se',
|
|
||||||
'Logout' => 'Odhlásit',
|
|
||||||
'Menu' => 'Menu',
|
|
||||||
'Module is not on this content container enabled!' => 'Modul nebyl nalezen nebo je vypnut!',
|
|
||||||
'My profile' => 'Můj profil',
|
|
||||||
'New profile image' => 'Nový profilový obrázek',
|
|
||||||
'Next' => 'Další',
|
|
||||||
'Oooops...' => 'Jejda...',
|
|
||||||
'Please type at least 3 characters' => 'Napište prosím alespoň 3 znaky',
|
|
||||||
'Save' => 'Uložit',
|
|
||||||
'Search' => 'Hledat',
|
|
||||||
'Search for users and spaces' => 'Hledat mezi uživateli a prostory',
|
|
||||||
'Space not found!' => 'Prostor nebyl nalezen!',
|
|
||||||
'User Approvals' => 'Uživatelská oprávnění',
|
|
||||||
'User not found!' => 'Uživatel nebyl nalezen!',
|
|
||||||
'You cannot create public visible content!' => 'Nemůžete vytvářet veřejně viditelný obsah!',
|
|
||||||
'Your daily summary' => 'Vaše denní shrnutí',
|
|
||||||
];
|
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
<?php
|
|
||||||
return array (
|
|
||||||
'Global {global} array cleaned using {method} method.' => 'Globální pole {global} bylo vyčištěno pomocí metody {method}.',
|
|
||||||
);
|
|
File diff suppressed because one or more lines are too long
@ -1,56 +1,37 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
return array (
|
||||||
* Message translations.
|
'<strong>Latest</strong> updates' => '<strong>Nyeste</ strong> opdateringer',
|
||||||
*
|
'Account settings' => 'Kontoindstillinger',
|
||||||
* This file is automatically generated by 'yii message' command.
|
'Administration' => 'Administration',
|
||||||
* It contains the localizable messages extracted from source code.
|
'Allow' => 'Tillad',
|
||||||
* You may modify this file by translating the extracted messages.
|
'Back' => 'Tilbage',
|
||||||
*
|
'Back to dashboard' => 'Tilbage til dashboard',
|
||||||
* Each array element represents the translation (value) of a message (key).
|
'Choose language:' => 'Vælg sprog:',
|
||||||
* If the value is empty, the message is considered as not translated.
|
'Collapse' => 'Kollaps',
|
||||||
* Messages that no longer need translation will have their translations
|
'Content Addon source must be instance of HActiveRecordContent or HActiveRecordContentAddon!' => 'Indholdskilde addon skal være del en af HActiveRecordContent eller HActiveRecordContentAddon!',
|
||||||
* enclosed between a pair of '@@' marks.
|
'Could not determine content container!' => 'Kunne ikke fastslå indholdscontainer!',
|
||||||
*
|
'Could not find content of addon!' => 'Kunne ikke finde addonindhold!',
|
||||||
* Message string can be used with plural forms format. Check i18n section
|
'Default' => 'Standard',
|
||||||
* of the guide for details.
|
'Deny' => 'Afslå',
|
||||||
*
|
'Error' => 'Fejl',
|
||||||
* NOTE: this file must be saved in UTF-8 encoding.
|
'Expand' => 'Udvid',
|
||||||
*/
|
'It looks like you may have taken the wrong turn.' => 'Det ser ud som du måske har taget den forkerte drejning.',
|
||||||
return [
|
'Language' => 'Sprog',
|
||||||
'<strong>Latest</strong> updates' => '<strong>Nyeste</ strong> opdateringer',
|
'Latest news' => 'Sidste nyt',
|
||||||
'Account settings' => 'Kontoindstillinger',
|
'Login' => 'Log ind',
|
||||||
'Administration' => 'Administration',
|
'Logout' => 'Log ud',
|
||||||
'Allow' => 'Tillad',
|
'Menu' => 'Menu',
|
||||||
'Back' => 'Tilbage',
|
'Module is not on this content container enabled!' => 'Modulet er ikke aktiveret i denne indholdscontainer!',
|
||||||
'Back to dashboard' => 'Tilbage til dashboard',
|
'My profile' => 'Min profil',
|
||||||
'Choose language:' => 'Vælg sprog:',
|
'New profile image' => 'Nyt profilbillede',
|
||||||
'Collapse' => 'Kollaps',
|
'Next' => 'Næste',
|
||||||
'Content Addon source must be instance of HActiveRecordContent or HActiveRecordContentAddon!' => 'Indholdskilde addon skal være del en af HActiveRecordContent eller HActiveRecordContentAddon!',
|
'Ok' => 'Ok',
|
||||||
'Could not determine content container!' => 'Kunne ikke fastslå indholdscontainer!',
|
'Oooops...' => 'Hovsa...',
|
||||||
'Could not find content of addon!' => 'Kunne ikke finde addonindhold!',
|
'Please type at least 3 characters' => 'Venligst indtast mindst 3 tegn',
|
||||||
'Default' => 'Standard',
|
'Save' => 'Gem',
|
||||||
'Deny' => 'Afslå',
|
'Search' => 'Søg',
|
||||||
'Error' => 'Fejl',
|
'Search for users and spaces' => 'Søg efter brugere eller sider',
|
||||||
'Expand' => 'Udvid',
|
'Space not found!' => 'Side ikke fundet!',
|
||||||
'Insufficent permissions to create content!' => 'Utilstrækkelige tilladelser til at skabe indhold!',
|
'User not found!' => 'Bruger ikke fundet!',
|
||||||
'It looks like you may have taken the wrong turn.' => 'Det ser ud som du måske har taget den forkerte drejning.',
|
'Your daily summary' => 'Dit daglige resumé',
|
||||||
'Language' => 'Sprog',
|
);
|
||||||
'Latest news' => 'Sidste nyt',
|
|
||||||
'Login' => 'Log ind',
|
|
||||||
'Logout' => 'Log ud',
|
|
||||||
'Menu' => 'Menu',
|
|
||||||
'Module is not on this content container enabled!' => 'Modulet er ikke aktiveret i denne indholdscontainer!',
|
|
||||||
'My profile' => 'Min profil',
|
|
||||||
'New profile image' => 'Nyt profilbillede',
|
|
||||||
'Next' => 'Næste',
|
|
||||||
'Oooops...' => 'Hovsa...',
|
|
||||||
'Please type at least 3 characters' => 'Venligst indtast mindst 3 tegn',
|
|
||||||
'Save' => 'Gem',
|
|
||||||
'Search' => 'Søg',
|
|
||||||
'Search for users and spaces' => 'Søg efter brugere eller sider',
|
|
||||||
'Space not found!' => 'Side ikke fundet!',
|
|
||||||
'User Approvals' => 'Bruger godkendelser',
|
|
||||||
'User not found!' => 'Bruger ikke fundet!',
|
|
||||||
'You cannot create public visible content!' => 'Du kan ikke oprette offentlig synligt indhold!',
|
|
||||||
'Your daily summary' => 'Dit daglige resumé',
|
|
||||||
];
|
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
<?php
|
|
||||||
return array (
|
|
||||||
'Global {global} array cleaned using {method} method.' => 'Global {global} array er rengjort ved brug af {method} metode.',
|
|
||||||
);
|
|
File diff suppressed because one or more lines are too long
@ -1,56 +1,37 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
return array (
|
||||||
* Message translations.
|
'<strong>Latest</strong> updates' => '<strong>Letzte</strong> Aktualisierungen',
|
||||||
*
|
'Account settings' => 'Kontoeinstellungen',
|
||||||
* This file is automatically generated by 'yii message' command.
|
'Administration' => 'Administration',
|
||||||
* It contains the localizable messages extracted from source code.
|
'Allow' => 'Erlauben',
|
||||||
* You may modify this file by translating the extracted messages.
|
'Back' => 'Zurück',
|
||||||
*
|
'Back to dashboard' => 'Zurück zur Übersicht',
|
||||||
* Each array element represents the translation (value) of a message (key).
|
'Choose language:' => 'Sprache wählen:',
|
||||||
* If the value is empty, the message is considered as not translated.
|
'Collapse' => 'Einklappen',
|
||||||
* Messages that no longer need translation will have their translations
|
'Content Addon source must be instance of HActiveRecordContent or HActiveRecordContentAddon!' => 'Die Quelle des Addons muss eine Instanz von HActiveRecordContent oder HActiveRecordContentAddon sein!',
|
||||||
* enclosed between a pair of '@@' marks.
|
'Could not determine content container!' => 'Kann Content Container nicht finden.',
|
||||||
*
|
'Could not find content of addon!' => 'Der Inhalt des Addons konnte nicht gefunden werden!',
|
||||||
* Message string can be used with plural forms format. Check i18n section
|
'Default' => 'Standard',
|
||||||
* of the guide for details.
|
'Deny' => 'Ablehnen',
|
||||||
*
|
'Error' => 'Fehler',
|
||||||
* NOTE: this file must be saved in UTF-8 encoding.
|
'Expand' => 'Erweitern',
|
||||||
*/
|
'It looks like you may have taken the wrong turn.' => 'Du hast womöglich den falschen Weg eingeschlagen.',
|
||||||
return [
|
'Language' => 'Sprache',
|
||||||
'<strong>Latest</strong> updates' => '<strong>Letzte</strong> Aktualisierungen',
|
'Latest news' => 'Neuigkeiten',
|
||||||
'Account settings' => 'Kontoeinstellungen',
|
'Login' => 'Anmelden',
|
||||||
'Administration' => 'Administration',
|
'Logout' => 'Ausloggen',
|
||||||
'Allow' => 'Erlauben',
|
'Menu' => 'Menü',
|
||||||
'Back' => 'Zurück',
|
'Module is not on this content container enabled!' => 'Dieses Modul ist in diesem Content Container nicht aktiviert!',
|
||||||
'Back to dashboard' => 'Zurück zur Übersicht',
|
'My profile' => 'Mein Profil',
|
||||||
'Choose language:' => 'Sprache wählen:',
|
'New profile image' => 'Neues Profilbild',
|
||||||
'Collapse' => 'Einklappen',
|
'Next' => 'Nächster',
|
||||||
'Content Addon source must be instance of HActiveRecordContent or HActiveRecordContentAddon!' => 'Die Quelle des Addons muss eine Instanz von HActiveRecordContent oder HActiveRecordContentAddon sein!',
|
'Ok' => 'Ok',
|
||||||
'Could not determine content container!' => 'Kann Content Container nicht finden.',
|
'Oooops...' => 'Uuuups...',
|
||||||
'Could not find content of addon!' => 'Der Inhalt des Addons konnte nicht gefunden werden!',
|
'Please type at least 3 characters' => 'Bitte wengistens 3 Zeichen eingeben',
|
||||||
'Default' => 'Standard',
|
'Save' => 'Speichern',
|
||||||
'Deny' => 'Ablehnen',
|
'Search' => 'Suchen',
|
||||||
'Error' => 'Fehler',
|
'Search for users and spaces' => 'Suche nach Benutzern und Spaces',
|
||||||
'Expand' => 'Erweitern',
|
'Space not found!' => 'Space nicht gefunden!',
|
||||||
'Insufficent permissions to create content!' => 'Unzureichende Berechtigungen um Inhalte zu erstellen!',
|
'User not found!' => 'Benutzer nicht gefunden!',
|
||||||
'It looks like you may have taken the wrong turn.' => 'Du hast womöglich den falschen Weg eingeschlagen.',
|
'Your daily summary' => 'Deine tägliche Übersicht',
|
||||||
'Language' => 'Sprache',
|
);
|
||||||
'Latest news' => 'Neuigkeiten',
|
|
||||||
'Login' => 'Anmelden',
|
|
||||||
'Logout' => 'Ausloggen',
|
|
||||||
'Menu' => 'Menü',
|
|
||||||
'Module is not on this content container enabled!' => 'Dieses Modul ist in diesem Content Container nicht aktiviert!',
|
|
||||||
'My profile' => 'Mein Profil',
|
|
||||||
'New profile image' => 'Neues Profilbild',
|
|
||||||
'Next' => 'Nächster',
|
|
||||||
'Oooops...' => 'Uuuups...',
|
|
||||||
'Please type at least 3 characters' => 'Bitte wengistens 3 Zeichen eingeben',
|
|
||||||
'Save' => 'Speichern',
|
|
||||||
'Search' => 'Suchen',
|
|
||||||
'Search for users and spaces' => 'Suche nach Benutzern und Spaces',
|
|
||||||
'Space not found!' => 'Space nicht gefunden!',
|
|
||||||
'User Approvals' => 'Benutzerfreigaben',
|
|
||||||
'User not found!' => 'Benutzer nicht gefunden!',
|
|
||||||
'You cannot create public visible content!' => 'Du hast nicht genügend Rechte um öffentlich sichtbaren Inhalt zu erstellen!',
|
|
||||||
'Your daily summary' => 'Deine tägliche Übersicht',
|
|
||||||
];
|
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Message translations.
|
|
||||||
*
|
|
||||||
* This file is automatically generated by 'yiic message' command.
|
|
||||||
* It contains the localizable messages extracted from source code.
|
|
||||||
* You may modify this file by translating the extracted messages.
|
|
||||||
*
|
|
||||||
* Each array element represents the translation (value) of a message (key).
|
|
||||||
* If the value is empty, the message is considered as not translated.
|
|
||||||
* Messages that no longer need translation will have their translations
|
|
||||||
* enclosed between a pair of '@@' marks.
|
|
||||||
*
|
|
||||||
* Message string can be used with plural forms format. Check i18n section
|
|
||||||
* of the guide for details.
|
|
||||||
*
|
|
||||||
* NOTE, this file must be saved in UTF-8 encoding.
|
|
||||||
*/
|
|
||||||
return array (
|
|
||||||
'Global {global} array cleaned using {method} method.' => 'Das globale {global} Array wurde mit der {method} Methode bereinigt.',
|
|
||||||
);
|
|
@ -1,22 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Message translations.
|
|
||||||
*
|
|
||||||
* This file is automatically generated by 'yiic message' command.
|
|
||||||
* It contains the localizable messages extracted from source code.
|
|
||||||
* You may modify this file by translating the extracted messages.
|
|
||||||
*
|
|
||||||
* Each array element represents the translation (value) of a message (key).
|
|
||||||
* If the value is empty, the message is considered as not translated.
|
|
||||||
* Messages that no longer need translation will have their translations
|
|
||||||
* enclosed between a pair of '@@' marks.
|
|
||||||
*
|
|
||||||
* Message string can be used with plural forms format. Check i18n section
|
|
||||||
* of the guide for details.
|
|
||||||
*
|
|
||||||
* NOTE, this file must be saved in UTF-8 encoding.
|
|
||||||
*/
|
|
||||||
return array (
|
|
||||||
'<strong>Upload</strong> error' => '<strong>Hochladen</strong> fehlgeschlagen',
|
|
||||||
'Close' => 'Schließen',
|
|
||||||
);
|
|
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user