AlexeyUna 8 سال پیش
والد
کامیت
475c07fe6a
38فایلهای تغییر یافته به همراه5837 افزوده شده و 8 حذف شده
  1. 161 0
      modules/boonex/dolphin_migration/classes/BxDolMBlogs.php
  2. 161 0
      modules/boonex/dolphin_migration/classes/BxDolMChat.php
  3. 245 0
      modules/boonex/dolphin_migration/classes/BxDolMConfig.php
  4. 215 0
      modules/boonex/dolphin_migration/classes/BxDolMConv.php
  5. 571 0
      modules/boonex/dolphin_migration/classes/BxDolMData.php
  6. 148 0
      modules/boonex/dolphin_migration/classes/BxDolMDb.php
  7. 234 0
      modules/boonex/dolphin_migration/classes/BxDolMEvents.php
  8. 167 0
      modules/boonex/dolphin_migration/classes/BxDolMFiles.php
  9. 318 0
      modules/boonex/dolphin_migration/classes/BxDolMForum.php
  10. 214 0
      modules/boonex/dolphin_migration/classes/BxDolMGroups.php
  11. 217 0
      modules/boonex/dolphin_migration/classes/BxDolMMarket.php
  12. 144 0
      modules/boonex/dolphin_migration/classes/BxDolMModule.php
  13. 177 0
      modules/boonex/dolphin_migration/classes/BxDolMPhotoAlbums.php
  14. 181 0
      modules/boonex/dolphin_migration/classes/BxDolMPolls.php
  15. 351 0
      modules/boonex/dolphin_migration/classes/BxDolMProfiles.php
  16. 383 0
      modules/boonex/dolphin_migration/classes/BxDolMProfilesFields.php
  17. 98 0
      modules/boonex/dolphin_migration/classes/BxDolMQuotes.php
  18. 126 0
      modules/boonex/dolphin_migration/classes/BxDolMShoutBox.php
  19. 123 0
      modules/boonex/dolphin_migration/classes/BxDolMSimpleMessenger.php
  20. 121 0
      modules/boonex/dolphin_migration/classes/BxDolMStudioPage.php
  21. 21 0
      modules/boonex/dolphin_migration/classes/BxDolMTemplate.php
  22. 476 0
      modules/boonex/dolphin_migration/classes/BxDolMTimeline.php
  23. 98 0
      modules/boonex/dolphin_migration/classes/BxDolMTransfers.php
  24. 187 0
      modules/boonex/dolphin_migration/classes/BxDolMVideoAlbums.php
  25. 375 0
      modules/boonex/dolphin_migration/classes/BxMDb.php
  26. 70 0
      modules/boonex/dolphin_migration/install/config.php
  27. 20 0
      modules/boonex/dolphin_migration/install/installer.php
  28. 115 0
      modules/boonex/dolphin_migration/install/langs/en.xml
  29. 13 0
      modules/boonex/dolphin_migration/install/sql/disable.sql
  30. 31 0
      modules/boonex/dolphin_migration/install/sql/enable.sql
  31. 33 0
      modules/boonex/dolphin_migration/install/sql/install.sql
  32. 8 0
      modules/boonex/dolphin_migration/install/sql/uninstall.sql
  33. 19 0
      modules/boonex/dolphin_migration/request.php
  34. 16 0
      modules/boonex/dolphin_migration/template/css/main.css
  35. 0 0
      modules/boonex/dolphin_migration/template/images/icons/std-icon.svg
  36. 0 4
      periodic/.htaccess
  37. BIN
      plugins/ffmpeg/ffmpeg.exe
  38. 0 4
      tmp/.htaccess

+ 161 - 0
modules/boonex/dolphin_migration/classes/BxDolMBlogs.php

