Browse Source

#668 Dolphin Connect module

Alex Trofimov 9 years ago
parent
commit
e5abbe29e4

+ 21 - 0
modules/boonex/dolphin_connect/classes/BxDolConAlerts.php

@@ -0,0 +1,21 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaConnect Dolphin Connect
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxDolConAlerts extends BxBaseModConnectAlerts
+{
+    function __construct()
+    {
+        parent::__construct();
+        $this -> oModule = BxDolModule::getInstance('bx_dolcon');
+    }
+}
+
+/** @} */

+ 49 - 0
modules/boonex/dolphin_connect/classes/BxDolConConfig.php

@@ -0,0 +1,49 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaConnect Dolphin Connect
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxDolConConfig extends BxBaseModConnectConfig
+{
+    public $sApiID;
+    public $sApiSecret;
+    public $sApiUrl;
+
+    public $sPageStart;
+    public $sPageHandle;
+
+    public $sScope = 'basic';
+
+    function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $this -> sApiID = getParam('bx_dolcon_api_key');
+        $this -> sApiSecret = getParam('bx_dolcon_secret');
+        $this -> sApiUrl = trim(getParam('bx_dolcon_url'), '/') . (getParam('bx_dolcon_url_rewrite') ? '/m/oauth2/' : '/modules/?r=oauth2/');
+
+        $this -> sSessionUid = 'dolcon_session';
+        $this -> sSessionProfile = 'dolcon_session_profile';
+
+        $this -> sEmailTemplatePasswordGenerated = 'bx_dolcon_password_generated';
+        $this -> sDefaultTitleLangKey = '_bx_dolcon';
+
+        $this -> sRedirectPage = getParam('bx_dolcon_redirect_page');
+        $this -> sProfilesModule = getParam('bx_dolcon_module');
+        $this -> isAlwaysConfirmEmail = (bool)getParam('bx_dolcon_confirm_email'); 
+        $this -> isAlwaysAutoApprove = (bool)getParam('bx_dolcon_approve');
+
+        $this -> bAutoFriends = 'on' == getParam('bx_dolcon_auto_friends');
+
+        $this -> sPageStart = BX_DOL_URL_ROOT . $this -> getBaseUri() . 'start';
+        $this -> sPageHandle = BX_DOL_URL_ROOT . $this -> getBaseUri() . 'handle';
+    }
+}
+
+/** @} */

+ 20 - 0
modules/boonex/dolphin_connect/classes/BxDolConDb.php

@@ -0,0 +1,20 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaConnect Dolphin Connect
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxDolConDb extends BxBaseModConnectDb
+{
+    function __construct(&$oConfig)
+    {
+        parent::__construct($oConfig);
+    }
+}
+
+/** @} */

+ 172 - 0
modules/boonex/dolphin_connect/classes/BxDolConModule.php

