Commit 8e8b451d authored by Marcello Pivanti's avatar Marcello Pivanti
Browse files

Initial Commit

parents
# Amos Community
Communities are network of people having common purposes/interest.
Common contents can be shared with community members and are available in community dashboard.
Community contents visibility for non-members depends on table fields contents_visibility that is 0 by default (contents are not available for non-members).
By default a community can be of type:
- Open: any user can subscribe (community visible in community list)
- Private: access reserved to user accepted by community managers or invited (visible but acceptance is required)
- Restricted to members (closed)- Subscription is only on invitation: community is visible only to community membership.
SubCommunities can be created under another community domain.
### Installation
Add community requirement in your composer.json:
```
"elitedivision/amos-community": "dev-master",
```
Enable the Community modules in modules-amos.php, add :
```
'community' => [
'class' => 'elitedivision\amos\community\AmosCommunity',
],
```
add community migrations to console modules (console/config/migrations-amos.php):
```
'@vendor/elitedivision/amos-community/src/migrations'
```
The community is suitable to be used with cwh as network.
To do so:
- Activate cwh plugin
- Open cwh configuration wizard (admin privilege is required) url: <yourPlatformurl>/cwh/configuration/wizard
- search for community in network configuration section
- edit configuration of community if needed and save
If tags are needed enable this module in "modules-amos.php" (backend/config folder in main project) in tag section. After that, enable the trees in tag manager.
### Configurable fields
Here the list of configurable fields, properties of module AmosCommunity.
If some property default is not suitable for your project, you can configure it in module, eg:
```php
'community' => [
'class' => 'elitedivision\amos\community\AmosCommunity',
'showSubcommunities' => false, //changed property (default was true)
],
```
* **showSubcommunities** - boolean, default = true
Define if subcommunities are visible in the lists (created by, my communities, etc..)
* **showSubcommunitiesWidget** - boolean, default = false
Define if the widget of subCommunities is visible in the community dashboard
* **bypassWorkflow** - boolean, default = false
If ignore community workflow
* **enableWizard** - boolean, default = true
If thew izard for community creation is enabled
* **communityType** - int, default = null
null if all community types are enabled, to have a fixed community type set this field
to change default, use constants in Community type model, eg:
```php
'community' => [
'class' => 'elitedivision\amos\community\AmosCommunity',
'communityType' => \elitedivision\amos\community\models\CommunityType::COMMUNITY_TYPE_CLOSED,
],
```
* **viewTabContents** - boolean, default = true
Define if tab contents in community view mode is visible
* **extendRoles** - boolean, default = false
If true additional roles Author and Reader are considered, participant will be editor
* **customInvitationForm** - boolean, default = false
If true associate or create user.
* **communityRequiredFields** - array, default = ['name', 'community_type_id', 'description']
Mandatory fields in community form: by default, community name, type and description are mandatory.
If in your platform, for example, you don't want community description to be a mandatory field, overwrite communityRequiredFields property as below:
```php
'community' => [
'class' => 'elitedivision\amos\community\AmosCommunity',
'communityRequiredFields' => ['name', 'community_type_id']
],
```
* **hideContentsModels** - array, default = [(ClassPath)ShowcaseProject, (ClassPath)EenPartnershipProposal',(ClassPath)Event']
Define the models class path to hide in view of content tab, overwrite hideContentsModels property as below:
```php
'community' => [
'class' => 'elitedivision\amos\community\AmosCommunity',
'communityRequiredFields' => [
'model/class/path',
]
],
```
* **inviteUserOfcommunityParent** - boolean, default = false
You can invite user in a subcomunity only if they belogs to the community father
* **hideWidgetGraphicsActions** - boolean, default = false
* **htmlMailContent** - array, default = []
You can personalize the email sent by the community
the values are present in getNumTypeEmail($type) in EmailUtility and are
('registration-notification', 'registration-request', 'invitation', 'accept-invitation', reject-invitation, 'registration-rejects', 'welcome', 'change-role' )
```php
'htmlMailContent' => [
'welcome' => '@backend/mail/community/welcome'
'change-role => '@backend/mail/community/change-role', //CHANGE_ROLE
],
```
* **htmlMailSubject** - array, default = []
It work in the some way of the previous param
* **enableUserJoinedReportDownload** - boolean, default = false
Enable to display the "User Reports" container in community view (this will also display the "download user joined report" button inside it)
{
"name": "arter/amos-community",
"description": "Sistema AMOS per le community",
"keywords": [
"amos",
"yii2",
"community"
],
"homepage": "http://git.elitedivision.it/elitedivision/amos-community",
"type": "component",
"license": "BSD-3-Clause",
"support": {
"issues": "http://git.elitedivision.it/elitedivision/amos-community/issues",
"forum": "http://www.example.com/forum/",
"wiki": "http://git.elitedivision.it/elitedivision/amos-community/wikis/home",
"source": "http://git.elitedivision.it/elitedivision/amos-community/tree/master"
},
"require": {
"php": ">=5.4.0",
"arter/amos-admin": "^2.0.24",
"arter/amos-attachments": "^1.1.11",
"arter/amos-core": "^1.9.60",
"arter/amos-cwh": "^2.1.5",
"arter/amos-dashboard": "^1.8.16",
"arter/amos-layout": "^1.0.33",
"arter/amos-notify": "^1.4.13",
"arter/amos-seo": "^1.0",
"yiidoc/yii2-redactor": "*",
"moonlandsoft/yii2-phpexcel": "*"
},
"config": {
"process-timeout": 1800,
"secure-http": false
},
"extra": {
"asset-installer-paths": {
"npm-asset-library": "vendor/npm",
"bower-asset-library": "vendor/bower"
}
},
"autoload": {
"psr-4": {
"elitedivision\\amos\\community\\": "src"
}
},
"require-dev": {
"yiisoft/yii2-faker": "*"
}
}
\ No newline at end of file
<?php
/**
* Art-ER Attrattività, ricerca e territorio dell’Emilia-Romagna
* OPEN 2.0
*
*
* @package elitedivision\amos\community
* @category CategoryName
* @author Elite Division S.r.l.
*/
namespace elitedivision\amos\community;
use elitedivision\amos\community\controllers\CommunityController;
use elitedivision\amos\community\exceptions\CommunityException;
use elitedivision\amos\community\models\Community;
use elitedivision\amos\community\models\CommunityInterface;
use elitedivision\amos\community\models\CommunityUserMm;
use elitedivision\amos\community\utilities\CommunityUtil;
use elitedivision\amos\community\utilities\EmailUtil;
use elitedivision\amos\community\widgets\icons\WidgetIconCommunity;
use elitedivision\amos\community\widgets\icons\WidgetIconCommunityDashboard;
use elitedivision\amos\community\widgets\icons\WidgetIconCreatedByCommunities;
use elitedivision\amos\community\widgets\icons\WidgetIconMyCommunities;
use elitedivision\amos\community\widgets\icons\WidgetIconToValidateCommunities;
use elitedivision\amos\core\interfaces\CmsModuleInterface;
use elitedivision\amos\core\interfaces\InvitationExternalInterface;
use elitedivision\amos\core\interfaces\SearchModuleInterface;
use elitedivision\amos\core\module\AmosModule;
use elitedivision\amos\core\module\ModuleInterface;
use elitedivision\amos\core\record\Record;
use elitedivision\amos\core\user\User;
use yii\db\ActiveQuery;
use yii\log\Logger;
/**
* Class AmosCommunity
* community module definition class
* @package elitedivision\amos\community
*/
class AmosCommunity extends AmosModule implements ModuleInterface, SearchModuleInterface, CmsModuleInterface, InvitationExternalInterface
{
public static $CONFIG_FOLDER = 'config';
/**
* @var string|boolean the layout that should be applied for views within this module. This refers to a view name
* relative to [[layoutPath]]. If this is not set, it means the layout value of the [[module|parent module]]
* will be taken. If this is false, layout will be disabled within this module.
*/
public $layout = 'main';
/**
* @inheritdoc
*/
public $controllerNamespace = 'elitedivision\amos\community\controllers';
public $newFileMode = 0666;
public $name = 'Community';
/**
* Define if subcommunities are visible in the lists (created by, my communities, etc..)
* @var bool|true $showSubcommunities
*/
public $showSubcommunities = true;
/**
* Define if the widget of subCommunities is visible in the community dashboard
* @var bool
*/
public $showSubcommunitiesWidget = false;
/**
* @var bool|false $bypassWorkflow - if ignore community workflow
*/
public $bypassWorkflow = false;
/**
* @var bool|true $enableWizard - if wizard for community creation is enabled
*/
public $enableWizard = false;
/**
* @var int|null $communityType - null if all community types are enabled, to have a fixed community type set this field
*/
public $communityType = null;
/**
* @var bool|true $viewTabContents - if tab contents in community view mode is visible
*/
public $viewTabContents = true;
/**
* @var bool|true $extendRoles - if true additional roles Author and Reader are considered
*/
public $extendRoles = false;
/**
*
* @var bool|true $customInvitationForm - if true associate or create user.
*/
public $customInvitationForm = false;
/**
* @var bool|true $disableButtonsUserNetworks - hide the butttons community associate, and delete in Network UserProfile
*/
public $disableCommunityAssociationUserProfile = false;
/**
* @var array $communityRequiredFields - mandatory fields in community form
*/
public $communityRequiredFields = ['name', 'community_type_id', 'description'];
/**
* task OPEN-2303 with defaul values
* @var array $hideContentsModels - hide this models in tab contents
*/
public $hideContentsModels = [
'elitedivision\amos\showcaseprojects\models\ShowcaseProject',
'elitedivision\amos\een\models\EenPartnershipProposal',
'elitedivision\amos\events\models\Event',
];
/**
* @var bool $inviteUserOfcommunityParent
*/
public $inviteUserOfcommunityParent = false;
/**
* @var array $htmlMailSubject
*/
public $htmlMailSubject = [];
/**
* @var array $htmlMailContent
*/
public $htmlMailContent = [];
/**
* @var bool $hideCommunityTypeSearchFilter
*/
public $hideCommunityTypeSearchFilter = false;
/**
* @var bool $deleteCommunityWithSubcommunities
*/
public $deleteCommunityWithSubcommunities = false;
/**
* @var bool $deleteCommunityWithContents
*/
public $deleteCommunityWithContents = false;
/**
* @var array $defaultListViews This set the default order for the views in lists
*/
public $defaultListViews = ['icon', 'grid'];
/**
* @var bool $forceDefaultViewType
*/
public $forceDefaultViewType = false;
/**
* @var bool $enableUserJoinedReportDownload Enable to display the "download user joined report" button
*/
public $enableUserJoinedReportDownload = false;
/**
* @var bool $enableUserJoinedReportDownload Enable to display the "download user joined report" button
*/
public $enableConfigureCommunityDashboard = false;
/**
* @var bool $enableUserNetworkWidget
*/
public $enableUserNetworkWidget = true;
/**
* @var bool $view_email_partecipants
*/
public $view_email_partecipants = false;
/**
* @var bool $disableWorkflow Force workflow for a single community
*/
public $forceWorkflowSingleCommunity = false;
/**
* @var bool $showCommunitiesParticipantPluging Force workflow for a single community
*/
public $showCommunitiesParticipantPluging = true;
/**
* @var bool $externalInvitationUsers
*/
public $externalInvitationUsers = true;
/**
* @var array $autoCommunityManagerRoles All the users with the platform roles in this array, when creating a community, are added as community managers.
*/
public $autoCommunityManagerRoles = [];
/**
* @inheritdoc
*/
public static function getModuleName()
{
return 'community';
}
/**
* @inheritdoc
*/
public function init()
{
parent::init();
\Yii::setAlias('@elitedivision/amos/' . static::getModuleName() . '/controllers', __DIR__ . '/controllers/');
// initialize the module with the configuration loaded from config.php
\Yii::configure($this, require(__DIR__ . DIRECTORY_SEPARATOR . self::$CONFIG_FOLDER . DIRECTORY_SEPARATOR . 'config.php'));
$this->autoCommunityManagerRoles = array_unique($this->autoCommunityManagerRoles);
}
/**
* @inheritdoc
*/
public function getWidgetGraphics()
{
return null;
}
/**
* @inheritdoc
*/
public function getWidgetIcons()
{
return [
WidgetIconCommunity::className(),
WidgetIconCreatedByCommunities::className(),
WidgetIconMyCommunities::className(),
WidgetIconCommunityDashboard::className(),
WidgetIconToValidateCommunities::className(),
];
}
/**
* @inheritdoc
*/
protected function getDefaultModels()
{
return [
'Community' => __NAMESPACE__ . '\\' . 'models\Community',
'CommunitySearch' => __NAMESPACE__ . '\\' . 'models\search\CommunitySearch',
];
}
/**
* @param Record $model
* @return bool|false
*/
public function forceWorkflow($model = null)
{
$forcecommunity = $this->bypassWorkflow;
if (!is_null($model) && !$model->isNewRecord) {
$forcecommunity = $model->force_workflow;
}
return $this->forceWorkflowSingleCommunity ? $forcecommunity : $this->bypassWorkflow;
}
/**
* Method to create a new validated community and add the current logged user as the manager.
* @param string $title
* @param int $type
* @param string $context
* @param string $managerRole
* @param string $description
* @param \elitedivision\amos\core\record\Record|null $model
* @param string $managerStatus
* @param int|null $managerId
* @return int
* @throws CommunityException
*/
public function createCommunity($title, $type, $context, $managerRole, $description = '', $model = null, $managerStatus = CommunityUserMm::STATUS_ACTIVE, $managerId = null)
{
self::verifyUserStatus($managerStatus, true);
try {
/** @var Community $community */
$community = AmosCommunity::instance()->createModel('Community');
$community->name = $title;
$community->description = $description;
$community->community_type_id = $type;
$community->cover_image_id = null; // TODO gestire quando le community useranno il campo
$community->status = $community->getWorkflowSource()->getWorkflow(Community::COMMUNITY_WORKFLOW)->getInitialStatusId();
$community->context = $context;
if ($this->forceWorkflow()) {
$community->validated_once = 1;
}
$ok = $community->save(false);
if ($ok) {
if ($managerId === null) {
$managerId = \Yii::$app->getUser()->id;
}
$this->createCommunityUser($community->id, $managerStatus, $managerRole, $managerId);
if (!is_null($model) && ($model instanceof CommunityInterface)) {
$model->communityId = $community->id;
}
$community->status = Community::COMMUNITY_WORKFLOW_STATUS_VALIDATED;
$community->validated_once = 1;
$community->detachBehavior('workflow');
$ok = $community->save(false);
}
if (!$ok) {
return 0;
}
} catch (\Exception $exception) {
\Yii::getLogger()->log($exception->getMessage(), Logger::LEVEL_ERROR);
throw new CommunityException(AmosCommunity::t('amoscommunity', 'Unable to create community'), null, $exception);
}
return $community->id;
}
/**
* Method to create a new community user if do not exists
* @param int $idCommunity
* @param string $userStatus
* @param string $userRole
* @param int $userId
* @throws CommunityException
*/
public function createCommunityUser($idCommunity, $userStatus, $userRole, $userId, $invited_at = null, $invitation_accepted_at = null, $invitation_partner_of = null)
{
$ok = true;
try {
self::verifyUserStatus($userStatus);
$searchUser = CommunityUserMm::findOne(['user_id' => $userId, 'community_id' => $idCommunity]);
if (empty($searchUser)) {
$userCommunityMm = new CommunityUserMm();
$userCommunityMm->community_id = $idCommunity;
$userCommunityMm->user_id = $userId;
$userCommunityMm->status = $userStatus;
$userCommunityMm->role = $userRole;
$userCommunityMm->invited_at = $invited_at;
$userCommunityMm->invitation_accepted_at = $invitation_accepted_at;
$userCommunityMm->invitation_partner_of = $invitation_partner_of;
$ok = $userCommunityMm->save(false);
$community = Community::findOne($idCommunity);
$community->setCwhAuthAssignments($userCommunityMm);
}
} catch (\Exception $exception) {
\Yii::getLogger()->log($exception->getMessage(), Logger::LEVEL_ERROR);
throw new CommunityException(AmosCommunity::t('amoscommunity', 'Unable to create user-community MM'), null, $exception);
}
return $ok;
}
/**
* @param int $communityId
* @param int $userId
* @return bool
* @throws \Throwable
* @throws \yii\db\StaleObjectException
*/
public function deleteCommunityUser($communityId, $userId)
{
/** @var Community $community */
$community = Community::findOne($communityId);
if ($community) {
$communityUserMmRow = CommunityUserMm::findOne(['community_id' => $communityId, 'user_id' => $userId]);
//remove all cwh permissions for domain = community
$community->setCwhAuthAssignments($communityUserMmRow, true);
$communityUserMmRow->delete();
return true;
}
return false;
}
/**
* @param int $communityId
* @param int $userId
* @param string $role
* @return bool
* @throws \yii\base\InvalidConfigException
*/
public function changeRoleCommunityUser($communityId, $userId, $role)
{
$userCommunity = CommunityUserMm::find()->andWhere(['community_id' => $communityId, 'user_id' => $userId])->one();
if (!is_null($userCommunity)) {
$nomeCognome = " ";
$communityName = '';
$userCommunity->role = $role;
$ok = $userCommunity->save(false);
if ($ok) {
$userCommunity->community->setCwhAuthAssignments($userCommunity);
/** @var UserProfile $userProfile */
$user = User::findOne($userId);
$userProfile = $user->getProfile();
if (!is_null($userProfile)) {
$nomeCognome = " '" . $userProfile->nomeCognome . "' ";
}
if (!is_null($userCommunity->community)) {
$communityName = " '" . $userCommunity->community->name . "'";
}
$message = $nomeCognome . " " . AmosCommunity::tHtml('amoscommunity',
"is now") . " " . $userCommunity->role . " " . AmosCommunity::tHtml('amoscommunity',
"of") . " '" . $communityName . "'";
$emailUtil = new EmailUtil(EmailUtil::CHANGE_ROLE, $userCommunity->role, $userCommunity->community,
$userProfile->nomeCognome, '', null, $userProfile->user_id);
$subject = $emailUtil->getSubject();
$text = $emailUtil->getText();
$communityController = new CommunityController('community', $this);
$communityController->sendMail(null, $user->email, $subject, $text, [], []);
}
return true;
}
return false;
}
/**
* If the state is not allowed, it generates an exception
* @param string $userStatus
* @param boolean $manager
* @throws CommunityException
*/
protected static function verifyUserStatus($userStatus, $manager = false)
{
$communityUserMmStates = CommunityUserMm::getUserStates();
if (!is_string($userStatus) || !strlen($userStatus) || !in_array($userStatus, $communityUserMmStates)) {
throw new CommunityException(AmosCommunity::t('amoscommunity', '{typeUser} status not allowed', ['typeUser' => ($manager ? AmosCommunity::t('amoscommunity', 'Manager') : AmosCommunity::t('amoscommunity', 'User'))]));
}
}
/**
* This method return an array of Community objects representing all the communities of a user.
* @param int $userId
* @param bool $onlyIds
* @return Community[]|int[]|ActiveQuery
* @throws CommunityException
*/
public function getCommunitiesByUserId($userId, $onlyIds = false)
{
return CommunityUtil::getCommunitiesByUserId($userId, $onlyIds);
}
/**
* @param int $userId
* @param bool $onlyIds
* @return Community[]|int[]
* @throws CommunityException
*/
public function getCommunitiesManagedByUserId($userId, $onlyIds = false)
{
return CommunityUtil::getCommunitiesManagedByUserId($userId, $onlyIds);
}
/**