AntonLV 8 лет назад
Родитель
Сommit
3531faf27d

+ 51 - 0
modules/boonex/dolphin_migration/updates/9.0.0_9.0.1/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Dolphin Migration',
+    'version_from' => '9.0.0',
+	'version_to' => '9.0.1',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '9.0.0-RC8'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/dolphin_migration/updates/update_9.0.0_9.0.1/',
+	'home_uri' => 'dolphin_migration_update_900_901',
+
+	'module_dir' => 'boonex/dolphin_migration/',
+	'module_uri' => 'dolphin_migration',
+
+    'db_prefix' => 'bx_dolphin_',
+    'class_prefix' => 'BxDolM',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+		'execute_sql' => 0,
+        'update_files' => 1,
+        'update_languages' => 0,
+		'clear_db_cache' => 0,
+    ),
+
+	/**
+     * Category for language keys.
+     */
+    'language_category' => 'Boonex Dolphin Migration Tool',
+
+	/**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/dolphin_migration/updates/9.0.0_9.0.1/install/installer.php

@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ */
+
+class BxDolMUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+	{
+        parent::__construct($aConfig);
+    }
+}

+ 144 - 0
modules/boonex/dolphin_migration/updates/9.0.0_9.0.1/source/classes/BxDolMModule.php

@@ -0,0 +1,144 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup   DolphinMigration  Dolphin Migration
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+require_once('BxMDb.php'); 
+if ( function_exists('ini_set'))
+{
+    ini_set('max_execution_time', 0);
+}
+	
+class BxDolMModule extends BxBaseModGeneralModule
+{
+    protected $_oMDb = null;			
+	public function __construct(&$aModule){
+        parent::__construct($aModule);       
+    }		
+	
+	public function actionPerformAction($sModule, $sAction = 'clean')
+	{
+		if (!$sModule || !isset($this -> _oConfig -> _aMigrationModules[$sModule]))
+		{
+			echo json_encode(array('code' => 1, 'message' => _t('_bx_dolphin_migration_nothing_to_remove')));
+			exit;
+		}
+		
+		require_once($this -> _oConfig -> _aMigrationModules[$sModule]['migration_class'] . '.php');
+        $oModule = new $this -> _oConfig -> _aMigrationModules[$sModule]['migration_class']($this, $this -> _oMDb);
+		
+		return $sAction == 'clean' ? $oModule -> dropMID() : $oModule -> removeContent();
+	}	
+	
+	public function actionStartTransfer($aModules)
+	{
+		if (empty($aModules))
+		{
+			echo json_encode(array('code' => 1, 'message' => _t('_bx_dolphin_migration_successfully_finished')));
+			exit;
+		}
+		
+		$this -> initDb();		
+		header('Content-Type:text/javascript');			
+		
+		foreach($aModules as $iKey => $sModule){
+            if( $sModule && !empty(($this -> _oConfig -> _aMigrationModules[$sModule])))
+			{
+				$sTransferred = $this -> _oDb -> getTransferStatus($sModule);	
+				if ($sTransferred == 'finished') 
+					continue;
+		             
+				if(isset($this -> _oConfig -> _aMigrationModules[$sModule]['dependencies']) && is_array($this -> _oConfig -> _aMigrationModules[$sModule]['dependencies']))
+				{ 
+						foreach($this -> _oConfig -> _aMigrationModules[$sModule]['dependencies'] as $iKey => $sDependenciesModule)
+	                    {
+	                        $sTransferred = $this -> _oDb -> getTransferStatus($sDependenciesModule);							
+	                        if( $sTransferred != 'finished')
+								return _t('_bx_dolphin_migration_install_before', _t("_bx_dolphin_migration_data_{$sDependenciesModule}"));
+						}			   
+				}
+				 
+				if(isset($this -> _oConfig -> _aMigrationModules[$sModule]['plugins']) && is_array($this -> _oConfig -> _aMigrationModules[$sModule]['plugins']))
+				{
+					$sPlugins = '';
+					foreach($this -> _oConfig -> _aMigrationModules[$sModule]['plugins'] as $sKey => $sTitle)
+					{
+						if (!$this -> _oDb -> isPluginInstalled($sKey)) 	                                      								
+							$sPlugins .= $sTitle . ', ';								
+					}
+						
+					if ($sPlugins)
+						return _t('_bx_dolphin_migration_install_plugin', trim($sPlugins, ', '), $sModule);														
+	            }		 
+					
+                // create new module's instance;
+				require_once($this -> _oConfig -> _aMigrationModules[$sModule]['migration_class'] . '.php');
+				// set as started;
+                $this -> _oDb -> updateTransferStatus($sModule, 'started');
+				
+                 // create new migration instance;
+                $oModule = new $this -> _oConfig -> _aMigrationModules[$sModule]['migration_class']($this, $this -> _oMDb);
+                if($oModule -> runMigration()) 
+	                $this -> _oDb -> updateTransferStatus($sModule, 'finished');                
+                else {                    
+                    $this -> _oDb -> updateTransferStatus($sModule, 'error');
+					return _t('_bx_dolphin_migration_successfully_failed');					
+                }
+            }		
+	     }
+		
+		return _t('_bx_dolphin_migration_successfully_finished');	
+	}
+	
+	/** 
+	* Creates date for migration
+	* @param ref $oMDb Dolphin database connect
+	*/
+	public function createMigration()
+	{
+		if (is_null($this -> _oMDb)) 
+			$this -> initDb();
+
+		$this -> _oDb -> cleanTrasnfersTable();
+		foreach ($this -> _oConfig -> _aMigrationModules as $sName => $aModule)
+		{			
+			if ($this -> _oMDb -> isTableExists($aModule['table_name']))
+			{
+				
+				//Create transferring class object
+				require_once($aModule['migration_class'] . '.php');			
+				$oObject = new $aModule['migration_class']($this, $this -> _oMDb);			
+				
+				if ($mixedNumber = $oObject -> getTotalRecords()) 
+						$this -> _oDb -> addToTransferList($sName, $mixedNumber);				
+			}	
+		}		
+	}
+	
+	/** 
+	* Init Dolphin database connect
+	* @return mixed
+	*/	
+	public function initDb()
+	{
+		$aConfig = array(
+                'host'    => $this -> _oDb -> getExtraParam('host'),
+                'user'	  => $this -> _oDb -> getExtraParam('user'),
+            	'pwd'     => $this -> _oDb -> getExtraParam('passwd'),
+                'name' 	  => $this -> _oDb -> getExtraParam('db'),
+				'port'    => $this -> _oDb -> getExtraParam('port'),
+				'sock'	  => $this -> _oDb -> getExtraParam('sock'),
+			);
+					
+		$this -> _oMDb = new BxMDb($aConfig);		
+		return $this -> _oMDb -> connect(); 
+	}	
+}
+
+/** @} */