@@ -0,0 +1,172 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaConnect Dolphin Connect
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxDolConModule extends BxBaseModConnectModule
+{
+    function __construct(&$aModule)
+    {
+        parent::__construct($aModule);
+    }
+
+    /**
+     * Redirect to remote site login form
+     *
+     * @return n/a/ - redirect or HTML page in case of error
+     */
+    function actionStart()
+    {
+        if (isLogged())
+            $this->_redirect ($this -> _oConfig -> sDefaultRedirectUrl);
+
+        if (!$this->_oConfig->sApiID || !$this->_oConfig->sApiSecret || !$this->_oConfig->sApiUrl) {
+            require_once(BX_DIRECTORY_PATH_INC . 'design.inc.php');
+            bx_import('BxDolLanguages');
+            $sCode =  MsgBox( _t('_bx_dolcon_profile_error_api_keys') );
+            $this->_oTemplate->getPage(_t('_bx_dolcon'), $sCode);            
+        } 
+        else {
+
+            // define redirect URL to the remote site                
+            $sUrl = bx_append_url_params($this->_oConfig->sApiUrl . 'auth', array(
+                'response_type' => 'code',
+                'client_id' => $this->_oConfig->sApiID,
+                'redirect_uri' => $this->_oConfig->sPageHandle,
+                'scope' => $this->_oConfig->sScope,
+                'state' => $this->_genCsrfToken(),
+            ));
+            $this->_redirect($sUrl);
+        }
+    }
+
+    function actionHandle()
+    {
+        require_once(BX_DIRECTORY_PATH_INC . 'design.inc.php');
+
+        // check CSRF token
+        if ($this->_getCsrfToken() != bx_get('state')) {
+            $this->_oTemplate->getPage(_t('_Error'), MsgBox(_t('_sys_connect_state_invalid')));
+            return;
+        }
+
+        // check code
+        $sCode = bx_get('code');
+        if (!$sCode) {
+            $sErrorDescription = bx_get('error_description') ? bx_get('error_description') : _t('_error occured');
+            $this->_oTemplate->getPage(_t('_Error'), MsgBox($sErrorDescription));
+            return;
+        }
+
+        // make request for token
+        $s = bx_file_get_contents($this->_oConfig->sApiUrl . 'token', array(
+            'client_id'     => $this->_oConfig->sApiID,
+            'client_secret' => $this->_oConfig->sApiSecret,
+            'grant_type'    => 'authorization_code',
+            'code'          => $sCode,
+            'redirect_uri'  => $this->_oConfig->sPageHandle,
+        ), 'post');
+
+        // handle error
+        if (!$s || NULL === ($aResponse = json_decode($s, true)) || !isset($aResponse['access_token']) || isset($aResponse['error'])) {
+            $sErrorDescription = isset($aResponse['error_description']) ? $aResponse['error_description'] : _t('_error occured');
+            $this->_oTemplate->getPage(_t('_Error'), MsgBox($sErrorDescription));
+            return;
+        }
+
+        // get the data, especially access_token
+        $sAccessToken = $aResponse['access_token'];
+        $sExpiresIn = $aResponse['expires_in'];
+        $sExpiresAt = new \DateTime('+' . $sExpiresIn . ' seconds');
+        $sRefreshToken = $aResponse['refresh_token'];
+
+        // request info about profile
+        $s = bx_file_get_contents($this->_oConfig->sApiUrl . 'api/me', array(), 'get', array(
+            'Authorization: Bearer ' . $sAccessToken,
+        ));
+
+        // handle error
+        if (!$s || NULL === ($aResponse = json_decode($s, true)) || !$aResponse || isset($aResponse['error'])) {
+            $sErrorDescription = isset($aResponse['error_description']) ? $aResponse['error_description'] : _t('_error occured'); 
+            $this->_oTemplate->getPage(_t('_Error'), MsgBox($sErrorDescription));
+            return;
+        }
+
+        $aRemoteProfileInfo = $aResponse;
+
+        if ($aRemoteProfileInfo) {
+
+            // check if user logged in before
+            $iLocalProfileId = $this->_oDb->getProfileId($aRemoteProfileInfo['id']);
+            
+            if ($iLocalProfileId && $oProfile = BxDolProfile::getInstance($iLocalProfileId)) {
+                // user already exists
+                $this->setLogged($oProfile ->id());
+            }             
+            else {  
+                // register new user
+                $this->_createProfile($aRemoteProfileInfo);
+            }
+        } 
+        else {
+            $this->_oTemplate->getPage(_t('_Error'), MsgBox(_t('_sys_connect_profile_error_info')));
+        }
+    }
+
+    /**
+     * @param $aProfileInfo - remote profile info
+     * @param $sAlternativeName - suffix to add to NickName to make it unique
+     * @return profile array info, ready for the local database
+     */
+    protected function _convertRemoteFields($aProfileInfo, $sAlternativeName = '')
+    {
+        $aProfileFields = $aProfileInfo;
+
+        $sFullname = $aProfileInfo['NickName'];
+        if (!empty($aProfileInfo['FullName']))
+            $sFullname = $aProfileInfo['FullName'];
+        if (!empty($aProfileInfo['FirstName']))
+            $sFullname = $aProfileInfo['FirstName'] . (!empty($aProfileInfo['LastName']) ? ' ' . $aProfileInfo['LastName'] : '');
+
+        $aProfileFields['name'] = $aProfileInfo['NickName'];
+        $aProfileFields['fullname'] = $sFullname;
+        $aProfileFields['picture'] = $aProfileInfo['picture'];
+        
+        return $aProfileFields;
+    }
+
+    protected function _genCsrfToken($bReturn = false)
+    {
+        if (getParam('sys_security_form_token_enable') != 'on' || defined('BX_DOL_CRON_EXECUTE'))
+            return false;
+
+        $oSession = BxDolSession::getInstance();
+
+        $iCsrfTokenLifetime = (int)$this->_oDb->getParam('sys_security_form_token_lifetime');
+        if ($oSession->getValue('bx_dolcon_csrf_token') === false || ($iCsrfTokenLifetime != 0 && time() - (int)$oSession->getValue('csrf_token_time') > $iCsrfTokenLifetime)) {
+            $sToken = genRndPwd(20, false);
+            $oSession->setValue('bx_dolcon_csrf_token', $sToken);
+            $oSession->setValue('bx_dolcon_csrf_token_time', time());
+        }
+        else {
+            $sToken = $oSession->getValue('bx_dolcon_csrf_token');
+        }
+
+        return $sToken;
+    }
+
+    protected function _getCsrfToken()
+    {
+        $oSession = BxDolSession::getInstance();
+        return $oSession->getValue('bx_dolcon_csrf_token');
+    }
+
+}
+
+/** @} */

