Răsfoiți Sursa

#108 - Registration by invitation only.

AntonLV 12 ani în urmă
părinte
comite
a225fb18db

+ 95 - 0
modules/boonex/invites/classes/BxInvConfig.php

@@ -0,0 +1,95 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Invites Invites
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxBaseModGeneralConfig');
+
+class BxInvConfig extends BxBaseModGeneralConfig
+{
+    protected $_oDb;
+
+    protected $_iCountPerUser;
+    protected $_sKeyCode;
+    protected $_iKeyLifetime;
+    protected $_bRequestInvite;
+    protected $_sRequestsEmail;
+
+    /**
+     * Constructor
+     */
+    public function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $this->CNF = array (
+        	'URL_INVITE' => 'page.php?i=invites-invite',
+        	'URL_REQUEST' => 'page.php?i=invites-request',
+        );
+
+		$this->_aObjects = array(
+			'alert' => $this->_sName,
+			'grid_requests' => $this->_sName . '_requests',
+			'form_invite' => $this->_sName . '_invite',
+			'form_request' => $this->_sName . '_request',
+			'form_display_invite_send' => $this->_sName . '_invite_send',
+			'form_display_request_send' => $this->_sName . '_request_send',
+		);
+
+		$this->_aPrefixes = array(
+        	'style' => 'bx-inv',
+        	'option' => 'bx_invites_',
+        );
+
+        $this->_iCountPerUser = 0;
+        $this->_sKeyCode = 'icode';
+        $this->_iKeyLifetime = 86400;
+        $this->_bRequestInvite = false;
+        $this->_sRequestsEmail = '';
+    }
+
+    public function init(&$oDb)
+    {
+        $this->_oDb = &$oDb;
+
+        $sOptionPrefix = $this->getPrefix('option');
+
+        $this->_iCountPerUser = (int)getParam($sOptionPrefix . 'count_per_user');
+        $this->_iKeyLifetime = 86400 * (int)getParam($sOptionPrefix . 'key_lifetime');
+        $this->_bRequestInvite = getParam($sOptionPrefix . 'enable_request_invite') == 'on';
+        $this->_sRequestsEmail = getParam($sOptionPrefix . 'requests_email');
+    }
+
+	public function getCountPerUser()
+    {
+        return $this->_iCountPerUser;
+    }
+
+	public function getKeyCode()
+    {
+        return $this->_sKeyCode;
+    }
+
+	public function getKeyLifetime()
+    {
+        return $this->_iKeyLifetime;
+    }
+
+    public function isRequestInvite()
+    {
+        return $this->_bRequestInvite;
+    }
+
+    public function getRequestsEmail()
+    {
+        return $this->_sRequestsEmail;
+    }
+}
+
+/** @} */

+ 94 - 0
modules/boonex/invites/classes/BxInvDb.php

@@ -0,0 +1,94 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Invites Invites
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxDolModuleDb');
+
+class BxInvDb extends BxDolModuleDb
+{
+    protected $_oConfig;
+
+    protected $_sTableInvites;
+    protected $_sTableRequests;
+
+    /*
+     * Constructor.
+     */
+    function __construct(&$oConfig)
+    {
+        parent::__construct($oConfig);
+
+        $this->_oConfig = $oConfig;
+
+        $this->_sTableInvites = $this->_sPrefix . 'invites';
+        $this->_sTableRequests = $this->_sPrefix . 'requests';
+    }
+
+	public function getInvites($aParams, $bReturnCount = false)
+    {
+    	$sMethod = 'getAll';
+        $sSelectClause = $sJoinClause = $sWhereClause = $sOrderClause = $sLimitClause = "";
+
+        $sSelectClause = "`{$this->_sTableInvites}`.*";
+
+        switch($aParams['type']) {
+            case 'count_by_account':
+                $sMethod = 'getOne';
+                $sSelectClause = "COUNT(`{$this->_sTableInvites}`.`id`) AS `count`";
+                $sWhereClause = $this->prepare("AND `{$this->_sTableInvites}`.`account_id`=? ", $aParams['value']);
+                $sLimitClause = "LIMIT 1";
+                break;
+        }
+
+        $sSql = "SELECT " . ($bReturnCount ? "SQL_CALC_FOUND_ROWS" : "") . " " . $sSelectClause . "
+            FROM `{$this->_sTableInvites}` " . $sJoinClause . "
+            WHERE 1 " . $sWhereClause . " " . $sOrderClause . " " . $sLimitClause;
+
+        $aEntries = $this->$sMethod($sSql);
+        if(!$bReturnCount)
+        	return $aEntries;
+
+		return array($aEntries, (int)$this->getOne("SELECT FOUND_ROWS()"));
+    }
+
+	public function getRequests($aParams, $bReturnCount = false)
+    {
+    	$sMethod = 'getAll';
+        $sSelectClause = $sJoinClause = $sWhereClause = $sOrderClause = $sLimitClause = "";
+
+        $sSelectClause = "`{$this->_sTableRequests}`.*";
+
+        switch($aParams['type']) {
+        	case 'by_id':
+        		$sMethod = 'getRow';
+        		$sWhereClause = $this->prepare("AND `{$this->_sTableRequests}`.`id`=? ", $aParams['value']);
+        		$sLimitClause = "LIMIT 1";
+        		break;
+
+            case 'count_all':
+                $sMethod = 'getOne';
+                $sSelectClause = "COUNT(`{$this->_sTableRequests}`.`id`) AS `count`";
+                $sLimitClause = "LIMIT 1";
+                break;
+        }
+
+        $sSql = "SELECT " . ($bReturnCount ? "SQL_CALC_FOUND_ROWS" : "") . " " . $sSelectClause . "
+            FROM `{$this->_sTableRequests}` " . $sJoinClause . "
+            WHERE 1 " . $sWhereClause . " " . $sOrderClause . " " . $sLimitClause;
+
+        $aEntries = $this->$sMethod($sSql);
+        if(!$bReturnCount)
+        	return $aEntries;
+
+		return array($aEntries, (int)$this->getOne("SELECT FOUND_ROWS()"));
+    }
+}
+
+/** @} */

+ 110 - 0
modules/boonex/invites/classes/BxInvGridRequests.php