+ 351 - 0
modules/boonex/dolphin_migration/updates/9.0.0_9.0.1/source/classes/BxDolMProfiles.php

@@ -0,0 +1,351 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    DolphinMigration  Dolphin Migration
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+bx_import('BxDolProfile');
+bx_import('BxDolTranscoderImage');
+bx_import('BxDolStorage');
+	
+require_once('BxDolMData.php');	
+	
+class BxDolMProfiles extends BxDolMData
+{
+    public function __construct(&$oMigrationModule, &$seDb)
+    {
+		parent::__construct($oMigrationModule, $seDb);
+		$this -> _sModuleName = 'profiles';
+		$this -> _sTableWithTransKey = 'sys_accounts';
+    }
+
+	public function getTotalRecords()
+	{
+		return (int)$this -> _mDb -> getOne("SELECT COUNT(*) FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] . "`");			
+	}
+	
+	public function runMigration()
+	{
+		if (!$this -> getTotalRecords())
+		{
+			  $this -> setResultStatus(_t('_bx_dolphin_migration_no_data_to_transfer'));
+	          return BX_MIG_SUCCESSFUL;
+		}	
+		
+		$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_profiles'));
+        $sError = $this -> profilesMigrtion();
+        if($sError) {
+              $this -> setResultStatus($sError);
+              return BX_MIG_FAILED;
+        }
+	
+        $this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_profiles_finished', $this -> _iTransferred));
+		return BX_MIG_SUCCESSFUL;
+    }
+	
+	/**
+	* Check if profile with the same nickname already exists
+	* @param string $sNickName name of the user
+	* @return string
+         */ 	 
+	private function isProfileExisted($sNickName, $sEmail)
+	{
+         $sQuery  = $this -> _oDb -> prepare("SELECT COUNT(*) FROM `sys_accounts` WHERE `name` = ? OR `email` = ?", $sNickName, $sEmail);
+         return $this -> _oDb -> getOne($sQuery) ? true : false;
+	} 
+	
+	function profilesMigrtion()
+    {
+			$this -> createMIdField();
+		
+			// get ID of the latest transferred profile from Dolphin
+			$iProfileID = $this -> getLastMIDField();
+			$sStart = '';
+			if ($iProfileID) 				
+				$sStart = "WHERE `ID` > {$iProfileID}";
+			else 
+				$this -> addPreValues('Sex', true, 2); // transfer all sex values more then 2 value
+
+			$aResult = $this -> _mDb -> getAll("SELECT * FROM `"  . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] . "` {$sStart} ORDER BY `ID` ASC");			
+
+			$aAdditionalProfileFields = $this -> getAssocFields();
+			$aSex = $this -> getPreValuesBy('Sex', 'Value', 'Order');
+				
+			$oLanguage = BxDolLanguages::getInstance();
+			foreach($aResult as $iKey => $aValue)
+			{                  
+
+				if($aValue['NickName'] && !$this -> isProfileExisted($aValue['NickName'], $aValue['Email'])) 
+				  {					
+					$sQuery = $this -> _oDb -> prepare( 
+                     "
+                     	INSERT INTO
+                     		`sys_accounts`
+                     	SET
+                     		`name`   			= ?,
+                     		`email`      		= ?,
+                     		`password`   		= ?,
+                     		`salt`		   		= ?,
+							`role`				= ?,		
+                     		`lang_id`			= ?,
+							`added`				= ?,
+                     		`changed`	  		= ?,
+                     		`logged` 			= ?,
+							`email_confirmed`	= ?,
+							`receive_updates`	= ?,	
+							`receive_news`		= ?
+							
+                     ", 
+						$aValue['NickName'], 
+						$aValue['Email'], 
+						$aValue['Password'],
+						$aValue['Salt'],
+						$aValue['Role'],
+						$aValue['LangID'],
+						strtotime($aValue['DateReg']),
+						strtotime($aValue['DateLastEdit']),
+						strtotime($aValue['DateLastLogin']),
+						isset($aValue['Status']) && $aValue['Status'] != 'Unconfirmed' ? 1 : 0,
+						$aValue['EmailNotify'],
+						$aValue['EmailNotify']
+						);
+						
+					$this -> _oDb -> query($sQuery);										
+					$iAccountId = $this -> _oDb -> lastId();
+					if (!$iAccountId) 
+						continue;
+					
+					$this -> setMID($iAccountId, $aValue['ID']);
+					
+					$sFullName = isset($aValue['FullName']) ? $aValue['FullName'] : "{$aValue['FirstName']} {$aValue['LastName']}";
+					
+					$sQuery = $this -> _oDb -> prepare( 
+	                     "
+	                     	INSERT INTO
+	                     		`bx_persons_data`
+	                     	SET
+	                     		`author`   			= 0,
+	                     		`added`      		= ?,
+	                     		`changed`   		= ?,
+								`picture`			= 0,		
+	                     		`cover`				= 0,
+								`fullname`			= ?,
+								`birthday`			= ?,
+								`gender`			= ?,
+								`allow_view_to`		= ?,
+								`featured`			= ?,
+								`views`				= ?,
+								`description`		= ?
+	                     ", 						
+							strtotime($aValue['DateReg']),
+							strtotime($aValue['DateLastEdit']),
+							$sFullName,
+							isset($aValue['DateOfBirth']) ? $aValue['DateOfBirth'] : 'NULL',
+							isset($aValue['Sex']) && $aValue['Sex'] ? $aSex[$aValue['Sex']] : 1,
+							isset($aValue['allow_view_to']) ? $aValue['allow_view_to'] : 3,
+							isset($aValue['Featured']) ? (int)$aValue['Featured'] : 0,
+							isset($aValue['Views']) ? (int)$aValue['Views'] : 0,
+							isset($aValue['DescriptionMe']) ? $aValue['DescriptionMe'] : ''
+							);
+						
+						$this -> _oDb -> query($sQuery);	
+						$iContentId = $this -> _oDb -> lastId();
+						
+						$this -> _oDb -> query("INSERT INTO `sys_profiles` SET `account_id` = {$iAccountId}, `type` = 'system', `content_id` = {$iContentId}, `status` = 'active'");
+						$this -> _oDb -> query("INSERT INTO `sys_profiles` SET `account_id` = {$iAccountId}, `type` = 'bx_persons', `content_id` = {$iContentId}, `status` = 'active'");
+						$iProfile = $this -> _oDb -> lastId();
+
+						if($iProfile)
+							BxDolAccountQuery::getInstance() -> updateCurrentProfile($iAccountId, $iProfile);
+						
+						$sQuery = $this -> _oDb -> prepare("UPDATE `bx_persons_data` SET `author` = ? WHERE `id` = ?", $iProfile, $iContentId);						
+						$this -> _oDb -> query($sQuery);
+
+						$this -> exportAvatar($iContentId, $aValue);                   
+						
+						$sResult = $this -> exportFriends($aValue['ID']);
+						if($sResult)
+							return $sResult;                     
+
+						 $this -> _iTransferred++;
+                  }
+             }
+        }
+
+	/**
+	* Get Avatar's image  path
+	* @param int $iImgId image ID
+	* @return string
+         */ 	
+	private function getProfileImage($aProfileInfo)
+	{	   
+       $iProfileId = $aProfileInfo['ID'];	   
+	   
+	   $sAvatarType = $this -> _mDb -> getParam('sys_member_info_thumb');
+	   $sImagePath = $this -> _oDb -> getExtraParam('root') . 'modules' . DIRECTORY_SEPARATOR . 'boonex' . DIRECTORY_SEPARATOR;
+	   if ($sAvatarType == 'bx_photos_thumb')
+		{
+			$sAlbumName = $this -> _mDb -> getParam('bx_photos_profile_album_name');
+			$aReplacement = array(
+				'{nickname}' => $aProfileInfo['NickName'],
+				'{fullname}' =>  $aProfileInfo['NickName']
+			);
+			
+			$sAlbumName = str_replace(array_keys($aReplacement), array_values($aReplacement), $sAlbumName);
+			$sAlbumName = uriFilter($sAlbumName);
+			$aInfo = $this -> _mDb -> getRow("SELECT `bx_photos_main`.*  FROM `bx_photos_main`
+					LEFT JOIN `sys_albums_objects` ON `sys_albums_objects`.`id_object`=`bx_photos_main`.`ID` 
+					LEFT JOIN `sys_albums` ON `sys_albums`.`ID`=`sys_albums_objects`.`id_album` 
+					WHERE `bx_photos_main`.`Status` ='approved' AND `bx_photos_main`.`Owner` =:id AND `sys_albums`.`Status` ='active' AND `sys_albums`.`Type` ='bx_photos' AND `sys_albums`.`Uri` = :uri LIMIT 1", array('uri' => $sAlbumName, 'id' => $aProfileInfo['ID']));
+			
+			if (!empty($aInfo) && isset($aInfo['ID']))
+				$sImagePath = $sImagePath . "photos" . DIRECTORY_SEPARATOR . "data" . DIRECTORY_SEPARATOR . "files" . DIRECTORY_SEPARATOR ."{$aInfo['ID']}.{$aInfo['Ext']}";
+		}
+		else
+		{
+			$iId = $this -> _mDb -> getOne("SELECT `id` FROM `bx_avatar_images` WHERE `author_id` = :id LIMIT 1", array('id' => $aProfileInfo['ID']));
+			if ($iId)
+				$sImagePath = $sImagePath . "avatar" . DIRECTORY_SEPARATOR . "data" . DIRECTORY_SEPARATOR . "images" . DIRECTORY_SEPARATOR ."{$iId}b.jpg";
+		}
+
+	   if (file_exists($sImagePath))
+		   return $sImagePath;
+
+	   return false;	 
+	}
+ 
+	private function exportFriends($iProfileId)
+    {
+       $iProfileId = (int) $iProfileId;
+       $sQuery = $this -> _mDb -> prepare("SELECT * FROM `sys_friend_list` WHERE `ID` = {$iProfileId} OR `Profile` = {$iProfileId}");
+	   $aFriends = $this -> _mDb -> getAll($sQuery);
+
+		foreach($aFriends as $iKey => $aValue)
+		{
+			$iUserId = $this -> getProfileId($aValue['ID']);
+			$iFriendId = $this -> getProfileId($aValue['Profile']);
+			if( !$this -> isFriendExists($iUserId, $iFriendId))
+			{
+
+				   $sQuery =  $this -> _oDb -> prepare("
+						INSERT IGNORE INTO
+							`sys_profiles_conn_friends`
+						SET
+						   `initiator`	= ?,
+						   `content`    = ?,
+						   `mutual`     = ?,
+						   `added`     	= UNIX_TIMESTAMP()
+				   ", $iUserId, $iFriendId, (int)($aValue['status'] == 'active'));
+
+				   $iResult = (int) $this -> _oDb -> query($sQuery);
+				   if($iResult <= 0) {
+					   return _t('_bx_dolphin_migration_friends_exports_error');
+				   }
+				}
+				
+		}	    
+	}
+
+	private function exportAvatar($iProfileId, $aProfileInfo)
+    {
+       $iProfileId = (int) $iProfileId;
+       $sAvatarPath = $this -> getProfileImage($aProfileInfo);
+       if($sAvatarPath)
+		{
+			$oStorage = BxDolStorage::getObjectInstance('bx_persons_pictures'); 				
+				$iId = $oStorage->storeFileFromPath($sAvatarPath, false, $iProfileId); 
+				if ($iId)
+				{ 
+					$sQuery = $this -> _oDb -> prepare("UPDATE `bx_persons_data` SET `Picture` = ? WHERE `id` = ?", $iId, $iProfileId);
+					$this -> _oDb -> query($sQuery);								
+				}
+		}
+    }
+
+	private function isFriendExists($iProfileId, $iFriendId)
+    {
+            $iProfileId = (int) $iProfileId;
+            $iFriendId  = (int) $iFriendId;
+
+            $sQuery =  "
+            	SELECT 
+            		COUNT(*) 
+            	FROM 
+            		`sys_profiles_conn_friends` 
+            	WHERE
+            		(
+            			(`initiator` = {$iProfileId} AND `content` = {$iFriendId})
+            				OR
+            			(`initiator` = {$iFriendId} AND `content` = {$iProfileId})	
+            		)
+            ";
+
+            return $this -> _oDb -> getOne($sQuery) ? true : false;
+	}
+	
+	public function removeContent()
+	{
+		if (!$this -> _oDb -> isTableExists($this -> _sTableWithTransKey) || !$this -> _oDb -> isFieldExists($this -> _sTableWithTransKey, $this -> _sTransferFieldIdent))
+			return false;
+		
+		$iNumber = 0;
+		$aRecords = $this -> _oDb -> getAll("SELECT * FROM `{$this -> _sTableWithTransKey}` WHERE `{$this -> _sTransferFieldIdent}` !=0");
+		if (!empty($aRecords))
+		{
+			foreach($aRecords as $iKey => $aValue)
+			{
+				$oAccount = BxDolAccount::getInstance($aValue['id']);
+				if ($oAccount)
+					$oAccount -> delete(true);			
+				
+				$iNumber++;
+			}
+					
+			if ($iNumber)
+			foreach ($this -> _oConfig -> _aMigrationModules as $sName => $aModule)
+			{
+				//Create transferring class object
+				require_once($aModule['migration_class'] . '.php');			
+				$oObject = new $aModule['migration_class']($this -> _oMainModule, $this -> _mDb);			
+				$oObject -> removeContent();				
+			}
+		}	
+		
+		parent::removeContent();
+		return $iNumber;
+	}
+	/**
+	 *  Adds fields list ()if doesn't exist or value to existed fields list 
+	 *  
+	 *  @param string $sName list name
+	 *  @param boolean $bUseOrder use Order field instead of Value as value for profile
+	 *  @param int $iStart start value, to show all above it
+	 *  @param boolean $bCreate create fields list if doesn't exists
+	 *  @return string fields list name
+	 */
+	private function addPreValues($sName, $bUseOrder = false, $iStart = 0, $bCreate = false)
+	{
+		$sKeyField = 'Value';
+		if ($bUseOrder)
+			$sKeyField = 'Order';
+
+		$aPairs = $this -> getPreValuesBy($sName, $sKeyField, 'LKey', $iStart);
+		$aValues = array();
+		foreach($aPairs as $sKey => $sValue)
+		{
+			$aTranslations = $this -> getLKeyTranslations($sValue);
+			$aValues[$sKey] = !empty($aTranslations) && sizeof($aTranslations) > 1 ? $this -> getLKeyTranslations($sValue) : $aTranslations[$this -> getDefaultLang()];
+		}
+
+		return $this -> transferPreValues($sName, $sName, $aValues, true);	
+	}
+	
+}
+
+	
+/** @} */

+ 383 - 0
modules/boonex/dolphin_migration/updates/9.0.0_9.0.1/source/classes/BxDolMProfilesFields.php

@@ -0,0 +1,383 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    DolphinMigration  Dolphin Migration
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+    
+require_once('BxDolMData.php');
+bx_import('BxDolStudioLanguagesUtils');
+
+class BxDolMProfilesFields extends BxDolMData
+{
+	/**
+	 *  @var  $_aProfileFields profile fields for transfer
+	 */
+	private $_aProfileFields = array();
+	
+	/**
+	 *  @var  $_aFiltered exclude listed filed from migration list
+	 */
+	private $_aFiltered = array(
+									'ID', 'NickName', 'Email', 'Password', 
+									'Role', 'LangID', 'DateLastNav', 'DateReg', 
+									'DateLastEdit', 'DateLastLogin', 'Sex', 
+									'DateOfBirth', 'EmailNotify', 'Avatar', 'allow_view_to', 
+									'Featured', 'DescriptionMe', 'FullName'
+								);
+	/**
+	 *  @var  $_oAssocFields list of the fields from Dolphin
+	 */	
+	private $_oAssocFields = null;
+
+    public function __construct($oMigrationModule, &$seDb)
+    {
+        parent::__construct($oMigrationModule, $seDb);  
+		$this -> _sModuleName = 'profile_fields';
+		$this -> _sTableWithTransKey = 'sys_form_inputs';	
+    }
+
+	public function getTotalRecords()
+	{
+		$this -> _oAssocFields =  $this -> getAssocFields();
+		foreach($this -> _oAssocFields as $sKey => $aValue)
+		{
+			if (in_array($aValue['name'], $this -> _aFiltered) || (!$aValue['add'] && !$aValue['edit'] && !$aValue['view'])) 
+				continue;
+			
+			$this -> _aProfileFields[$aValue['name']] = array(
+		           'name' => $aValue['name'],
+				   'type' => $this -> getConvertToUnaType($aValue['type']),
+		           'caption' => $this -> getLKeyTranslations($aValue['title']),
+				   'required' => $aValue['required'],
+				   'add' =>  $aValue['add'],
+				   'edit' =>  $aValue['edit'],
+				   'view' =>  $aValue['view'],
+				   'values' => $this -> getFieldValues($sKey)
+		       );
+		}
+		
+		return sizeof($this -> _aProfileFields);
+	}
+	
+	/**
+	 *  Convert Dolphin's fields types to UNA format
+	 *  
+	 *  @param int $sType Dolphin's field
+	 *  @return array
+	 */
+	private function getConvertToUnaType($sType)
+	{
+		$aM2UNATypes = array(
+			'text' => array(
+				'type' => 'text',
+				'db_pass' => 'Xss',
+				'sql' => "varchar(255) default ''",
+			),
+			'system' => array(
+				'type' => 'text',
+				'db_pass' => 'Xss',
+				'sql' => "varchar(255) default ''",
+			),
+			'html_area' => array(
+				'type' => 'textarea',
+				'db_pass' => 'XssMultiline',
+				'sql' => "text default ''",
+			),
+			'area' => array(
+				'type' => 'textarea',
+				'db_pass' => 'XssMultiline',
+				'sql' => "text default ''",
+			),
+			'select_one' =>  array(
+				'type' => 'select',
+				'db_pass' => 'Xss',
+				'sql' => "varchar(255) default NULL",
+			),
+			'date' => array(
+				'type' => 'date',
+				'db_pass' => 'Date',
+				'sql' => "date default NULL",
+			),
+			'num' => array(
+				'type' => 'text',
+				'db_pass' => 'Int',
+				'sql' => "int(10) default NULL",
+			),
+			'bool' =>  array(
+				'type' => 'checkbox',
+				'db_pass' => 'Xss',
+				'sql' => "varchar(255) default NULL",
+			),
+			'select_set' => array(
+				'type' => 'checkbox_set',
+				'db_pass' => 'Set',
+				'sql' => "bigint(20) default NULL",
+			),
+			'pass' =>  array(
+				'type' => 'password',
+				'sql' => "varchar(40) default NULL",
+			),
+			'range' => array(
+				'type' => 'doublerange',
+				'db_pass' => 'Xss',
+				'sql' => "varchar(255) default NULL",
+			)
+		);
+
+		return $aM2UNATypes[$sType] ? $aM2UNATypes[$sType] : $aM2UNATypes['text']; 
+	}
+		
+	public function runMigration()
+	{		 
+		if (!$this -> getTotalRecords())
+		{
+			$this -> setResultStatus(_t('_bx_dolphin_migration_no_data_to_transfer'));
+	        return BX_MIG_SUCCESSFUL;			  
+		}	 
+		
+		$this -> createMIdField();		
+		$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_profile_fields'));		
+		$i = 0;
+		foreach($this -> _aProfileFields as $sKey => $aItem)
+		{
+			if (!$this -> _oDb -> isFieldExists('bx_persons_data', $sKey))
+			{
+			if (!$this -> _oDb -> query("ALTER TABLE `bx_persons_data` ADD `{$sKey}` {$aItem['type']['sql']}")){
+						 $this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_profile_field_can_not_be_transferred'));
+						 return BX_MIG_FAILED;
+				   }			   
+			}
+			  
+			//continue;
+			if ($this -> isFieldTransfered($sKey)) 
+				continue;
+			   
+			$iKeyID = time() + $i++; // unique language keys postfix			
+			$sQuery = $this -> _oDb -> prepare("
+				INSERT INTO `{$this -> _sTableWithTransKey}` SET
+					`object`	= 'bx_person', 
+					`module`	= 'custom',
+					`values`	= ?,
+					`name`		= ?,
+					`db_pass`	= ?,
+					`type`		= ?,
+					`required`	= ?,
+					`caption_system` = ?,
+					`caption`	= ?", 
+					$this -> transferPreValues($sKey, $aItem['name'], $aItem['values']), 
+					$sKey,
+					$aItem['type']['db_pass'],
+					$aItem['type']['type'],
+					$aItem['required'],
+					'_sys_form_txt_field_caption_system_' . $iKeyID,
+					'_sys_form_txt_field_caption_' . $iKeyID
+					);
+			
+			if (!$this -> _oDb -> query($sQuery))
+			{
+				$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_profile_field_can_not_be_transferred'));
+				return BX_MIG_FAILED;				
+			}			   
+			
+			$iFieldId = $this -> _oDb -> lastId();
+			$this -> setMID($iFieldId, $iFieldId);
+			
+			// create form fields	
+			$this -> _oDb -> query($sQuery);
+			
+			$sQueryDisplay = "INSERT INTO `sys_form_display_inputs` (`id`, `display_name`, `input_name`, `visible_for_levels`, `active`, `order`) VALUES";			
+			if ($aItem['view'])
+				$sQueryDisplay .= "(NULL, 'bx_person_view', '{$sKey}', 2147483647, 1, 0),";
+			
+			if ($aItem['add'])
+				$sQueryDisplay .= "(NULL, 'bx_person_add', '{$sKey}', 2147483647, 1, 0),";
+			
+			if ($aItem['edit'])
+				$sQueryDisplay .= "(NULL, 'bx_person_edit', '{$sKey}', 2147483647, 1, 0),";
+			
+			// add display for view and add forms
+			$this -> _oDb -> query(trim($sQueryDisplay, ','));
+			// add lanungage keys with translations
+			
+			foreach($this -> _aLanguages as $sLangKey => $sValue)
+			{
+				$sTitle = isset($aItem['caption'][$sLangKey]) ? $aItem['caption'][$sLangKey] : $sKey;
+				$this -> _oLanguage -> addLanguageString('_sys_form_txt_field_caption_system_' . $iKeyID, $sTitle, $this -> _aLanguages[$sLangKey], 0, false);
+				$this -> _oLanguage -> addLanguageString('_sys_form_txt_field_caption_' . $iKeyID, $sTitle, $this -> _aLanguages[$sLangKey]);
+			}
+			
+				$this -> _iTransferred++;
+		}		
+			
+		$this -> migrateProfileFieldsInfo(); 
+			
+		$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_profile_fields_finished', $this -> _iTransferred));
+		return BX_MIG_SUCCESSFUL;
+	}
+
+	private function isFieldTransfered($sName)
+	{
+		$sQuery = $this -> _oDb -> prepare("SELECT COUNT(*) FROM `sys_form_inputs` WHERE `object` = 'bx_person' AND `module` = 'custom' AND `name` = ? LIMIT 1", $sName);
+		return (int)$this -> _oDb -> getOne($sQuery) > 0;
+	}        
+			
+	/**
+	* Returns Una profile fields list
+	* @param int $iProfileId profile ID
+	* @return array
+	*/ 
+	private function getPersonsFieldValues($iProfileId)
+	{
+		return $this -> _oDb -> getRow("SELECT * FROM `bx_persons_data` WHERE `id` = {$iProfileId} LIMIT 1");			
+	}		
+	
+	/**
+	 *  Builds value for multivalues type fields
+	 *  
+	 *  @param array $aFiled fields params
+	 *  @param string $sFiledValue value
+	 *  @return int value
+	 */
+	private function convertValues($aFiled, $sFiledValue)
+	{
+		$aOriginalFields = $this -> getAssocFields();
+		if (!$aOriginalFields[$aFiled['name']]['values'] || $aOriginalFields[$aFiled['name']]['values'] && substr($aOriginalFields[$aFiled['name']]['values'], 0, 2) != '#!')
+			return $sFiledValue;
+		
+		$aItems = explode(',', $sFiledValue);
+		$aPairs = $this -> getPreValuesBy(substr($aOriginalFields[$aFiled['name']]['values'], 2), 'Value', 'Order');
+		$iResult = 0;
+		foreach($aItems as $iKey => $sValue)
+			$iResult += pow(2, (int)$aPairs[$sValue] - 1);			
+		
+		return $iResult ? $iResult : $sFiledValue;
+	}
+	
+	/**
+	* Migrate profile fields values for transferred profiles
+	 *  
+	 *  @return void
+	 */
+	private function migrateProfileFieldsInfo()
+    {
+        $sQuery = "SELECT * FROM `" . $this -> _oConfig -> _aMigrationModules['profiles']['table_name'] . "`";
+        $aProfiles = $this -> _mDb -> getAll($sQuery);
+		
+		foreach($aProfiles as $iKey => $aProfile)
+		{
+           if (!($iProfileId =  $this -> getContentId($aProfile['ID']))) 
+			   continue;
+		   	                
+			$aValues = array();
+			$sNewField = '';
+			$aCurrentMembersValues = $this -> getPersonsFieldValues($iProfileId);
+	        foreach($this -> _aProfileFields as $sFieldName => $aItem)
+			{
+				if (!(isset($aProfile[$sFieldName]) && $aProfile[$sFieldName] && empty($aCurrentMembersValues[$sFieldName])))
+					continue;
+				
+				$sNewField .= "`{$aItem['name']}` = :{$aItem['name']},";
+				$aValues[$sFieldName] = $this -> convertValues($aItem, $aProfile[$sFieldName]);				
+			}
+			
+			if ($sNewField)
+			{
+				$sNewField = trim($sNewField, ',');
+
+			    $sQuery = 
+				"
+					UPDATE
+						`bx_persons_data`
+					SET
+						{$sNewField}
+					WHERE
+						`id` = {$iProfileId}
+				";
+				
+				$this -> _oDb -> query($sQuery, $aValues);
+			}
+							
+		}	
+	}		
+	/**
+	 *  Builds list for fields lists with translations
+	 *  
+	 *  @param int $sField fields list's name
+	 *  @param int $bGetKeyIfExists dont add values if list exists.
+	 *  @return mixed array with fields list or pre values key list name
+	 */
+	public function getFieldValues($sField, $bGetKeyIfExists = true)
+	{
+		$aItems = array();
+		$sValues = $this -> _mDb -> getOne("SELECT `Values` FROM `sys_profile_fields` WHERE `name` = :name", array('name' => $sField));
+		if (empty($sValues))
+			return '';
+		
+		$aItems = array();
+		if (substr($sValues, 0, 2) == '#!')
+		{
+			$sKey = substr($sValues, 2);			
+			if ($this -> isKeyPreKeyExits($sKey) && $bGetKeyIfExists)
+				return $sValues;
+			
+			$aValues = $this -> getPreValuesBy();
+			foreach($aValues as $iKey => $sValue)
+				$aItems[$iKey] = $this -> getLKeyTranslations($sValue);
+		}
+		else
+		{
+			$aValues = preg_split('/\r\n|\n|\r/', $sValues);		
+			foreach($aValues as $iKey => $sValue)
+				$aItems[$sValue] = $this -> getLKeyTranslations("_FieldValues_{$sValue}");
+		}
+
+		return $aItems;		
+	}
+	
+	public function removeContent()
+	{
+		if (!$this -> _oDb -> isTableExists($this -> _sTableWithTransKey) || !$this -> _oDb -> isFieldExists($this -> _sTableWithTransKey, $this -> _sTransferFieldIdent))
+			return false;
+	
+		$aRecords = $this -> _oDb -> getAll("SELECT `ti` . * , `tdi`.`id` AS  `di_id` , `tdi`.`display_name` AS  `display_name` , `tdi`.`visible_for_levels` AS `visible_for_levels` 
+											FROM  `sys_form_display_inputs` AS  `tdi` 
+											LEFT JOIN  `sys_form_inputs` AS  `ti` ON  `tdi`.`input_name` =  `ti`.`name` 
+											WHERE `ti`.`object` =  'bx_person' AND `ti`.`{$this -> _sTransferFieldIdent}` !=0");
+		if (!empty($aRecords))
+		{
+			$iNumber = 0;		
+			foreach($aRecords as $iKey => $aValue)
+			{
+				$sSql = $this -> _oDb -> prepare("DELETE `td`, `tdi` FROM `sys_form_display_inputs` AS `tdi` LEFT JOIN `sys_form_inputs` AS `td` ON `tdi`.`input_name`=`td`.`name` WHERE `td`.`object`='bx_person' AND `td`.`name` = ?", $aValue['name']);
+				if ($this-> _oDb -> query($sSql))
+				{
+					$oLanguage = BxDolStudioLanguagesUtils::getInstance();
+					if(!empty($aValue['caption']))
+						$oLanguage->deleteLanguageString($aValue['caption']);
+					
+					if(!empty($aValue['caption_system']))
+						$oLanguage->deleteLanguageString($aValue['caption_system']);
+					
+					if(!empty($aValue['info']))
+						$oLanguage->deleteLanguageString($aValue['info']);
+					
+					if(!empty($aValue['checker_error']))
+						$oLanguage->deleteLanguageString($aValue['checker_error']);
+				
+					(int)$this -> _oDb -> query("ALTER TABLE `bx_persons_data` DROP `{$aValue['name']}`");
+					
+					$iNumber++;
+				}
+			}
+		}				
+		parent::removeContent();			
+		return $iNumber;
+	}
+}
+
+/** @} */

+ 387 - 0
modules/boonex/dolphin_migration/updates/9.0.0_9.0.1/source/classes/BxMDb.php

@@ -0,0 +1,387 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    DolphinMigration  Dolphin Migration
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+/** 
+ * BxMDb Class allows to create connect with Dolphin's database
+  */	
+class BxMDb
+{
+	static $_rLink;
+    static $_aDbCacheData;
+    static $_sErrorKey = 'bx_db_error';	
+    static $_aErrors = array(
+    	BX_DB_ERR_CONNECT_FAILD => 'Database connect failed',
+    	BX_DB_ERR_QUERY_ERROR => 'Database query error',
+    	BX_DB_ERR_ESCAPE => 'Escape string error'
+    );
+
+	var $_bPdoPersistent;
+	var $_iPdoFetchType;
+	var $_iPdoErrorMode;
+
+	var $_bErrorChecking;
+    var $_aError;
+
+	var $_sHost, $_sPort, $_sSocket, $_sDbname, $_sUser, $_sPassword, $_sCharset, $_sStorageEngine;
+
+    var $_oStatement = null;
+    var $_oDbCacheObject = null;
+	
+	public function __construct($aDbConf = false)
+    {
+
+        $this->_iPdoFetchType = PDO::FETCH_ASSOC;
+        $this->_iPdoErrorMode = BX_DB_MODE_EXCEPTION;
+
+        $this->_bErrorChecking = true;
+        $this->_aError = array();
+
+        $this->_sStorageEngine = 'MYISAM';
+				
+		$this->_sHost = $aDbConf['host'];
+        $this->_sPort = $aDbConf['port'];
+        $this->_sSocket = $aDbConf['sock'];
+        $this->_sDbname = $aDbConf['name'];
+        $this->_sUser = $aDbConf['user'];
+        $this->_sPassword = $aDbConf['pwd'];
+      
+       @set_exception_handler(array($this, 'pdoExceptionHandler'));
+    }
+	
+	/**
+	 * get mysql version
+	 */
+    public function getVersion()
+    {
+        $s = $this->getOne("SELECT VERSION()");
+        return preg_match("/([0-9\.]+)/", $s, $m) ? $m[1] : false;
+    }
+	
+	public function connect()
+    {
+    	if(self::$_rLink)
+    		return true;
+
+    	try {
+	    	$sDsn = "mysql:host=" . $this->_sHost . ";";
+	   		$sDsn .= $this->_sPort ? "port=" . $this->_sPort . ";" : "";
+	   		$sDsn .= $this->_sSocket ? "unix_socket=" . $this->_sSocket . ";" : "";
+	    	$sDsn .= "dbname=" . $this->_sDbname . ";charset=UTF8";
+
+	        self::$_rLink = new PDO($sDsn, $this->_sUser, $this->_sPassword, array(
+				PDO::ATTR_ERRMODE => $this->_iPdoErrorMode,
+				PDO::ATTR_DEFAULT_FETCH_MODE => $this->_iPdoFetchType,
+				PDO::ATTR_PERSISTENT => $this->_bPdoPersistent
+	        ));
+
+	    	$this->pdoExec("SET NAMES 'utf8'");
+	        $this->pdoExec("SET sql_mode = ''");
+			
+			$sVer = $this->getVersion();
+            $sStorageEngine = !$sVer || version_compare($sVer, '5.7.5', '>=') ? 'default_storage_engine' : 'storage_engine';
+            $this->pdoExec("SET $sStorageEngine=" . $this->_sStorageEngine);
+
+			self::$_aDbCacheData = array();
+    	}
+    	catch (PDOException $oException) {
+    		$oException->errorInfo[self::$_sErrorKey] = array(
+    			'code' => BX_DB_ERR_CONNECT_FAILD,
+    			'message' => $oException->getMessage(),
+    			'trace' => $oException->getTrace()
+    		);
+
+    		throw $oException;
+    	}
+		
+		return true;
+    }
+	
+	public function res($oStatement, $aBindings = array(), $bVerbose = null)
+    {
+		if(!$oStatement || !($oStatement instanceof PDOStatement))
+            return false;
+
+		if($oStatement->errorCode() == BX_PDO_STATE_SUCCESS)
+			return true;
+
+		if(isset($GLOBALS['bx_profiler']))
+        	$GLOBALS['bx_profiler']->beginQuery($oStatement->queryString);
+		
+		$bResult = $this->executeStatement($oStatement, $aBindings, $bVerbose);
+
+		//if mysql connection is lost - reconnect and try again
+        if(!$bResult && !$this->ping()) {
+            $this->disconnect();
+            $this->connect();
+
+            $bResult = $this->executeStatement($oStatement, $aBindings, $bVerbose);
+        }
+
+        if(isset($GLOBALS['bx_profiler']))
+        	$GLOBALS['bx_profiler']->endQuery($bResult);
+
+		//is needed for SILENT mode
+		if(!$bResult && !empty($this->_aError))
+			$this->error($this->_aError);
+
+        return $bResult;
+    }
+	
+	public function ping()
+    {
+    	try {
+    		$this->pdoQuery("SELECT 1");
+    	}
+    	catch (PDOException $e) {
+    		return false;
+    	}
+
+    	return true;
+    }
+	
+	public function pdoQuery($sQuery)
+    {
+    	return self::$_rLink->query($sQuery);
+    }
+	
+	public function pdoExec($sQuery)
+    {
+    	return self::$_rLink->exec($sQuery);
+    }
+	
+	 public function getOne($oStatement, $aBindings = array(), $iIndex = 0)
+    {
+        if(!$oStatement)
+			return false;
+		else if(!($oStatement instanceof PDOStatement) && is_string($oStatement))
+			$oStatement = $this->prepare($oStatement);
+
+		$aResult = array();
+		if($this->res($oStatement, $aBindings))
+            $aResult = $oStatement->fetch(PDO::FETCH_NUM);
+
+        return is_array($aResult) && count($aResult) ? $aResult[$iIndex] : false;
+    }
+	
+	public function prepare($sQuery)
+    {
+    	if(!self::$_rLink)
+    		return false;
+
+        $aArgs = func_get_args();
+        $sQuery = array_shift($aArgs);
+
+        $oStatement = self::$_rLink->prepare($sQuery);
+
+        $iIndex = 1;
+        foreach($aArgs as $mixedArg) {
+        	if(is_null($mixedArg))
+				$iValueType = PDO::PARAM_NULL;
+            else if(is_numeric($mixedArg))
+                $iValueType = PDO::PARAM_INT;
+            else
+                $iValueType = PDO::PARAM_STR;
+
+        	$oStatement->bindValue($iIndex++, $mixedArg, $iValueType);
+        }
+
+        return $oStatement;
+    }
+	
+	protected function executeStatement($oStatement, $aBindings = array(), $bVerbose = null)
+    {
+    	$bResult = false;
+
+    	switch (self::$_rLink->getAttribute(PDO::ATTR_ERRMODE)) {
+    		case PDO::ERRMODE_SILENT:
+    			$bResult = $this->executeStatementSilent($oStatement, $aBindings, $bVerbose);
+    			break;
+
+    		case PDO::ERRMODE_EXCEPTION:
+    			$bResult = $this->executeStatementException($oStatement, $aBindings, $bVerbose);
+    			break;
+    	}
+
+    	return $bResult;
+    }
+
+    protected function executeStatementException($oStatement, $aBindings = array(), $bVerbose = null)
+    {
+    	$bResult = false;
+
+    	try {
+			$bResult = $oStatement->execute(!empty($aBindings) && is_array($aBindings) ? $aBindings : null);
+		}
+		catch (PDOException $oException) {
+			$aError = $oStatement->errorInfo();
+
+			$oException->errorInfo[self::$_sErrorKey] = array(
+				'code' => BX_DB_ERR_QUERY_ERROR,
+				'message' => !empty($aError[2]) ? $aError[2] : $oException->getMessage(),
+				'query' => $oStatement->queryString,
+				'trace' => $oException->getTrace(),
+				'verbose' => $bVerbose
+			);
+
+			throw $oException;
+		}
+
+		return $bResult;
+    }
+
+    protected function executeStatementSilent($oStatement, $aBindings = array(), $bVerbose = null)
+    {
+    	$bResult = $oStatement->execute(!empty($aBindings) && is_array($aBindings) ? $aBindings : null);
+    	if($bResult)
+    		return true;
+
+		$aError = $oStatement->errorInfo();
+
+        $aTrace = debug_backtrace();
+        unset($aTrace[0]);
+
+		$this->_aError = array(
+			'code' => BX_DB_ERR_QUERY_ERROR,
+			'message' => !empty($aError[2]) ? $aError[2] : '',
+			'query' => $oStatement->queryString,
+			'trace' => $aTrace,
+			'verbose' => $bVerbose
+		);
+
+		return false;
+    }
+	
+	function getRow($oStatement, $aBindings = array(), $iFetchType = PDO::FETCH_ASSOC)
+    {
+    	$aResult = array();
+        if(!$oStatement)
+            return $aResult;
+		else if(!($oStatement instanceof PDOStatement) && is_string($oStatement))
+			$oStatement = $this->prepare($oStatement);
+
+        if(!in_array($iFetchType, array(PDO::FETCH_NUM, PDO::FETCH_ASSOC, PDO::FETCH_BOTH)))
+            $iFetchType = $this->_iPdoFetchType;
+
+        if(!$this->res($oStatement, $aBindings))
+        	return array();
+
+		$aResult = $oStatement->fetch($iFetchType);
+		if($aResult === false)
+        	return array();
+
+        return $aResult;
+    }
+	
+	public function query($oStatement, $aBindings = array(), $bVerbose = null)
+    {
+    	if(!$oStatement)
+            return false;
+		else if(!($oStatement instanceof PDOStatement) && is_string($oStatement))
+			$oStatement = $this->prepare($oStatement);
+
+        if($this->res($oStatement, $aBindings, $bVerbose))
+            return $oStatement->rowCount();
+
+        return false;
+    }
+	
+	public function getAll($oStatement, $aBindings = array(), $iFetchType = PDO::FETCH_ASSOC)
+    {
+    	$aResult = array();
+        if(!$oStatement)
+            return $aResult;
+		else if(!($oStatement instanceof PDOStatement) && is_string($oStatement))
+			$oStatement = $this->prepare($oStatement);
+
+        if(!in_array($iFetchType, array(PDO::FETCH_NUM, PDO::FETCH_ASSOC, PDO::FETCH_BOTH)))
+            $iFetchType = $this->_iPdoFetchType;
+
+        if(!$this->res($oStatement, $aBindings))
+        	return array();
+
+		$aResult = $oStatement->fetchAll($iFetchType);
+		if($aResult === false)
+        	return array();
+
+        return $aResult;
+    }
+
+    public function getPairs($oStatement, $sFieldKey, $sFieldValue, $aBindings = array())
+    {
+    	$aResult = array();
+        if(!$oStatement)
+            return $aResult;
+		else if(!($oStatement instanceof PDOStatement) && is_string($oStatement))
+			$oStatement = $this->prepare($oStatement);
+
+        $aRow = $this->getFirstRow($oStatement, $aBindings, PDO::FETCH_ASSOC);
+        while(!empty($aRow)) {
+        	$aResult[$aRow[$sFieldKey]] = $aRow[$sFieldValue];
+
+        	$aRow = $this->getNextRow(PDO::FETCH_ASSOC);
+        }
+
+        return $aResult;
+    }
+	
+	public function getFirstRow($oStatement, $aBindings = array(), $iFetchType = PDO::FETCH_ASSOC)
+    {
+        if(!$oStatement)
+            return array();
+		else if(!($oStatement instanceof PDOStatement) && is_string($oStatement))
+			$oStatement = $this->prepare($oStatement);
+
+        if(!in_array($iFetchType, array(PDO::FETCH_NUM, PDO::FETCH_ASSOC, PDO::FETCH_BOTH)))
+            $iFetchType = $this->_iPdoFetchType;
+
+        if(!$this->res($oStatement, $aBindings)) 
+        	return array();
+
+        $aResult = $oStatement->fetch($iFetchType);
+        if($aResult === false)
+        	return array();
+
+		$this->_oStatement = $oStatement;
+        return $aResult;
+    }
+
+    public function getNextRow($iFetchType = PDO::FETCH_ASSOC)
+    {
+    	if(!$this->_oStatement)
+            return array();
+
+		if(!in_array($iFetchType, array(PDO::FETCH_NUM, PDO::FETCH_ASSOC, PDO::FETCH_BOTH)))
+            $iFetchType = $this->_iPdoFetchType;
+
+		$aResult = $this->_oStatement->fetch($iFetchType);
+		if($aResult !== false)
+			return $aResult;
+
+		$this->_oStatement = null;
+    	return array();
+    }
+		
+	public function isTableExists($sTable){
+		$sQuery = $this -> prepare("SHOW TABLES LIKE ?", $sTable);
+		$aResult = $this -> getRow($sQuery);
+		return !empty($aResult);
+   }
+
+   public function getParam($sName){
+		if (!$this -> isTableExists('sys_options')) return '';
+		
+		$sQuery = $this -> prepare("SELECT `value` FROM `sys_options` WHERE `name` = ?", $sName);
+		return $this -> getOne($sQuery);
+   }
+
+}
+
+/** @} */

+ 70 - 0
modules/boonex/dolphin_migration/updates/9.0.0_9.0.1/source/install/config.php

@@ -0,0 +1,70 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    DolphinMigration  Dolphin Migration
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_dolphin_migration',
+    'title' => 'Dolphin Migration',
+    'note' => 'Migration Tool',
+    'version' => '9.0.1',
+    'vendor' => 'Boonex',
+	'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '9.0.0-RC8'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/dolphin_migration/',
+    'home_uri' => 'dolphin_migration',
+
+    'db_prefix' => 'bx_dolphin_',
+    'class_prefix' => 'BxDolM',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Boonex Dolphin Migration Tool',
+
+    /**
+     * 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(),
+);
+
+/** @} */

Разница между файлами не показана из-за своего большого размера
+ 42 - 0
modules/boonex/dolphin_migration/updates/9.0.0_9.0.1/source/template/images/icons/std-icon.svg


Некоторые файлы не были показаны из-за большого количества измененных файлов