@@ -0,0 +1,161 @@
+<?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('BxDolStorage');
+	
+class BxDolMBlogs extends BxDolMData
+{	
+	public function __construct(&$oMigrationModule, &$oDb)
+	{
+        parent::__construct($oMigrationModule, $oDb);
+		$this -> _sModuleName = 'blogs';
+		$this -> _sTableWithTransKey = 'bx_posts_posts';
+    }    
+	
+	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_blogs'));		
+			
+		$this -> createMIdField();
+		$iBlogId = $this -> getLastMIDField();						
+		$sStart = '';
+		if ($iBlogId)
+			$sStart = " WHERE `PostID` >= {$iBlogId}";
+		
+		$aResult = $this -> _mDb -> getAll("SELECT * FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] . "` {$sStart} ORDER BY `PostID`");
+		
+		$iCmts = 0;
+		foreach($aResult as $iKey => $aValue)
+		{
+			$iProfileId = $this -> getProfileId((int)$aValue['OwnerID']);
+			$iBlogId = $this -> isItemExisted($aValue['PostID']);			
+			if (!$iProfileId)
+				continue;
+			
+			if (!$iBlogId)
+			{
+				$sQuery = $this -> _oDb -> prepare( 
+                     "
+                     	INSERT INTO
+                     		`{$this -> _sTableWithTransKey}`
+                     	SET
+                     		`author`   			= ?,
+                     		`added`      		= ?,
+                     		`changed`   		= ?,
+							`thumb`				= 0,
+							`title`				= ?,		
+                     		`text`				= ?,							
+							`cat`				= ?,
+							`views`				= ?,
+							`featured`			= ?
+							
+                     ", 
+						$iProfileId, 
+						isset($aValue['PostDate']) ? $aValue['PostDate'] : time(),
+						isset($aValue['PostDate']) ? $aValue['PostDate'] : time(),
+						isset($aValue['PostCaption']) ? $aValue['PostCaption'] : time() + 1,
+						isset($aValue['PostText']) ? $aValue['PostText'] : '',						
+						$this -> transferCategory($aValue['Categories']),						
+						isset($aValue['Views']) ? (int)$aValue['Views'] : 0,
+						isset($aValue['Featured']) ? (int)$aValue['Featured'] : 0
+						);			
+		
+				$this -> _oDb -> query($sQuery);
+				
+				$iBlogId = $this -> _oDb -> lastId();			
+				if (!$iBlogId){
+					$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_blogs_error', (int)$aValue['PostID']));
+					return BX_MIG_FAILED;
+				}	
+				
+				$this -> setMID($iBlogId, $aValue['PostID']);				
+			}
+			
+			if (isset($aValue['PostPhoto']))
+				$this -> exportThumb($iBlogId, $aValue['PostPhoto'], $iProfileId);
+						
+			$iCmts = $this -> transferComments($iBlogId, (int)$aValue['PostID'], 'blogs');
+			$this -> _iTransferred++;
+						
+			$this -> _oDb ->  query("UPDATE `{$this -> _sTableWithTransKey}` SET `allow_view_to` = :privacy, `comments` = :cmts WHERE `id` = :id", array('privacy' => $aValue['allowView'], 'id' => $iBlogId, 'cmts' => $iCmts));
+			
+			$this -> trasnferTags((int)$aValue['PostID'], $iBlogId, $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['type'], $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['keywords']);
+        }
+
+        $this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_blogs_finished', $this -> _iTransferred));
+        return BX_MIG_SUCCESSFUL;
+    }
+	
+	protected function transferCategory($sCategory, $sPrefix = 'bx_posts', $sPreValueCateg = 'bx_posts_cats')
+	{
+		return parent::transferCategory($sCategory, $sPrefix, $sPreValueCateg);
+	}
+	
+	/**
+	 * Export blog's thumbnail
+	 *
+	 * @param integer $iEntryId una blog Id
+	 * @param string $sPhotoName photo file name
+	 * @param integer $iProfileId  profile id
+	 * @return void
+	 */
+	private function exportThumb($iEntryId, $sPhotoName, $iProfileId)
+    {
+       if (!$sPhotoName || $this -> _oDb -> getOne("SELECT `thumb` FROM `{$this -> _sTableWithTransKey}` WHERE `id` = :id", array('id' => $iEntryId)))
+		   return;
+	   
+       $sBlogImgePath = $this -> _oDb -> getExtraParam('root') . 'media' . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . "blog" . DIRECTORY_SEPARATOR ."orig_{$sPhotoName}";
+       if($sBlogImgePath)
+		{
+			$oFileStorage = BxDolStorage::getObjectInstance('bx_posts_files');
+			$iFile = $oFileStorage -> storeFileFromPath($sBlogImgePath, false, $iProfileId, (int)$iEntryId);
+			if ($iFile)
+			{
+				$oFileStorage -> afterUploadCleanup($iFile, $iProfileId);
+				$sQuery = $this -> _oDb -> prepare("UPDATE `{$this -> _sTableWithTransKey}` SET `thumb` = ? WHERE `id` = ?", $iFile, $iEntryId);
+				$this -> _oDb -> query($sQuery);
+			}		
+		}
+    }
+	
+	public function removeContent()
+	{
+		if (!$this -> _oDb -> isTableExists($this -> _sTableWithTransKey) || !$this -> _oDb -> isFieldExists($this -> _sTableWithTransKey, $this -> _sTransferFieldIdent))
+			return false;
+		
+		$aRecords = $this -> _oDb -> getAll("SELECT * FROM `{$this -> _sTableWithTransKey}` WHERE `{$this -> _sTransferFieldIdent}` !=0");
+		$iNumber = 0;
+		if (!empty($aRecords))
+		{
+			foreach($aRecords as $iKey => $aValue)
+			{
+				BxDolService::call('bx_posts', 'delete_entity', array($aValue['id']));
+				$iNumber++;
+			}
+		}		
+		parent::removeContent();
+		return $iNumber;
+	}	
+}
+
+/** @} */

+ 161 - 0
modules/boonex/dolphin_migration/classes/BxDolMChat.php

@@ -0,0 +1,161 @@
+<?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('BxDolStorage');
+	
+class BxDolMChat extends BxDolMData 
+{	
+	public function __construct(&$oMigrationModule, &$oDb)
+	{
+        parent::__construct($oMigrationModule, $oDb);
+		$this -> _sModuleName = 'chat';
+		$this -> _sTableWithTransKey = 'bx_messenger_jots';
+		$this -> _sTransferFieldIdent = 'c_mig_id';
+    }    
+	
+	public function getTotalRecords()
+	{
+		return $this -> _mDb -> getOne("SELECT COUNT(*) FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] . "`");
+	}
+	
+	private function getLotId($iSenderId, $iRecipientId)
+	{
+		$iLot = $this -> _oDb -> getOne("SELECT `id` FROM `bx_messenger_lots` WHERE `participants` = :l1 OR `participants` = :l2 AND `type`=2 LIMIT 1", array('l1' => "{$iSenderId},{$iRecipientId}", 'l2' => "{$iRecipientId},{$iSenderId}"));
+		if ($iLot)
+			return $iLot;
+		
+		$this -> _oDb -> query("INSERT INTO `bx_messenger_lots` SET `created` = UNIX_TIMESTAMP(), `author`= :author, `participants` = :parts, `type` = 2", array('parts' => "{$iSenderId},{$iRecipientId}", 'author' => $iSenderId));
+		return $this -> _oDb -> lastId();
+	}
+	/**
+	 *  Transfer Flash chat rooms
+	 *  
+	 *  @return array - created Lots ids associated with Dolphin chat rooms
+	 *  
+	 */
+	private function tansferRooms()
+	{
+		$aRooms = $this -> _mDb -> getAll("SELECT * FROM `RayChatRooms`");
+		if (empty($aRooms))
+			return false;
+		$aResult = array();
+		$ilotId = 0;
+			
+		foreach($aRooms as $iKey => $aRoom)
+		{
+			$aUsers = $this -> _mDb -> getPairs("SELECT `Sender` FROM `RayChatHistory` WHERE `Room`=:Room GROUP BY `Sender`", 'Sender', 'Sender', array('Room' => $aRoom['ID']));
+			if (empty($aUsers))
+				continue;
+			
+			foreach($aUsers as $iKey => $iId)
+				$aRealProfiles[] = $this -> getProfileId($iId);			
+			
+			$aParams = array('title' => $aRoom['Name'], 'parts' => implode(',', $aRealProfiles));			
+			if (!($ilotId = $this -> _oDb -> getOne("SELECT `id` FROM `bx_messenger_lots` WHERE `title` = :title AND `participants` = :parts AND `type` = 2", $aParams)))
+			{
+				$this -> _oDb -> query("INSERT INTO `bx_messenger_lots` SET `created` = UNIX_TIMESTAMP(), `title` = :title, `participants` = :parts, `type` = 2", $aParams);
+				$ilotId = $this -> _oDb -> lastId();
+			}
+			
+			$aResult[$aRoom['ID']] = $ilotId;
+		}
+		
+		
+		return $aResult;
+	}
+	
+	public function runMigration()
+	{        
+		$aLots = $this -> tansferRooms();
+		if (!$this -> getTotalRecords() || empty($aLots))
+		{
+			$this -> setResultStatus(_t('_bx_dolphin_migration_no_data_to_transfer'));
+	        return BX_MIG_SUCCESSFUL;
+		}	
+		
+		$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_simple_messanger'));		
+	
+
+		$this -> createMIdField();
+		$aMessages = $this -> _mDb -> getAll("SELECT * FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] . "` ORDER BY `ID`");
+		foreach($aMessages as $iMes => $aMessage)
+		{
+			$iMessageId = $this -> isItemExisted($aMessage['ID']);
+			$iSenderId = $this -> getProfileId((int)$aMessage['Sender']);
+			if (!$iMessageId && $iSenderId)
+			{
+				$sQuery = $this -> _oDb -> prepare( 
+						"
+							INSERT INTO
+								`{$this -> _sTableWithTransKey}`
+							SET
+								`lot_id`   			= ?,
+								`message`			= ?,	
+								`user_id`			= ?,
+								`created`			= ?
+						",
+						$aLots[$aMessage['Room']],
+						$aMessage['Message'],
+						$iSenderId,
+						$aMessage['When']
+					);
+			
+					$this -> _oDb -> query($sQuery);
+					
+					$iMessageId = $this -> _oDb -> lastId();
+					if (!$iMessageId)
+					{
+						$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_simple_messanger_error', (int)$aMessage['ID']));
+						return BX_MIG_FAILED;					
+					}
+					
+					$this -> setMID($iMessageId, $aMessage['ID']);
+				
+				$this -> _iTransferred++;
+			}	
+		}
+
+        // set as finished;
+		$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_simple_messanger_finished', $this -> _iTransferred));
+        return BX_MIG_SUCCESSFUL;
+    }
+
+	public function removeContent()
+	{
+		if (!$this -> _oDb -> isTableExists($this -> _sTableWithTransKey) || !$this -> _oDb -> isFieldExists($this -> _sTableWithTransKey, $this -> _sTransferFieldIdent))
+			return false;		
+		
+		$aRecords = $this -> _oDb -> getAll("SELECT * FROM `{$this -> _sTableWithTransKey}` WHERE `{$this -> _sTransferFieldIdent}` !=0");
+		$aLots = $this -> _oDb -> getPairs("SELECT `lot_id` FROM `{$this -> _sTableWithTransKey}` WHERE `{$this -> _sTransferFieldIdent}` !=0 GROUP BY `lot_id`", 'lot_id', 'lot_id');
+		
+		$iNumber = 0;		
+		if (!empty($aRecords))
+		{
+			foreach($aRecords as $iKey => $aValue)
+			{
+				$this -> _oDb -> query("DELETE FROM `{$this -> _sTableWithTransKey}` WHERE `id`=:id", array('id' => $aValue['id']));			
+				$iNumber++;
+			}
+		}
+
+		if (!empty($aLots))
+		{
+			$sIn = "WHERE `id` IN (" . implode(',', $aLots) . ")";
+			$this -> _oDb -> query("DELETE FROM `bx_messenger_lots` {$sIn}");
+		}
+		
+		parent::removeContent();
+		return $iNumber;
+	}
+}
+
+/** @} */

+ 245 - 0
modules/boonex/dolphin_migration/classes/BxDolMConfig.php

@@ -0,0 +1,245 @@
+<?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
+ *
+ * @{
+ */
+
+class BxDolMConfig extends BxBaseModGeneralConfig
+{
+	/**
+	 *  @var array una modules uris, associated with migration modules names (mainly uses for Timeline migration) 
+	 */
+	public $_aModulesAliases =	array(
+		'bx_store' => 'store',
+		'bx_files' => 'files',		
+		'bx_poll' => 'polls',
+		'bx_events' => 'events',
+		'bx_groups' => 'groups',		
+		'bx_blogs' => 'blogs'
+	);
+	
+	/**
+	 *  @var array modules for transfer from Dolphin to una with parameters
+	 *  	[table_name] -  (string) table from which to get data
+	 *  	[migration_class] - (string) class name/file name for data migration
+	 *  	[dependencies] -  (array) list of the modules which should be migrated before transferring selected module 
+	 *  	[plugins] - (array) list of the modules which should be installed on UNA before transferring selected module
+	 */
+	 
+	public $_aMigrationModules = array(
+				'profiles' => array(
+                    'table_name'     => 'Profiles', 
+                    'migration_class' => 'BxDolMProfiles',
+            		'dependencies' => array(
+			        ),
+					'plugins' => array(
+						'bx_persons' => 'Persons',
+			        ),
+                ),
+				'profile_fields' => array(
+                    'table_name'		=> 'sys_profile_fields',
+                    'migration_class'	=> 'BxDolMProfilesFields',
+			        'dependencies' => array(
+                        'profiles',
+                    ),
+					'plugins' => array(
+						'bx_persons' => 'Persons',
+			        ),
+                ),				
+				'blogs' => array(
+                    'table_name'		=> 'bx_blogs_posts',					
+                    'migration_class'	=> 'BxDolMBlogs',
+					'type'				=> 'blog',
+					'keywords'			=> 'bx_posts_meta_keywords',					
+			        'dependencies' => array(
+                		'profiles',
+                     ),
+					 'plugins' => array(
+						'bx_persons'	=> 'Persons',
+						'bx_posts'		=> 'Posts'			
+			        ),
+                ),				
+				'groups' => array(
+                    'table_name'		=> 'bx_groups_main',
+                    'migration_class'	=> 'BxDolMGroups',
+					'type'				=> 'bx_groups',
+					'keywords'			=> 'bx_groups_meta_keywords',
+			        'dependencies' => array(
+                		'profiles',
+                     ),
+					 'plugins' => array(
+						'bx_persons'	=> 'Persons',
+						'bx_groups'	=> 'Groups'					
+			        ),
+                ),
+				'events' => array(
+                    'table_name'		=> 'bx_events_main',
+					'type'				=> 'bx_events',
+					'keywords'			=> 'bx_events_meta_keywords',					
+                    'migration_class'	=> 'BxDolMEvents',					
+			        'dependencies' => array(
+                		'profiles',
+                     ),
+					 'plugins' => array(
+						'bx_persons'	=> 'Persons',
+						'bx_events'	=> 'Events'					
+			        ),
+                ),
+				'photos' => array(
+                    'table_name'	=> 'bx_photos_main',	
+					'table_name_albums' => 'sys_albums',
+					'type'				=> 'bx_photos',
+					'keywords'			=> 'bx_albums_meta_keywords_media',
+                    'migration_class' => 'BxDolMPhotoAlbums',
+			        'dependencies' => array(
+                		'profiles',
+                     ),
+					 'plugins' => array(
+						'bx_persons'	=> 'Persons',
+						'bx_albums'		=> 'Albums'	
+			        ),
+                ),
+				'videos' => array(
+                    'table_name'	=> 'RayVideoFiles',
+					'table_name_albums' => 'sys_albums',
+					'type'				=> 'bx_videos',
+					'keywords'			=> 'bx_albums_meta_keywords_media',
+                    'migration_class' => 'BxDolMVideoAlbums',
+			        'dependencies' => array(
+                		'profiles',
+                     ),
+					 'plugins' => array(
+						'bx_persons'	=> 'Persons',
+						'bx_albums'		=> 'Albums'	
+			        ),
+                ),				
+				'conversations' => array(
+					'table_name'		=> 'sys_messages',					
+                    'migration_class'	=> 'BxDolMConv',
+					'dependencies' => array(
+                		'profiles',
+                     ),
+					 'plugins' => array(
+						'bx_persons'	=> 'Persons',
+						'bx_convos'	=> 'Conversations'					
+			        ),
+                ),
+				'forum' => array(
+					'table_name' => 'bx_forum_topic',
+					'table_name_post' => 'bx_forum_post',
+                    'migration_class'	=> 'BxDolMForum',
+					'dependencies' => array(
+                		'profiles',
+                     ),
+					 'plugins' => array(
+						'bx_persons'	=> 'Persons',
+						'bx_forum'	=> 'Discussions'					
+			        ),
+                ),
+				'polls' => array(
+                    'table_name'		=> 'bx_poll_data',						
+                    'migration_class'	=> 'BxDolMPolls',
+					'type'				=> 'bx_poll',
+					'keywords'			=> 'bx_polls_meta_keywords',
+			        'dependencies' => array(
+                		'profiles',
+                     ),
+					 'plugins' => array(
+						'bx_persons'	=> 'Persons',
+						'bx_polls'		=> 'Polls'	
+			        ),
+                ),
+				'files' => array(
+                    'table_name'		=> 'bx_files_main',
+                    'migration_class'	=> 'BxDolMFiles',
+					'type'				=> 'bx_files',
+					'keywords'			=> 'bx_files_meta_keywords',
+			        'dependencies' => array(
+                		'profiles',
+                     ),
+					 'plugins' => array(
+						'bx_persons'	=> 'Persons',
+						'bx_files'	=> 'Files'					
+			        ),
+                ),
+				'store' => array(
+                    'table_name'		=> 'bx_store_products',
+                    'migration_class'	=> 'BxDolMMarket',
+					'type'				=> 'bx_store',
+					'keywords'			=> 'bx_market_meta_keywords',
+			        'dependencies' => array(
+                		'profiles',
+                     ),
+					 'plugins' => array(
+						'bx_persons'	=> 'Persons',
+						'bx_market'	=> 'Market'
+			        ),
+                ),
+				'quotes' => array(
+                    'table_name'		=> 'bx_quotes_units',
+                    'migration_class'	=> 'BxDolMQuotes',			        
+					 'plugins' => array(						
+						'bx_quoteofday'	=> 'Quotes'
+			        ),
+                ),
+				'shoutbox' => array(
+                    'table_name'		=> 'bx_shoutbox_messages',
+                    'migration_class'	=> 'BxDolMShoutBox',
+			        'dependencies' => array(
+                		'profiles',
+                     ),
+					 'plugins' => array(
+						'bx_persons'	=> 'Persons',
+						'bx_messenger'	=> 'Jot Messenger'
+			        ),
+                ),
+				'simple_messenger' => array(
+                    'table_name'		=> 'bx_simple_messenger_messages',
+                    'migration_class'	=> 'BxDolMSimpleMessenger',
+			        'dependencies' => array(
+                		'profiles',
+                     ),
+					 'plugins' => array(
+						'bx_persons'	=> 'Persons',
+						'bx_messenger'	=> 'Jot Messenger'
+			        ),
+                ),
+				'chat' => array(
+                    'table_name'		=> 'RayChatHistory',
+                    'migration_class'	=> 'BxDolMChat',
+			        'dependencies' => array(
+                		'profiles',
+                     ),
+					 'plugins' => array(
+						'bx_persons'	=> 'Persons',
+						'bx_messenger'	=> 'Jot Messenger'
+			        ),
+                ),
+				'timeline' => array(
+                    'table_name' => 'bx_wall_events',
+                    'migration_class'	=> 'BxDolMTimeline',
+					'dependencies' => array
+					(
+                		'profiles',
+                    ),
+					'plugins' => array
+					(
+						'bx_persons'	=> 'Persons',
+						'bx_timeline'	=> 'Timeline'		
+			        ),
+                )
+             );
+			 
+	public function __construct($aModule)
+	{
+		parent::__construct($aModule);		
+	}
+
+}
+
+/** @} */

+ 215 - 0
modules/boonex/dolphin_migration/classes/BxDolMConv.php

@@ -0,0 +1,215 @@
+<?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('BxDolStorage');
+	
+class BxDolMConv extends BxDolMData
+{	
+	public function __construct(&$oMigrationModule, &$oDb)
+	{
+        parent::__construct($oMigrationModule, $oDb);
+		$this -> _sModuleName = 'conversations';
+		$this -> _sTableWithTransKey = 'bx_convos_cmts';
+    }    
+	
+	public function getTotalRecords()
+	{
+		return (int)$this -> _mDb -> getOne("SELECT COUNT(*) FROM  `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] . "` WHERE `Type` = 'letter' ORDER BY `ID`");			
+	}
+	
+	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_conversations'));		
+			
+		$aResult = $this -> _mDb -> getAll("SELECT  * FROM  `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] . "` ORDER BY `ID`");
+		
+		$iCmts = 0;
+		foreach($aResult as $iKey => $aValue)
+		{
+			$iSenderId = $this -> getProfileId((int)$aValue['Sender']);
+			$iRecipientId = $this -> getProfileId((int)$aValue['Recipient']);			
+			$iDate = isset($aValue['Date']) ? strtotime($aValue['Date']) : time();				
+			if (!$iSenderId || !$iRecipientId)
+				continue;
+			
+			$iConvId = $this -> isConvExisted($aValue['Subject'], $iSenderId, $iRecipientId);		
+			if (!$iConvId)
+			{
+				$sQuery = $this -> _oDb -> prepare( 
+							 "
+								INSERT INTO
+									`bx_convos_conversations`
+								SET
+									`author`   				= ?,
+									`added`      			= ?,
+									`changed`   			= ?,
+									`views`					= ?,
+									`last_reply_timestamp`	= ?,
+									`text`					= ?
+							 ", 
+							$iSenderId, 
+							$iDate, 
+							$iDate,
+							$aValue['New'] ? 0 : 1,
+							$iDate,
+							$aValue['Subject']
+						);			
+		
+				$this -> _oDb -> query($sQuery);
+				
+				$iConvId = $this -> _oDb -> lastId();			
+				if (!$iConvId){
+					$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_conv_error', (int)$aValue['ID']));
+					return BX_MIG_FAILED;
+				}	
+								
+
+				$sQuery = $this -> _oDb -> prepare( 
+						"
+							INSERT INTO
+								`bx_convos_conv2folder`
+							SET
+								`conv_id`      		= ?,
+								`folder_id`   		= ?,
+								`collaborator`		= ?
+						", 
+						$iConvId,
+						stripos($aValue['Trash'], 'sender') !== FALSE ? 4 : 1,
+						$iSenderId
+						);
+				$this -> _oDb -> query($sQuery);
+				
+				$sQuery = $this -> _oDb -> prepare( 
+						"
+							INSERT INTO
+								`bx_convos_conv2folder`
+							SET
+								`conv_id`      		= ?,
+								`folder_id`   		= ?,
+								`collaborator`		= ?
+						", 
+						$iConvId,
+						stripos($aValue['Trash'], 'recipient') !== FALSE ? 4 : 1,
+						$iRecipientId
+						);
+				$this -> _oDb -> query($sQuery);
+			}
+			
+			$this -> createMIdField();
+			
+			if (!($iMessId = $this -> isItemExisted($aValue['ID'], 'cmt_id')))
+			{
+				$this -> _oDb -> query("INSERT INTO `bx_convos_cmts` (`cmt_id`, `cmt_parent_id`, `cmt_vparent_id`, `cmt_object_id`, `cmt_author_id`, `cmt_level`, `cmt_text`, `cmt_time`, `cmt_replies`, `cmt_rate`, `cmt_rate_count`)
+									VALUES	(NULL, 0, 0, :object, :user, 0, :message, :time, 0, 0, 0)", 
+									array(
+											'object' => $iConvId,
+											'user' => $iSenderId, 
+											'message' => $aValue['Text'], 
+											'time' => $iDate	
+										));
+				
+				$iMessId = $this -> _oDb -> lastId();
+				$this -> setMID($iMessId, $aValue['ID'], 'cmt_id');				
+			}
+										
+			$this -> _iTransferred ++;
+			
+			$this -> _oDb ->  query("UPDATE `bx_convos_conversations`
+									SET 
+										`comments` = `comments` + 1, 
+										`last_reply_profile_id` = :lpi, 
+										`last_reply_comment_id` = :lci,
+										`last_reply_timestamp`	= :time
+									WHERE `id` = :id", 
+										array(
+												'lpi' => $iSenderId, 
+												'lci' => $iMessId, 
+												'id' => $iMessId,
+												'time' => $iDate
+											));			
+			
+			$this -> updateOwnTables($iConvId, $iSenderId, $aValue['New']);
+		}
+
+        //set as finished;
+        $this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_conv_finished', $this -> _iTransferred));
+        return BX_MIG_SUCCESSFUL;
+    }
+	
+	protected function isConvExisted($sSubject, $iSenderId, $iRecipientId)
+	{
+		$sSubject = preg_replace('/^Re.*:\s+(.*)$/i', '\\1', $sSubject);
+		
+		return (int)$this -> _oDb -> getOne("SELECT `c`.`id`
+											 FROM `bx_convos_conversations` as `c`
+											 LEFT JOIN `bx_convos_conv2folder` as `f` ON `c`.`id` = `conv_id`
+											 WHERE `text` = :text AND ((`f`.`collaborator`=:sender AND `c`.`author` = :recipient) OR (`f`.`collaborator`=:recipient AND `c`.`author` = :sender)) LIMIT 1", array('text' => $sSubject, 'sender' => $iSenderId, 'recipient' => $iRecipientId));
+	}	
+	/**
+	 *  Builds folders for conversations
+	 *  
+	 *  @param int $iObject conversation id
+	 *  @param int $iProfileId profile id
+	 *  @param int $iComments message id
+	 *  @return res query result
+	 */
+	protected function updateOwnTables($iObject, $iProfileId, $iComments)
+	{
+		$sQuery = $this -> _oDb -> prepare( 
+			"
+				UPDATE
+					`bx_convos_conv2folder`
+				SET
+					`read_comments`	= `read_comments` + ?							
+				WHERE `conv_id` = ? AND `collaborator` = ?
+			", 
+			$iComments ? 1 : 0,
+			$iObject, 
+			$iProfileId						
+		);
+		
+		return $this -> _oDb -> query($sQuery);	
+	}
+	
+	public function removeContent()
+	{
+		if (!$this -> _oDb -> isTableExists($this -> _sTableWithTransKey) || !$this -> _oDb -> isFieldExists($this -> _sTableWithTransKey, $this -> _sTransferFieldIdent))
+			return false;
+		
+		$aRecords = $this -> _oDb -> getAll("SELECT *
+											FROM `{$this -> _sTableWithTransKey}`										
+											WHERE `{$this -> _sTransferFieldIdent}`!=0");
+		$iNumber = 0;
+		if (!empty($aRecords))
+		{
+			foreach($aRecords as $iKey => $aValue)
+			{			
+				$sQuery = $this-> _oDb -> prepare("DELETE FROM `tl`, `tle` USING `bx_convos_conversations` AS `tl` LEFT JOIN `bx_convos_cmts` AS `tle` ON `tl`.`id`=`tle`.`cmt_object_id` WHERE `tle`.`cmt_object_id` = ?", $aValue['cmt_object_id']);
+				$this -> _oDb -> query($sQuery);
+						
+				$this -> _oDb -> query("DELETE FROM `bx_convos_conv2folder` WHERE `conv_id`=:id", array('id' => $aValue['cmt_object_id']));
+				$iNumber++;
+			}
+		}	
+		
+		parent::removeContent();		
+		return $iNumber;
+	}	
+}
+
+/** @} */

+ 571 - 0
modules/boonex/dolphin_migration/classes/BxDolMData.php

@@ -0,0 +1,571 @@
+<?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
+ *
+ * @{
+ */
+ 
+define('BX_MIG_SUCCESSFUL', 1);
+define('BX_MIG_FAILED', 0);
+
+/**
+ * Base class for all migration classes
+ * contains general variables and function for modules' migration classes
+ */
+class BxDolMData
+{      
+	/**
+	* @var ref $_oMainModule the reference to the main module object
+	*/	
+	protected $_oMainModule;
+	
+	/**
+	* @var  ref $_mDb the reference to Dolphin's database connect
+	*/
+	protected $_mDb;
+	
+	/**
+	* @var string  $_sPrefix migration module database prefix
+	*/
+	protected $_sPrefix;
+	
+	/**
+	* @var ref $_oDb connect to UNA database
+	*/
+	protected $_oDb;
+
+	/**
+	* @var string $_sModuleName module name, it is set by inherited object and equal to value from {@link $_aMigrationModules}
+	*@uses BxDolMConfig::_aMigrationModules modules array
+	*/
+	protected $_sModuleName = '';
+	
+	/**
+	* @var string $_sTableWithTransKey the main a module's table name into which transferring data from Dolphin's module
+	* it is individual for each module and set in constructor of each class
+	*/
+	protected $_sTableWithTransKey;
+	
+	/**
+	* @var int $_iTransferred number of transferred records
+	*/	
+	protected $_iTransferred = 0;
+	
+	/**
+	* @var ref $_oLanguage  reference on @uses BxDolStudioLanguagesUtils::getInstance() 
+	*/		
+	protected $_oLanguage = null;
+	
+	/**
+	* @var array $_aLanguages list of the installed languages in appropriate format 
+	*/		
+	protected $_aLanguages = array();
+	
+	/**
+	* @var string $_sImagePhotoFiles path to the photo module's data files in Dolphin
+	*/
+	protected $_sImagePhotoFiles = '';
+	
+	/**
+	* @var string $_sTransferFieldIdent field name which is created in table into which records are added, it allows to set connect between ids from Dolphin and UNA's tables
+	*/
+	protected $_sTransferFieldIdent = 'mig_id';
+	
+	/**
+	 *  Base class constructor
+	 *  
+	 *  @param ref $oMainModule main module 
+	 *  @param ref $oDb connect with Dolphin database
+	 *  @return void
+	 */
+	public function __construct(&$oMainModule, &$oDb)
+	{
+	     $this -> _sPrefix = $oMainModule -> _aModule['db_prefix'];
+	     $this -> _oMainModule = $oMainModule;
+		 $this -> _oConfig = $oMainModule -> _oConfig;
+	     $this -> _mDb  = $oDb;
+	     $this -> _oDb = $this -> _oMainModule -> _oDb;		 
+		 $this -> _sTableWithTransKey = '';
+		 $this -> _oLanguage = BxDolStudioLanguagesUtils::getInstance();
+		 $this -> _aLanguages = $this -> _oDb -> getPairs("SELECT * FROM `sys_localization_languages` WHERE `Enabled`='1'", 'Name', 'ID');
+		 $this -> _sImagePhotoFiles = $this -> _oDb -> getExtraParam('root') . 'modules' . DIRECTORY_SEPARATOR . 'boonex' . DIRECTORY_SEPARATOR . "photos" . DIRECTORY_SEPARATOR . "data" . DIRECTORY_SEPARATOR . "files" . DIRECTORY_SEPARATOR;		 
+	}
+	/**
+	* Main migration function, executes required operations for transfer 
+	* @return boolean 
+	*/
+	public function runMigration()
+	{
+	    $this -> setResultStatus(_t('_bx_dolphin_migration_define_migration_method'));
+	    return BX_MIG_FAILED;
+	}
+
+	/**
+	* Gets total records for transferring
+	* @return boolean
+	*/
+	public function getTotalRecords()
+	{
+	    $this -> setResultStatus(_t('_bx_dolphin_migration_define_total_method'));
+	    return BX_MIG_FAILED;		
+	}
+
+	/**
+	* Set Migration Status
+	* @param string $sStatus message
+	*/         
+	protected function setResultStatus($sStatus, $sModule = '')
+	{
+	    $sQuery = $this -> _oDb -> prepare("UPDATE `{$this -> _sPrefix}transfers` SET `status_text` = ? WHERE `module` = ? ", $sStatus, $this -> _sModuleName);
+	    $this -> _oDb -> query($sQuery);
+	}
+
+	/**
+	* Returns content id of transferred member from Dolphin
+	* @param int $iId Dolphin's profile ID
+	* @return int
+	*/	
+	protected function getContentId($iId){
+		$sQuery = $this -> _oDb -> prepare("SELECT `p`.`content_id` FROM  `sys_accounts` AS  `a` 
+											LEFT JOIN  `sys_profiles` AS  `p` ON `a`.`id` =  `p`.`account_id` 
+											WHERE  `mig_id` = ? AND  `p`.`type` =  'bx_persons' LIMIT 1", $iId);
+											
+		return $this -> _oDb -> getOne($sQuery);
+	}
+
+	/**
+	* Returns person id of transferred member from Dolphin
+	* @param int $iId Dolphin's profile ID
+	* @return int
+	*/	
+	protected function getProfileId($iId)
+	{
+		$sQuery = $this -> _oDb -> prepare("SELECT `p`.`id` FROM  `sys_accounts` AS  `a` 
+											LEFT JOIN  `sys_profiles` AS  `p` ON `a`.`id` =  `p`.`account_id` 
+											WHERE  `mig_id` = ? AND  `p`.`type` =  'bx_persons' LIMIT 1", $iId);
+											
+		return $this -> _oDb -> getOne($sQuery);
+	}
+
+	/**
+	* Check if the module was transfered
+	* @param string $sModule name from the list @uses  BxDolMConfig::_aMigrationModules
+	* @return int
+	*/	
+	protected function isModuleContentTransferred($sModule)
+	{
+		return isset($this -> _oConfig -> _aModulesAliases[$sModule])
+				? (int)$this -> _oDb -> getOne("SELECT `number` FROM `{$this -> _sPrefix}transfers` WHERE `status` != 'not_started' AND `module`=:module", array('module' => $this -> _oConfig -> _aModulesAliases[$sModule]))
+				: false;
+	}
+	
+	/**
+	* Returns list of the fields which should be transferred to Persons module
+	* @return array list of the fields names
+	*/
+	protected function getAssocFields()
+	{
+		$aFields = array();
+		$aExclude = array('Status', 'Couple', 'Captcha', 'aff_num', 'TermsOfUse', 'UserStatus', 'UserStatusMessage', 'UserStatusMessageWhen', 'Agree', 'Tags', 'Age', 'Featured', 'Keyword', 'Location', 'ProfilePhoto');
+		$sWhere = "";
+		if (!empty($aExclude))
+			$sWhere = " AND `Name` NOT IN ('" . implode("','" , $aExclude) . "')";
+			
+		$aItems = $this -> _mDb -> getAll("SELECT * FROM `sys_profile_fields` WHERE `Type` != 'block' {$sWhere}");
+	
+		foreach($aItems as $iKey => $aValue)
+		{
+				$aFields[$aValue['Name']] = array(
+					'name' => $aValue['Name'],
+					'type' => $aValue['Type'],
+					'required' => $aValue['Mandatory'],					
+					'title' => "_FieldCaption_{$aValue['Name']}_Edit",
+					'add' =>  (int)$aValue['JoinBlock'] !=0,
+					'edit' =>  (int)$aValue['EditOwnBlock'] !=0,
+					'view' =>  $aValue['ViewVisBlock'] !=0,
+					'values' => $aValue['Values']
+				);							
+		}
+		
+		return $aFields;
+	}
+	/**
+	 *  Check if the list already exists in una pre values list 
+	 *  
+	 *  @param string $sName list name 
+	 *  @return Boolean
+	 */
+	protected function isKeyPreKeyExits($sName)
+	{
+		return $this -> _oDb -> getOne("SELECT COUNT(*) FROM `sys_form_pre_lists` WHERE `key` = :key", array('key' => $sName)) == 1;
+	}
+	/**
+	 *  Adds category to existed list 
+	 *  
+	 *  @param string $sName category title
+	 *  @param string $sPrefix prefix for the module which should be used for new category (depends on module)
+	 *  @param int $sCategory module's category's pre values Name
+	 *  @return string value of the added category
+	 */
+	protected function transferCategory($sName, $sPrefix, $sCategory)
+	{
+		if (strpos($sName, ';') !== false)
+			$sName = substr($sName, 0, strpos($sName, ';'));
+		
+		$sTitle = str_replace(' ', '_', $sName);
+		$aValues = $this -> _oDb -> getRow("SELECT * FROM `sys_form_pre_values` WHERE `Key` = :cat AND `LKey` LIKE CONCAT('%', :value, '%') LIMIT 1", array('cat' => $sCategory, 'value' => $sTitle));
+
+		if (!empty($aValues))
+			return $aValues['Value'];
+		
+		$aValues = $this -> _oDb -> getRow("SELECT MAX(`Value`) + 1 as `Value`, MAX(`Order`) + 1 as `Order` FROM `sys_form_pre_values` WHERE `Key` = :cat", array('cat' => $sCategory));
+		
+		$sQuery = $this -> _oDb -> prepare("
+			INSERT INTO `sys_form_pre_values` SET
+				`Key`	= ?, 
+				`Value`	= ?,
+				`Order`	= ?,
+				`LKey`	= ?", $sCategory, $aValues['Value'], $aValues['Order'], "_{$sPrefix}_cat_{$sTitle}");
+				
+		$this -> _oDb -> query($sQuery);
+		BxDolStudioLanguagesUtils::getInstance() -> addLanguageString("_{$sPrefix}_cat_{$sTitle}", $sName);
+		return $aValues['Value'];
+	}
+	/**
+	 *  Transfer fields lists with translations 
+	 *  
+	 *  @param string $sName field name 
+	 *  @param string $sTitle translation
+	 *  @param mixed $mixedValues  contains name of the list which already exists or array values for transfer
+	 *  @param bool $bAdd don't add value to already exited fields list 
+	 *  @return string list name for db insert with #!
+	 */
+	protected function transferPreValues($sName, $sTitle, $mixedValues, $bAdd = false)
+		{
+			if (empty($mixedValues))
+				return '';
+			
+			if (is_string($mixedValues) && substr($mixedValues, 0, 2) == '#!')
+				return $mixedValues;
+						
+			$i = 1;
+			if (!$this -> isKeyPreKeyExits($sName))
+			{
+				$sQuery = $this -> _oDb -> prepare("INSERT INTO `sys_form_pre_lists` (`id`, `module`, `key`, `title`, `use_for_sets`, `extendable`) VALUES
+												(NULL, 'bx_persons', ?, ?, 0, 1)", $sName, '_bx_' . $sName . '_pre_lists_cats');			
+				$this -> _oLanguage -> addLanguageString('_bx_' . $sName . '_pre_lists_cats', $sTitle);
+				$this -> _oDb -> query($sQuery);
+				
+				$sQuery = $this -> _oDb -> prepare("
+					INSERT INTO `sys_form_pre_values` SET
+						`Key`	= ?, 
+						`Value`	= ?,
+						`Order`	= ?,
+						`LKey`	= ?", $sName, 0, 0, '_sys_please_select');
+				$this -> _oDb -> query($sQuery);
+			}
+			else
+			{
+				if (!$bAdd)
+					return '';
+				
+				$i = $this -> _oDb -> getOne("SELECT MAX(`Order`) FROM `sys_form_pre_values` WHERE `Key` =:key", array('key' => $sName)) + 1;
+			}
+						
+			
+			foreach($mixedValues as $mixedKey => $mixedValue)
+			{
+				$sLangKey = "_bx_fields_cat_{$sName}_value_{$mixedKey}";
+				
+				if (is_array($mixedValue))
+				{
+					foreach($mixedValue as $sLang => $sValue)
+					{
+						if (isset($this -> _aLanguages[$sLang]))
+							$this -> _oLanguage -> addLanguageString($sLangKey, $sValue, $this -> _aLanguages[$sLang]);
+					}					
+				}
+				else
+					$this -> _oLanguage -> addLanguageString($sLangKey, $mixedValue);
+				
+				$sQuery = $this -> _oDb -> prepare("
+				INSERT INTO `sys_form_pre_values` SET
+					`Key`	= ?, 
+					`Value`	= ?,
+					`Order`		= ?,
+					`LKey`	= ?", $sName, $mixedKey, $i++, $sLangKey);
+				
+				$this -> _oDb -> query($sQuery);
+			}
+			
+		return "#!{$sName}";
+	}
+	/**
+	 *  Returns pre values array by list name in pairs format
+	 *  
+	 *  @param string $sName name of the list
+	 *  @param string $sField array's index field name
+	 *  @param string $sValue array's value field name
+	 *  @param int $iStart  -  allows to set start value and get values above it only
+	 *  @return array 
+	 */
+	protected function getPreValuesBy($sName, $sField = 'Order', $sValue = 'LKey', $iStart = 0)
+	{
+		$sStart = '';
+		if ($iStart)
+			$sStart = "AND `$sField` >  $iStart";
+		
+		$sQuery = $this -> _mDb -> prepare("SELECT * FROM `sys_pre_values` WHERE `Key` = ? {$sStart} ORDER BY `Order`", $sName);
+		return $this -> _mDb -> getPairs($sQuery, $sField, $sValue);
+	}
+	
+	/**
+	 *  Returns default language name/id
+	 *  
+	 *  @param boolean $bName return language name, otherwise id 
+	 *  @return mixed default language
+	 */
+	protected function getDefaultLang($bName = true)
+	{
+		$aLang = $this -> _mDb -> getPairs("SELECT * FROM `sys_localization_languages` ORDER BY `id`", 'Name', 'ID'); 
+		$sDefultLang = $this -> _mDb -> getParam('lang_default'); 
+		return $bName ? $sDefultLang : $aLang[$sDefultLang];
+	}
+	/**
+	 *  Returns translations for all existed languages on Dolphin by language key
+	 *  
+	 *  @param string $LKey language key
+	 *  @return array 
+	 */
+	protected function getLKeyTranslations($LKey)
+	{
+		return $this -> _mDb -> getPairs("SELECT `l`.`Name`, `s`.`String`, `l`.`ID`
+										FROM `sys_localization_keys` as `k`
+										LEFT JOIN `sys_localization_strings` as `s` ON `k`.`ID` = `s`.`IDKey`
+										LEFT JOIN `sys_localization_languages` as `l` ON `s`.`IDLanguage` = `l`.`ID`
+										WHERE `k`.`Key` = :key", 'Name', 'String', array('key' => $LKey));
+	}
+	
+	/**
+	 *  Returns pre values field value of defined field, by Key and Value
+	 *  
+	 *  @param string $sKey Key name
+	 *  @param mixed $mixedValue Value 
+	 *  @param string $sField field name
+	 *  @return mixed value
+	 */
+	public function getPreValuesFieldBy($sKey, $mixedValue, $sField = 'Order')
+	{
+		return $this -> _mDb -> getOne("SELECT `{$sField}` FROM `sys_pre_values` WHERE `Key` = ? AND `Value` = ? LIMIT 1", $sName, $mixedValue);
+	}
+	
+	/**
+	 *  Transfer Tags from the module, to meta 
+	 *  
+	 *  @param int $iObjectId module's item ID in Dolphin
+	 *  @param int $iNewObjectId module's item ID in UNA
+	 *  @param int $sType module's  prefix in Dolphin
+	 *  @param int $sTableKeywords table name in UNA for tags migration
+	 *  @return void
+	 */
+	protected function trasnferTags($iObjectId, $iNewObjectId, $sType, $sTableKeywords)
+	{
+		$aTags = $this -> _mDb -> getAll("SELECT `Tag` FROM `sys_tags` WHERE `ObjID`=:id AND `Type`=:type", array('id' => $iObjectId, 'type' => $sType));
+		if (empty($aTags))
+			return false;
+		
+		foreach($aTags as $aTag)
+			$this -> _oDb -> query("INSERT IGNORE INTO `{$sTableKeywords}` SET `keyword`=:keyword, `object_id`=:id", array('keyword' => $aTag['Tag'], 'id' => $iNewObjectId));
+	}
+	
+	/**
+	 *  Transfer comments for module's items
+	 *  
+	 *  @param int $iObject object ID in UNA
+	 *  @param int $iEntryId object ID in Dolphin 
+	 *  @param string $sType module name for transfer @uses BxDolMConfig::_aMigrationModules
+	 *  @return int transferred comments number
+	 */
+	protected function transferComments($iObject, $iEntryId, $sType = 'photos')
+	{
+		
+		switch($sType)
+		{
+			case 'photos': 
+							$sCmtsTable = 'bx_photos_cmts';
+							$sTable = 'bx_albums_cmts_media';
+							break;
+			case 'photo_albums': 
+							$sCmtsTable = 'bx_photos_cmts_albums';
+							$sTable = 'bx_albums_cmts';
+							break;
+			case 'videos': 
+							$sCmtsTable = 'bx_videos_cmts';
+							$sTable = 'bx_albums_cmts_media';
+							break;
+			case 'video_albums': 
+							$sCmtsTable = 'bx_videos_cmts_albums';
+							$sTable = 'bx_albums_cmts';
+							break;
+			case 'blogs': 
+							$sCmtsTable = 'bx_blogs_cmts';
+							$sTable = 'bx_posts_cmts';
+							break;
+			case 'groups': 
+							$sCmtsTable = 'bx_groups_cmts';
+							$sTable = 'bx_groups_cmts';
+							break;
+			case 'events': 
+							$sCmtsTable = 'bx_events_cmts';
+							$sTable = 'bx_events_cmts';
+							break;
+			case 'polls': 
+							$sCmtsTable = 'bx_poll_cmts';
+							$sTable = 'bx_polls_cmts';
+							break;
+			case 'files': 
+							$sCmtsTable = 'bx_files_cmts';
+							$sTable = 'bx_files_cmts';
+							break;
+			case 'market': 
+							$sCmtsTable = 'bx_store_cmts';
+							$sTable = 'bx_market_cmts';
+							break;
+			case 'timeline': 
+							$sCmtsTable = 'bx_wall_comments';
+							$sTable = 'bx_timeline_comments';
+							break;
+		}
+		
+		$aComments = $this -> _mDb -> getAll("SELECT * FROM `{$sCmtsTable}` WHERE `cmt_object_id` = :id ORDER BY `cmt_id` ASC", array('id' => $iEntryId));
+		
+		$iCommnets = 0;
+		$aCommentsArray = array();
+		foreach($aComments as $iKey => $aValue)
+		{
+			$iProfileId = $this -> getProfileId($aValue['cmt_author_id']);			
+			if ($iProfileId)
+			{
+				$bIscmtsArray = $aValue['cmt_parent_id'] && isset($aCommentsArray[$aValue['cmt_parent_id']]);
+				$this -> _oDb -> query("INSERT INTO `{$sTable}` (`cmt_id`, `cmt_parent_id`, `cmt_vparent_id`, `cmt_object_id`, `cmt_author_id`, `cmt_level`, `cmt_text`, `cmt_time`, `cmt_replies`, `cmt_rate`, `cmt_rate_count`)
+									VALUES	(NULL, :parent_id, :vparent_id, :object, :user, :level, :message, :time, :replies, :rate, :rate_count)", 
+									array(
+											'parent_id'	=> $bIscmtsArray ? $aCommentsArray[$aValue['cmt_parent_id']]['id'] : 0,
+											'vparent_id' => $bIscmtsArray ? ($aCommentsArray[$aValue['cmt_parent_id']]['vparent'] ? $aCommentsArray[$aValue['cmt_parent_id']]['vparent'] : $aCommentsArray[$aValue['cmt_parent_id']]['id']) : 0,
+											'object' => $iObject,
+											'user' => $iProfileId, 
+											'message' => $aValue['cmt_text'], 
+											'time' => strtotime($aValue['cmt_time']),
+											'replies' => $aValue['cmt_replies'],
+											'rate' => $aValue['cmt_rate'],
+											'rate_count' => $aValue['cmt_rate_count'],
+											'level' => isset($aCommentsArray[$aValue['cmt_parent_id']]) && $aCommentsArray[$aValue['cmt_parent_id']] ? $aCommentsArray[$aValue['cmt_parent_id']]['level'] + 1 : 0
+										));
+				
+				$aCommentsArray[$aValue['cmt_id']] = array(
+																'id' => $this -> _oDb -> lastId(),
+																'level' => $bIscmtsArray ? (int)$aCommentsArray[$aValue['cmt_parent_id']]['level'] + 1 : 0,
+																'vparent' => 
+																			$bIscmtsArray ? 
+																			(
+																				$aCommentsArray[$aValue['cmt_parent_id']]['vparent'] ? $aCommentsArray[$aValue['cmt_parent_id']]['vparent'] :  $aCommentsArray[$aValue['cmt_parent_id']]['id']
+																			) : 0 
+															);
+				$iCommnets++;				
+			}
+		}
+		
+		return $iCommnets;
+	}
+
+	
+	
+	/**
+	* Create migration field in main table for transferring content from Dolphin to UNA and contains id of the object in Dolphin 
+	* @return mixed
+         */
+	protected function createMIDField()
+	{
+		if (!$this -> _sTableWithTransKey)
+			return false;
+		
+		if ($this -> _oDb -> isFieldExists($this -> _sTableWithTransKey, $this -> _sTransferFieldIdent))
+			return true;
+		
+		return $this -> _oDb -> query("ALTER TABLE `{$this -> _sTableWithTransKey}` ADD `{$this -> _sTransferFieldIdent}` int(11) unsigned NOT NULL default '0'");
+	}
+	
+	/**
+	 *  Returns last migration field value
+	 *  
+	 *  @return int
+	 */
+	protected function getLastMIDField()
+	{
+		if (!$this -> _sTableWithTransKey)
+			return false;
+
+		return (int)$this -> _oDb -> getOne("SELECT `{$this -> _sTransferFieldIdent}` FROM `{$this -> _sTableWithTransKey}` WHERE `{$this -> _sTransferFieldIdent}` <> 0 ORDER BY `ID` DESC LIMIT 1");
+	}
+
+	/**
+	 *  Check if this record was already transferred
+	 *  
+	 *  @param int $iItemId object id in Dolphin 
+	 *  @param string $sField field name with id values in Dolphin
+	 *  @return int 
+	 */	
+	protected function isItemExisted($iItemId, $sField = 'id')
+	{
+		if (!$this -> _sTableWithTransKey)
+			return false;
+
+		return (int)$this -> _oDb -> getOne("SELECT `{$sField}` FROM `{$this -> _sTableWithTransKey}` WHERE `{$this -> _sTransferFieldIdent}` = :item LIMIT 1", array('item' => $iItemId));
+	}	
+	
+	/**
+	 *  Set value for migrated record to migration field 
+	 *  
+	 *  @param int $iId object id in UNA
+	 *  @param int $iItemId object id in Dolphin
+	 *  @param string $sField id field name 
+	 *  @return int affected rows
+	 */
+	protected function setMID($iId, $iItemId, $sField ='id')
+	{
+		if (!$this -> _sTableWithTransKey)
+			return false;
+
+		return (int)$this -> _oDb -> query("UPDATE `{$this -> _sTableWithTransKey}` SET `{$this -> _sTransferFieldIdent}` = :item WHERE `{$sField}` = :id", array('id' => $iId, 'item' => $iItemId));
+	}
+	/**
+	 *  Drop migration field from the table
+	 *  
+	 *  @return int affected rows
+	 */
+	public function dropMID()
+	{
+		if (!$this -> _sTableWithTransKey || !$this -> _oDb -> isFieldExists($this -> _sTableWithTransKey, $this -> _sTransferFieldIdent))
+			return false;
+
+		return (int)$this -> _oDb -> query("ALTER TABLE `{$this -> _sTableWithTransKey}` DROP `{$this -> _sTransferFieldIdent}`");
+	}
+	
+	/**
+	 *  Removes all transferred content from UNA
+	 *  
+	 *  @return void
+	 */
+	public function removeContent()
+	{
+		$this -> dropMID();
+		$this -> _oDb -> updateTransferStatus($this -> _sModuleName, 'not_started');
+		$this -> setResultStatus('');
+	}
+}
+   
+/** @} */

+ 148 - 0
modules/boonex/dolphin_migration/classes/BxDolMDb.php

@@ -0,0 +1,148 @@
+<?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('BxDolDb');
+
+class BxDolMDb extends BxBaseModGeneralDb
+{	
+	public function __construct(&$oConfig)
+	{
+		parent::__construct($oConfig);			
+	}
+
+	/** 
+	* Save Dolphin configuration 
+	* @param array $aConfig parameters
+	*/ 
+	public function saveConfig($aConfig)
+	{
+		if(is_array($aConfig))
+		{
+            
+			$bRecords = true;
+			foreach($aConfig as $sName => $mValue)
+            {
+                $mValue = bx_process_input($mValue);
+                $sName  = bx_process_input($sName);
+				$sQuery = $this -> prepare("REPLACE INTO `{$this -> _sPrefix}config` SET `name` = ?, `value` = ?", $sName, $mValue);
+				if (!$this -> res($sQuery))
+					$bRecords &= false;
+            }	
+		}
+		
+		return $bRecords;
+	} 
+	
+	/** 
+	* Get config parameter value
+	* @param string $sConfigName param's name 
+	* @return string 
+	*/
+	public function getExtraParam($sConfigName){ 
+		$sQuery = $this -> prepare("SELECT `value` FROM `{$this -> _sPrefix}config` WHERE `name` = ?", $sConfigName);
+		return $this -> getOne($sQuery);
+	}
+
+	/** 
+	* Creates/edits migration list
+	* @param array $aConfig Dolphin config info 
+	*/	
+	public function createConfig($aConfig){
+        if( is_array($aConfig) ) {
+            foreach($aConfig as $sName => $mValue)
+            {
+                $mValue = $this -> escape($mValue);
+                $sName  = $this -> escape($sName);
+
+                // add new;
+                if(!$this -> getExtraParam($sName))
+				{
+                    $sQuery = $this -> prepare("INSERT INTO `{$this -> _sPrefix}config` SET `name` = ?, `value` = ?", $sName, $mValue);
+                    $this -> query($sQuery);
+                }
+                else
+				{
+                // update exsisting;
+                    $sQuery = $this -> prepare("UPDATE `{$this -> _sPrefix}config` SET  `value` = ? WHERE `name` = ?", $mValue, $sName);					
+                    $this -> query($sQuery);
+                }
+            }
+        }
+	}
+	
+	/** 
+	* Returns Migration Result information
+	* @param string $sModule name
+	* @return  string
+	*/
+	public function getTransferStatusText($sModule)
+    {
+        $sQuery = $this -> prepare("SELECT `status_text` FROM `{$this -> _sPrefix}transfers` WHERE `module` = ? LIMIT 1", $sModule);
+        return $this -> getOne($sQuery);
+    }
+
+	/** 
+	* Returns current migration status
+	* @param string $sModule name @uses  BxDolMConfig::_aMigrationModules
+	* @return  string
+	*/
+	 public function getTransferStatus($sModule)
+	 {
+	     $sQuery = $this -> prepare("SELECT `status` FROM `{$this -> _sPrefix}transfers` WHERE `module` = ? LIMIT 1", $sModule);
+	     return $this -> getOne($sQuery);
+	 }
+
+	 public function updateTransferStatus($sModule, $sStatus)
+	 {            
+	     $this -> query("UPDATE `{$this -> _sPrefix}transfers` SET `status` = :status WHERE `module` = :module", array('module' => $sModule, 'status' => $sStatus));
+	 }
+
+	/** 
+	* Check if configuration already exists
+	* @return  Boolean
+	*/
+	 public function isConfigInstalled()
+	 {
+		return $this -> getExtraParam('dbname') && $this -> getExtraParam('username');
+	 }
+	
+	/** 
+	* Adds module for migration to migration list
+	* @param string $sName modules name
+	* @param string $mixedNumber records number
+	* @return mixed 
+	*/		
+	public function addToTransferList($sName, $mixedNumber)
+	{
+		$sNumber = $mixedNumber;
+		if (is_array($mixedNumber))
+			$sNumber = implode(',', $mixedNumber);	
+		return $this -> query("INSERT INTO `{$this -> _sPrefix}transfers` SET `module` = :module, `status` = 'not_started', `number` = :number", array('module' => $sName, 'number' => $sNumber));
+	}		
+
+	/** 
+	* Check whether required Una plug-in installed for transferring
+	* @param string $sName pugin name
+	* @return Boolean
+	*/			
+	public function isPluginInstalled($sName)
+	{
+		$sQuery = $this -> prepare("SELECT COUNT(*) FROM `sys_modules` WHERE `type` = 'module' AND `name` = ? LIMIT 1" , $sName);
+		return (int)$this -> getOne($sQuery) == 1;
+	}
+	
+	public function cleanTrasnfersTable()
+	{
+		return $this -> query("TRUNCATE TABLE `{$this -> _sPrefix}transfers`");
+	}
+}
+
+/** @} */

+ 234 - 0
modules/boonex/dolphin_migration/classes/BxDolMEvents.php

@@ -0,0 +1,234 @@
+<?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('BxDolStorage');
+	
+class BxDolMEvents extends BxDolMData
+{	
+	public function __construct(&$oMigrationModule, &$oDb)
+	{
+        parent::__construct($oMigrationModule, $oDb);
+		$this -> _sModuleName = 'events';
+		$this -> _sTableWithTransKey = 'bx_events_data';
+    }    
+	
+	public function getTotalRecords()
+	{
+		return (int)$this -> _mDb -> getOne("SELECT COUNT(*) FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] . "` WHERE `Status` = 'approved'");			
+	}
+	
+	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_events'));
+		
+			
+		$this -> createMIdField();
+		$iEventId = $this -> getLastMIDField();						
+		$sStart = '';
+		if ($iEventId)
+			$sStart = " AND `ID` >= {$iEventId}";
+		
+		$aResult = $this -> _mDb -> getAll("SELECT * FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] . "` WHERE `Status` = 'approved' {$sStart} ORDER BY `ID`");
+		$iCmts = 0;
+		foreach($aResult as $iKey => $aValue)
+		{ 
+			$iProfileId = $this -> getProfileId((int)$aValue['ResponsibleID']);
+			$iEventId = $this -> isItemExisted($aValue['ID']);			
+			if (!$iProfileId)
+				continue;
+			
+			if (!$iEventId)
+			{
+				$sQuery = $this -> _oDb -> prepare( 
+                     "
+                     	INSERT INTO
+                     		`{$this -> _sTableWithTransKey}`
+                     	SET
+                     		`author`   			= ?,
+                     		`added`      		= ?,
+                     		`changed`   		= ?,
+							`event_name`		= ?,
+                     		`event_desc`		= ?,							
+							`event_cat`			= ?,
+							`views`				= ?,
+							`featured`			= ?,
+							`allow_view_to`		= ?,
+							`join_confirmation`	= ?,
+							`date_start`		= ?,
+							`date_end`			= ?
+                     ", 
+						$iProfileId, 
+						isset($aValue['Date']) ? $aValue['Date'] : time(),
+						isset($aValue['Date']) ? $aValue['Date'] : time(),						
+						isset($aValue['Title']) ? $aValue['Title'] : '',
+						isset($aValue['Description']) ? $aValue['Description'] : '',						
+						$this -> transferCategory($aValue['Categories']),
+						isset($aValue['Views']) ? (int)$aValue['Views'] : 0,
+						isset($aValue['Featured']) ? (int)$aValue['Featured'] : 0,
+						isset($aValue['allow_view_event_to']) ? (int)$aValue['allow_view_event_to'] : 0,
+						isset($aValue['JoinConfirmation']) ? (int)$aValue['JoinConfirmation'] : 0,
+						isset($aValue['EventStart']) ? $aValue['EventStart'] : time(), 
+						isset($aValue['EventEnd']) ? $aValue['EventEnd'] : time()
+						);			
+		
+				$this -> _oDb -> query($sQuery);
+				
+				$iEventId = $this -> _oDb -> lastId();			
+				if (!$iEventId)
+				{
+					$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_events_error', (int)$aValue['ID']));
+					return BX_MIG_FAILED;
+				}				
+				
+				$this -> setMID($iEventId, $aValue['ID']);	
+			
+				$this -> exportFans($aValue['ID'], $this-> addEventToProfiles($iProfileId, $iEventId));				
+			}					
+			
+			$iCmts = $this -> transferComments($iEventId, (int)$aValue['ID'], 'events');
+			
+			$iPic = $this -> exportPictures($aValue['ID'], $iProfileId);			
+			
+			$this -> _iTransferred++;
+					
+			$this -> _oDb ->  query("UPDATE `{$this -> _sTableWithTransKey}` 
+										SET 
+											`picture` = :pic,
+											`comments` = :cmts 
+									WHERE `id` = :id", array('pic' => $iPic, 'id' => $iEventId, 'cmts' => $iCmts));
+			
+			$this -> trasnferTags((int)$aValue['ID'], $iEventId, $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['type'], $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['keywords']);
+        }      	
+        
+		// set as finished;
+        $this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_events_finished', $this -> _iTransferred, $iCmts));
+        return BX_MIG_SUCCESSFUL;
+    }
+	
+	protected function transferCategory($sCategory, $sPrefix = 'bx_events', $sPreValueCateg = 'bx_events_cats')
+	{
+		return parent::transferCategory($sCategory, $sPrefix, $sPreValueCateg);
+	}
+	/**
+	 *  Transfers all Dolphin's events pictures
+	 *  
+	 *  @param int $iEventId Dolphin's event's id
+	 *  @param int $iProfileId event's owner id in UNA events table
+	 *  @return int  first transferred events image's id
+	 */
+	private function exportPictures($iEventId, $iProfileId)
+    {
+        $iFirstImage = 0;
+		$iProfileId = (int)$iProfileId;
+		$aPhotos = $this -> _mDb -> getAll("SELECT `p`.* FROM `bx_photos_main` as `p`
+											LEFT JOIN `bx_events_images` as `e` ON `p`.`ID` = `e`.`media_id`
+											WHERE `e`.`entry_id` = :id", array('id' => $iEventId));
+		
+		if (empty($aPhotos))
+			return false;
+		
+		foreach($aPhotos as $iKey => $aFile)
+		{
+			$sImageFile = $this -> _sImagePhotoFiles . "{$aFile['ID']}.{$aFile['Ext']}";
+			if (file_exists($sImageFile))
+			{
+	        	$oStorage = BxDolStorage::getObjectInstance('bx_events_pics'); 				
+				$iId = $oStorage->storeFileFromPath($sImageFile, false, $iProfileId);
+				$oStorage -> afterUploadCleanup($iId, $iProfileId);
+				$iFirstImage = $iFirstImage ? $iFirstImage : $iId;
+			}
+		}
+		
+		return $iFirstImage;
+    }
+	/**
+	 *  Add event to sys_profiles table in una
+	 *  
+	 *  @param int $iProfileId profile id
+	 *  @param int $iEventId event id
+	 *  @return int last insert id
+	 */
+	private function addEventToProfiles($iProfileId, $iEventId)
+	{
+		$sQuery = $this -> _oDb -> prepare("
+						INSERT INTO
+							`sys_profiles`
+						SET
+						   `account_id`	= ?,
+						   `type`    	= 'bx_events',
+						   `content_id` = ?,
+						   `status`    	= 'active'
+				   ", (int)BxDolProfile::getInstance($iProfileId)->getAccountId(), $iEventId);
+
+		$this -> _oDb -> query($sQuery);
+		return $this -> _oDb -> lastId();
+	}
+	/**
+	 *  Transfer Event's participants lists
+	 *  
+	 *  @param int $iMID event's id in Dolphin
+	 *  @param int $iEventProfileId events id from sys_profile
+	 *  @return int participants number
+	 */
+	private function exportFans($iMID, $iEventProfileId)
+    {
+		$iCount = 0;
+		$aFans =  $this -> _mDb -> getAll("SELECT * FROM `bx_events_participants` WHERE `id_entry`=:id ", array('id' => $iMID));
+		foreach($aFans as $iKey => $aValue)
+		{
+			$iProfileId = $this -> getProfileId($aValue['id_profile']);
+			$sQuery =  $this -> _oDb -> prepare("
+						INSERT IGNORE INTO
+							`bx_events_fans`
+						SET
+						   `initiator`	= ?,
+						   `content`    = ?,
+						   `mutual`     = ?,
+						   `added`     	= ?
+			", $iProfileId,  $iEventProfileId, $aValue['confirmed'], $aValue['when']);
+				
+			if(!$this -> _oDb -> query($sQuery))
+			   return _t('_bx_dolphin_migration_friends_exports_error');
+		   
+		   $iCount++;
+		}
+		
+		return $iCount;
+	}
+	
+	public function removeContent()
+	{
+		if (!$this -> _oDb -> isTableExists($this -> _sTableWithTransKey) || !$this -> _oDb -> isFieldExists($this -> _sTableWithTransKey, $this -> _sTransferFieldIdent))
+			return false;
+		
+		$aRecords = $this -> _oDb -> getAll("SELECT * FROM `{$this -> _sTableWithTransKey}` WHERE `{$this -> _sTransferFieldIdent}` !=0 ");
+		$iNumber = 0;
+		if (!empty($aRecords))
+		{	
+			foreach($aRecords as $iKey => $aValue)
+			{
+				BxDolService::call('bx_events', 'delete_entity_service', array($aValue['id'], true));
+				$iNumber++;
+			}
+		}		
+		parent::removeContent();
+		return $iNumber;
+	}
+}
+
+/** @} */

+ 167 - 0
modules/boonex/dolphin_migration/classes/BxDolMFiles.php

@@ -0,0 +1,167 @@
+<?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('BxDolStorage');
+	
+class BxDolMFiles extends BxDolMData
+{	
+	/**
+	*@var path to the directory with Dolphin files
+	*/
+	private $_sFilesPath = '';
+	
+	public function __construct(&$oMigrationModule, &$oDb)
+	{
+        parent::__construct($oMigrationModule, $oDb);
+		$this -> _sModuleName = 'files';
+		$this -> _sTableWithTransKey = 'bx_files_main';
+		$this -> _sFilesPath = $this -> _oDb -> getExtraParam('root') . 'modules' . DIRECTORY_SEPARATOR . 'boonex' . DIRECTORY_SEPARATOR . 'files' . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'files' .  DIRECTORY_SEPARATOR ;
+	}    
+	
+	public function getTotalRecords()
+	{
+		return (int)$this -> _mDb -> getOne("SELECT COUNT(*) FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] . "` WHERE `Status` IN ('approved', 'pending')");			
+	}
+	
+	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_files'));		
+			
+		$this -> createMIdField();
+		$iFileId = $this -> getLastMIDField();						
+		$sStart = '';
+		if ($iFileId)
+			$sStart = " AND `ID` >= {$iFileId}";
+		
+		$aResult = $this -> _mDb -> getAll("SELECT * FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] . "` WHERE `Status` IN ('approved', 'pending') {$sStart} ORDER BY `ID`");
+		$iCmts = 0;
+		foreach($aResult as $iKey => $aValue)
+		{ 
+			$iProfileId = $this -> getProfileId((int)$aValue['Owner']);
+			$iFileId = $this -> isItemExisted($aValue['ID']);			
+			if (!$iProfileId)
+				continue;
+			
+			$iDate = isset($aValue['Date']) ? $aValue['Date'] : time();
+			if (!$iFileId)
+			{
+				$sQuery = $this -> _oDb -> prepare( 
+                     "
+                     	INSERT INTO
+                     		`{$this -> _sTableWithTransKey}`
+                     	SET
+                     		`author`   			= ?,
+                     		`added`      		= ?,
+                     		`changed`   		= ?,
+							`title`				= ?,
+                     		`desc`				= ?,							
+							`cat`				= ?,
+							`views`				= ?,
+							`featured`			= ?,
+							`allow_view_to`		= ?
+                     ", 
+						$iProfileId, 
+						$iDate,
+						$iDate,
+						isset($aValue['Title']) ? $aValue['Title'] : '',
+						isset($aValue['Desc']) ? $aValue['Desc'] : '',						
+						$this -> transferCategory($aValue['Categories']),
+						isset($aValue['Views']) ? (int)$aValue['Views'] : 0,
+						isset($aValue['Featured']) ? (int)$aValue['Featured'] : 0,
+						isset($aValue['AllowDownload']) ? (int)$aValue['AllowDownload'] : 0
+						);			
+		
+				$this -> _oDb -> query($sQuery);
+				
+				$iFileId = $this -> _oDb -> lastId();			
+				if (!$iFileId)
+				{
+					$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_files_error', (int)$aValue['ID']));
+					return BX_MIG_FAILED;
+				}				
+				
+				$this -> setMID($iFileId, $aValue['ID']);			
+				$this -> exportFile($aValue['ID'] . '_' . sha1($iDate), $aValue['Ext'], $iFileId, $iProfileId);		
+			}					
+			
+			$iCmts = $this -> transferComments($iFileId, (int)$aValue['ID'], 'files');
+		
+			$this -> _iTransferred++;
+					
+			$this -> _oDb ->  query("UPDATE `{$this -> _sTableWithTransKey}`
+									SET 
+											`comments` = :cmts 
+									WHERE `id` = :id", array('id' => $iFileId, 'cmts' => $iCmts));
+			
+			$this -> trasnferTags((int)$aValue['ID'], $iFileId, $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['type'], $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['keywords']);
+        }      	
+
+        // set as finished;
+        $this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_files_finished', $this -> _iTransferred, $iCmts));
+        return BX_MIG_SUCCESSFUL;
+    }
+	/**
+	 *  Export file by hash name
+	 *  
+	 *  @param string $sName hash
+	 *  @param string $sExt file extension
+	 *  @param int $iFileID filed id in UNA
+	 *  @param int $iProfileId file owner id in UNA
+	 *  @return mixed affected rows or false
+	 */
+	private function exportFile($sName, $sExt, $iFileID, $iProfileId)
+	 {
+		$sFilesPath = $this -> _sFilesPath . "{$sName}";				
+		if (file_exists($sFilesPath) && copy($sFilesPath, BX_DIRECTORY_PATH_TMP . "{$sName}.{$sExt}"))
+		{
+	        	$oStorage = BxDolStorage::getObjectInstance('bx_files_files');
+				$iId = $oStorage->storeFileFromPath(BX_DIRECTORY_PATH_TMP . "{$sName}.{$sExt}", false, $iProfileId);
+				$oStorage -> afterUploadCleanup($iId, $iProfileId);
+				$sQuery = $this -> _oDb -> prepare("UPDATE `{$this -> _sTableWithTransKey}` SET `file_id`=? WHERE `id`=?", $iId, $iFileID);
+				return $this -> _oDb-> query($sQuery);
+		}
+		
+		return false;		
+    }
+   
+	protected function transferCategory($sCategory, $sPrefix = 'bx_files', $sPreValueCateg = 'bx_files_cats')
+	{
+		return parent::transferCategory($sCategory, $sPrefix, $sPreValueCateg);
+	}
+	
+	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)
+			{
+				BxDolService::call('bx_files', 'delete_entity', array($aValue['id']));
+				$iNumber++;
+			}
+		}
+		parent::removeContent();
+		return $iNumber;
+	}
+}
+
+/** @} */

+ 318 - 0
modules/boonex/dolphin_migration/classes/BxDolMForum.php

@@ -0,0 +1,318 @@
+<?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('BxDolStorage');
+	
+class BxDolMForum extends BxDolMData
+{	
+	private $_iSystem = 0;
+	
+	public function __construct(&$oMigrationModule, &$oDb)
+	{
+        parent::__construct($oMigrationModule, $oDb);
+		$this -> _sModuleName = 'forum';
+		$this -> _sTableWithTransKey = 'bx_forum_discussions';
+		$this -> _iSystem = $this -> _oDb -> getOne("SELECT `ID` FROM `sys_objects_cmts` WHERE `Name` = 'bx_forum' LIMIT 1");
+    }    
+	
+	public function getTotalRecords()
+	{
+		$aResult = $this -> _mDb -> getRow("SELECT SUM(`forum_topics`) as `topics`, SUM(`forum_posts`) as `posts` FROM `bx_forum`");
+		return !(int)$aResult['topics'] && !(int)$aResult['posts'] ? 0 : $aResult;
+	}
+
+	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_forum'));
+		
+			
+		$this -> createMIdField();	
+		$aResult = $this -> _mDb -> getAll("SELECT * FROM `bx_forum` ORDER BY `forum_id`");	
+		$iCmts = $iCount = 0;
+		foreach($aResult as $iKey => $aValue)
+		{ 
+			$iCategory = $aValue['forum_uri'] == 'General-discussions' ? 1 : $this -> transferCategory($aValue['forum_title']);		
+			$aTopicts = $this -> _mDb -> getAll("SELECT * FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] . "` 
+												  WHERE `forum_id` = :categ
+												  ORDER BY `topic_id`", array('categ' => $aValue['forum_id']));
+
+			foreach($aTopicts as $iTopic => $aTopic)
+			{
+				$iTopicId = $this -> isItemExisted($aTopic['topic_id']);
+				$iProfileId = $this -> getProfileIdByNickName($aTopic['first_post_user']);
+				if (!$iTopicId && $iProfileId)
+				{
+					$sTitle = isset($aTopic['topic_title']) ? $aTopic['topic_title'] : time();
+					$sStatus = !$aTopic['topic_hidden'] ? 'active' : 'hidden';
+					$sQuery = $this -> _oDb -> prepare( 
+							"
+								INSERT INTO
+									`{$this -> _sTableWithTransKey}`
+								SET
+									`author`   			= ?,
+									`added`				= ?,	
+									`title`				= ?,
+									`text`				= ?,
+									`status_admin`		= ?,									
+									`cat`				= ?,
+									`lock`				= ?,
+									`stick`				= ?
+							",
+							$iProfileId,
+							$aTopic['when'],
+							$sTitle,
+							$sTitle,
+							$sStatus,
+							$iCategory,
+							$aTopic['topic_locked'],
+							$aTopic['topic_sticky']							
+							);			
+			
+					$this -> _oDb -> query($sQuery);
+					
+					$iTopicId = $this -> _oDb -> lastId();
+					if (!$iTopicId)
+					{
+						$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_forum_error', (int)$aTopic['topic_id']));
+						return BX_MIG_FAILED;					
+					}
+					
+					$this -> setMID($iTopicId, $aTopic['topic_id']);	
+				}
+				
+				$aTopicsTrasnferInfo = $this -> transferMessages($iTopicId, (int)$aTopic['topic_id']);	
+				$this -> transferSubscribers($iTopicId, (int)$aTopic['topic_id']);
+				$this -> _iTransferred++;				
+					
+				$aStat = $this -> getTopicStat($iTopicId);
+				$this -> _oDb ->  query("UPDATE `{$this -> _sTableWithTransKey}` SET 
+									`allow_view_to` = 3, 
+									`comments` = :cmts,
+									`lr_timestamp` = :lr_timestamp,
+									`lr_profile_id` = :lr_profile_id,
+									`lr_comment_id` = :lrc_id,
+									`added` = :added,
+									`changed` = :changed,
+									`text_comments` = :all_text,
+									`text` = :text
+									 WHERE `id` = :id", 
+									array(
+											'id' => $iTopicId, 
+											'cmts' => $aTopicsTrasnferInfo['number'],
+											'lr_timestamp' =>  $aTopicsTrasnferInfo['lrt'],
+											'lr_profile_id' =>  $aTopicsTrasnferInfo['lrp'],
+											'lrc_id' =>  $aStat['lrc_id'],
+											'added' => $aStat['first_time'] ? $aStat['first_time'] : time(),
+											'changed' => $aStat['lr_timestamp'] ? $aStat['lr_timestamp'] : time(),
+											'all_text' => strip_tags($aStat['text']),
+											'text' => $aTopicsTrasnferInfo['first_message'],											
+										 )
+									);
+			}
+			
+        }      	
+
+        // set as finished;
+		$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_forum_finished', $this -> _iTransferred));
+        return BX_MIG_SUCCESSFUL;
+    } 
+	
+	/**
+	 *  Transfer Forum posts 
+	 *  
+	 *  @param int $iEntryId UNA forum ID
+	 *  @param int $iTopicId Dolphin topic id
+	 *  @return array first message, transferred posts number, last replay profile id, last replay time
+	 */
+	protected function transferMessages($iEntryId, $iTopicId)
+	{
+		$aItems = $this -> _mDb -> getAll("SELECT
+												`Profiles`.`ID` as `user`,
+												`post_text` as `message`,
+												`when`,
+												`p`.`post_id`
+												FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name_post'] . "` AS  `p`
+												LEFT JOIN `Profiles` ON `p`.`user` = `Profiles`.`NickName`
+												WHERE `topic_id` = :id 
+												ORDER BY `id` ASC", array('id' => $iTopicId));
+												
+		if (empty($aItems))
+			return false;
+		
+		$iNumber = 0;
+		$sMessage = '';
+		$iProfileId = 0;
+		foreach($aItems as $iKey => $aValue)
+		{
+			$iProfileId	= $this -> getProfileId($aValue['user']);
+			$this -> _oDb -> query("INSERT INTO `bx_forum_cmts` (`cmt_id`, `cmt_parent_id`, `cmt_vparent_id`, `cmt_object_id`, `cmt_author_id`, `cmt_level`, `cmt_text`, `cmt_time`, `cmt_replies`, `cmt_rate`, `cmt_rate_count`)
+									VALUES	(NULL, 0, 0, :object, :user, 0, :message, :time, 0, 0, 0)", 
+									array(
+											'object' => $iEntryId,
+											'user' => $iProfileId, 
+											'message' => $aValue['message'], 
+											'time' => $aValue['when'],
+										));
+			$iNumber++;
+			if (!$sMessage)
+				$sMessage = $aValue['message'];
+			
+			$iTime = $aValue['when'];						
+			$this -> transferAttachments($aValue['post_id'], $this -> _oDb -> lastId(), $iProfileId);
+		}
+		
+		return array('first_message' => $sMessage, 'number' => $iNumber, 'lrp' => $iProfileId, 'lrt' => $iTime);
+	}
+	/**
+	 *  Get profile ID in Una by Nickname in Dolphin
+	 *  
+	 *  @param string $sNickName Dolphin's nickname
+	 *  @return mixed profile id or false if not found
+	 */
+	private function getProfileIdByNickName($sNickName)
+	{
+		$iProfileId = $this -> _mDb -> getOne("SELECT `ID` FROM `Profiles` WHERE `NickName` = :user  LIMIT 1", array('user' => $sNickName));
+		return $iProfileId ? $this -> getProfileId($iProfileId) : 0;
+	}
+	
+	protected function transferCategory($sTitle, $sPrefix = 'bx_forum', $sCategory = 'bx_forum_cats')
+	{
+		$iId = parent::transferCategory($sTitle, $sPrefix, $sCategory);
+		$sQuery = $this -> _oDb -> prepare("INSERT IGNORE INTO `bx_forum_categories` SET `category`=? ", $iId);
+		return $this -> _oDb-> query($sQuery) ? $iId : false;
+	}	
+
+	/**
+	 *  Transfer forum's subscribers
+	 *  
+	 *  @param int $iTopicId topic id in UNA
+	 *  @param int $iEntryId forum id in Dolphin
+	 *  @return void
+	 */
+	private function transferSubscribers($iTopicId, $iEntryId)
+	{
+		$aSubscribers = $this -> _mDb -> getAll("SELECT
+											*
+											FROM `bx_forum_flag`
+											WHERE `topic_id` = :id", array('id' => $iEntryId));
+		
+		foreach($aSubscribers as $iKey => $aValue)
+		{
+			$iProfileId = $this -> getProfileIdByNickName((int)$aValue['user']);			
+			if (!$iProfileId)
+				continue;
+			
+			$sQuery = $this -> _oDb -> prepare( 
+						"
+							REPLACE INTO
+								`bx_forum_subscribers`
+							SET
+								`initiator` = ?,
+								`content`	= ?,
+								`added`		= ?
+						", 
+						$iProfileId,
+						$iTopicId,
+						$aValue['when']
+						);
+			
+			$this -> _oDb -> query($sQuery);
+		}
+	}
+	/**
+	 *  Builds path to Forum image files in Dolphin 
+	 *  
+	 *  @param string $s hash
+	 *  @return string path
+	 */
+	private function orca_build_path ($s)
+	{
+		return substr($s, 0, 1) . DIRECTORY_SEPARATOR . substr($s, 0, 2) . DIRECTORY_SEPARATOR . substr($s, 0, 3) . '/';
+	}
+	/**
+	 *  Transfer attached images to the forum
+	 *  
+	 *  @param int $iPostId Dolphin's post ID
+	 *  @param int $iCommentId una post ID
+	 *  @param int $iProfileId profile ID
+	 *  @return int first image ID
+	 */
+	private function transferAttachments($iPostId, $iCommentId, $iProfileId)
+    {
+        $iFirstImage = 0;
+		$iProfileId = (int)$iProfileId;
+		$aAttachments = $this -> _mDb -> getAll("SELECT * FROM `bx_forum_attachments`
+											WHERE `post_id` = :id", array('id' => $iPostId));
+		
+		if (empty($aAttachments))
+			return false;
+		
+		$this -> _sImageForumFiles = $this -> _oDb -> getExtraParam('root') . 'modules' . DIRECTORY_SEPARATOR . 'boonex' . DIRECTORY_SEPARATOR . "forum" . DIRECTORY_SEPARATOR . "data" . DIRECTORY_SEPARATOR . "attachments" . DIRECTORY_SEPARATOR;		
+		foreach($aAttachments as $iKey => $aFile)
+		{
+			$sImageFile = $this -> _sImageForumFiles . $this ->  orca_build_path($aFile['att_hash']). $aFile['att_hash'];
+			if (file_exists($sImageFile) && copy($sImageFile, BX_DIRECTORY_PATH_TMP . $aFile['att_name']))
+			{
+	        	$oStorage = BxDolStorage::getObjectInstance('bx_forum_files_cmts');
+				$iId = $oStorage->storeFileFromPath(BX_DIRECTORY_PATH_TMP . $aFile['att_name'], true, $iProfileId);
+				$oStorage -> afterUploadCleanup($iId, $iProfileId);
+				$sQuery = $this -> _oDb -> prepare("INSERT IGNORE INTO `sys_cmts_images2entries` SET `system_id`=?, `cmt_id`=?, `image_id`=?", $this -> _iSystem, $iCommentId, $iId);
+				$this -> _oDb-> query($sQuery);
+			}
+		}
+		
+		return $iFirstImage;
+    }
+	/**
+	 *  Returns Forums topics params
+	 *  
+	 *  @param int $iObjectId forum ID
+	 *  @return array
+	 */
+	private function getTopicStat($iObjectId)
+	{
+		return $this -> _oDb -> getRow("SELECT
+											MAX(`cmt_id`) as `lrc_id`, 
+											MAX(`cmt_time`) as `lr_timestamp`,
+											MIN(`cmt_time`) as `first_time`,
+											GROUP_CONCAT(`cmt_text` SEPARATOR '\n') as `text`
+											FROM `bx_forum_cmts`
+											WHERE `cmt_object_id` = :id", array('id' => $iObjectId));
+	}
+	
+	public function removeContent()
+	{
+		if (!$this -> _oDb -> isTableExists($this -> _sTableWithTransKey) || !$this -> _oDb -> isFieldExists($this -> _sTableWithTransKey, $this -> _sTransferFieldIdent))
+			return false;
+		
+		$aRecords = $this -> _oDb -> getAll("SELECT * FROM `{$this -> _sTableWithTransKey}` WHERE `{$this -> _sTransferFieldIdent}` !=0");
+		$iNumber = 0;
+		if (!empty($aRecords))
+		{			
+			foreach($aRecords as $iKey => $aValue)
+			{
+				BxDolService::call('bx_forum', 'delete_entity', array($aValue['id']));
+				$iNumber++;
+			}
+		}
+		parent::removeContent();
+		return $iNumber;
+	}
+}
+
+/** @} */

+ 214 - 0
modules/boonex/dolphin_migration/classes/BxDolMGroups.php

@@ -0,0 +1,214 @@
+<?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('BxDolStorage');
+	
+class BxDolMGroups extends BxDolMData
+{	
+	public function __construct(&$oMigrationModule, &$oDb)
+	{
+        parent::__construct($oMigrationModule, $oDb);
+		$this -> _sModuleName = 'groups';
+		$this -> _sTableWithTransKey = 'bx_groups_data';
+    }    
+	
+	public function getTotalRecords()
+	{
+		return (int)$this -> _mDb -> getOne("SELECT COUNT(*) FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] . "` WHERE `status` = 'approved'");			
+	}
+	
+	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_groups'));		
+			
+		$this -> createMIdField();
+		$iGroupId = $this -> getLastMIDField();						
+		$sStart = '';
+		if ($iGroupId)
+			$sStart = " AND `id` >= {$iGroupId}";
+		
+		$aResult = $this -> _mDb -> getAll("SELECT * FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] . "` WHERE `status` = 'approved' {$sStart} ORDER BY `id`");
+		
+		$iCmts = 0;
+		foreach($aResult as $iKey => $aValue)
+		{ 
+			$iProfileId = $this -> getProfileId((int)$aValue['author_id']);
+			$iGroupId = $this -> isItemExisted($aValue['id']);			
+			if (!$iProfileId)
+				continue;
+			
+			if (!$iGroupId)
+			{
+				$sQuery = $this -> _oDb -> prepare( 
+                     "
+                     	INSERT INTO
+                     		`bx_groups_data`
+                     	SET
+                     		`author`   			= ?,
+                     		`added`      		= ?,
+                     		`changed`   		= ?,
+							`group_name`		= ?,
+                     		`group_desc`		= ?,							
+							`group_cat`			= ?,
+							`views`				= ?,
+							`featured`			= ?,
+							`allow_view_to`		= ?,
+							`join_confirmation`	= ?
+                     ", 
+						$iProfileId, 
+						isset($aValue['created']) ? $aValue['created'] : time(), 
+						isset($aValue['created']) ? $aValue['created'] : time(), 						
+						isset($aValue['title']) ? $aValue['title'] : '',
+						isset($aValue['desc']) ? $aValue['desc'] : '',
+						$this -> transferCategory($aValue['categories']),
+						isset($aValue['views']) ? (int)$aValue['views'] : 0,
+						isset($aValue['featured']) ? (int)$aValue['featured'] : 0,
+						isset($aValue['allow_view_group_to']) ? (int)$aValue['allow_view_group_to'] : 0,
+						isset($aValue['join_confirmation']) ? (int)$aValue['join_confirmation'] : 0
+						);			
+		
+				$this -> _oDb -> query($sQuery);
+				
+				$iGroupId = $this -> _oDb -> lastId();			
+				if (!$iGroupId)
+				{
+					$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_groups_error', (int)$aValue['id']));
+					return BX_MIG_FAILED;
+				}				
+				
+				$this -> setMID($iGroupId, $aValue['id']);	
+			
+				$this -> exportFans($aValue['id'], $this-> addGroupToProfiles($iProfileId, $iGroupId));				
+			}					
+			
+			$iCmts = $this -> transferComments($iGroupId, (int)$aValue['id'], 'groups');
+			
+			$iPic = $this -> exportPictures($aValue['id'], $iProfileId);			
+			
+			$this -> _iTransferred++;
+					
+			$this -> _oDb ->  query("UPDATE `{$this -> _sTableWithTransKey}` 
+										SET 
+											`picture` = :pic,
+											`comments` = :cmts 
+									WHERE `id` = :id", array('pic' => $iPic, 'id' => $iGroupId, 'cmts' => $iCmts));
+			
+			$this -> trasnferTags((int)$aValue['id'], $iGroupId, $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['type'], $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['keywords']);
+        }      	
+
+        // set as finished;
+        $this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_groups_finished', $this -> _iTransferred, $iCmts));
+        return BX_MIG_SUCCESSFUL;
+    }
+	
+	protected function transferCategory($sCategory, $sPrefix = 'bx_groups', $sPreValueCateg = 'bx_groups_cats')
+	{
+		return parent::transferCategory($sCategory, $sPrefix, $sPreValueCateg);
+	}
+	/**
+	 *  Transfer groups pictures 
+	 *  
+	 *  @param int $iGroupId Dolphin group ID
+	 *  @param int $iProfileId UNA profile ID
+	 *  @return Return description
+	 */
+	private function exportPictures($iGroupId, $iProfileId)
+    {
+        $iFirstImage = 0;
+		$iProfileId = (int)$iProfileId;
+		$aPhotos = $this -> _mDb -> getAll("SELECT `p`.* FROM `bx_photos_main` as `p`
+											LEFT JOIN `bx_groups_images` as `g` ON `p`.`ID` = `g`.`media_id`
+											WHERE `g`.`entry_id` = :id", array('id' => $iGroupId));
+		
+		if (empty($aPhotos))
+			return false;
+		
+		foreach($aPhotos as $iKey => $aFile)
+		{
+			$sImageFile = $this -> _sImagePhotoFiles . "{$aFile['ID']}.{$aFile['Ext']}";
+			if (file_exists($sImageFile))
+			{
+	        	$oStorage = BxDolStorage::getObjectInstance('bx_groups_pics'); 				
+				$iId = $oStorage->storeFileFromPath($sImageFile, false, $iProfileId);
+				$oStorage -> afterUploadCleanup($iId, $iProfileId);
+				$iFirstImage = $iFirstImage ? $iFirstImage : $iId;
+			}
+		}
+		
+		return $iFirstImage;
+    }
+	
+	private function addGroupToProfiles($iProfileId, $iGroupId)
+	{
+		$sQuery = $this -> _oDb -> prepare("
+						INSERT INTO
+							`sys_profiles`
+						SET
+						   `account_id`	= ?,
+						   `type`    	= 'bx_groups',
+						   `content_id` = ?,
+						   `status`    	= 'active'
+				   ", (int)BxDolProfile::getInstance($iProfileId)->getAccountId(), $iGroupId);
+
+		$this -> _oDb -> query($sQuery);
+		return $this -> _oDb -> lastId();
+	}
+	
+	private function exportFans($iMID, $iGroupProfileId)
+    {
+		$aFans =  $this -> _mDb -> getAll("SELECT * FROM `bx_groups_fans` WHERE `id_entry`=:id ", array('id' => $iMID));
+		foreach($aFans as $iKey => $aValue)
+		{
+			$iProfileId = $this -> getProfileId($aValue['id_profile']);
+			$sQuery =  $this -> _oDb -> prepare("
+						INSERT IGNORE INTO
+							`bx_groups_fans`
+						SET
+						   `initiator`	= ?,
+						   `content`    = ?,
+						   `mutual`     = ?,
+						   `added`     	= ?
+			", $iProfileId,  $iGroupProfileId, $aValue['confirmed'], $aValue['when']);
+				
+			if(!$this -> _oDb -> query($sQuery))
+			   return _t('_bx_dolphin_migration_friends_exports_error');
+		}
+	}
+	
+	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)
+			{
+				BxDolService::call('bx_groups', 'delete_entity_service', array($aValue['id'], true));
+				$iNumber++;
+			}
+		}
+		
+		parent::removeContent();
+		return $iNumber;
+	}
+}
+
+/** @} */

+ 217 - 0
modules/boonex/dolphin_migration/classes/BxDolMMarket.php

@@ -0,0 +1,217 @@
+<?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('BxDolStorage');
+	
+class BxDolMMarket extends BxDolMData
+{
+	private $_sFilesPath = '';
+	public function __construct(&$oMigrationModule, &$oDb)
+	{
+        parent::__construct($oMigrationModule, $oDb);
+		$this -> _sModuleName = 'store';
+		$this -> _sTableWithTransKey = 'bx_market_products';
+		$this -> _sFilesPath = $this -> _oDb -> getExtraParam('root') . 'modules' . DIRECTORY_SEPARATOR . 'boonex' . DIRECTORY_SEPARATOR . 'files' . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'files' .  DIRECTORY_SEPARATOR ;
+    }    
+	
+	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_market'));		
+			
+		$this -> createMIdField();
+		$iProductId = $this -> getLastMIDField();						
+		$sStart = '';
+		if ($iProductId)
+			$sStart = " AND `id` >= {$iProductId}";
+		
+		$aResult = $this -> _mDb -> getAll("SELECT * FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] . "` {$sStart} ORDER BY `id`");
+			
+		$iCmts = 0;
+		foreach($aResult as $iKey => $aValue)
+		{ 
+			$iProfileId = $this -> getProfileId((int)$aValue['author_id']);
+			$iProductId = $this -> isItemExisted($aValue['id']);			
+			if (!$iProfileId)
+				continue;
+			
+			$iCreated = isset($aValue['created']) ? $aValue['created'] : time();
+			$sTitle = isset($aValue['title']) ? $aValue['title'] : '';
+			if (!$iProductId)
+			{
+				$sQuery = $this -> _oDb -> prepare( 
+						 "
+							INSERT INTO
+								`{$this -> _sTableWithTransKey}`
+							SET
+								`author`   			= ?,
+								`added`      		= ?,
+								`changed`   		= ?,
+								`name`				= ?,
+								`title`				= ?,
+								`text`				= ?,	
+								`cat`				= ?,
+								`views`				= ?,
+								`featured`			= ?,
+								`allow_view_to`		= ?
+						 ", 
+						$iProfileId, 
+						$iCreated,
+						$iCreated,
+						$sTitle,
+						$sTitle,
+						isset($aValue['desc']) ? $aValue['desc'] : '',						
+						$this -> transferCategory($aValue['categories']),
+						isset($aValue['views']) ? (int)$aValue['views'] : 0,
+						isset($aValue['featured']) ? (int)$aValue['featured'] : 0,
+						isset($aValue['allow_view_product_to']) ? (int)$aValue['allow_view_product_to'] : 0
+					);			
+		
+				$this -> _oDb -> query($sQuery);				
+				$iProductId = $this -> _oDb -> lastId();			
+				if (!$iProductId)
+				{
+					$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_market_error', (int)$aValue['id']));
+					return BX_MIG_FAILED;
+				}				
+				
+				$this -> setMID($iProductId, $aValue['id']);			
+				$aInfo = $this -> exportFiles($aValue['id'], $iProductId);
+				$iCmts = $this -> transferComments($iProductId, (int)$aValue['id'], 'market');
+				$this -> _iTransferred++;
+			}					
+			
+			
+			$iPic = $this -> exportPictures($aValue['id'], $iProductId, (int)$aValue['thumb']);
+			$this -> _oDb ->  query("UPDATE `{$this -> _sTableWithTransKey}` 
+										SET 
+											`thumb` = :thumb,
+											`cover`	= :thumb,
+											`comments` = :cmts,
+											`price_single`	= :price,
+											`package`		= :file_id
+									WHERE `id` = :id", array('thumb' => $iPic, 'id' => $iProductId, 'cmts' => $iCmts, 'price' => $aInfo['price'], 'file_id' => $aInfo['file_id']));
+			
+			$this -> trasnferTags($aValue['id'], $iProductId, $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['type'], $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['keywords']);
+		}      	
+
+        // set as finished;
+        $this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_market_finished', $this -> _iTransferred, $iCmts));
+        return BX_MIG_SUCCESSFUL;
+    }
+	
+	private function exportFiles($iStoreId, $iProductId)
+	{
+		$aFiles = $this -> _mDb -> getAll("SELECT * 
+											FROM `bx_store_product_files` as `f1`
+											LEFT JOIN `bx_files_main` as `f2` ON `f1`.`media_id` = `f2`.`ID`
+											WHERE `entry_id` = :id", array('id' => $iStoreId));
+		
+		$aResult = array('price' => 0, 'file_id' => 0);
+		$oZip = new ZipArchive();
+		$i = 0;
+		foreach($aFiles as $iKey => $aFile)
+		{
+			$sFilesPath = $this -> _sFilesPath . "{$aFile['media_id']}_" . sha1($aFile['Date']);
+			$sName = $aFile['Title'];
+			$sExt = $aFile['Ext'];		
+			
+			if (file_exists($sFilesPath) && copy($sFilesPath, BX_DIRECTORY_PATH_TMP . "{$sName}.{$sExt}"))
+			{
+				if ($oZip -> open(BX_DIRECTORY_PATH_TMP . "{$sName}.zip", ZipArchive::CREATE) !== TRUE)
+					continue;
+				
+				$oZip -> addFile(BX_DIRECTORY_PATH_TMP . "{$sName}.{$sExt}", "{$sName}.{$sExt}");
+				$oZip -> close();
+				
+				$iProfileId = $this -> getProfileId((int)$aFile['Owner']);
+				$oStorage = BxDolStorage::getObjectInstance('bx_market_files');
+				$iId = $oStorage->storeFileFromPath(BX_DIRECTORY_PATH_TMP . "{$sName}.zip", true, $iProfileId, $iProductId);				
+				$sQuery = $this -> _oDb -> prepare("INSERT IGNORE INTO `bx_market_files2products` SET `content_id`=?, `file_id`=?, `version`='1.0', `order`=? ", $iProductId, $iId, $i++);
+				$this -> _oDb-> query($sQuery);	
+				
+				if (floatval($aFile['price']))
+				{
+					$aResult = array(
+						'price' => floatval($aFile['price']),
+						'file_id' => $iId
+					);				
+				}
+			}			
+		}
+		
+		return $aResult;
+    }
+	
+	protected function transferCategory($sCategory, $sPrefix = 'bx_market', $sPreValueCateg = 'bx_market_cats')
+	{
+		return parent::transferCategory($sCategory, $sPrefix, $sPreValueCateg);
+	}
+	
+	private function exportPictures($iStoreId, $iProductId, $iThumb)
+    {
+        $iImage = 0;
+		$aPhotos = $this -> _mDb -> getAll("SELECT `p`.* FROM `bx_store_product_images` as `g` 
+											LEFT JOIN `bx_photos_main` as `p` ON `p`.`ID` = `g`.`media_id`
+											WHERE `g`.`entry_id` = :id", array('id' => $iStoreId));
+		
+		$i = 0;
+		foreach($aPhotos as $iKey => $aFile)
+		{
+			$sImageFile = $this -> _sImagePhotoFiles . "{$aFile['ID']}.{$aFile['Ext']}";
+			$iProfileId = $this -> getProfileId((int)$aFile['Owner']);
+			if (file_exists($sImageFile))
+			{
+	        	$oStorage = BxDolStorage::getObjectInstance('bx_market_photos'); 				
+				$iId = $oStorage->storeFileFromPath($sImageFile, false, $iProfileId);
+				$oStorage -> afterUploadCleanup($iId, $iProfileId);
+				$sQuery = $this -> _oDb -> prepare("INSERT IGNORE INTO `bx_market_photos2products` SET `content_id`=?, `file_id`=?, `title` = ?, `order`=?", $iProductId, $iId, $aFile['Title'], $i++);
+				$this -> _oDb-> query($sQuery);	
+				if ($iThumb == $aFile['ID'])
+					$iImage = $iId;
+			}
+		}
+		
+		return $iImage;
+    }
+	
+	public function removeContent()
+	{
+		if (!$this -> _oDb -> isTableExists($this -> _sTableWithTransKey) || !$this -> _oDb -> isFieldExists($this -> _sTableWithTransKey, $this -> _sTransferFieldIdent))
+			return false;
+		
+		$aRecords = $this -> _oDb -> getAll("SELECT * FROM `{$this -> _sTableWithTransKey}` WHERE `{$this -> _sTransferFieldIdent}` !=0");
+		$iNumber = 0;
+		if (!empty($aRecords))
+		{		
+			foreach($aRecords as $iKey => $aValue)
+			{
+				BxDolService::call('bx_market', 'delete_entity', array($aValue['id']));
+				$iNumber++;
+			}
+		}
+		parent::removeContent();
+		return $iNumber;
+	}
+}
+
+/** @} */

+ 144 - 0
modules/boonex/dolphin_migration/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 -> _oMDb = new BxMDb($aConfig);		
+		return $this -> _oMDb	-> connect(); 
+	}	
+}
+
+/** @} */

+ 177 - 0
modules/boonex/dolphin_migration/classes/BxDolMPhotoAlbums.php

@@ -0,0 +1,177 @@
+<?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('BxDolStorage');
+	
+class BxDolMPhotoAlbums extends BxDolMData
+{
+	/**
+	*  @var $_iTransferredAlbums transferred alums number 
+	*/
+	private $_iTransferredAlbums;
+    
+	public function __construct(&$oMigrationModule, &$oDb)
+	{
+        parent::__construct($oMigrationModule, $oDb);
+		$this -> _sModuleName = 'photos';
+		$this -> _sTableWithTransKey = 'bx_albums_albums';
+    }
+	
+	public function getTotalRecords()
+	{
+		$aResult = $this -> _mDb -> getRow("SELECT COUNT(*) as `count`, SUM(`ObjCount`) as `obj` FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name_albums'] ."` WHERE `Type` = 'bx_photos' AND `Uri` <> 'Hidden'");
+		return !(int)$aResult['count'] && !(int)$aResult['obj'] ? 0 : $aResult;
+	}
+    
+	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_photos'));
+		
+		$this -> createMIdField();
+		$aResult = $this -> _mDb -> getAll("SELECT * FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name_albums'] ."` WHERE `Type` = 'bx_photos' AND `Uri` <> 'Hidden' ORDER BY `ID` ASC");
+		foreach($aResult as $iKey => $aValue)
+		{ 			
+			$iProfileId = $this -> getProfileId((int)$aValue['Owner']);
+			if (!$iProfileId) 
+				continue;
+			
+			$iAlbumId = $this -> isItemExisted($aValue['ID']);			
+			if (!$iAlbumId)
+			{
+				$sAlbumTitle = isset($aValue['Caption']) && $aValue['Caption'] ? $aValue['Caption'] : 'Profile Photos';			
+				$sQuery = $this -> _oDb -> prepare( 
+							 "
+								INSERT INTO
+									`bx_albums_albums`
+								SET
+									`author`   			= ?,
+									`added`      		= ?,
+									`changed`   		= ?,
+									`thumb`				= 0,
+									`title`				= ?,
+									`allow_view_to` 	= ?,
+									`text`				= ?,
+									`status_admin`		= ?	
+							 ", 
+								$iProfileId, 
+								$aValue['Date'] ? $aValue['Date'] : time(), 
+								$aValue['Date'] ? $aValue['Date'] : time(), 
+								$sAlbumTitle,
+								$aValue['AllowAlbumView'],
+								$aValue['Description'],
+								$aValue['Status'] == 'active' ? 'active' : 'hidden'
+								);			
+				
+					$this -> _oDb -> query($sQuery);
+					$iAlbumId = $this -> _oDb -> lastId();					
+						
+					if (!$iAlbumId)
+					{
+						$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_photos_album_error'));
+						return BX_MIG_FAILED;
+					}
+					
+				$this -> setMID($iAlbumId, $aValue['ID']);				
+			}
+			
+			$iAlbumsCmts = $this -> transferComments($iAlbumId, $aValue['ID'], 'photo_albums');
+			if ($iAlbumsCmts)
+				$this -> _oDb -> query("UPDATE `bx_albums_albums` SET `comments` = :comments WHERE `id` = :id", array('id' => $iAlbumId, 'comments' => $iAlbumsCmts));
+			
+			$this -> migrateAlbumPhotos($aValue['ID'], $iProfileId, $iAlbumId);	
+			$this -> _iTransferredAlbums++;
+       }        
+
+        // set as finished;
+        $this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_photos_finished', $this -> _iTransferredAlbums, $this -> _iTransferred));
+        return BX_MIG_SUCCESSFUL;
+    }
+   	
+   /**
+	* Migrates all photo albums and users photos
+	* @param int $iAlbumId original albums id
+	* @param int $iProfileId una profile ID
+	* @param int $iNewAlbumID created una Album		
+	* @return Integer
+         */  
+   private function migrateAlbumPhotos($iAlbumId, $iProfileId, $iNewAlbumID){
+			$aResult = $this -> _mDb -> getAll("SELECT * 
+													FROM  `sys_albums_objects` 
+													LEFT JOIN `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] ."` ON `id_object` = `ID`
+													WHERE  `id_album` = :album ORDER BY `id_object` ASC", array('album' => $iAlbumId));
+
+			$iTransferred  = 0;
+			foreach($aResult as $iKey => $aValue)
+			{ 
+				if ($this -> isFileExisted($iProfileId, $aValue['Title'], $aValue['Date'])) 
+					continue;
+				
+				$sImagePath = $this -> _sImagePhotoFiles . "{$aValue['ID']}.{$aValue['Ext']}";				
+				if (file_exists($sImagePath))
+				{
+					$oStorage = BxDolStorage::getObjectInstance('bx_albums_files'); 
+					$iId = $oStorage -> storeFileFromPath($sImagePath, false, $iProfileId);					
+					if ($iId)
+					{ 
+						$oStorage -> afterUploadCleanup($iId, $iProfileId);
+						
+						$sQuery = $this -> _oDb -> prepare("INSERT INTO `bx_albums_files2albums` SET `content_id` = ?, `file_id` = ?, `data` = ?, `title` = ?", $iNewAlbumID, $iId, $aValue['Size'], $aValue['Title']);
+						$this -> _oDb -> query($sQuery);
+						
+						$iCmts = $this -> transferComments($iItemId = $this -> _oDb -> lastId(), $aValue['ID']);
+						if ($iCmts)
+							$this -> _oDb -> query("UPDATE `bx_albums_files2albums` SET `comments` = :comments WHERE `id` = :id", array('id' => $iItemId, 'comments' => $iCmts));
+						
+						$this -> _iTransferred++;
+						$iTransferred++;
+						
+						$this -> trasnferTags((int)$aValue['ID'], $iId, $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['type'], $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['keywords']);
+					}
+				}
+			}	
+				  
+	  return $iTransferred;
+   }
+       	
+	private function isFileExisted($iAuthor, $sTitle, $iDate){    	
+    	$sQuery  = $this -> _oDb ->  prepare("SELECT COUNT(*) FROM `bx_albums_files` WHERE `profile_id` = ? AND `file_name` = ? AND `added` = ? LIMIT 1", $iAuthor, $sTitle, $iDate);
+        return (bool)$this -> _oDb -> getOne($sQuery);
+    }
+	
+	public function removeContent()
+	{
+		if (!$this -> _oDb -> isTableExists($this -> _sTableWithTransKey) || !$this -> _oDb -> isFieldExists($this -> _sTableWithTransKey, $this -> _sTransferFieldIdent))
+			return false;
+		
+		$aRecords = $this -> _oDb -> getAll("SELECT * FROM `{$this -> _sTableWithTransKey}` WHERE `{$this -> _sTransferFieldIdent}` !=0");
+		$iNumber = 0;		
+		if (!empty($aRecords))
+		{		
+			foreach($aRecords as $iKey => $aValue)
+			{
+				BxDolService::call('bx_albums', 'delete_entity', array($aValue['id']));
+				$iNumber++;
+			}
+		}
+		
+		parent::removeContent();
+		return $iNumber;
+	}
+}
+
+/** @} */

+ 181 - 0
modules/boonex/dolphin_migration/classes/BxDolMPolls.php

@@ -0,0 +1,181 @@
+<?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('BxDolStorage');
+	
+class BxDolMPolls extends BxDolMData
+{	
+	public function __construct(&$oMigrationModule, &$oDb)
+	{
+        parent::__construct($oMigrationModule, $oDb);
+		$this -> _sModuleName = 'polls';
+		$this -> _sTableWithTransKey = 'bx_polls_entries';
+    }    
+	
+	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_polls'));
+		
+			
+		$this -> createMIdField();
+		$iPollId = $this -> getLastMIDField();						
+		$sStart = '';
+		if ($iPollId)
+			$sStart = " WHERE `id_poll` >= {$iPollId}";
+		
+		$aResult = $this -> _mDb -> getAll("SELECT * FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] . "` {$sStart} ORDER BY `id_poll`");
+		$iCmts = 0;
+		foreach($aResult as $iKey => $aValue)
+		{ 
+			$iProfileId = $this -> getProfileId((int)$aValue['id_profile']);						
+			if (!$iProfileId)
+				continue;
+			
+			$iPollId = $this -> isItemExisted($aValue['id_poll']);
+			if (!$iPollId)
+			{
+				$sQuery = $this -> _oDb -> prepare( 
+                     "
+                     	INSERT INTO
+                     		`{$this -> _sTableWithTransKey}`
+                     	SET
+                     		`author`   			= ?,
+                     		`added`      		= ?,
+                     		`changed`   		= ?,
+                     		`text`				= ?,							
+							`cat`				= ?,
+							`featured`			= ?,
+							`allow_view_to`		= ?,
+							`status_admin`		= ?
+                     ", 
+						$iProfileId, 
+						isset($aValue['poll_date']) ? $aValue['poll_date'] : time(),
+						isset($aValue['poll_date']) ? $aValue['poll_date'] : time(),						
+						isset($aValue['poll_question']) ? $aValue['poll_question'] : '',
+						$this -> transferCategory($aValue['poll_categories']),
+						isset($aValue['poll_featured']) ? (int)$aValue['poll_featured'] : 0,
+						isset($aValue['allow_view_to']) ? (int)$aValue['allow_view_to'] : 3,
+						$aValue['poll_status'] = 'active' && $aValue['poll_approval'] ? 'active' : 'hidden'
+						);			
+		
+				$this -> _oDb -> query($sQuery);
+				
+				$iPollId = $this -> _oDb -> lastId();
+				if (!$iPollId)
+				{
+					$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_polls_error', (int)$aValue['id_poll']));
+					return BX_MIG_FAILED;
+				}				
+				
+				$this -> setMID($iPollId, $aValue['id_poll']);	
+			
+				$this -> exportAnswers($aValue['poll_results'], $aValue['poll_answers'], $iPollId);				
+			}
+			
+			$iCmts = $this -> transferComments($iPollId, (int)$aValue['id_poll'], 'polls');
+			
+			$this -> _oDb ->  query("UPDATE `{$this -> _sTableWithTransKey}` 
+										SET 
+											`comments` = :cmts 
+										WHERE `id` = :id", array('id' => $iPollId, 'cmts' => $iCmts));
+			
+			$this -> _iTransferred++;
+			
+			$this -> trasnferTags($aValue['id_poll'], $iPollId, $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['type'], $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['keywords']);
+        }      	
+        
+		//$this -> dropMID();
+
+        // set as finished;
+        $this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_polls_finished', $this -> _iTransferred));
+        return BX_MIG_SUCCESSFUL;
+    }
+	
+	protected function transferCategory($sCategory, $sPrefix = 'bx_polls', $sPreValueCateg = 'bx_polls_cats')
+	{
+		return parent::transferCategory($sCategory, $sPrefix, $sPreValueCateg);
+	}
+	
+	private function exportAnswers($sResults, $sQuestions, $iPollId)
+    {
+		$aResults = preg_split('/[;]/', $sResults, -1, PREG_SPLIT_NO_EMPTY);
+		$aQuestions = preg_split('/<delim>/', $sQuestions, -1, PREG_SPLIT_NO_EMPTY);
+		if (empty($aQuestions))
+			return false;
+
+		$aObjects = array();
+		foreach($aQuestions as $iKey => $sQ)
+		{
+			$sQuery =  $this -> _oDb -> prepare("
+						INSERT INTO
+							`bx_polls_subentries`
+						SET
+						   `entry_id`	= ?,
+						   `title`  	= ?,
+						   `rate`	    = ?,
+						   `votes`	    = ?,
+						   `order`	    = ?
+						", $iPollId, $sQ, (int)($aResults[$iKey] != 0), $aResults[$iKey], $iKey);
+			
+			$this -> _oDb -> query($sQuery);
+			$aObjects[$this -> _oDb -> lastId()] = $aResults[$iKey];
+		}
+		
+		foreach($aObjects as $iKey => $iValue)
+		{
+			$sQuery =  $this -> _oDb -> prepare("
+						INSERT INTO
+							`bx_polls_votes_subentries`
+						SET
+						   `object_id`	= ?,
+						   `count`  	= ?,
+						   `sum`	    = ?
+			", $iKey, $iValue, $iValue);
+				
+			$this -> _oDb -> query($sQuery);
+		}
+		
+		return true;
+	}
+	
+	public function removeContent()
+	{
+		if (!$this -> _oDb -> isTableExists($this -> _sTableWithTransKey) || !$this -> _oDb -> isFieldExists($this -> _sTableWithTransKey, $this -> _sTransferFieldIdent))
+			return false;
+		
+		$aRecords = $this -> _oDb -> getAll("SELECT * FROM `{$this -> _sTableWithTransKey}` WHERE `{$this -> _sTransferFieldIdent}` !=0");
+		$iNumber = 0;
+		if (!empty($aRecords))
+		{			
+			foreach($aRecords as $iKey => $aValue)
+			{
+				BxDolService::call('bx_polls', 'delete_entity', array($aValue['id']));
+				$iNumber++;
+			}
+		}
+		parent::removeContent();		
+		return $iNumber;
+	}
+}
+
+/** @} */

+ 351 - 0
modules/boonex/dolphin_migration/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 LIMIT 2");			
+
+			$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/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;
+	}
+}
+
+/** @} */

+ 98 - 0
modules/boonex/dolphin_migration/classes/BxDolMQuotes.php

@@ -0,0 +1,98 @@
+<?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('BxDolStorage');
+	
+class BxDolMQuotes extends BxDolMData
+{	
+	public function __construct(&$oMigrationModule, &$oDb)
+	{
+        parent::__construct($oMigrationModule, $oDb);
+		$this -> _sModuleName = 'quotes';
+		$this -> _sTableWithTransKey = 'bx_quoteofday_internal';
+    }    
+	
+	public function getTotalRecords()
+	{
+		return $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_quotes'));		
+			
+		$this -> createMIdField();
+		$aQuotes = $this -> _mDb -> getAll("SELECT * FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] . "` ORDER BY `ID`");
+		$aParticipantsList = array();
+		foreach($aQuotes as $iMes => $aQuote)
+		{
+			$iQuoteId = $this -> isItemExisted($aQuote['ID']);
+			if (!$iQuoteId)
+			{
+				$sQuery = $this -> _oDb -> prepare( 
+						"
+							INSERT INTO
+								`{$this -> _sTableWithTransKey}`
+							SET
+								`text`	= ?,
+								`added`	= UNIX_TIMESTAMP()
+						",
+						$aQuote['Text']
+					);
+			
+					$this -> _oDb -> query($sQuery);
+					
+					$iQuoteId = $this -> _oDb -> lastId();
+					if (!$iQuoteId)
+					{
+						$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_quotes_error', (int)$aQuote['ID']));
+						return BX_MIG_FAILED;					
+					}
+					
+					$this -> setMID($iQuoteId, $aQuote['ID']);
+				
+				$this -> _iTransferred++;
+			}		
+		}
+
+        // set as finished;
+		$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_quotes_finished', $this -> _iTransferred));
+        return BX_MIG_SUCCESSFUL;
+    }
+	
+	public function removeContent()
+	{
+		if (!$this -> _oDb -> isTableExists($this -> _sTableWithTransKey) || !$this -> _oDb -> isFieldExists($this -> _sTableWithTransKey, $this -> _sTransferFieldIdent))
+			return false;
+		
+		$aRecords = $this -> _oDb -> getAll("SELECT * FROM `{$this -> _sTableWithTransKey}` WHERE `{$this -> _sTransferFieldIdent}` !=0 ");	
+		$iNumber = 0;		
+		if (!empty($aRecords))
+		{
+			foreach($aRecords as $iKey => $aValue)
+			{
+				$this -> _oDb -> query("DELETE FROM `{$this -> _sTableWithTransKey}` WHERE `id`=:id", array('id' => $aValue['id']));
+				$iNumber++;
+			}
+		}	
+		parent::removeContent();
+		return $iNumber;
+	}
+}
+
+/** @} */

+ 126 - 0
modules/boonex/dolphin_migration/classes/BxDolMShoutBox.php

@@ -0,0 +1,126 @@
+<?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('BxDolStorage');
+	
+class BxDolMShoutBox extends BxDolMData
+{	
+	
+	/**
+	 *  @var shout box Lot id in Jot Messenger
+	 */
+	private $_iLotID = 2;
+	
+	public function __construct(&$oMigrationModule, &$oDb)
+	{
+        parent::__construct($oMigrationModule, $oDb);
+		$this -> _sModuleName = 'shoutbox';
+		$this -> _sTableWithTransKey = 'bx_messenger_jots';
+		$this -> _sTransferFieldIdent = 'shoutbx_id';
+    }    
+	
+	public function getTotalRecords()
+	{
+		return $this -> _mDb -> getOne("SELECT COUNT(*) FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] . "` WHERE `HandlerID` = 0 AND `OwnerID` != 0 ");
+	}
+		
+	public function runMigration() 
+	{        
+		if (!$this -> getTotalRecords())
+		{
+			  $this -> setResultStatus(_t('_bx_dolphin_migration_no_data_to_transfer'));
+	          return BX_SEMIG_SUCCESSFUL;
+		}	
+		
+		$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_shoutbox'));
+		
+		$this -> createMIdField();
+		
+		$aMessages = $this -> _mDb -> getAll("SELECT * FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] . "` WHERE `HandlerID` = 0 AND `OwnerID` != 0 ORDER BY `ID`");
+		$aParticipantsList = array();
+		foreach($aMessages as $iMes => $aMessage)
+		{
+			$iMessageId = $this -> isItemExisted($aMessage['ID']);
+			$iProfileId = $this -> getProfileId((int)$aMessage['OwnerID']);
+			if (!$iProfileId)
+				continue;
+			
+			if (!$iMessageId && $iProfileId)
+			{
+				$sQuery = $this -> _oDb -> prepare( 
+						"
+							INSERT INTO
+								`{$this -> _sTableWithTransKey}`
+							SET
+								`lot_id`   			= {$this -> _iLotID},
+								`message`			= ?,	
+								`user_id`			= ?,
+								`created`			= ?
+						",
+						$aMessage['Message'],
+						$iProfileId,
+						strtotime($aMessage['Date'])
+					);
+			
+					$this -> _oDb -> query($sQuery);
+					
+					$iMessageId = $this -> _oDb -> lastId();
+					if (!$iMessageId)
+					{
+						$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_shoutbox_error', (int)$aMessage['ID']));
+						return BX_MIG_FAILED;					
+					}					
+				
+				if (!in_array($iProfileId, $aParticipantsList))
+					array_push($aParticipantsList, $iProfileId);
+				
+				$this -> setMID($iMessageId, $aMessage['ID']);
+			}	
+		
+			$this -> _iTransferred++;
+		}
+		
+		if (!empty($aParticipantsList))
+			$this -> _oDb ->  query("UPDATE `bx_messenger_lots` 
+									SET 
+										`participants` = :parts										
+								WHERE `id` = :id", array('parts' => implode(',', $aParticipantsList), 'id' => $this -> _iLotID));
+        
+
+		// set as finished;
+		$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_shoutbox_finished', $this -> _iTransferred));
+        return BX_SEMIG_SUCCESSFUL;
+    }
+
+	public function removeContent()
+	{
+		if (!$this -> _oDb -> isTableExists($this -> _sTableWithTransKey) || !$this -> _oDb -> isFieldExists($this -> _sTableWithTransKey, $this -> _sTransferFieldIdent))
+			return false;
+		
+		$aRecords = $this -> _oDb -> getAll("SELECT * FROM `{$this -> _sTableWithTransKey}` WHERE `{$this -> _sTransferFieldIdent}` !=0 ");
+		$iNumber = 0;
+		if (!empty($aRecords))
+		{
+			foreach($aRecords as $iKey => $aValue)
+			{
+				$this -> _oDb -> query("DELETE FROM `{$this -> _sTableWithTransKey}` WHERE `id`=:id", array('id' => $aValue['id']));
+				$iNumber++;
+			}
+		}
+
+		parent::removeContent();		
+		return $iNumber;
+	}
+	
+}
+
+/** @} */

+ 123 - 0
modules/boonex/dolphin_migration/classes/BxDolMSimpleMessenger.php

@@ -0,0 +1,123 @@
+<?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('BxDolStorage');
+	
+class BxDolMSimpleMessenger extends BxDolMData
+{
+	public function __construct(&$oMigrationModule, &$oDb)
+	{
+        parent::__construct($oMigrationModule, $oDb);
+		$this -> _sModuleName = 'simple_messenger';
+		$this -> _sTableWithTransKey = 'bx_messenger_jots';
+    }    
+	
+	public function getTotalRecords()
+	{
+		return $this -> _mDb -> getOne("SELECT COUNT(*) FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] . "`");
+	}
+	
+	private function getLotId($iSenderId, $iRecipientId)
+	{
+		$iLot = $this -> _oDb -> getOne("SELECT `id` FROM `bx_messenger_lots` WHERE (`participants` = :l1 OR `participants` = :l2) AND `type`=2 AND `author` != 0 LIMIT 1", array('l1' => "{$iSenderId},{$iRecipientId}", 'l2' => "{$iRecipientId},{$iSenderId}"));
+		if ((int)$iLot)
+			return $iLot;
+		
+		$this -> _oDb -> query("INSERT INTO `bx_messenger_lots` SET `created` = UNIX_TIMESTAMP(), `author`= :author, `participants` = :parts, `type` = 2", array('parts' => "{$iSenderId},{$iRecipientId}", 'author' => $iSenderId));
+		return $this -> _oDb -> lastId();
+	}
+	
+	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_simple_messanger'));		
+			
+		$this -> createMIdField();
+		$aMessages = $this -> _mDb -> getAll("SELECT * FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] . "` ORDER BY `ID`");
+		foreach($aMessages as $iMes => $aMessage)
+		{
+			$iMessageId = $this -> isItemExisted($aMessage['ID']);
+			$iSenderId = $this -> getProfileId((int)$aMessage['SenderID']);
+			$iRecipientId = $this -> getProfileId((int)$aMessage['RecipientID']);
+			if (!$iMessageId && $iSenderId && $iRecipientId)
+			{
+				$sQuery = $this -> _oDb -> prepare( 
+						"
+							INSERT INTO
+								`{$this -> _sTableWithTransKey}`
+							SET
+								`lot_id`   			= ?,
+								`message`			= ?,	
+								`user_id`			= ?,
+								`created`			= ?
+						",
+						$this -> getLotId($iSenderId, $iRecipientId),
+						$aMessage['Message'],
+						$iSenderId,
+						strtotime($aMessage['Date'])
+					);
+			
+					$this -> _oDb -> query($sQuery);
+					
+					$iMessageId = $this -> _oDb -> lastId();
+					if (!$iMessageId)
+					{
+						$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_simple_messanger_error', (int)$aMessage['ID']));
+						return BX_MIG_FAILED;					
+					}
+					
+					$this -> setMID($iMessageId, $aMessage['ID']);
+			}
+			
+			$this -> _iTransferred++;
+		}
+
+        // set as finished;
+		$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_simple_messanger_finished', $this -> _iTransferred));
+        return BX_MIG_SUCCESSFUL;
+    }
+	
+	public function removeContent()
+	{
+		if (!$this -> _oDb -> isTableExists($this -> _sTableWithTransKey) || !$this -> _oDb -> isFieldExists($this -> _sTableWithTransKey, $this -> _sTransferFieldIdent))
+			return false;
+		
+		$aRecords = $this -> _oDb -> getAll("SELECT * FROM `{$this -> _sTableWithTransKey}` WHERE `{$this -> _sTransferFieldIdent}` !=0");
+		$aLots = $this -> _oDb -> getPairs("SELECT `lot_id` FROM `{$this -> _sTableWithTransKey}` WHERE `{$this -> _sTransferFieldIdent}` !=0 GROUP BY `lot_id`", 'lot_id', 'lot_id');
+		parent::removeContent();
+		
+		$iNumber = 0;
+		if (!empty($aRecords))
+		{
+			foreach($aRecords as $iKey => $aValue)
+			{
+				$this -> _oDb -> query("DELETE FROM `{$this -> _sTableWithTransKey}` WHERE `id`=:id", array('id' => $aValue['id']));			
+				$iNumber++;
+			}
+		}
+		
+		if (!empty($aLots))
+		{
+			$sIn = "WHERE `id` IN (" . implode(',', $aLots) . ")";
+			$this -> _oDb -> query("DELETE FROM `bx_messenger_lots` {$sIn}");
+		}
+		
+		return $iNumber;
+	}
+}
+
+/** @} */

+ 121 - 0
modules/boonex/dolphin_migration/classes/BxDolMStudioPage.php

@@ -0,0 +1,121 @@
+<?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('BxDolMTransfers.php');
+
+class BxDolMStudioPage extends BxTemplStudioModule
+{    
+	/**
+	 *  @var ref $_oModule main module reference
+	 */
+	protected $_oModule;
+	
+	function __construct($sModule = "", $sPage = "")
+    {
+		$this -> MODULE = 'bx_dolphin_migration';
+		parent::__construct($sModule, $sPage);
+	
+		$this -> _oModule = BxDolModule::getInstance($sModule);			
+		
+		$this->aMenuItems = array(
+            array('name' => 'settings', 'icon' => 'cogs', 'title' => '_bx_dolphin_migration_cpt_settings'),
+            array('name' => 'config', 'icon' => 'exchange', 'title' => '_bx_dolphin_migration_cpt_transfer_data'),
+        );	
+		
+		$this -> _oModule -> _oTemplate -> addStudioJs(array('transfer.js', 'BxDolGrid.js'));
+		$this -> _oModule -> _oTemplate -> addStudioCss(array('main.css'));	
+     } 
+	
+	public function saveData($sPath)
+	{
+		$aConfig = array();		
+		if (substr($sPath, strlen($sPath) - 1 ) != DIRECTORY_SEPARATOR)
+			$sPath .= DIRECTORY_SEPARATOR;
+
+	   // get settings from Dolphin's header file info;
+		$sConfigFile = "{$sPath}inc" . DIRECTORY_SEPARATOR . "header.inc.php";
+		if (file_exists($sConfigFile))
+		{
+			$sFile = @file_get_contents($sConfigFile);
+			preg_match_all('/\s*\$(db|dir)\[[\'"](.*)[\'"]\]\s*=\s*[\'"](.*)[\'"];/im', $sFile, $aData);
+			for($i=0; $i < sizeof($aData[1]); $i++)
+				if (($aData[1][$i] == 'dir' && $aData[2][$i] == 'root') || $aData[1][$i] == 'db')
+					$aConfig[$aData[2][$i]] = trim($aData[3][$i], "'");
+		}
+		
+		if (empty($aConfig))
+			return MsgBox( _t('_bx_dolphin_migration_error_config_file_was_not_found'));
+		
+      if(!empty($aConfig)) {
+			$this -> _oModule -> _oDb -> saveConfig($aConfig);
+			
+			$this -> _oModule -> createMigration();
+			if ($this -> _oModule -> initDb())
+				$this -> _oModule -> createMigration();
+			else
+				return MsgBox( _t('_bx_dolphin_migration_error_data_was_not_set'), 2);
+       }
+       else
+			return MsgBox( _t('_bx_dolphin_migration_error_data_was_not_set'), 2);
+              
+
+		return MsgBox( _t('_bx_dolphin_migration_data_was_set'), 2);			
+	}
+	
+	 protected function getSettings()
+    {
+        $aForm = array(
+			'params' => array(
+				'db' => array(
+					'submit_name' => 'save'
+				)
+			),
+            'inputs' => array (
+                'path' => array(
+                    'type' => 'text',
+                    'name' => 'path',
+                    'caption' => $this -> _oModule -> _oDb -> isConfigInstalled() ? _t('_bx_dolphin_migration_defined_path') : _t('_bx_dolphin_migration_cpt_put_path'),
+                    'value' => $this -> _oModule -> _oDb -> getExtraParam('root'),
+					'attrs_wrap'
+                ),   
+				
+				'save' => array (
+                    'type' => 'submit',
+                    'name' => 'save',
+                    'value' => _t('_bx_dolphin_migration_cpt_' . ($this -> _oModule -> _oDb -> getExtraParam('root') ? 'update' : 'save'))					
+                )
+            )
+        );
+        
+		
+		if ($this -> _oModule -> _oDb -> isConfigInstalled())
+				$aForm['inputs']['save']['attrs'] = array('onclick' => "javascript:return confirm('" . bx_js_string(_t('_bx_dolphin_migration_reupload_data')) . "');");
+		
+		$oForm = new BxTemplStudioFormView($aForm);	
+		
+		$sMessage = '';
+		if ($oForm -> isSubmitted()) 
+			$sMessage = $this -> saveData($oForm -> getCleanValue('path'));		
+		
+        return $sMessage . $oForm -> getCode();
+    }
+	
+	protected function getConfig()
+	{		
+		$oGrid = BxDolMTransfers::getObjectInstance('bx_dolphin_migration_transfers'); 
+		if ($oGrid)	
+			return $oGrid -> getCode(); // print grid object 		
+        
+		return MsgBox(_t('_bx_dolphin_migration_installation_problem'));
+	}
+}
+
+/** @} */

+ 21 - 0
modules/boonex/dolphin_migration/classes/BxDolMTemplate.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    DolphinMigration  Dolphin Migration
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxDolMTemplate extends BxBaseModGeneralTemplate
+{
+    public function __construct(&$oConfig, &$oDb)
+    {
+        $this -> MODULE = 'bx_dolphin_migration';
+        parent::__construct($oConfig, $oDb);
+    }
+}
+
+/** @} */

+ 476 - 0
modules/boonex/dolphin_migration/classes/BxDolMTimeline.php

@@ -0,0 +1,476 @@
+<?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('BxDolStorage');
+	
+class BxDolMTimeline extends BxDolMData
+{	
+	/**
+	 *  @var path in Dolphin to the video modules files
+	 */
+	private $_sImageVideoFiles = null;
+
+	public function __construct(&$oMigrationModule, &$oDb)
+	{
+        parent::__construct($oMigrationModule, $oDb);
+		$this -> _sModuleName = 'timeline';
+		$this -> _sTableWithTransKey = 'bx_timeline_events';
+		$this -> _sImageVideoFiles = $this -> _oDb -> getExtraParam('root') . 'flash' . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR . "video" . DIRECTORY_SEPARATOR . "files" . DIRECTORY_SEPARATOR;
+    }    
+	
+	public function getTotalRecords()
+	{
+		return (int)$this -> _mDb -> getOne("SELECT COUNT(*) FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] . "` ORDER BY `id`");
+	}
+	/**
+	 *  Returns data from the module into which data was added
+	 *  
+	 *  @param int $iModuleItemId object id
+	 *  @param string $sModule module name @uses BxDolMConfig::_aMigrationModules
+	 *  @return array
+	 */
+	private function getModuleItemInfo($iModuleItemId, $sModule = 'forum')
+	{
+		switch($sModule)
+		{
+			case 'events':
+					$sTable = 'bx_events_data';
+					break;
+			case 'store':
+					$sTable = 'bx_market_products';
+					break;
+			case 'files':
+					$sTable = 'bx_files_main';
+					break;
+			case 'polls':
+					$sTable = 'bx_polls_entries';
+					break;
+			case 'groups':
+					$sTable = 'bx_groups_data';
+					break;
+			case 'blogs':
+					$sTable = 'bx_posts_posts';
+					break;
+		}
+		if (!$sTable)
+			return array();
+		
+		if (!$this -> _oDb -> isFieldExists($sTable, $this -> _sTransferFieldIdent))
+			return array();
+
+		return $this -> _oDb -> getRow("SELECT * FROM `{$sTable}` WHERE `{$this -> _sTransferFieldIdent}` = :id", array('id' => $iModuleItemId));
+	}
+	/**
+	 *  Convert Dolphin timeline record into UNA timeline record
+	 *  
+	 *  @param array $aInfo Dolphin timeline record
+	 *  @return array
+	 */
+	private function getFormatedData(&$aInfo)
+	{
+		$sAction = '';
+		$sType = '';
+		$sContent = '';
+		$sDescription = '';
+		$iAuthor = $this -> getProfileId($aInfo['owner_id']);
+		$iObjectId = $this -> getProfileId($aInfo['object_id']);
+		$iTime	= time();
+		$sTitle = '';
+		$sUrl = '';
+		$iMediaId = 0;
+		$sMediaType = 0;
+		$aData = array();
+		
+		$mixedTransferred = $this -> isModuleContentTransferred($aInfo['type']);
+		if ($mixedTransferred === 0)
+			return array();
+		
+		switch($aInfo['type'])
+		{
+			case 'bx_events':
+			case 'bx_forum':
+			case 'bx_groups':
+			case 'bx_blogs':
+			case 'bx_store':
+			case 'bx_polls':
+				if (!($aInfo['action'] == 'add' || $aInfo['action'] == 'create'))
+					return array();
+						
+				$sModule = $this -> _oConfig -> _aModulesAliases[$aInfo['type']];
+				$aItemInfo = $this -> getModuleItemInfo($aInfo['object_id'], $sModule);
+				if (empty($aItemInfo))
+					return array();
+
+				$sAction = 'added';
+				$sType = $aInfo['type'];
+				$iObjectId = $aItemInfo['id'];
+				$iTime = $aInfo['date'];
+				switch($sModule)
+				{
+					case 'events':
+							$sTitle = $aItemInfo['event_name'];
+							break;
+					case 'store':
+							$sTitle = $aItemInfo['title'];
+							$sType = 'bx_market';
+							break;
+					case 'files':
+							$sTitle = $aItemInfo['title'];
+							break;
+					case 'videos':
+							$sTitle = $aItemInfo['title'];
+							break;
+					case 'photos':
+							$sTitle = $aItemInfo['title'];
+							break;
+					case 'polls':
+							$sTitle = $aItemInfo['text'];
+							break;
+					case 'groups':
+							$sTitle = $aItemInfo['group_name'];
+							break;
+					case 'blogs':
+							$sTitle = $aItemInfo['title'];
+							$sType = 'bx_posts';
+							break;
+				}
+								
+				$oProfile = BxDolProfile::getInstance($iAuthor);
+				$sDescription = _t('_bx_timeline_txt_user_added_sample', $oProfile -> getDisplayName(), _t("_{$sType}_txt_sample_single_with_article"));
+				break;
+
+			case 'wall_common_link':
+				$sType = 'timeline_common_post';
+				$sTitle = '<i class="sys-icon link"></i>';
+				preg_match('!https?://\S+!', $aInfo['description'], $aUrl);				
+				if (!empty($aUrl[0]))
+				{
+					$aData = array(
+									'url' => $aUrl[0],
+									'type' => 'link'
+									);
+					$sContent =  serialize(array());
+				}
+				break;				
+			case 'wall_common_photos':				
+			case 'wall_common_videos':
+				$sType = 'timeline_common_post';
+				$sTitle = $aInfo['type'] == 'wall_common_photos' ? '<i class="sys-icon picture-o"></i>' : '<i class="sys-icon film"></i>';
+				$aItemInfo = @unserialize($aInfo['content']);
+				if (!empty($aItemInfo))
+				{
+					$aData = array(
+									'media_id' => $aItemInfo['id'],
+									'type'	=> $aItemInfo['type']
+									);
+					$sContent =  serialize(array());
+				}				
+				break;				
+			case 'wall_common_text':
+				$sTitle = html2txt($aInfo['content']);				
+				$sType = 'timeline_common_post';		
+				$sContent =  serialize(array());
+				break;
+			case 'wall_common_repost':
+				$sType = 'timeline_common_repost';
+				 
+				if (isset($aInfo['content']))
+					$aItemInfo = @unserialize($aInfo['content']);
+				
+				if (!isset($aItemInfo['action']) || !($aItemInfo['action'] == 'add' || $aItemInfo['action'] == 'create'))
+					break;
+				else
+					$sSubAction = 'added';
+
+				$aSubInfo = $this -> getModuleItemInfo($aItemInfo['object_id'], $this -> _oConfig -> _aModulesAliases[$aItemInfo['type']]);
+				if (empty($aSubInfo))
+					break;
+				
+				$sSubType = $aItemInfo['type'];
+				$sSubType = $sSubType == 'bx_blogs' ? 'bx_posts' : $sSubType;
+				$sSubType = $sSubType == 'bx_store' ? 'bx_market' : $sSubType;			
+
+				$sContent = serialize(array('type' => $sSubType, 'action' => 'added', 'object_id' => $aSubInfo['id']));
+				break;
+		}
+		
+
+		$aResult = array
+		(
+			'type' => $sType,
+			'action' => $sAction,
+			'owner_id' => $iAuthor,
+			'object_id' => $iObjectId,
+			'privacy' => 3,
+			'content' => $sContent,
+			'title'	=> $sTitle,
+			'description' => $sDescription,
+			'date'	=> $iTime,
+			'active' => (int)$aInfo['active'],
+			'hidden' => (int)$aInfo['hidden'],
+			'data' => $aData
+		);		
+		
+		return $aResult;
+	}
+	/**
+	 *  Migrate timeline link from Dolphin to UNA
+	 *  
+	 *  @param int $iEventId record id 
+	 *  @param string $sUrl html url
+	 *  @param int $iProfileId profile id
+	 *  @return int affected rows
+	 */
+	private function addLink($iEventId, $sUrl, $iProfileId)
+    {
+		$aSiteInfo = bx_get_site_info($sUrl, array(
+            'thumbnailUrl' => array('tag' => 'link', 'content_attr' => 'href'),
+            'OGImage' => array('name_attr' => 'property', 'name' => 'og:image'),
+        ));
+
+        $sTitle = !empty($aSiteInfo['title']) ? $aSiteInfo['title'] : _t('_Empty');
+        $sDescription = !empty($aSiteInfo['description']) ? $aSiteInfo['description'] : _t('_Empty');
+
+        $sMediaUrl = '';
+        if(!empty($aSiteInfo['thumbnailUrl']))
+        	$sMediaUrl = $aSiteInfo['thumbnailUrl'];
+        else if(!empty($aSiteInfo['OGImage']))
+        	$sMediaUrl = $aSiteInfo['OGImage'];
+
+		$iMediaId = 0;
+		$oStorage = null;
+        if(!empty($sMediaUrl))
+		{
+        	$oStorage = BxDolStorage::getObjectInstance('bx_timeline_photos');
+        	$iMediaId = $oStorage->storeFileFromUrl($sMediaUrl, true, $iProfileId);
+			$oStorage -> afterUploadCleanup($iMediaId, $iProfileId);		
+        }
+	
+		if (!$sTitle && !$sDescription && !$iMediaId)
+			return false;
+		
+		$sQuery = $this -> _oDb -> prepare("
+							INSERT INTO
+								`bx_timeline_links`
+							SET
+							   `profile_id`	= ?,
+							   `media_id`  	= ?,
+							   `url` 		= ?,
+							   `title` 		= ?,
+							   `text`  		= ?,
+							   `added` 		= UNIX_TIMESTAMP()
+					   ", $iProfileId, $iMediaId, $sUrl, $sTitle, $sDescription);
+
+		$this -> _oDb -> query($sQuery);
+		return $this -> _oDb -> query("INSERT INTO `bx_timeline_links2events` SET `event_id` = :event, `link_id` = :link", array('event' => $iEventId, 'link' => $this -> _oDb -> lastId()));		
+    }
+	/**
+	 *  Transfer timeline photos 
+	 *  
+	 *  @param int $iEventId UNA record id
+	 *  @param int $iPhotoId Description for $iPhotoId
+	 *  @param int $iProfileId Description for $iProfileId
+	 *  @return Return description
+	 */
+	private function addPhoto($iEventId, $iPhotoId, $iProfileId)
+    {
+		$aMedia = $this -> _mDb -> getRow("SELECT * FROM `bx_photos_main` WHERE `ID`=:id LIMIT 1", array('id' => $iPhotoId));		
+		if (empty($aMedia))
+			return false;
+		
+		$sImagePath = $this -> _sImagePhotoFiles . "{$aMedia['ID']}.{$aMedia['Ext']}";				
+		if (file_exists($sImagePath))
+		{
+			$oStorage = BxDolStorage::getObjectInstance('bx_timeline_photos'); 
+			$iMediaId = $oStorage -> storeFileFromPath($sImagePath, true, $iProfileId, $iEventId);
+			if ($iMediaId)
+			{ 
+				$oStorage -> afterUploadCleanup($iMediaId, $iProfileId);
+				return $this -> _oDb -> query("INSERT INTO `bx_timeline_photos2events` SET `event_id` = :event, `media_id` = :media_id", array('event' => $iEventId, 'media_id' => $iMediaId));
+			}			
+		}	
+		
+		return false;
+    }
+	
+	private function addVideo($iEventId, $iVideoId, $iProfileId)
+    {
+		$aMedia = $this -> _mDb -> getRow("SELECT * FROM `RayVideoFiles` WHERE `ID`=:id LIMIT 1", array('id' => $iVideoId));
+		if (empty($aMedia))
+			return false;
+		
+		$sVideoPath = $this -> _sImageVideoFiles . "{$iVideoId}.m4v";				
+		if (file_exists($sVideoPath))
+		{
+			$oStorage = BxDolStorage::getObjectInstance('bx_timeline_videos'); 
+			$iMediaId = $oStorage -> storeFileFromPath($sVideoPath, true, $iProfileId, $iEventId);					
+			if ($iMediaId)
+			{ 
+				$oStorage -> afterUploadCleanup($iMediaId, $iProfileId);			
+				return $this -> _oDb -> query("INSERT INTO `bx_timeline_videos2events` SET `event_id` = :event, `media_id` = :media_id", array('event' => $iEventId, 'media_id' => $iMediaId));
+			}			
+		}	
+		
+		return false;		
+    }
+	
+	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_timeline'));
+		
+		$this -> createMIdField();
+		$iFeedsId = $this -> getLastMIDField();						
+		$sStart = '';
+		if ($iFeedsId)
+			$sStart = " WHERE `id` > {$iFeedsId}";
+													 
+		$aResult = $this -> _mDb -> getAll("SELECT * FROM `". $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] . "` {$sStart} ORDER BY `id`");
+		
+		$iCounter = 0;
+		foreach($aResult as $iKey => $aValue)
+		{
+			$aInfo = $this -> getFormatedData($aValue);
+			if (empty($aInfo) || !$aInfo['type'])
+				continue;
+			
+			$iFeedId = $this -> isItemExisted($aValue['id']);
+			if (!$iFeedId)
+			{
+				$sQuery = $this -> _oDb -> prepare( 
+						 "
+							INSERT INTO
+								`{$this -> _sTableWithTransKey}`
+							SET
+								`owner_id`   			= ?,
+								`type`      			= ?,
+								`action`   				= ?,
+								`object_id`				= ?,
+								`object_privacy_view`	= ?,
+								`content`				= ?,
+								`title`					= ?,		
+								`description`			= ?,		
+								`date`					= ?,
+								`active`				= ?,
+								`hidden`				= ?
+						 ", 
+							$aInfo['owner_id'], 
+							$aInfo['type'],
+							$aInfo['action'],
+							$aInfo['object_id'],
+							$aInfo['privacy'],
+							$aInfo['content'],
+							$aInfo['title'],
+							$aInfo['description'],
+							$aInfo['date'],
+							$aInfo['active'],
+							$aInfo['hidden']
+							);			
+			
+				$this -> _oDb -> query($sQuery);
+				
+				$iFeedId = $this -> _oDb -> lastId();			
+				if (!$iFeedId){
+					$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_timeline_error', (int)$aValue['id']));
+					return BX_MIG_FAILED;
+				}
+				
+				$this -> _iTransferred++;
+			}
+			
+			if (!empty($aInfo['data']))
+				switch($aInfo['data']['type'])
+				{
+					case 'videos' :  $this -> addVideo($iFeedId, $aInfo['data']['media_id'], $aInfo['owner_id']); break;
+					case 'photos' :  $this -> addPhoto($iFeedId, $aInfo['data']['media_id'], $aInfo['owner_id']); break;
+					case 'link' :  $this -> addLink($iFeedId, $aInfo['data']['url'], $aInfo['owner_id']); break;
+				}
+					
+			$iComments = $this -> transferComments($iFeedId, (int)$aValue['id'], 'timeline');			
+			$this -> _oDb ->  query("UPDATE `{$this -> _sTableWithTransKey}`
+									SET 
+										`comments` = :cmts
+									WHERE `id` = :id", 
+										array(
+												'id' => $iFeedId, 
+												'cmts' => (int)$iComments, 
+											));
+			
+			$this -> setMID($iFeedId, $aValue['id']);
+		}
+        
+		
+        // set as finished;
+        $this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_timeline_finished', $this -> _iTransferred));
+        return BX_MIG_SUCCESSFUL;
+    }
+ 
+	public function removeContent()
+	{
+		if (!$this -> _oDb -> isTableExists($this -> _sTableWithTransKey) || !$this -> _oDb -> isFieldExists($this -> _sTableWithTransKey, $this -> _sTransferFieldIdent))
+			return false;
+		
+		$aRecords = $this -> _oDb -> getAll("SELECT 
+												`e`.`id`,
+												`l`.`link_id`,
+												`p`.`media_id` as `photo_id`,
+												`v`.`media_id` as `video_id`
+											FROM `{$this -> _sTableWithTransKey}` as `e`
+											LEFT JOIN `bx_timeline_links2events` as `l` ON `e`.`id` = `l`.`event_id`
+											LEFT JOIN `bx_timeline_photos2events` as `p` ON `e`.`id` = `p`.`event_id`
+											LEFT JOIN `bx_timeline_videos2events` as `v` ON `e`.`id` = `v`.`event_id`
+											WHERE `e`.`{$this -> _sTransferFieldIdent}`!=0");
+		if (!empty($aRecords))
+		{
+			$iNumber = 0;
+			foreach($aRecords as $iKey => $aValue)
+			{			
+				$oComments =  BxDolCmts::getObjectInstance('bx_timeline', $aValue['id']);
+				if($oComments !== false)
+					$oComments->onObjectDelete($aValue['id']);
+				
+				if ($aValue['video_id'])
+				{
+					$oStorage = BxDolStorage::getObjectInstance('bx_timeline_videos');
+					$oStorage->deleteFile($aValue['video_id']);
+					$this -> _oDb -> query("DELETE FROM `bx_timeline_videos2events` WHERE `event_id`=:id", array('id' => $aValue['id']));
+				}
+				
+				if ($aValue['photo_id'])
+				{
+					$oStorage = BxDolStorage::getObjectInstance('bx_timeline_photos');
+					$oStorage->deleteFile($aValue['photo_id']);
+					$this -> _oDb -> query("DELETE FROM `bx_timeline_photos2events` WHERE `event_id`=:id", array('id' => $aValue['id']));
+				}
+				
+				if ($aValue['link_id'])
+				{
+					$sQuery = $this-> _oDb -> prepare("DELETE FROM `tl`, `tle` USING `bx_timeline_links` AS `tl` LEFT JOIN `bx_timeline_links2events` AS `tle` ON `tl`.`id`=`tle`.`link_id` WHERE `tle`.`event_id` = ?", $aValue['id']);
+					$this -> _oDb -> query($sQuery);
+				}			
+				
+				$this -> _oDb -> query("DELETE FROM `{$this -> _sTableWithTransKey}` WHERE `id`=:id", array('id' => $aValue['id']));
+				$iNumber++;
+			}
+		}
+		parent::removeContent();
+		
+		return $iNumber;
+	}	
+}
+
+/** @} */

+ 98 - 0
modules/boonex/dolphin_migration/classes/BxDolMTransfers.php

@@ -0,0 +1,98 @@
+<?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
+ * 
+ * @{
+ */
+
+class BxDolMTransfers extends BxTemplGrid
+{
+    public function __construct ($aOptions, $oTemplate = false)
+    {
+    	$this -> MODULE = 'bx_dolphin_migration';
+		$this -> _oModule = BxDolModule::getInstance('bx_dolphin_migration');
+		$this -> _aConfirmMessages = array(
+												'run' => _t('_bx_dolphin_migration_start_transfer_confirmation'),
+												'clean' => _t('_bx_dolphin_migration_clean_confirmation'),
+												'remove' => _t('_bx_dolphin_migration_remove_content_confirmation'),
+												'remove_profiles' => _t('_bx_dolphin_migration_remove_profile_content_confirmation')
+											);				
+        parent::__construct ($aOptions, $oTemplate);
+    }
+	
+	protected function _getCellStatusText($mixedValue, $sKey, $aField, $aRow)
+	{        
+		$sAttr = $this->_convertAttrs($aField, 'attr_cell', false, isset($aField['width']) ? 'width:' . $aField['width'] : false);				
+		
+		if ($aRow['status'] != 'finished') 
+			$mixedValue = _t('_bx_dolphin_migration_status_' . $aRow['status']);
+		
+		return '<td ' . $sAttr . '><span class="' . ($aRow['status'] == 'finished' ? 'bx-migrate-not-finished' : ($aRow['status'] == 'error' ? 'bx-migrate-error' : '')) . '">' . $mixedValue . '</span></td>';
+	} 
+	
+	protected function _getCellModule($mixedValue, $sKey, $aField, $aRow)
+	{
+		$aNumber = explode(',', $aRow['number']);
+
+		if (sizeof($aNumber) > 1)
+			$sTitle = call_user_func_array('_t', array_merge(array('_bx_dolphin_migration_data_' . $mixedValue), $aNumber));
+		else
+			$sTitle = _t('_bx_dolphin_migration_data_' . $mixedValue);
+			
+		return '<td>' .  $sTitle . '</td>';
+	} 
+	
+	public function performActionRun()
+	{
+		$aElements = bx_get('ids');
+		echoJson(array(
+			'msg' => $this-> _oModule -> actionStartTransfer($aElements), 
+			'grid' => $this -> getCode(false),
+			'blink' => $aElements,
+		));		   
+	}
+	
+	protected function _getFilterControls ()
+    {
+        return '';
+    }
+	
+	public function performActionRemoveProfiles()
+	{
+		$this -> performActionRemove();
+	}
+	
+	public function performActionRemove()
+	{
+		$sModule = bx_get('ids')[0];
+		$iNumber = $this-> _oModule -> actionPerformAction($sModule, 'remove');
+		echoJson(array(
+			'msg' => $iNumber ? _t('_bx_dolphin_migration_successfully_removed', $iNumber) : _t('_bx_dolphin_migration_nothing_removed'),
+			'grid' => $this -> getCode(false),
+			'blink' => $sModule,
+		));	
+	}
+	
+	protected function _getActionRemove ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
+    {
+		if ($aRow['module'] == 'profiles')
+			$a['attr']['bx_grid_action_single'] = 'remove_profiles';
+		return parent::_getActionDefault($sType, $sKey, $a, $isSmall, $isDisabled, $aRow);
+    }
+	
+	public function performActionClean()
+	{
+		$sModule = bx_get('ids')[0];
+		echoJson(array(
+			'msg' => $this-> _oModule -> actionPerformAction($sModule, 'clean') ? _t('_bx_dolphin_migration_successfully_cleaned') : _t('_bx_dolphin_migration_nothing_removed'),
+			'grid' => $this -> getCode(false),
+			'blink' => $sModule,
+		));	
+	}
+}
+
+/** @} */

+ 187 - 0
modules/boonex/dolphin_migration/classes/BxDolMVideoAlbums.php

@@ -0,0 +1,187 @@
+<?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('BxDolStorage');
+	
+class BxDolMVideoAlbums extends BxDolMData {		
+	/**
+	 *  @var $_iTransferredAlbums transferred albums number
+	 */	
+	private $_iTransferredAlbums;	
+	
+	/**
+	 *  @var $_sVideoFilesPath path to the video albums files
+	 */	
+	private $_sVideoFilesPath;
+    
+	public function __construct(&$oMigrationModule, &$oDb)
+	{
+        parent::__construct($oMigrationModule, $oDb);
+		$this -> _sModuleName = 'videos';
+		$this -> _sTableWithTransKey = 'bx_albums_albums';
+		$this -> _sTransferFieldIdent = 'vid_id';
+		$this -> _sVideoFilesPath = $this -> _oDb -> getExtraParam('root') . 'flash' . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR . "video" . DIRECTORY_SEPARATOR . "files" . DIRECTORY_SEPARATOR;
+    }
+	
+	public function getTotalRecords()
+	{
+		$aResult = $this -> _mDb -> getRow("SELECT COUNT(*) as `count`, SUM(`ObjCount`) as `obj` FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name_albums'] ."` WHERE `Type` = 'bx_videos' AND `Uri` <> 'Hidden'");
+		return !(int)$aResult['count'] && !(int)$aResult['obj'] ? 0 : $aResult;
+	}
+    
+	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_videos'));
+		
+		$this -> createMIdField();
+
+		$aResult = $this -> _mDb -> getAll("SELECT * FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name_albums'] ."` WHERE `Type` = 'bx_videos' AND `Uri` <> 'Hidden' ORDER BY `ID` ASC");		
+		foreach($aResult as $iKey => $aValue)
+		{ 			
+			$iProfileId = $this -> getProfileId((int)$aValue['Owner']);
+			if (!$iProfileId) 
+				continue;
+			
+			$iAlbumId = $this -> isItemExisted($aValue['ID']);			
+			if (!$iAlbumId)
+			{
+				$sAlbumTitle = isset($aValue['Caption']) && $aValue['Caption'] ? $aValue['Caption'] : 'Profile Videos';			
+				$sQuery = $this -> _oDb -> prepare( 
+							 "
+								INSERT INTO
+									`bx_albums_albums`
+								SET
+									`author`   			= ?,
+									`added`      		= ?,
+									`changed`   		= ?,
+									`thumb`				= 0,
+									`title`				= ?,
+									`allow_view_to` 	= ?,
+									`text`				= ?,
+									`status_admin`		= ?
+							 ", 
+								$iProfileId, 
+								$aValue['Date'] ? $aValue['Date'] : time(), 
+								$aValue['Date'] ? $aValue['Date'] : time(), 
+								$sAlbumTitle,
+								$aValue['AllowAlbumView'],
+								$aValue['Description'],
+								$aValue['Status'] == 'active' ? 'active' : 'hidden'
+								);			
+				
+					$this -> _oDb -> query($sQuery);
+					$iAlbumId = $this -> _oDb -> lastId();					
+						
+					if (!$iAlbumId)
+					{
+						$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_videos_album_error'));
+						return BX_MIG_FAILED;
+					}
+					
+				$this -> setMID($iAlbumId, $aValue['ID']);
+				
+			}
+			
+			$iAlbumsCmts = $this -> transferComments($iAlbumId, $aValue['ID'], 'video_albums');
+			if ($iAlbumsCmts)
+				$this -> _oDb -> query("UPDATE `bx_albums_albums` SET `comments` = :comments WHERE `id` = :id", array('id' => $iAlbumId, 'comments' => $iAlbumsCmts));
+			
+			$this -> migrateAlbumVideos($aValue['ID'], $iProfileId, $iAlbumId);	
+			$this -> _iTransferredAlbums++;
+       }        
+
+        $this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_videos_finished', $this -> _iTransferredAlbums, $this -> _iTransferred));
+        return BX_MIG_SUCCESSFUL;
+    }
+   	
+   /**
+	* Migrates all photo albums and users videos
+	* @param int $iAlbumId original albums id
+	* @param int $iProfileId una profile ID
+	* @param int $iNewAlbumID created una Album		
+	* @return Integer
+         */  
+   private function migrateAlbumVideos($iAlbumId, $iProfileId, $iNewAlbumID)
+   {
+			$aResult = $this -> _mDb -> getAll("SELECT * 
+													FROM  `sys_albums_objects` 
+													LEFT JOIN `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] ."` ON `id_object` = `ID`
+													WHERE  `id_album` = :album ORDER BY `id_object` ASC", array('album' => $iAlbumId));
+
+			$iTransferred  = 0;
+			foreach($aResult as $iKey => $aValue)
+			{ 
+				if ($this -> isFileExisted($iProfileId, $aValue['Title'], $aValue['Date'])) 
+					continue;
+				
+				$sVideoPath = $this -> _sVideoFilesPath . "{$aValue['ID']}.m4v";				
+				if (file_exists($sVideoPath))
+				{
+					$oStorage = BxDolStorage::getObjectInstance('bx_albums_files'); 
+					$iId = $oStorage -> storeFileFromPath($sVideoPath, false, $iProfileId);					
+					if ($iId)
+					{ 
+						$oStorage -> afterUploadCleanup($iId, $iProfileId);
+						
+						$sQuery = $this -> _oDb -> prepare("INSERT INTO `bx_albums_files2albums` SET `content_id` = ?, `file_id` = ?, `title` = ?", $iNewAlbumID, $iId, $aValue['Title']);
+						$this -> _oDb -> query($sQuery);
+						
+						$iCmts = $this -> transferComments($iItemId = $this -> _oDb -> lastId(), $aValue['ID'], 'videos');
+						if ($iCmts)
+							$this -> _oDb -> query("UPDATE `bx_albums_files2albums` SET `comments` = :comments WHERE `id` = :id", array('id' => $iItemId, 'comments' => $iCmts));
+						
+						$this -> _iTransferred++;
+						$iTransferred++;
+						
+						$this -> trasnferTags((int)$aValue['ID'], $iId, $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['type'], $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['keywords']);
+					}
+				}
+			}	
+				  
+	  return $iTransferred;
+   }
+       	
+	private function isFileExisted($iAuthor, $sTitle, $iDate)
+	{    	
+    	$sQuery  = $this -> _oDb ->  prepare("SELECT COUNT(*) FROM `bx_albums_files` WHERE `profile_id` = ? AND `file_name` = ? AND `added` = ? LIMIT 1", $iAuthor, $sTitle, $iDate);
+        return (bool)$this -> _oDb -> getOne($sQuery);
+    }
+	
+	public function removeContent()
+	{
+		if (!$this -> _oDb -> isTableExists($this -> _sTableWithTransKey) || !$this -> _oDb -> isFieldExists($this -> _sTableWithTransKey, $this -> _sTransferFieldIdent))
+			return false;
+		
+		$aRecords = $this -> _oDb -> getAll("SELECT * FROM `{$this -> _sTableWithTransKey}` WHERE `{$this -> _sTransferFieldIdent}` !=0");
+		
+		$iNumber = 0;
+		if (!empty($aRecords))
+		{
+			foreach($aRecords as $iKey => $aValue)
+			{
+				BxDolService::call('bx_albums', 'delete_entity', array($aValue['id']));
+				$iNumber++;
+			}
+		}
+		
+		parent::removeContent();		
+		return $iNumber;
+	}
+}
+
+/** @} */

+ 375 - 0
modules/boonex/dolphin_migration/classes/BxMDb.php

@@ -0,0 +1,375 @@
+<?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'));
+    }
+	
+	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 = ''");
+			$this->pdoExec("SET storage_engine=" . $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/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.0',
+    'vendor' => 'Boonex',
+	'help_url' => 'http://feed.una.io/?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_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(),
+);
+
+/** @} */

+ 20 - 0
modules/boonex/dolphin_migration/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    DolphinMigration  Dolphin Migration
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxDolMInstaller extends BxBaseModTemplateInstaller
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}
+
+/** @} */

+ 115 - 0
modules/boonex/dolphin_migration/install/langs/en.xml

@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+	<string name="_bx_dolphin_migration_wgt_cpt"><![CDATA[Dolphin Migration]]></string>
+	<string name="_bx_dolphin_migration_stg_cpt_type"><![CDATA[Dolphin Migration]]></string>	
+	<string name="_bx_dolphin_migration_cpt_settings"><![CDATA[Settings]]></string>
+	<string name="_bx_dolphin_migration_cpt_transfer_data"><![CDATA[Data Transfer]]></string>
+	<string name="_bx_dolphin_migration_cpt_put_path"><![CDATA[Define path to the root Dolphin's folder]]></string>  
+	<string name="_bx_dolphin_migration_cpt_save"><![CDATA[Save]]></string>
+	<string name="_bx_dolphin_migration_cpt_update"><![CDATA[Update]]></string>
+	<string name="_bx_dolphin_migration_error_data_was_not_set"><![CDATA[Configuration was not defined]]></string>
+	<string name="_bx_dolphin_migration_error_config_file_was_not_found"><![CDATA[Sorry configuration file was not found, please check path to the Dolphin Script!]]></string>
+	<string name="_bx_dolphin_migration_data_was_set"><![CDATA[Dolphin Configuration was successfully set. Go to Data Transfer area to continue!]]></string>
+	<string name="_bx_dolphin_migration_avaialble_modules_to_transfer"><![CDATA[Available content for transfer]]></string>
+	<string name="_bx_dolphin_migration_no_data_to_transfer"><![CDATA[No data to transfer]]></string>  
+	<string name="_bx_dolphin_migration_modules_name"><![CDATA[Data]]></string>  
+	<string name="_bx_dolphin_migration_modules_records_number"><![CDATA[Records number]]></string>  
+	<string name="_bx_dolphin_migration_modules_status"><![CDATA[Status]]></string>
+	<string name="_bx_dolphin_migration_defined_path"><![CDATA[Path to Dolphin script]]></string>
+	<string name="_bx_dolphin_migration_start_transfer"><![CDATA[Start transfer]]></string>
+	<string name="_bx_dolphin_migration_start_transfer_confirmation"><![CDATA[Please don't reload or close the page during data transferring]]></string>  
+	<string name="_bx_dolphin_migration_reupload_data"><![CDATA[If you update path to config file, all information from table below will be lost, but all transferred data will be saved.]]></string>  
+	<string name="_bx_dolphin_migration_already_transfer"><![CDATA[Module {0} already transferred]]></string>
+	<string name="_bx_dolphin_migration_install_before"><![CDATA[Please transfer {0} first!]]></string>
+	<string name="_bx_dolphin_migration_install_plugin"><![CDATA[You need to install {0} plugin(s), before {1} transfer]]></string>
+	<string name="_bx_dolphin_migration_successfully_finished"><![CDATA[Transfer was successfully finished]]></string>
+	<string name="_bx_dolphin_migration_successfully_failed"><![CDATA[Transfer is failed]]></string>
+	<string name="_bx_dolphin_migration_define_migration_method"><![CDATA[Please define migration method for this Data]]></string>
+	<string name="_bx_dolphin_migration_started_migration_profiles"><![CDATA[Profile Migration was started]]></string>
+	<string name="_bx_dolphin_migration_started_migration_profiles_finished"><![CDATA[{0} Profiles were transferred]]></string>
+	<string name="_bx_dolphin_migration_started_migration_profile_fields"><![CDATA[Profile Fields Migration was started]]></string>
+	<string name="_bx_dolphin_migration_started_migration_profile_fields_finished"><![CDATA[{0} Profile Fields were transferred]]></string>
+	<string name="_bx_dolphin_migration_started_migration_profile_field_can_not_be_transferred"><![CDATA[Custom Fields can not be transferred]]></string>  
+	<string name="_bx_dolphin_migration_started_migration_blogs"><![CDATA[Blogs Migration was started]]></string>
+	<string name="_bx_dolphin_migration_started_migration_photos"><![CDATA[Photos Migration was started]]></string>
+	<string name="_bx_dolphin_migration_started_migration_photos_finished"><![CDATA[{0} Albums and {1} Photos were transferred]]></string>
+	<string name="_bx_dolphin_migration_started_migration_videos_finished"><![CDATA[{0} Albums and {1} Video files were transferred]]></string>
+	<string name="_bx_dolphin_migration_started_migration_photos_album_error"><![CDATA[Database Error. Albums can not be created!]]></string>  
+	<string name="_bx_dolphin_migration_started_migration_videos"><![CDATA[Videos Migration was started]]></string>
+	<string name="_bx_dolphin_migration_friends_exports_error"><![CDATA[Database error: Friends can not be transferred]]></string>
+	<string name="_bx_dolphin_migration_all_data_transferred"><![CDATA[All Data was transferred]]></string>
+	<string name="_bx_dolphin_migration_status_not_started"><![CDATA[Not started Yet]]></string>
+	<string name="_bx_dolphin_migration_status_started"><![CDATA[Already started]]></string>  
+	<string name="_bx_dolphin_migration_status_finished"><![CDATA[Finished]]></string>
+	<string name="_bx_dolphin_migration_status_error"><![CDATA[Error occurred]]></string>
+	<string name="_bx_dolphin_migration_data_profiles"><![CDATA[Profiles]]></string>
+	<string name="_bx_dolphin_migration_data_profile_fields"><![CDATA[Profile Fields]]></string>  
+	<string name="_bx_dolphin_migration_data_blogs"><![CDATA[Blogs]]></string>
+	<string name="_bx_dolphin_migration_data_photos"><![CDATA[Photo Albums, Photos]]></string>
+	<string name="_bx_dolphin_migration_data_videos"><![CDATA[Video Albums, Videos]]></string>
+	<string name="_bx_dolphin_migration_data_groups"><![CDATA[Groups]]></string>
+	<string name="_bx_dolphin_migration_data_events"><![CDATA[Events]]></string>
+	<string name="_bx_dolphin_migration_data_polls"><![CDATA[Polls]]></string>
+	<string name="_bx_dolphin_migration_data_files"><![CDATA[Files]]></string>
+	<string name="_bx_dolphin_migration_data_store"><![CDATA[Store]]></string>
+	<string name="_bx_dolphin_migration_data_quotes"><![CDATA[Quotes]]></string>
+	<string name="_bx_dolphin_migration_data_shoutbox"><![CDATA[Shoutbox]]></string>
+	<string name="_bx_dolphin_migration_data_simple_messenger"><![CDATA[Simple messenger]]></string>
+	<string name="_bx_dolphin_migration_data_chat"><![CDATA[Flash Chat]]></string>
+	<string name="_bx_dolphin_migration_data_forum"><![CDATA[Topicts, Posts]]></string>
+	<string name="_bx_dolphin_migration_data_conversations"><![CDATA[Conversations]]></string>
+	<string name="_bx_dolphin_migration_data_timeline"><![CDATA[Timeline]]></string>
+	<string name="_bx_dolphin_migration_started_migration_blogs"><![CDATA[Blogs Migration was started]]></string>
+	<string name="_bx_dolphin_migration_started_migration_blogs_finished"><![CDATA[{0} blogs posts with comments were transferred]]></string>
+	<string name="_bx_dolphin_migration_started_migration_blogs_error"><![CDATA[Error occurred. Record Id is {0}]]></string>
+	<string name="_bx_dolphin_migration_started_migration_shoutbox"><![CDATA[Shoutbox migration was started]]></string>
+	<string name="_bx_dolphin_migration_started_migration_shoutbox_finished"><![CDATA[{0} messages were transferred]]></string>
+	<string name="_bx_dolphin_migration_started_migration_shoutbox_error"><![CDATA[Error occurred. Record Id is {0}]]></string>
+	<string name="_bx_dolphin_migration_started_migration_simple_messanger"><![CDATA[Simple messenger migration was started]]></string>
+	<string name="_bx_dolphin_migration_started_migration_simple_messanger_finished"><![CDATA[{0} messages were transferred]]></string>
+	<string name="_bx_dolphin_migration_started_migration_simple_messanger_error"><![CDATA[Error occurred. Record Id is {0}]]></string>
+	<string name="_bx_dolphin_migration_started_migration_chat"><![CDATA[Flash Chat migration was started]]></string>
+	<string name="_bx_dolphin_migration_started_migration_chat_finished"><![CDATA[{0} messages were transferred]]></string>
+	<string name="_bx_dolphin_migration_started_migration_chat_error"><![CDATA[Error occurred. Record Id is {0}]]></string>
+	<string name="_bx_dolphin_migration_started_migration_market"><![CDATA[Store migration was started]]></string>
+	<string name="_bx_dolphin_migration_started_migration_market_finished"><![CDATA[{0} store products with comments were transferred]]></string>
+	<string name="_bx_dolphin_migration_started_migration_market_error"><![CDATA[Error occurred. Record Id is {0}]]></string>
+	<string name="_bx_dolphin_migration_started_migration_files"><![CDATA[Files migration was started]]></string>
+	<string name="_bx_dolphin_migration_started_migration_files_finished"><![CDATA[{0} files with comments were transferred]]></string>
+	<string name="_bx_dolphin_migration_started_migration_files_error"><![CDATA[Error occurred. Record Id is {0}]]></string>
+	<string name="_bx_dolphin_migration_started_migration_quotes"><![CDATA[Quotes migration was started]]></string>
+	<string name="_bx_dolphin_migration_started_migration_quotes_finished"><![CDATA[{0} Quotes were transferred]]></string>
+	<string name="_bx_dolphin_migration_started_migration_quotes_error"><![CDATA[Error occurred. Record Id is {0}]]></string>
+	<string name="_bx_dolphin_migration_started_migration_groups"><![CDATA[Groups Migration was started]]></string>
+	<string name="_bx_dolphin_migration_started_migration_groups_finished"><![CDATA[{0} groups with fans were transferred]]></string>
+	<string name="_bx_dolphin_migration_started_migration_groups_error"><![CDATA[Error occurred. Record Id is {0}]]></string>
+	<string name="_bx_dolphin_migration_started_migration_events"><![CDATA[Events Migration was started]]></string>
+	<string name="_bx_dolphin_migration_started_migration_events_finished"><![CDATA[{0} events with fans were transferred]]></string>
+	<string name="_bx_dolphin_migration_started_migration_error"><![CDATA[Error occurred. Record Id is {0}]]></string>
+	<string name="_bx_dolphin_migration_started_migration_conv"><![CDATA[Conversations Migration was started]]></string>
+	<string name="_bx_dolphin_migration_started_migration_conv_finished"><![CDATA[{0} conversations with messages were transferred]]></string>
+	<string name="_bx_dolphin_migration_started_migration_conv_error"><![CDATA[Error occurred. Record Id is {0}]]></string>
+	<string name="_bx_dolphin_migration_started_migration_forum"><![CDATA[Forum Migration was started]]></string>
+	<string name="_bx_dolphin_migration_started_migration_forum_finished"><![CDATA[{0} topics with posts and comments were transferred]]></string>
+	<string name="_bx_dolphin_migration_started_migration_forum_error"><![CDATA[Error occurred. Record Id is {0}]]></string>
+	<string name="_bx_dolphin_migration_started_migration_polls"><![CDATA[Polls migration was started]]></string>
+	<string name="_bx_dolphin_migration_started_migration_polls_finished"><![CDATA[Polls were transferred]]></string>
+	<string name="_bx_dolphin_migration_started_migration_polls_error"><![CDATA[Error occurred. Record Id is {0}]]></string>
+	<string name="_bx_dolphin_migration_started_migration_timeline"><![CDATA[Wall Migration was started]]></string>
+	<string name="_bx_dolphin_migration_started_migration_timeline_finished"><![CDATA[{0} wall posts with comments were transferred]]></string>
+	<string name="_bx_dolphin_migration_started_migration_timeline_error"><![CDATA[Error occurred. Record Id is {0}]]></string>
+	<string name="_bx_dolphin_migration_define_total_method"><![CDATA[Please define how to calculate total records number for this Data]]></string>
+	<string name="_bx_dolphin_migration_salt"><![CDATA[Dolphin Secret]]></string>
+	<string name="_bx_dolphin_migration_installation_problem"><![CDATA[Seems like module was installed not correct. Please reinstall it.]]></string>
+	<string name="_bx_dolphin_started_migration_groups_finished"><![CDATA[{0} Groups and {1} comments were transferred]]></string>
+	<string name="_bx_dolphin_migration_conversation_title"><![CDATA[Conversation]]></string>
+	<string name="_bx_dolphin_migration_remove_content"><![CDATA[Remove transferred content]]></string>
+	<string name="_bx_dolphin_migration_remove_content_confirmation"><![CDATA[Are you sure, you want to delete all transferred records for this module?]]></string>
+	<string name="_bx_dolphin_migration_clean"><![CDATA[Remove additional fields for transfer]]></string>   
+	<string name="_bx_dolphin_migration_clean_confirmation"><![CDATA[If you clean tables, you will not be able to remove transferred content or to make timeline transfer later. Continue?]]></string>   
+	<string name="_bx_dolphin_migration_nothing_to_remove"><![CDATA[No data to remove]]></string>
+	<string name="_bx_dolphin_migration_successfully_cleaned"><![CDATA[Table is successfully cleaned!]]></string>
+	<string name="_bx_dolphin_migration_successfully_removed"><![CDATA[{0} records were successfully removed!]]></string>
+	<string name="_bx_dolphin_migration_nothing_removed"><![CDATA[Nothing was removed!]]></string>
+	<string name="_bx_dolphin_migration_remove_profile_content_confirmation"><![CDATA[If you remove profiles, it will remove all transferred profiles' content also. Continue?]]></string>
+</resources>

+ 13 - 0
modules/boonex/dolphin_migration/install/sql/disable.sql

@@ -0,0 +1,13 @@
+SET @sName = 'bx_dolphin_migration';
+
+-- SETTINGS
+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`=@sName;
+
+DELETE FROM `sys_options` WHERE `name` = 'bx_dolphin_migration_salt';
+
+-- GRIDS
+DELETE FROM `sys_objects_grid` WHERE `object` IN ('bx_dolphin_migration_transfers');
+DELETE FROM `sys_grid_fields` WHERE `object` IN ('bx_dolphin_migration_transfers', 'bx_dolphin_migration_transfers_path');
+DELETE FROM `sys_grid_actions` WHERE `object` IN ('bx_dolphin_migration_transfers');

+ 31 - 0
modules/boonex/dolphin_migration/install/sql/enable.sql

@@ -0,0 +1,31 @@
+SET @sName = 'bx_dolphin_migration';
+
+-- 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_dolphin_migration_wgt_cpt', 'bx_dolphin_migration@modules/boonex/bx_dolphin_migration/|std-icon.svg', 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_dolphin_migration_wgt_cpt', 1);
+SET @iCategId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `check`, `check_error`, `extra`, `order`) VALUES
+('bx_dolphin_migration_salt', '', 0, '_bx_dolphin_migration_salt', 'digit', '', '', '', 0);
+
+-- 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`, `visible_for_levels`, `override_class_name`, `override_class_file`) VALUES
+('bx_dolphin_migration_transfers', 'Sql', 'SELECT `id`, `module`, `number`, `status`, `status_text`, '''' as `datatype` FROM `bx_dolphin_transfers`', 'bx_dolphin_transfers', 'module', 'id', '', '', 0, '', 'start', '', 'path', '', 'auto', 'module', '', 2147483647, 'BxDolMTransfers', 'modules/boonex/dolphin_migration/classes/BxDolMTransfers.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
+('bx_dolphin_migration_transfers', 'checkbox', '', '1%', 0, 0, '', 1),
+('bx_dolphin_migration_transfers', 'module', '_bx_dolphin_migration_modules_name', '30%', 0, 0, '', 2),
+('bx_dolphin_migration_transfers', 'number', '_bx_dolphin_migration_modules_records_number', '10%', 0, 0, '', 3),
+('bx_dolphin_migration_transfers', 'status_text', '_bx_dolphin_migration_modules_status', '45%', 0, 0, '', 4),
+('bx_dolphin_migration_transfers', 'actions', '', '14%', 0, 0, '', 5),
+('bx_dolphin_migration_transfers_path', 'title', '_bx_dolphin_migration_modules_path', '100%', 0, 0, '', 0);
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
+('bx_dolphin_migration_transfers', 'bulk', 'run', '_bx_dolphin_migration_start_transfer', '', 0, 1, 1),
+('bx_dolphin_migration_transfers', 'single', 'remove', '_bx_dolphin_migration_remove_content', 'trash', 1, 1, 2),
+('bx_dolphin_migration_transfers', 'single', 'clean', '_bx_dolphin_migration_clean', 'eraser ', 1, 1, 1);

+ 33 - 0
modules/boonex/dolphin_migration/install/sql/install.sql

@@ -0,0 +1,33 @@
+SET @sName = 'bx_dolphin_migration';
+
+-- STUDIO: page & widget
+INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
+(3, @sName, '_bx_dolphin_migration_wgt_cpt', '_bx_dolphin_migration_wgt_cpt', 'bx_dolphin_migration@modules/boonex/dolphin_migration/|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, @sName, '{url_studio}module.php?name=bx_dolphin_migration', '', 'bx_dolphin_migration@modules/boonex/dolphin_migration/|std-icon.svg', '_bx_dolphin_migration_wgt_cpt', '', '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));
+
+
+CREATE TABLE IF NOT EXISTS `bx_dolphin_transfers` (
+	`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+	`module` varchar(50) NOT NULL,
+	`number` varchar(50) NOT NULL,
+	`status` enum('not_started','started','finished','error') NOT NULL,
+	`status_text` varchar(255) NOT NULL,
+	PRIMARY KEY (`id`),
+	UNIQUE  `module` (  `module` )
+);
+
+CREATE TABLE IF NOT EXISTS `bx_dolphin_config` (
+	`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+	`name` varchar(100) NOT NULL,
+	`value` varchar(150) NOT NULL,
+	PRIMARY KEY (`id`),
+	UNIQUE `name` (`name`)
+);

+ 8 - 0
modules/boonex/dolphin_migration/install/sql/uninstall.sql

@@ -0,0 +1,8 @@
+SET @sName = 'bx_dolphin_migration';
+
+-- 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;
+
+DROP TABLE IF EXISTS `bx_dolphin_config`, `bx_dolphin_transfers`;

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

@@ -0,0 +1,19 @@
+<?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(BX_DIRECTORY_PATH_INC . "design.inc.php");
+
+bx_import('BxDolLanguages');
+bx_import('BxDolRequest');
+
+BxDolRequest::processAsAction($GLOBALS['aModule'], $GLOBALS['aRequest']);
+
+/** @} */

+ 16 - 0
modules/boonex/dolphin_migration/template/css/main.css

@@ -0,0 +1,16 @@
+.bx-migrate-not-finished {
+	color:limegreen;
+	font-weight:bold;
+}
+
+.bx-migrate-error {
+	font-weight:bold;
+	color:red;
+}
+table.bx-grid-table td{
+	text-align:center;
+}
+
+.bx-grid-header-cnt > div{
+	width:50%;	
+}

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
modules/boonex/dolphin_migration/template/images/icons/std-icon.svg


+ 0 - 4
periodic/.htaccess

@@ -1,4 +0,0 @@
-Deny from all
-<FilesMatch "^.*\.php|.*\.html$">
-ForceType application/x-httpd-php-source
-</FilesMatch>

BIN
plugins/ffmpeg/ffmpeg.exe


+ 0 - 4
tmp/.htaccess

@@ -1,4 +0,0 @@
-Options -Indexes
-<FilesMatch "^.*\.php|.*\.html$">
-ForceType application/x-httpd-php-source
-</FilesMatch>

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است