@@ -0,0 +1,110 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Invites Invites
+ * @ingroup     DolphinModules
+ * 
+ * @{
+ */
+
+bx_import('BxDolModule');
+bx_import('BxTemplGrid');
+
+class BxInvGridRequests extends BxTemplGrid
+{
+	protected $_sModule;
+	protected $_oModule;
+
+    public function __construct ($aOptions, $oTemplate = false)
+    {
+        parent::__construct ($aOptions, $oTemplate);
+
+		$this->_sModule = 'bx_invites';
+		$this->_oModule = BxDolModule::getInstance($this->_sModule);
+    }
+
+	public function performActionInvite($aParams = array())
+    {
+    	$iProfileId = $this->_oModule->getProfileId();
+
+    	$mixedAllowed = $this->_oModule->isAllowedInvite($iProfileId);
+    	if($mixedAllowed !== true) {
+	    	$this->_echoResultJson(array('msg' => $mixedAllowed));
+			exit;
+    	}
+
+        $iAffected = 0;
+        $aIds = bx_get('ids');
+        if(!$aIds || !is_array($aIds)) {
+            $this->_echoResultJson(array());
+            exit;
+        }
+
+        $sText = _t('_bx_invites_msg_invitation');
+
+        $aIdsAffected = array ();
+        foreach($aIds as $iId) {
+			$aRequest = $this->_oModule->_oDb->getRequests(array('type' => 'by_id', 'value' => $iId));
+			if(empty($aRequest) || !is_array($aRequest))
+				continue;
+
+        	$mixedResult = $this->_oModule->invite($aRequest['email'], $sText);
+        	if($mixedResult === false)
+        		continue;
+
+			$this->_oModule->isAllowedInvite($iProfileId, true);
+
+            $aIdsAffected[] = $iId;
+            $iAffected++;
+        }
+
+        $this->_echoResultJson($iAffected ? array('grid' => $this->getCode(false), 'blink' => $aIdsAffected, 'msg' => _t('_bx_invites_msg_invitation_sent', $iAffected)) : array('msg' => _t('_bx_invites_err_invite')));
+    }
+	public function performActionDelete($aParams = array())
+    {
+    	$iProfileId = $this->_oModule->getProfileId();
+
+    	$mixedAllowed = $this->_oModule->isAllowedDeleteRequest($iProfileId);
+    	if($mixedAllowed !== true) {
+	    	$this->_echoResultJson(array('msg' => $mixedAllowed));
+			exit;
+    	}
+
+        $iAffected = 0;
+        $aIds = bx_get('ids');
+        if(!$aIds || !is_array($aIds)) {
+            $this->_echoResultJson(array());
+            exit;
+        }
+
+        bx_import('BxDolForm');
+        $oForm = BxDolForm::getObjectInstance($this->_oModule->_oConfig->getObject('form_request'), $this->_oModule->_oConfig->getObject('form_display_request_send'));
+
+        $aIdsAffected = array ();
+        foreach($aIds as $iId) {
+        	if(!$oForm->delete($iId))
+                continue;
+
+			$this->_oModule->isAllowedDeleteRequest($iProfileId, true);
+
+            $aIdsAffected[] = $iId;
+            $iAffected++;
+        }
+
+        $this->_echoResultJson($iAffected ? array('grid' => $this->getCode(false), 'blink' => $aIdsAffected) : array('msg' => _t('_bx_invites_err_delete_request')));
+    }
+
+	protected function _getCellNip($mixedValue, $sKey, $aField, $aRow)
+    {
+        return parent::_getCellDefault(long2ip($mixedValue), $sKey, $aField, $aRow);
+    }
+
+	protected function _getCellDate($mixedValue, $sKey, $aField, $aRow)
+    {
+        return parent::_getCellDefault(bx_time_js($mixedValue), $sKey, $aField, $aRow);
+    }
+}
+
+/** @} */

+ 275 - 0
modules/boonex/invites/classes/BxInvModule.php

@@ -0,0 +1,275 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Invites Invites
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxDolModule');
+
+class BxInvModule extends BxDolModule
+{
+    /**
+     * Constructor
+     */
+    function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $this->_oConfig->init($this->_oDb);
+    }
+
+    /**
+     * SERVICE METHODS
+     */
+    public function serviceGetBlockInvite()
+    {
+		$iProfileId = $this->getProfileId();
+		$iAccountId = $this->getAccountId($iProfileId);
+
+		$mixedAllowed = $this->isAllowedInvite($iProfileId);
+        if($mixedAllowed !== true)
+            return '';
+
+		$iInvited = (int)$this->_oDb->getInvites(array('type' => 'count_by_account', 'value' => $iAccountId));
+		if($iInvited >= $this->_oConfig->getCountPerUser())
+			return '';
+
+    	return array(
+    		'content' => $this->_oTemplate->getBlockInvite($iAccountId, $iProfileId)
+    	);
+    }
+
+    public function serviceGetBlockFormInvite()
+    {
+    	$iProfileId = $this->getProfileId();
+		$iAccountId = $this->getAccountId($iProfileId);
+
+        $mixedAllowed = $this->isAllowedInvite($iProfileId);
+        if($mixedAllowed !== true)
+            return array(
+                'content' => MsgBox($mixedAllowed)
+            );
+
+		$iInvited = (int)$this->_oDb->getInvites(array('type' => 'count_by_account', 'value' => $iAccountId));
+		$iInvites = $this->_oConfig->getCountPerUser() - $iInvited;
+		if($iInvites <= 0)
+			return array(
+				'content' => MsgBox(_t('_bx_invites_err_limit_reached'))
+			);
+
+        bx_import('BxDolForm');
+        $oForm = BxDolForm::getObjectInstance($this->_oConfig->getObject('form_invite'), $this->_oConfig->getObject('form_display_invite_send'));
+        $oForm->aInputs['text']['value'] = _t('_bx_invites_msg_invitation');
+
+        $sResult = '';
+        $oForm->initChecker();
+        if($oForm->isSubmittedAndValid()) {
+        	$sEmails = bx_process_input($oForm->getCleanValue('emails'));
+        	$sText = bx_process_pass($oForm->getCleanValue('text'));
+
+        	$mixedResult = $this->invite($sEmails, $sText, $iInvites, $oForm);
+        	if($mixedResult !== false)
+        		$sResult = _t('_bx_invites_msg_invitation_sent', (int)$mixedResult);
+        	else
+				$sResult = _t('_bx_invites_err_not_available');
+
+        	$sResult = MsgBox($sResult);
+        }
+
+        return array(
+            'content' => $sResult . $oForm->getCode()
+        );
+    }
+
+    public function serviceGetBlockFormRequest()
+    {
+    	if(!$this->_oConfig->isRequestInvite())
+    		return array(
+                'content' => MsgBox(_t('_bx_invites_err_not_available'))
+            );
+
+    	$mixedAllowed = $this->isAllowedRequest(0);
+        if($mixedAllowed !== true)
+            return array(
+                'content' => MsgBox($mixedAllowed)
+            );
+
+    	$sResult = '';
+
+        bx_import('BxDolForm');
+        $oForm = BxDolForm::getObjectInstance($this->_oConfig->getObject('form_request'), $this->_oConfig->getObject('form_display_request_send'));
+
+        $oForm->initChecker();
+        if($oForm->isSubmittedAndValid()) {
+        	$sIp = getVisitorIP();
+
+        	$iId = (int)$oForm->insert(array(
+        		'nip' => ip2long($sIp),
+				'date' => time()
+			));
+
+			if($iId !== false) {
+				$sRequestsEmail = $this->_oConfig->getRequestsEmail();
+				if(!empty($sRequestsEmail)) {
+					bx_import('BxDolEmailTemplates');
+					$aMessage = BxDolEmailTemplates::getInstance()->parseTemplate('bx_invites_request_form_message', array(
+						'sender_name' => bx_process_output($oForm->getCleanValue('name')),
+						'sender_email' => bx_process_output($oForm->getCleanValue('email')),
+						'sender_ip' => $sIp
+					));
+
+					sendMail($sRequestsEmail, $aMessage['Subject'], $aMessage['Body'], 0, array(), BX_EMAIL_SYSTEM);
+				}
+
+				$sResult = MsgBox(_t('_bx_invites_msg_request_sent'));
+			}
+        }
+
+        return array(
+            'content' => $sResult . $oForm->getCode()
+        );
+    }
+
+    public function serviceGetBlockManageRequests()
+    {
+    	bx_import('BxDolGrid');
+        $oGrid = BxDolGrid::getObjectInstance($this->_oConfig->getObject('grid_requests'));
+        if(!$oGrid)
+            return '';
+
+		return $oGrid->getCode();
+    }
+
+	public function serviceGetMenuAddonRequests()
+	{
+        return $this->_oDb->getRequests(array('type' => 'count_all'));
+	}
+
+	public function invite($sEmails, $sText, $iLimit = false, $oForm = null)
+	{
+		$iProfileId = $this->getProfileId();
+		$iAccountId = $this->getAccountId($iProfileId);
+
+		bx_import('BxDolKey');
+		$oKeys = BxDolKey::getInstance();
+		if(!$oKeys)
+			return false;
+
+		$sKeyCode = $this->_oConfig->getKeyCode();
+		$iKeyLifetime = $this->_oConfig->getKeyLifetime();
+
+		if(empty($oForm)) {
+			bx_import('BxDolForm');
+			$oForm = BxDolForm::getObjectInstance($this->_oConfig->getObject('form_invite'), $this->_oConfig->getObject('form_display_invite_send'));
+		}
+
+		bx_import('BxDolPermalinks');
+		$sJoinUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=create-account');
+
+		bx_import('BxDolEmailTemplates');
+		$aMessage = BxDolEmailTemplates::getInstance()->parseTemplate('bx_invites_invite_form_message', array(
+			'text' => $sText
+		), $iAccountId, $iProfileId);
+
+		$iSent = 0;
+		$iDate = time();
+		$aEmails = explode(';', $sEmails);
+		if(is_array($aEmails) && !empty($aEmails))
+			foreach($aEmails as $sEmail) {
+				if($iLimit !== false && (int)$iLimit <= 0)
+					break;
+
+				$sKey = $oKeys->getNewKey(false, $iKeyLifetime);
+				$sJoinUrl .= '&' . $sKeyCode . '=' . $sKey;
+
+				$sEmail = trim($sEmail);
+				if(sendMail($sEmail, $aMessage['Subject'], $aMessage['Body'], 0, array('join_url' => $sJoinUrl), BX_EMAIL_SYSTEM)) {
+					$oForm->insert(array(
+						'account_id' => $iAccountId,
+						'profile_id' => $iProfileId,
+						'email' => $sEmail,
+						'date' => $iDate
+					));
+
+					$this->onInvite($iAccountId, $iProfileId);
+
+					$iSent += 1;
+					if($iLimit !== false) 
+						$iLimit -= 1;					
+				}
+			}
+
+		return $iSent;
+	}
+
+	public function isAllowedInvite($iProfileId, $bPerform = false)
+    {
+        $aCheckResult = checkActionModule($iProfileId, 'invite', $this->getName(), $bPerform);
+        return $aCheckResult[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED ? $aCheckResult[CHECK_ACTION_MESSAGE] : true;
+    }
+
+	public function isAllowedRequest($iProfileId, $bPerform = false)
+    {
+        $aCheckResult = checkActionModule($iProfileId, 'request', $this->getName(), $bPerform);
+        return $aCheckResult[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED ? $aCheckResult[CHECK_ACTION_MESSAGE] : true;
+    }
+
+	public function isAllowedDeleteRequest($iProfileId, $bPerform = false)
+    {
+        $aCheckResult = checkActionModule($iProfileId, 'delete request', $this->getName(), $bPerform);
+        return $aCheckResult[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED ? $aCheckResult[CHECK_ACTION_MESSAGE] : true;
+    }
+
+    public function getProfileId()
+    {
+        return isLogged() ? bx_get_logged_profile_id() : 0;
+    }
+
+    public function getProfileObject($iProfileId = 0)
+    {
+    	bx_import('BxDolProfile');
+        $oProfile = BxDolProfile::getInstance($iProfileId);
+        if (!$oProfile) {
+            bx_import('BxDolProfileUndefined');
+            $oProfile = BxDolProfileUndefined::getInstance();
+        }
+
+        return $oProfile;
+    }
+
+	public function getAccountId($iProfileId)
+    {
+    	$oProfile = $this->getProfileObject($iProfileId);
+    	if($oProfile->id() == 0)
+    		return 0;
+
+        return $oProfile->getAccountId();
+    }
+
+    protected function onInvite($iAccountId, $iProfileId)
+    {
+        $this->isAllowedInvite($iProfileId, true);
+
+        //--- Event -> Invite for Alerts Engine ---//
+        bx_import('BxDolAlerts');
+        $oAlert = new BxDolAlerts($this->_oConfig->getObject('alert'), 'invite', 0, $iProfileId);
+        $oAlert->alert();
+        //--- Event -> Invite for Alerts Engine ---//
+    }
+
+	protected function onRequest()
+    {
+        //--- Event -> Request for Alerts Engine ---//
+        bx_import('BxDolAlerts');
+        $oAlert = new BxDolAlerts($this->_oConfig->getObject('alert'), 'request');
+        $oAlert->alert();
+        //--- Event -> Request for Alerts Engine ---//
+    }
+}
+
+/** @} */

+ 85 - 0
modules/boonex/invites/classes/BxInvResponse.php

@@ -0,0 +1,85 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Invites Invites
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxDolModule');
+bx_import('BxDolAlertsResponse');
+
+class BxInvResponse extends BxDolAlertsResponse
+{
+	protected $_sModule;
+	protected $_oModule;
+
+    public function __construct()
+    {
+        parent::__construct();
+
+        $this->_sModule = 'bx_invites';
+        $this->_oModule = BxDolModule::getInstance($this->_sModule);
+    }
+
+    /**
+     * Overwtire the method of parent class.
+     *
+     * @param BxDolAlerts $oAlert an instance of alert.
+     */
+    public function response($oAlert)
+    {
+    	if($oAlert->sUnit != 'account' || !in_array($oAlert->sAction, array('add_form', 'added')))
+    		return;
+
+		$sMethod = '_process' . bx_gen_method_name($oAlert->sUnit . '_' . $oAlert->sAction);
+		if(!method_exists($this, $sMethod))
+			return;
+
+		return $this->$sMethod($oAlert);
+    }
+
+    protected function _processAccountAddForm($oAlert)
+    {
+    	bx_import('BxDolSession');
+    	$oSession = BxDolSession::getInstance();
+
+		$sKeyCode = $this->_oModule->_oConfig->getKeyCode();
+		if(bx_get($sKeyCode) !== false) {
+			$sKey = bx_process_input(bx_get($sKeyCode));
+
+			bx_import('BxDolKey');
+        	$oKeys = BxDolKey::getInstance();
+        	if($oKeys && $oKeys->isKeyExists($sKey))
+		    	$oSession->setValue($sKeyCode, $sKey);
+		}
+
+		$sKey = $oSession->getValue($sKeyCode);
+		if($sKey === false)
+			$oAlert->aExtras['form_code'] = $this->_oModule->_oTemplate->getBlockRequest();
+
+		return;    	
+    }
+
+    protected function _processAccountAdded($oAlert)
+    {
+    	$sKeyCode = $this->_oModule->_oConfig->getKeyCode();
+
+    	bx_import('BxDolSession');
+    	$sKey = BxDolSession::getInstance()->getUnsetValue($sKeyCode);
+    	if($sKey === false)
+    		return;
+
+		bx_import('BxDolKey');
+		$oKeys = BxDolKey::getInstance();
+    	if($oKeys && $oKeys->isKeyExists($sKey))
+    		$oKeys->removeKey($sKey);
+
+    	return;
+    }
+}
+
+/** @} */

+ 51 - 0
modules/boonex/invites/classes/BxInvTemplate.php

@@ -0,0 +1,51 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Invites Invites
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxDolModuleTemplate');
+
+class BxInvTemplate extends BxDolModuleTemplate
+{
+    function __construct(&$oConfig, &$oDb)
+    {
+        parent::__construct($oConfig, $oDb);
+    }
+
+    public function getBlockInvite($iAccountId, $iProfileId)
+    {
+    	$iInvites = $this->_oConfig->getCountPerUser();
+        $iInvited = $this->_oDb->getInvites(array('type' => 'count_by_account', 'value' => $iAccountId));
+
+    	bx_import('BxDolPermalinks');
+        $sUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink($this->_oConfig->CNF['URL_INVITE']);
+
+        $this->addCss(array('main.css'));
+    	return $this->parseHtmlByName('block_invite.html', array(
+    		'style_prefix' => $this->_oConfig->getPrefix('style'),
+    		'text' => _t('_bx_invites_txt_invite_block_text', $iInvites - $iInvited),
+    		'url' => $sUrl
+    	));
+    }
+
+    public function getBlockRequest()
+    {
+    	bx_import('BxDolPermalinks');
+        $sUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink($this->_oConfig->CNF['URL_REQUEST']);
+
+    	$this->addCss(array('main.css'));
+    	return $this->parseHtmlByName('block_request.html', array(
+    		'style_prefix' => $this->_oConfig->getPrefix('style'),
+    		'text' => _t('_bx_invites_txt_request_block_text'),
+    		'url' => $sUrl
+    	));
+    }
+}
+
+/** @} */

+ 70 - 0
modules/boonex/invites/install/config.php

@@ -0,0 +1,70 @@
+<?php
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Invites Invites
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_invites',
+    'title' => 'Invites',
+    'note' => 'Invites module.',
+    'version' => '8.0.0.DEV',
+    'vendor' => 'BoonEx',
+	'help_url' => 'http://feed.boonex.com/?section={module_name}',
+
+    'compatible_with' => array(
+        '8.0.x'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/invites/',
+    'home_uri' => 'invites',
+
+    'db_prefix' => 'bx_inv_',
+    'class_prefix' => 'BxInv',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Invites',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'uninstall' => array (
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+);
+
+/** @} */

+ 22 - 0
modules/boonex/invites/install/installer.php

@@ -0,0 +1,22 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Invites Invites
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxDolStudioInstaller');
+
+class BxInvInstaller extends BxDolStudioInstaller
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}
+
+/** @} */

+ 109 - 0
modules/boonex/invites/install/langs/en.xml

@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+
+	<string name="_bx_invites"><![CDATA[Invites]]></string>
+
+	<!-- Forms -->
+	<string name="_bx_invites_form_invite"><![CDATA[Invite]]></string>
+	<string name="_bx_invites_form_invite_display_send"><![CDATA[Send]]></string>
+	<string name="_bx_invites_form_invite_input_sys_emails"><![CDATA[Emails]]></string>
+	<string name="_bx_invites_form_invite_input_emails"><![CDATA[Emails]]></string>
+	<string name="_bx_invites_form_invite_input_emails_inf"><![CDATA[Use semicolon to separate emails.]]></string>
+	<string name="_bx_invites_form_invite_input_emails_err"><![CDATA[You need to type at least one email.]]></string>
+	<string name="_bx_invites_form_invite_input_sys_text"><![CDATA[Text]]></string>
+	<string name="_bx_invites_form_invite_input_text"><![CDATA[Text]]></string>
+	<string name="_bx_invites_form_invite_input_text_err"><![CDATA[You need to type the text which will be added to invitation email.]]></string>
+	<string name="_bx_invites_form_invite_input_sys_do_submit"><![CDATA[Send]]></string>
+	<string name="_bx_invites_form_invite_input_do_submit"><![CDATA[Send]]></string>
+
+	<string name="_bx_invites_form_request"><![CDATA[Request Invite]]></string>
+	<string name="_bx_invites_form_request_display_send"><![CDATA[Send]]></string>
+	<string name="_bx_invites_form_request_input_sys_name"><![CDATA[Your Name]]></string>
+	<string name="_bx_invites_form_request_input_name"><![CDATA[Your Name]]></string>
+	<string name="_bx_invites_form_request_input_name_err"><![CDATA[You need to type your name.]]></string>
+	<string name="_bx_invites_form_request_input_sys_email"><![CDATA[Your email]]></string>
+	<string name="_bx_invites_form_request_input_email"><![CDATA[Your email]]></string>
+	<string name="_bx_invites_form_request_input_email_err"><![CDATA[You need to type the correct email.]]></string>
+	<string name="_bx_invites_form_request_input_sys_do_submit"><![CDATA[Send]]></string>
+	<string name="_bx_invites_form_request_input_do_submit"><![CDATA[Send]]></string>
+
+
+	<!-- Grids -->
+	<string name="_bx_invites_grid_column_title_name"><![CDATA[Name]]></string>
+	<string name="_bx_invites_grid_column_title_email"><![CDATA[Email]]></string>
+	<string name="_bx_invites_grid_column_title_nip"><![CDATA[IP]]></string>
+	<string name="_bx_invites_grid_column_title_date"><![CDATA[Date]]></string>
+
+	<string name="_bx_invites_grid_action_title_adm_invite"><![CDATA[Invite]]></string>
+	<string name="_bx_invites_grid_action_title_adm_delete"><![CDATA[Delete]]></string>
+
+
+	<!-- Pages and Blocks -->
+	<string name="_bx_invites_page_title_sys_invite"><![CDATA[Invite]]></string>
+	<string name="_bx_invites_page_title_invite"><![CDATA[Invite]]></string>
+	<string name="_bx_invites_page_block_title_invite_form"><![CDATA[Invite]]></string>
+
+	<string name="_bx_invites_page_title_sys_request"><![CDATA[Request Invite]]></string>
+	<string name="_bx_invites_page_title_request"><![CDATA[Request Invite]]></string>
+	<string name="_bx_invites_page_block_title_request_form"><![CDATA[Request Invite]]></string>
+
+	<string name="_bx_invites_page_title_sys_requests"><![CDATA[Manage Requests]]></string>
+	<string name="_bx_invites_page_title_requests"><![CDATA[Manage Requests]]></string>
+	<string name="_bx_invites_page_block_title_requests"><![CDATA[Manage Requests]]></string>
+
+	<string name="_bx_invites_page_block_title_invite"><![CDATA[Invite]]></string>
+
+
+	<!-- Menus -->
+	<string name="_bx_invites_menu_item_title_system_requests"><![CDATA[Invitation requests]]></string>
+	<string name="_bx_invites_menu_item_title_requests"><![CDATA[Invitation requests - {addon} awaiting]]></string>
+
+
+	<!-- Options -->
+	<string name="_bx_invites_option_count_per_user"><![CDATA[How many invitations one user can send]]></string>
+	<string name="_bx_invites_option_key_lifetime"><![CDATA[Ivitation key lifetime (in days)]]></string>
+	<string name="_bx_invites_option_enable_request_invite"><![CDATA[Enable "request invite" feature]]></string>
+	<string name="_bx_invites_option_requests_email"><![CDATA[Email to send invitation requests to]]></string>
+
+
+	<!-- ACL -->
+	<string name="_bx_invites_acl_action_invite"><![CDATA[Invite]]></string>
+	<string name="_bx_invites_acl_action_request"><![CDATA[Request invite]]></string>
+	<string name="_bx_invites_acl_action_delete_request"><![CDATA[Delete invitation requests]]></string>
+
+
+	<!-- Email Templates -->
+	<string name="_bx_invites_et_invite_form_message"><![CDATA[Invite form message.]]></string>
+	<string name="_bx_invites_et_invite_form_message_subject"><![CDATA[Invitation from {site_name}.]]></string>
+	<string name="_bx_invites_et_invite_form_message_body"><![CDATA[<bx_include_auto:_email_header.html />
+<p><b>Dear Friend</b>,</p>
+<p>You were invited by <u>{profile_name}</u> to join to <a href="{site_url}">{site_name}</a> community.<br />He(She) also wants to tell you the following:</p>
+<hr />
+<p>{text}</p>
+<hr />
+<p>Click the following link to join: <a href="{join_url}">{join_url}</a></p>
+<bx_include_auto:_email_footer.html />]]></string>
+
+	<string name="_bx_invites_et_request_form_message"><![CDATA[Request invite form message.]]></string>
+	<string name="_bx_invites_et_request_form_message_subject"><![CDATA[Request invitation.]]></string>
+	<string name="_bx_invites_et_request_form_message_body"><![CDATA[<bx_include_auto:_email_header.html />
+<p><b>Dear Administrator</b>,</p>
+<p>You were contacted by <u>{sender_name}</u> with email <u>{sender_email}</u> from <u>{sender_ip}</u> IP address.</p>
+<p>He (She) wants to get an invitation to join <b>{site_name}</b> site.</p>
+<bx_include_auto:_email_footer.html />]]></string>
+
+
+	<!-- Common Texts -->
+	<string name="_bx_invites_txt_invite_block_text"><![CDATA[You are very welcome to invite your friends to became members of our site. You have <b>{0}</b> invites.]]></string>
+	<string name="_bx_invites_txt_request_block_text"><![CDATA[Currently, registration is available by invitation only.]]></string>
+	
+	<string name="_bx_invites_btn_invite"><![CDATA[Invite]]></string>
+	<string name="_bx_invites_btn_request"><![CDATA[Request Invite]]></string>
+	<string name="_bx_invites_msg_invitation"><![CDATA[Hello! This site might be interesting for you.]]></string>
+	<string name="_bx_invites_msg_invitation_sent"><![CDATA[Invitation message was sent to {0} email addresses from the list.]]></string>
+	<string name="_bx_invites_msg_request_sent"><![CDATA[Invitation request was sent.]]></string>
+	<string name="_bx_invites_err_limit_reached"><![CDATA[The number of invitations sent by you reached the limit.]]></string>
+	<string name="_bx_invites_err_not_available"><![CDATA[The feature is not available now. Please, try again later.]]></string>
+	<string name="_bx_invites_err_invite"><![CDATA[Cannot send an invitation on request.]]></string>
+	<string name="_bx_invites_err_delete_request"><![CDATA[Cannot delete the request.]]></string>
+</resources>

+ 41 - 0
modules/boonex/invites/install/sql/disable.sql

@@ -0,0 +1,41 @@
+SET @sName = 'bx_invites';
+
+
+-- PAGES & BLOCKS
+DELETE FROM `sys_objects_page` WHERE `module` = @sName;
+DELETE FROM `sys_pages_blocks` WHERE `module` = @sName;
+
+
+-- MENU
+DELETE FROM `sys_objects_menu` WHERE `module` = @sName;
+DELETE FROM `sys_menu_sets` WHERE `module` = @sName;
+DELETE FROM `sys_menu_items` WHERE `module` = @sName;
+
+
+-- SETTINGS
+SET @iTypeId = (SELECT `ID` FROM `sys_options_types` WHERE `name` = @sName LIMIT 1);
+SET @iCategId = (SELECT `ID` FROM `sys_options_categories` WHERE `type_id` = @iTypeId LIMIT 1);
+DELETE FROM `sys_options` WHERE `category_id` = @iCategId;
+DELETE FROM `sys_options_categories` WHERE `type_id` = @iTypeId;
+DELETE FROM `sys_options_types` WHERE `id` = @iTypeId;
+
+
+-- ACL
+DELETE `sys_acl_actions`, `sys_acl_matrix` FROM `sys_acl_actions`, `sys_acl_matrix` WHERE `sys_acl_matrix`.`IDAction` = `sys_acl_actions`.`ID` AND `sys_acl_actions`.`Module` = @sName;
+DELETE FROM `sys_acl_actions` WHERE `Module` = @sName;
+
+
+-- EMAIL TEMPLATES
+DELETE FROM `sys_email_templates` WHERE `Module` = @sName;
+
+
+-- ALERTS
+SET @iHandlerId = (SELECT `id` FROM `sys_alerts_handlers` WHERE `name` = @sName LIMIT 1);
+DELETE FROM `sys_alerts` WHERE `handler_id` = @iHandlerId;
+DELETE FROM `sys_alerts_handlers` WHERE `id` = @iHandlerId LIMIT 1;
+
+
+-- GRIDS
+DELETE FROM `sys_objects_grid` WHERE `object` IN ('bx_invites_requests');
+DELETE FROM `sys_grid_fields` WHERE `object` IN ('bx_invites_requests');
+DELETE FROM `sys_grid_actions` WHERE `object` IN ('bx_invites_requests');

+ 129 - 0
modules/boonex/invites/install/sql/enable.sql

@@ -0,0 +1,129 @@
+SET @sName = 'bx_invites';
+
+
+-- PAGES & BLOCKS
+INSERT INTO `sys_objects_page`(`object`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `uri`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
+('bx_invites_invite', '_bx_invites_page_title_sys_invite', '_bx_invites_page_title_invite', @sName, 5, 2147483647, 1, 'invites-invite', 'page.php?i=invites-invite', '', '', '', 0, 1, 0, '', '');
+
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_invites_invite', 1, @sName, '_bx_invites_page_block_title_invite_form', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_invites";s:6:"method";s:21:"get_block_form_invite";}', 0, 1, 1);
+
+INSERT INTO `sys_objects_page`(`object`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `uri`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
+('bx_invites_request', '_bx_invites_page_title_sys_request', '_bx_invites_page_title_request', @sName, 5, 2147483647, 1, 'invites-request', 'page.php?i=invites-request', '', '', '', 0, 1, 0, '', '');
+
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_invites_request', 1, @sName, '_bx_invites_page_block_title_request_form', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_invites";s:6:"method";s:22:"get_block_form_request";}', 0, 1, 1);
+
+INSERT INTO `sys_objects_page`(`object`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `uri`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
+('bx_invites_requests', '_bx_invites_page_title_sys_requests', '_bx_invites_page_title_requests', @sName, 5, 192, 1, 'invites-requests', 'page.php?i=invites-requests', '', '', '', 0, 1, 0, '', '');
+
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_invites_requests', 1, @sName, '_bx_invites_page_block_title_requests', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_invites";s:6:"method";s:25:"get_block_manage_requests";}', 0, 1, 1);
+
+
+-- PAGES: add page block on dashboard
+SET @iPBCellDashboard = 3;
+SET @iPBOrderDashboard = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_pages_blocks` WHERE `object` = 'sys_dashboard' AND `cell_id` = @iPBCellDashboard LIMIT 1);
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('sys_dashboard', @iPBCellDashboard, @sName, '_bx_invites_page_block_title_invite', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_invites";s:6:"method";s:16:"get_block_invite";}', 0, 1, @iPBOrderDashboard + 1);
+
+
+-- MENU: dashboard manage tools
+SET @iManageMenuOrder = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_menu_items` WHERE `set_name`='sys_account_dashboard_manage_tools' LIMIT 1);
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `addon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
+('sys_account_dashboard_manage_tools', @sName, 'invites-requests', '_bx_invites_menu_item_title_system_requests', '_bx_invites_menu_item_title_requests', 'page.php?i=invites-requests', '', '_self', '', 'a:2:{s:6:"module";s:10:"bx_invites";s:6:"method";s:23:"get_menu_addon_requests";}', '', 192, 1, 0, @iManageMenuOrder + 1);
+
+
+-- SETTINGS
+SET @iTypeOrder = (SELECT MAX(`order`) FROM `sys_options_types` WHERE `group` = 'modules');
+INSERT INTO `sys_options_types`(`group`, `name`, `caption`, `icon`, `order`) VALUES 
+('modules', @sName, '_bx_invites', 'bx_invites@modules/boonex/invites/|std-mi.png', IF(ISNULL(@iTypeOrder), 1, @iTypeOrder + 1));
+SET @iTypeId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options_categories` (`type_id`, `name`, `caption`, `order`)
+VALUES (@iTypeId, @sName, '_bx_invites', 1);
+SET @iCategId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `check`, `check_error`, `extra`, `order`) VALUES
+('bx_invites_count_per_user', '5', @iCategId, '_bx_invites_option_count_per_user', 'digit', '', '', '', 1),
+('bx_invites_key_lifetime', '7', @iCategId, '_bx_invites_option_key_lifetime', 'digit', '', '', '', 2),
+('bx_invites_enable_request_invite', 'on', @iCategId, '_bx_invites_option_enable_request_invite', 'checkbox', '', '', '', 3),
+('bx_invites_requests_email', '', @iCategId, '_bx_invites_option_requests_email', 'digit', '', '', '', 4);
+
+
+-- ACL
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+(@sName, 'request', NULL, '_bx_invites_acl_action_request', '', 0, 2147483646);
+SET @iIdActionRequest = LAST_INSERT_ID();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+(@sName, 'delete request', NULL, '_bx_invites_acl_action_delete_request', '', 0, 1);
+SET @iIdActionDeleteRequest = LAST_INSERT_ID();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+(@sName, 'invite', NULL, '_bx_invites_acl_action_invite', '', 1, 1);
+SET @iIdActionInvite = LAST_INSERT_ID();
+
+SET @iUnauthenticated = 1;
+SET @iAccount = 2;
+SET @iStandard = 3;
+SET @iUnconfirmed = 4;
+SET @iPending = 5;
+SET @iSuspended = 6;
+SET @iModerator = 7;
+SET @iAdministrator = 8;
+SET @iPremium = 9;
+
+INSERT INTO `sys_acl_matrix` (`IDLevel`, `IDAction`) VALUES
+
+-- request invite
+(@iUnauthenticated, @iIdActionRequest),
+
+-- delete request
+(@iModerator, @iIdActionDeleteRequest),
+(@iAdministrator, @iIdActionDeleteRequest),
+
+-- invite
+(@iAccount, @iIdActionInvite),
+(@iStandard, @iIdActionInvite),
+(@iUnconfirmed, @iIdActionInvite),
+(@iPending, @iIdActionInvite),
+(@iSuspended, @iIdActionInvite),
+(@iModerator, @iIdActionInvite),
+(@iAdministrator, @iIdActionInvite),
+(@iPremium, @iIdActionInvite);
+
+
+-- EMAIL TEMPLATES
+INSERT INTO `sys_email_templates` (`Module`, `NameSystem`, `Name`, `Subject`, `Body`) VALUES 
+(@sName, '_bx_invites_et_invite_form_message', 'bx_invites_invite_form_message', '_bx_invites_et_invite_form_message_subject', '_bx_invites_et_invite_form_message_body'),
+(@sName, '_bx_invites_et_request_form_message', 'bx_invites_request_form_message', '_bx_invites_et_request_form_message_subject', '_bx_invites_et_request_form_message_body');
+
+
+-- ALERTS
+INSERT INTO `sys_alerts_handlers`(`name`, `class`, `file`, `service_call`) VALUES 
+(@sName, 'BxInvResponse', 'modules/boonex/invites/classes/BxInvResponse.php', '');
+SET @iHandler := LAST_INSERT_ID();
+
+INSERT INTO `sys_alerts` (`unit`, `action`, `handler_id`) VALUES
+('account', 'add_form', @iHandler),
+('account', 'added', @iHandler);
+
+
+-- GRIDS
+INSERT INTO `sys_objects_grid` (`object`, `source_type`, `source`, `table`, `field_id`, `field_order`, `field_active`, `paginate_url`, `paginate_per_page`, `paginate_simple`, `paginate_get_start`, `paginate_get_per_page`, `filter_fields`, `filter_fields_translatable`, `filter_mode`, `sorting_fields`, `sorting_fields_translatable`, `override_class_name`, `override_class_file`) VALUES
+('bx_invites_requests', 'Sql', 'SELECT * FROM `bx_inv_requests` WHERE 1 ', 'bx_inv_requests', 'id', '', '', '', 20, NULL, 'start', '', 'name,email', '', 'like', '', '', 'BxInvGridRequests', 'modules/boonex/invites/classes/BxInvGridRequests.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
+('bx_invites_requests', 'checkbox', '_sys_select', '2%', 0, '', '', 1),
+('bx_invites_requests', 'name', '_bx_invites_grid_column_title_name', '25%', 0, '', '', 2),
+('bx_invites_requests', 'email', '_bx_invites_grid_column_title_email', '20%', 1, '25', '', 3),
+('bx_invites_requests', 'nip', '_bx_invites_grid_column_title_nip', '15%', 0, '15', '', 4),
+('bx_invites_requests', 'date', '_bx_invites_grid_column_title_date', '20%', 0, '20', '', 5),
+('bx_invites_requests', 'actions', '', '18%', 0, '', '', 6);
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `confirm`, `order`) VALUES
+('bx_invites_requests', 'bulk', 'invite', '_bx_invites_grid_action_title_adm_invite', '', 0, 1),
+('bx_invites_requests', 'bulk', 'delete', '_bx_invites_grid_action_title_adm_delete', '', 1, 2),
+('bx_invites_requests', 'single', 'invite', '', 'envelope', 0, 1),
+('bx_invites_requests', 'single', 'delete', '', 'remove', 1, 2);