+ 27 - 0
modules/boonex/dolphin_connect/classes/BxDolConStudioPage.php

@@ -0,0 +1,27 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaConnect Dolphin Connect
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxDolConStudioPage extends BxTemplStudioModule
+{
+    function getHelp ()
+    {
+        return _t('_bx_dolcon_information_block', BX_DOL_URL_ROOT);
+    }
+
+    protected function getPageCaptionHelp()
+    {
+        $oTemplate = BxDolStudioTemplate::getInstance();
+        $sContent = '<a href="' . BX_DOL_URL_STUDIO . 'module.php?name=bx_dolcon&page=help">' . _t('_sys_connect_information') . "</a>";
+        return $oTemplate->parseHtmlByName('page_caption_help.html', array('content' => $sContent));
+    }
+}
+
+/** @} */

+ 20 - 0
modules/boonex/dolphin_connect/classes/BxDolConTemplate.php

@@ -0,0 +1,20 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaConnect Dolphin Connect
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxDolConTemplate extends BxBaseModConnectTemplate
+{
+    function __construct(&$oConfig, &$oDb)
+    {
+        parent::__construct($oConfig, $oDb);
+    }
+}
+
+/** @} */

+ 68 - 0
modules/boonex/dolphin_connect/install/config.php

@@ -0,0 +1,68 @@
+<?php 
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaConnect Dolphin Connect
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_dolcon',
+    'title' => 'Dolphin connect',
+    'note' => 'Join the site using Dolphin site account credentials.',
+    'version' => '9.0.0.DEV',
+    'vendor' => 'Boonex',
+    'help_url' => 'http://feed.boonex.com/?section={module_name}',
+
+    'compatible_with' => array(
+        '9.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/dolphin_connect/',
+    'home_uri' => 'dolcon',
+
+    'db_prefix' => 'bx_dolcon_',
+    'class_prefix' => 'BxDolCon',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Dolphin Connect',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+    ),
+    'uninstall' => array (
+        'execute_sql' => 1,
+        'update_languages' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+);
+
+/** @} */

+ 20 - 0
modules/boonex/dolphin_connect/install/installer.php

@@ -0,0 +1,20 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaConnect Dolphin Connect
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxDolConInstaller extends BxDolStudioInstaller
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}
+
+/** @} */