+ 69 - 0
modules/boonex/invites/install/sql/install.sql

@@ -0,0 +1,69 @@
+SET @sName = 'bx_invites';
+
+
+-- TABLES
+CREATE TABLE IF NOT EXISTS `bx_inv_invites` (
+  `id` int(11) NOT NULL auto_increment,
+  `account_id` int(11) collate utf8_unicode_ci NOT NULL,
+  `profile_id` int(11) collate utf8_unicode_ci NOT NULL,
+  `email` varchar(128) collate utf8_unicode_ci NOT NULL,
+  `date` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_inv_requests` (
+  `id` int(11) NOT NULL auto_increment,
+  `name` varchar(255) collate utf8_unicode_ci NOT NULL,
+  `email` varchar(128) collate utf8_unicode_ci NOT NULL,
+  `nip` int(11) unsigned NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`id`)
+);
+
+
+-- FORMS
+INSERT INTO `sys_objects_form` (`object`, `module`, `title`, `action`, `form_attrs`, `submit_name`, `table`, `key`, `uri`, `uri_title`, `params`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES
+('bx_invites_invite', @sName, '_bx_invites_form_invite', '', '', 'do_submit', 'bx_inv_invites', 'id', '', '', '', 0, 1, '', '');
+
+INSERT INTO `sys_form_displays` (`display_name`, `module`, `object`, `title`, `view_mode`) VALUES
+('bx_invites_invite_send', @sName, 'bx_invites_invite', '_bx_invites_form_invite_display_send', 0);
+
+INSERT INTO `sys_form_inputs` (`object`, `module`, `name`, `value`, `values`, `checked`, `type`, `caption_system`, `caption`, `info`, `required`, `collapsed`, `html`, `attrs`, `attrs_tr`, `attrs_wrapper`, `checker_func`, `checker_params`, `checker_error`, `db_pass`, `db_params`, `editable`, `deletable`) VALUES
+('bx_invites_invite', @sName, 'emails', '', '', 0, 'textarea', '_bx_invites_form_invite_input_sys_emails', '_bx_invites_form_invite_input_emails', '_bx_invites_form_invite_input_emails_inf', 1, 0, 0, '', '', '', 'Avail', '', '_bx_invites_form_invite_input_emails_err', '', '', 0, 0),
+('bx_invites_invite', @sName, 'text', '', '', 0, 'textarea', '_bx_invites_form_invite_input_sys_text', '_bx_invites_form_invite_input_text', '', 1, 0, 0, '', '', '', 'Length', 'a:2:{s:3:"min";i:10;s:3:"max";i:5000;}', '_bx_invites_form_invite_input_text_err', '', '', 0, 0),
+('bx_invites_invite', @sName, 'do_submit', '_bx_invites_form_invite_input_do_submit', '', 0, 'submit', '_bx_invites_form_invite_input_sys_do_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0);
+
+INSERT INTO `sys_form_display_inputs` (`display_name`, `input_name`, `visible_for_levels`, `active`, `order`) VALUES
+('bx_invites_invite_send', 'emails', 2147483647, 1, 1),
+('bx_invites_invite_send', 'text', 2147483647, 1, 2),
+('bx_invites_invite_send', 'do_submit', 2147483647, 1, 3);
+
+
+INSERT INTO `sys_objects_form` (`object`, `module`, `title`, `action`, `form_attrs`, `submit_name`, `table`, `key`, `uri`, `uri_title`, `params`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES
+('bx_invites_request', @sName, '_bx_invites_form_request', '', '', 'do_submit', 'bx_inv_requests', 'id', '', '', '', 0, 1, '', '');
+
+INSERT INTO `sys_form_displays` (`display_name`, `module`, `object`, `title`, `view_mode`) VALUES
+('bx_invites_request_send', @sName, 'bx_invites_request', '_bx_invites_form_request_display_send', 0);
+
+INSERT INTO `sys_form_inputs` (`object`, `module`, `name`, `value`, `values`, `checked`, `type`, `caption_system`, `caption`, `info`, `required`, `collapsed`, `html`, `attrs`, `attrs_tr`, `attrs_wrapper`, `checker_func`, `checker_params`, `checker_error`, `db_pass`, `db_params`, `editable`, `deletable`) VALUES
+('bx_invites_request', @sName, 'name', '', '', 0, 'text', '_bx_invites_form_request_input_sys_name', '_bx_invites_form_request_input_name', '', 1, 0, 0, '', '', '', 'Length', 'a:2:{s:3:"min";i:1;s:3:"max";i:150;}', '_bx_invites_form_request_input_name_err', 'Xss', '', 0, 0),
+('bx_invites_request', @sName, 'email', '', '', 0, 'text', '_bx_invites_form_request_input_sys_email', '_bx_invites_form_request_input_email', '', 1, 0, 0, '', '', '', 'Email', '', '_bx_invites_form_request_input_email_err', 'Xss', '', 0, 0),
+('bx_invites_request', @sName, 'do_submit', '_bx_invites_form_request_input_do_submit', '', 0, 'submit', '_bx_invites_form_request_input_sys_do_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0);
+
+INSERT INTO `sys_form_display_inputs` (`display_name`, `input_name`, `visible_for_levels`, `active`, `order`) VALUES
+('bx_invites_request_send', 'name', 2147483647, 1, 1),
+('bx_invites_request_send', 'email', 2147483647, 1, 2),
+('bx_invites_request_send', 'do_submit', 2147483647, 1, 3);
+
+
+-- STUDIO PAGE & WIDGET
+INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
+(3, @sName, '_bx_invites', '_bx_invites', 'bx_invites@modules/boonex/invites/|std-pi.png');
+SET @iPageId = LAST_INSERT_ID();
+
+SET @iParentPageId = (SELECT `id` FROM `sys_std_pages` WHERE `name` = 'home');
+SET @iParentPageOrder = (SELECT MAX(`order`) FROM `sys_std_pages_widgets` WHERE `page_id` = @iParentPageId);
+INSERT INTO `sys_std_widgets` (`page_id`, `module`, `url`, `click`, `icon`, `caption`, `cnt_notices`, `cnt_actions`) VALUES
+(@iPageId, @sName, '{url_studio}module.php?name=bx_invites', '', 'bx_invites@modules/boonex/invites/|std-wi.png', '_bx_invites', '', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:11:"get_actions";s:6:"params";a:0:{}s:5:"class";s:18:"TemplStudioModules";}');
+INSERT INTO `sys_std_pages_widgets` (`page_id`, `widget_id`, `order`) VALUES
+(@iParentPageId, LAST_INSERT_ID(), IF(ISNULL(@iParentPageOrder), 1, @iParentPageOrder + 1));

+ 19 - 0
modules/boonex/invites/install/sql/uninstall.sql

@@ -0,0 +1,19 @@
+SET @sName = 'bx_invites';
+
+
+-- TABLES
+DROP TABLE IF EXISTS `bx_inv_invites`;
+DROP TABLE IF EXISTS `bx_inv_requests`;
+
+
+-- FORMS ALL
+DELETE FROM `sys_form_display_inputs` WHERE `display_name` IN  (SELECT `display_name` FROM `sys_form_displays` WHERE `module` = @sName);
+DELETE FROM `sys_form_inputs` WHERE `module` = @sName;
+DELETE FROM `sys_form_displays` WHERE `module` = @sName;
+DELETE FROM `sys_objects_form` WHERE `module` = @sName;
+
+
+-- STUDIO PAGE & WIDGET
+DELETE FROM `tp`, `tw`, `tpw`
+USING `sys_std_pages` AS `tp`, `sys_std_widgets` AS `tw`, `sys_std_pages_widgets` AS `tpw`
+WHERE `tp`.`id` = `tw`.`page_id` AND `tw`.`id` = `tpw`.`widget_id` AND `tp`.`name` = @sName;

+ 19 - 0
modules/boonex/invites/request.php

@@ -0,0 +1,19 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Invites Invites
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+require_once(BX_DIRECTORY_PATH_INC . "design.inc.php");
+
+bx_import('BxDolLanguages');
+bx_import('BxDolRequest');
+
+BxDolRequest::processAsAction($GLOBALS['aModule'], $GLOBALS['aRequest']);
+
+/** @} */

+ 6 - 0
modules/boonex/invites/template/block_invite.html

@@ -0,0 +1,6 @@
+<div class="__style_prefix__-invite-text">__text__</div>
+<div class="__style_prefix__-invite-btn bx-def-margin-top">
+	<button type="button" onclick="javascript: window.open('__url__','_self');" class="bx-btn">
+		<bx_text:_bx_invites_btn_invite />
+	</button>
+</div>

+ 6 - 0
modules/boonex/invites/template/block_request.html

@@ -0,0 +1,6 @@
+<div class="__style_prefix__-request-text">__text__</div>
+<div class="__style_prefix__-request-btn bx-def-margin-top">
+	<button type="button" onclick="javascript: window.open('__url__','_self');" class="bx-btn">
+		<bx_text:_bx_invites_btn_request />
+	</button>
+</div>

+ 11 - 0
modules/boonex/invites/template/css/main.css

@@ -0,0 +1,11 @@
+/*--- Invite block ---*/
+div.bx-inv-invite-btn  {
+	text-align: center;
+}
+div.bx-inv-invite-btn .bx-btn {
+	float: none;
+	display: inline-block;
+}
+
+/*--- Request Invite block ---*/
+div.bx-inv-request-btn  {}

BIN
modules/boonex/invites/template/images/icons/std-mi.png


BIN
modules/boonex/invites/template/images/icons/std-pi.png


BIN
modules/boonex/invites/template/images/icons/std-si.png


BIN
modules/boonex/invites/template/images/icons/std-wi.png