+ 28 - 0
modules/boonex/dolphin_connect/install/langs/en.xml

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+	<string name="_sys_module_dolcon"><![CDATA[Dolphin Connect]]></string>
+	<string name="_bx_dolcon"><![CDATA[Dolphin Connect]]></string>
+	<string name="_bx_dolcon_settings"><![CDATA[Dolphin Connect]]></string>
+	<string name="_bx_dolcon_information_block"><![CDATA[
+This module can be used to login to this site using Dolphin site (master site) credentials. <br />
+To make it work, go to the master site, install "OAuth2 Server" module and add new client site, specify the desired title and the following URL:<br />
+<strong>{0}</strong><br />
+Then enter generated on the master site the Key & Server pair in this module settings.]]></string>
+	<string name="_bx_dolcon_profile_error_api_keys"><![CDATA[Please configure the module in admin panel (can't define API key, secret & URL)]]></string>
+	<string name="_bx_dolcon_chart"><![CDATA[Dolphin Profiles]]></string>
+	<string name="_bx_dolcon_auth_title"><![CDATA[Dolphin Connect]]></string>
+
+    <string name="_bx_dolcon_adm_stg_cpt_type"><![CDATA[Dolphin Connect]]></string>
+    <string name="_bx_dolcon_option_app_id"><![CDATA[Dolphin App Key]]></string>
+    <string name="_bx_dolcon_option_app_secret"><![CDATA[Dolphin App Secret]]></string>
+    <string name="_bx_dolcon_option_app_url"><![CDATA[Dolphin Site URL]]></string>
+    <string name="_bx_dolcon_option_auto_friends"><![CDATA[Auto-friend members if they are already friends on Dolphin site]]></string>
+    <string name="_bx_dolcon_option_rewrite"><![CDATA[Use rewrite URLs on Dolphin site]]></string>
+
+	<string name="_bx_dolcon_et_password_generated"><![CDATA[Dolphin connect temporary password]]></string>
+	<string name="_bx_dolcon_et_password_generated_subject"><![CDATA[Temporary password]]></string>
+	<string name="_bx_dolcon_et_password_generated_body"><![CDATA[{email_header}
+<p>Temporary password - <b>{password}</b></p>
+<p>Change it after logging-in.</p>
+{email_footer}]]></string>
+</resources>

+ 25 - 0
modules/boonex/dolphin_connect/install/sql/disable.sql

@@ -0,0 +1,25 @@
+
+-- Email template
+
+DELETE FROM `sys_email_templates` WHERE `Name` = 'bx_dolcon_password_generated';
+
+-- Auth objects
+
+DELETE FROM `sys_objects_auths` WHERE `Name` = 'bx_dolcon';
+
+-- Alerts
+
+SET @iHandlerId := (SELECT `id` FROM `sys_alerts_handlers`  WHERE `name`  =  'bx_dolcon');
+
+DELETE FROM `sys_alerts_handlers` WHERE `id` = @iHandlerId;
+DELETE FROM `sys_alerts` WHERE `handler_id` =  @iHandlerId;
+
+-- Options
+
+DELETE FROM `top`, `toc`, `to` USING `sys_options_types` AS `top` LEFT JOIN `sys_options_categories` AS `toc` ON `top`.`id`=`toc`.`type_id` LEFT JOIN `sys_options` AS `to` ON `toc`.`id`=`to`.`category_id` WHERE `top`.`name` = 'bx_dolcon';
+
+-- Pages
+
+DELETE FROM `sys_objects_page` WHERE `module` = 'bx_dolcon';
+DELETE FROM `sys_pages_blocks` WHERE `module` = 'bx_dolcon';
+

+ 51 - 0
modules/boonex/dolphin_connect/install/sql/enable.sql

@@ -0,0 +1,51 @@
+
+-- Email template
+
+INSERT INTO `sys_email_templates` (`Module`, `NameSystem`, `Name`, `Subject`, `Body`) VALUES
+('bx_dolcon', '_bx_dolcon_et_password_generated', 'bx_dolcon_password_generated', '_bx_dolcon_et_password_generated_subject', '_bx_dolcon_et_password_generated_body');
+
+-- Auth objects
+
+INSERT INTO `sys_objects_auths` (`Name`, `Title`, `Link`, `Icon`) VALUES
+('bx_dolcon', '_bx_dolcon_auth_title', 'modules/?r=dolcon/start', 'sign-in');
+
+-- Alerts
+
+INSERT INTO `sys_alerts_handlers` SET `name` = 'bx_dolcon', `class` = 'BxDolConAlerts', `file` = 'modules/boonex/dolphin_connect/classes/BxDolConAlerts.php';
+
+SET @iHandlerId := (SELECT `id` FROM `sys_alerts_handlers`  WHERE `name` = 'bx_dolcon');
+
+INSERT INTO `sys_alerts` (`unit`, `action`, `handler_id`) VALUES
+('account', 'logout', @iHandlerId),
+('profile', 'delete', @iHandlerId),
+('profile', 'add', @iHandlerId);
+
+-- Options
+
+SET @iTypeOrder = (SELECT MAX(`order`) FROM `sys_options_types` WHERE `group` = 'modules');
+INSERT INTO `sys_options_types` (`group`, `name`, `caption`, `icon`, `order`) VALUES 
+('modules', 'bx_dolcon', '_bx_dolcon_adm_stg_cpt_type', 'bx_dolcon@modules/boonex/dolphin_connect/|std-icon.svg', IF(NOT ISNULL(@iTypeOrder), @iTypeOrder + 1, 1));
+SET @iTypeId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options_categories` (`type_id`, `name`, `caption`, `order` )  
+VALUES (@iTypeId, 'bx_dolcon_general', '_sys_connect_adm_stg_cpt_category_general', 1);
+SET @iCategId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `check`, `check_error`, `order`, `extra`) VALUES
+('bx_dolcon_api_key', '', @iCategId, '_bx_dolcon_option_app_id', 'digit', '', '', 10, ''),
+('bx_dolcon_secret', '', @iCategId, '_bx_dolcon_option_app_secret', 'digit', '', '', 20, ''),
+('bx_dolcon_url', '', @iCategId, '_bx_dolcon_option_app_url', 'digit', '', '', 30, ''),
+('bx_dolcon_redirect_page', 'dashboard', @iCategId, '_sys_connect_option_redirect', 'select', '', '', 40, 'join,settings,dashboard,index'),
+('bx_dolcon_module', 'bx_persons', @iCategId, '_sys_connect_option_module', 'select', '', '', 50, 'a:2:{s:6:"module";s:9:"bx_dolcon";s:6:"method";s:20:"get_profiles_modules";}'),
+('bx_dolcon_auto_friends', 'on', @iCategId, '_bx_dolcon_option_auto_friends', 'checkbox', '', '', 60, ''),
+('bx_dolcon_confirm_email', 'on', @iCategId, '_sys_connect_option_confirm_email', 'checkbox', '', '', 70, ''),
+('bx_dolcon_approve', '', @iCategId, '_sys_connect_option_approve', 'checkbox', '', '', 80, ''),
+('bx_dolcon_url_rewrite', 'on', @iCategId, '_bx_dolcon_option_rewrite', 'checkbox', '', '', 90, '');
+
+-- Pages
+
+INSERT INTO `sys_objects_page`(`object`, `uri`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
+('bx_dolcon_error', 'dolcon-error', '_bx_dolcon_error', '_bx_dolcon_error', 'bx_dolcon', 5, 2147483647, 0, '', '', '', '', 0, 1, 0, 'BxDolConPage', 'modules/boonex/dolphin_connect/classes/BxDolConPage.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES 
+('bx_dolcon_error', 1, 'bx_dolcon', '_bx_dolcon_error', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_dolcon\";s:6:\"method\";s:10:\"last_error\";}', 0, 0, 1, 1);

+ 21 - 0
modules/boonex/dolphin_connect/install/sql/install.sql

@@ -0,0 +1,21 @@
+
+CREATE TABLE `bx_dolcon_accounts` (
+  `local_profile` int(10) unsigned NOT NULL,
+  `remote_profile` int(10) unsigned NOT NULL,
+  PRIMARY KEY (`local_profile`),
+  KEY `remote_profile` (`remote_profile`)
+) ENGINE=MyISAM;
+
+-- Studio page and widget
+
+INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
+(3, 'bx_dolcon', '_bx_dolcon', '_bx_dolcon', 'bx_dolcon@modules/boonex/dolphin_connect/|std-icon.svg');
+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, 'bx_dolcon', '{url_studio}module.php?name=bx_dolcon', '', 'bx_dolcon@modules/boonex/dolphin_connect/|std-icon.svg', '_bx_dolcon', '', '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));
+

+ 9 - 0
modules/boonex/dolphin_connect/install/sql/uninstall.sql

@@ -0,0 +1,9 @@
+
+DROP TABLE IF EXISTS `bx_dolcon_accounts`;
+
+-- Studio page and 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` = 'bx_dolcon';
+

+ 18 - 0
modules/boonex/dolphin_connect/request.php

@@ -0,0 +1,18 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaConnect Dolphin Connect
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+require_once(BX_DIRECTORY_PATH_INC . 'profiles.inc.php');
+
+check_logged();
+
+BxDolRequest::processAsAction($GLOBALS['aModule'], $GLOBALS['aRequest']);
+
+/** @} */

+ 31 - 0
modules/boonex/dolphin_connect/template/images/icons/std-icon.svg

@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="606px" height="606px" viewBox="0 0 606 606" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>Dolphin connect</title>
+    <defs>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
+            <stop stop-color="#FFFFFF" stop-opacity="0.2" offset="0%"></stop>
+            <stop stop-color="#000000" stop-opacity="0.2" offset="100%"></stop>
+        </linearGradient>
+        <path d="M552.268958,552.268958 C600,504.537813 600,431.458333 600,300 C600,168.541667 600,95.4621875 552.268958,47.7310417 C504.537813,0 431.458333,0 300,0 C168.541667,0 95.4621875,0 47.7310417,47.7310417 C0,95.4621875 0,168.541667 0,300 C0,431.458333 0,504.537813 47.7310417,552.268958 C95.4621875,600 168.541667,600 300,600 C431.458333,600 504.537813,600 552.268958,552.268958 Z" id="path-2"></path>
+    </defs>
+    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="dolphin-connect" transform="translate(3.000000, 3.000000)">
+            <g id="Squircle2-Copy-6">
+                <g id="Shape">
+                    <use fill="#FFFFFF" xlink:href="#path-2"></use>
+                    <use stroke="#000000" stroke-width="4.04" fill="url(#linearGradient-1)" xlink:href="#path-2"></use>
+                </g>
+            </g>
+            <g id="Dolphin_Logo" transform="matrix(75 0 0 -75 42 420)" stroke-width="0.1" stroke="#3399ff" stroke-linejoin="round">
+                <path d="M 2.4 1 L 2.4 0 L 3.4 0 L 3.4 1 L 2.4 1 z" fill="#3399ff" />
+                <path d="M 2.2 0.1 L 1.2 1.1 L 1.2 2.1 L 2.2 1.1 L 2.2 0.1 z" fill="#3399ff" />
+                <path d="M 3.6 1 L 4.6 1 L 3.6 0 L 3.6 1 z" fill="#3399ff" />
+                <path d="M 1.05 1 L 2.05 0 L 0.05 0 L 1.05 1 z" fill="#3399ff" />
+                <path d="M 2.55 1.2 L 4.55 3.2 L 4.55 1.2 L 2.55 1.2 z" fill="#3399ff" />
+                <path d="M 4.75 1.2 L 4.75 3.2 L 6.75 3.2 L 4.75 1.2 z" fill="#3399ff" />
+                <path d="M 4.841 1 L 5.549 1.707 L 5.549 0.293 L 4.841 1 z" fill="#3399ff" />
+            </g>
+        </g>
+    </g>
+</svg>
+