Просмотр исходного кода

Dolphin Migration Tool update script 9.0.5

AlexeyUna 8 лет назад
Родитель
Сommit
6d061d8691
27 измененных файлов с 5140 добавлено и 1 удалено
  1. 1 1
      modules/boonex/dolphin_migration/install/config.php
  2. 51 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/install/config.php
  3. 26 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/install/installer.php
  4. 4 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/install/langs/en.xml
  5. 13 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/install/sql/enable.sql
  6. 163 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMBlogs.php
  7. 166 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMChat.php
  8. 285 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMConfig.php
  9. 608 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMData.php
  10. 178 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMDb.php
  11. 233 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMEvents.php
  12. 168 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMFiles.php
  13. 319 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMForum.php
  14. 214 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMGroups.php
  15. 218 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMMarket.php
  16. 150 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMModule.php
  17. 187 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMPhotoAlbums.php
  18. 181 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMPolls.php
  19. 466 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMProfiles.php
  20. 383 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMProfilesFields.php
  21. 97 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMQuotes.php
  22. 130 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMShoutBox.php
  23. 475 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMTimeline.php
  24. 193 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMVideoAlbums.php
  25. 70 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/install/config.php
  26. 126 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/install/langs/en.xml
  27. 35 0
      modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/install/sql/enable.sql

+ 1 - 1
modules/boonex/dolphin_migration/install/config.php

@@ -17,7 +17,7 @@ $aConfig = array(
     'name' => 'bx_dolphin_migration',
     'title' => 'Dolphin Migration',
     'note' => 'Migration Tool',
-    'version' => '9.0.4.DEV',
+    'version' => '9.0.5.DEV',
     'vendor' => 'Boonex',
 	'help_url' => 'http://feed.una.io/?section={module_name}',
 

+ 51 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/install/config.php

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

+ 26 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/install/installer.php

@@ -0,0 +1,26 @@
+<?php
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ */
+
+class BxDolMUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+	{
+        parent::__construct($aConfig);
+    }
+	
+	 public function update($aParams)
+    {
+        $aResult = parent::update($aParams);
+		if(!$aResult['result'])
+			return $aResult;
+
+        $oCacheUtilities = BxDolCacheUtilities::getInstance();
+        $oCacheUtilities->clear('css');
+        $oCacheUtilities->clear('template');
+
+        return $aResult;
+    }
+}

+ 4 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/install/langs/en.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+	<string_add name="_bx_dolphin_migration_cpt_default_privacy"><![CDATA[This privacy group will be set in case if you have not standard privacy groups in Dolphin and transferring item's privacy doesn't exist in UNA]]></string_add>	
+</resources>

+ 13 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/install/sql/enable.sql

@@ -0,0 +1,13 @@
+SET @sName = 'bx_dolphin_migration';
+
+SET @iCategId = (SELECT `id` FROM `sys_options_categories` WHERE `name` = @sName LIMIT 1);
+
+UPDATE `sys_options` SET `order` = 1 WHERE `category_id`=@iCategId AND `name`='bx_dolphin_migration_salt';
+UPDATE `sys_options` SET `order` = 2 WHERE `category_id`=@iCategId AND `name`='bx_dolphin_migration_overwrite';
+UPDATE `sys_options` SET `order` = 3 WHERE `category_id`=@iCategId AND `name`='bx_dolphin_migration_use_nickname';
+UPDATE `sys_options` SET `order` = 4 WHERE `category_id`=@iCategId AND `name`='bx_dolphin_migration_empty_albums';
+
+DELETE FROM `sys_options` WHERE `name` = 'bx_dolphin_migration_default_privacy';
+
+INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `check`, `check_error`, `extra`, `order`) VALUES
+('bx_dolphin_migration_default_privacy', 3, @iCategId, '_bx_dolphin_migration_cpt_default_privacy', 'select', '', '', 'a:2:{s:6:"module";s:20:"bx_dolphin_migration";s:6:"method";s:18:"get_privacy_groups";}', 5);

+ 163 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMBlogs.php

@@ -0,0 +1,163 @@
+<?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`			= ?,
+                     	    `allow_view_to`     = ?
+							
+                     ", 
+						$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 -> getPrivacy((int)$aValue['OwnerID'], isset($aValue['allowView']) ? (int)$aValue['allowView'] : 0, 'blogs', 'view')
+						);			
+		
+				$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 -> transferTags((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;
+	}	
+}
+
+/** @} */

+ 166 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMChat.php

@@ -0,0 +1,166 @@
+<?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 
+{
+    private $_sMigField = 'c_mig_id';
+    public function __construct(&$oMigrationModule, &$oDb)
+	{
+        parent::__construct($oMigrationModule, $oDb);
+		$this -> _sModuleName = 'chat';
+		$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 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($this -> _sMigField);
+		$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'], 'id', $this -> _sMigField);
+				
+				$this -> _iTransferred++;
+			}	
+		}
+
+        // set as finished;
+		$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_simple_messanger_finished', $this -> _iTransferred));
+        return BX_MIG_SUCCESSFUL;
+    }
+
+    public function dropMID($sIdentFieldName = '', $sTableName = '')
+    {
+        return parent::dropMID($this -> _sMigField);
+    }
+
+	public function removeContent()
+	{
+		if (!$this -> _oDb -> isTableExists($this -> _sTableWithTransKey) || !$this -> _oDb -> isFieldExists($this -> _sTableWithTransKey, $this -> _sMigField))
+			return false;		
+		
+		$aRecords = $this -> _oDb -> getAll("SELECT * FROM `{$this -> _sTableWithTransKey}` WHERE `{$this -> _sMigField}` !=0");
+		$aLots = $this -> _oDb -> getPairs("SELECT `lot_id` FROM `{$this -> _sTableWithTransKey}` WHERE `{$this -> _sMigField}` !=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;
+	}
+}
+
+/** @} */

+ 285 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMConfig.php

@@ -0,0 +1,285 @@
+<?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 bool allows to overwrite existed members profile data
+     */
+	public $_bIsOverwrite = false;
+
+	/**
+     * @var bool allows to transfer photo albums even if they are empty
+     */
+    public $_bTransferEmpty = true;
+
+    /**
+     * @var bool allows to use members NickName instead of FullName
+     */
+    public $_bUseNickName = false;
+
+    /**
+     * @var integer contains default privacy value
+     */
+    public $_iDefaultPrivacyGroup = 3;
+
+    /**
+     * @var int interval in milliseconds for checking if the data already transferred but script still works.
+     */
+    public $_iCheckInterval = 60000;
+
+    /**
+     *  @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'		
+			        ),
+                ),
+                'membership_levels' => array(
+                    'table_name'		=> 'sys_acl_levels',
+                    'migration_class'	=> 'BxDolMMemLevels',
+                    'dependencies' => array(
+                        'profiles',
+                    ),
+                    'plugins' => array(
+                        'bx_acl'	=> 'Paid Levels'
+                    ),
+                )
+             );
+			 
+	public function __construct($aModule)
+	{
+        $this -> _bIsOverwrite = getParam('bx_dolphin_migration_overwrite');
+        $this -> _bTransferEmpty = getParam('bx_dolphin_migration_empty_albums');
+        $this -> _bUseNickName = getParam('bx_dolphin_migration_use_nickname');
+        $this -> _iDefaultPrivacyGroup = (int)getParam('bx_dolphin_migration_default_privacy');
+
+        parent::__construct($aModule);
+	}
+
+}
+
+/** @} */

+ 608 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMData.php

@@ -0,0 +1,608 @@
+<?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)
+	{
+	    $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  `{$this -> _sTransferFieldIdent}` = ? 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  `{$this -> _sTransferFieldIdent}` = ? 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, '_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));
+	}
+
+	/**
+	 *  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 transferTags($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));
+	}
+	private function addCmtsIds($sCmtsTable, $iId, $iRate){
+        $iSystem = $this -> _oDb -> getOne("SELECT `ID` FROM `sys_objects_cmts` WHERE `Table`=:table LIMIT 1", array('table' => $sCmtsTable));
+        if (!$iSystem)
+            return false;
+
+        return $this -> _oDb -> query("INSERT INTO `sys_cmts_ids` SET `system_id` = :id, `rate`=:rate, `cmt_id`=:cmt_id",
+                                       array('id' => $iSystem, 'rate' => $iRate, 'cmt_id' => $iId));
+    }
+	/**
+	 *  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));
+		
+		$iComments = 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`)
+									VALUES	(NULL, :parent_id, :vparent_id, :object, :user, :level, :message, :time, :replies)",
+									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'],
+											'level' => isset($aCommentsArray[$aValue['cmt_parent_id']]) && $aCommentsArray[$aValue['cmt_parent_id']] ? $aCommentsArray[$aValue['cmt_parent_id']]['level'] + 1 : 0
+										));
+
+				$iLastInsertId = $this -> _oDb -> lastId();
+
+				$this -> addCmtsIds($sTable, $iLastInsertId, $aValue['cmt_rate'], $aValue['cmt_rate_count']);
+				$aCommentsArray[$aValue['cmt_id']] = array(
+																'id' => $iLastInsertId,
+																'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 
+															);
+				$iComments++;
+			}
+		}
+		
+		return $iComments;
+	}
+
+    /**
+     * Create migration field in main table for transferring content from Dolphin to UNA and contains id of the object in Dolphin
+     * @param string $sIdentFieldName
+     * @param string $sTableName name of the table to add the index field
+     * @return mixed
+     */
+    protected function createMIDField($sIdentFieldName = '', $sTableName = '')
+    {
+        if (!$this -> _sTableWithTransKey)
+            return false;
+
+        $sIdentFieldName = $sIdentFieldName ? $sIdentFieldName : $this -> _sTransferFieldIdent;
+        $sTableName = $sTableName ? $sTableName : $this -> _sTableWithTransKey;
+
+        if ($this -> _oDb -> isFieldExists($sTableName, $sIdentFieldName))
+            return true;
+
+        return $this -> _oDb -> query("ALTER TABLE `{$sTableName}` ADD `{$sIdentFieldName}` int(11) unsigned NOT NULL default '0'");
+    }
+
+	/**
+	 *  Returns last migration field value
+     * @param string $sIdentFieldName
+     * @param string $sTableName name of the table to add the index field
+	 * @return int
+	 */
+	protected function getLastMIDField($sIdentFieldName = '', $sTableName = '')
+	{
+		if (!$this -> _sTableWithTransKey)
+			return false;
+
+        $sIdentFieldName = $sIdentFieldName ? $sIdentFieldName : $this -> _sTransferFieldIdent;
+        $sTableName = $sTableName ? $sTableName : $this -> _sTableWithTransKey;
+
+		return (int)$this -> _oDb -> getOne("SELECT `{$sIdentFieldName}` FROM `{$sTableName}` WHERE `{$sIdentFieldName}` <> 0 ORDER BY `{$sIdentFieldName}` 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
+     * @param string $sIdentFieldName
+     * @param string $sTableName name of the table to add the index field
+	 * @return int
+	 */	
+	protected function isItemExisted($iItemId, $sField = 'id', $sIdentFieldName = '', $sTableName = '')
+	{
+		if (!$this -> _sTableWithTransKey)
+			return false;
+
+		$sIdentFieldName = $sIdentFieldName ? $sIdentFieldName : $this -> _sTransferFieldIdent;
+        $sTableName = $sTableName ? $sTableName : $this -> _sTableWithTransKey;
+
+		return (int)$this -> _oDb -> getOne("SELECT `{$sField}` FROM `{$sTableName}` WHERE `{$sIdentFieldName}` = :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
+     * @param string $sIdentFieldName
+	 *  @return int affected rows
+	 */
+	protected function setMID($iId, $iItemId, $sField ='id', $sIdentFieldName = '')
+	{
+		if (!$this -> _sTableWithTransKey)
+			return false;
+
+        $sIdentFieldName = $sIdentFieldName ? $sIdentFieldName : $this -> _sTransferFieldIdent;
+
+		return (int)$this -> _oDb -> query("UPDATE `{$this -> _sTableWithTransKey}` SET `{$sIdentFieldName}` = :item WHERE `{$sField}` = :id", array('id' => $iId, 'item' => $iItemId));
+	}
+
+    /**
+     *  Drop migration field from the table
+     *  @param string $sIdentFieldName field name to store id from original table (in case if you don't want to use default field)
+     *  @param string $sTableName table name in which to create the field
+     *  @return int affected rows
+     */
+    public function dropMID($sIdentFieldName = '', $sTableName = '')
+    {
+        $sIdentFieldName = $sIdentFieldName ? $sIdentFieldName : $this -> _sTransferFieldIdent;
+        $sTableName = $sTableName ? $sTableName : $this -> _sTableWithTransKey;
+
+        if (!$sTableName || !$this -> _oDb -> isFieldExists($sTableName, $sIdentFieldName))
+            return false;
+
+        return (int)$this -> _oDb -> query("ALTER TABLE `{$sTableName}` DROP `{$sIdentFieldName}`");
+    }
+	
+	/**
+	 *  Removes all transferred content from UNA
+	 *  @return void
+	 */
+	public function removeContent()
+	{
+        $this -> dropMID();
+	    $this -> _oDb -> updateTransferStatus($this -> _sModuleName, 'not_started');
+		$this -> setResultStatus('');
+	}
+
+    protected function getDefaultPrivacy($iDolProfileId, $sModule, $sAction){
+	    $iPrivacy = $this->_mDb->getOne("SELECT IF (`d`.`group_id` IS NULL, `a`.`default_group`, `d`.`group_id`)
+                                         FROM `sys_privacy_actions` as `a` 
+                                         LEFT JOIN `sys_privacy_defaults` as `d` ON `a`.`id` = `d`.`action_id` AND `d`.`owner_id` = :owner
+                                         WHERE `a`.`module_uri`=:module AND `a`.`name`=:action
+                                         ", array('owner' => $iDolProfileId, 'module' => $sModule, 'action' => $sAction));
+
+        $aProfileInfo = $this->_mDb->getRow("SELECT * FROM `Profiles` WHERE `ID`=:id LIMIT 1", array('id' => $iDolProfileId));
+        return $iPrivacy == 1 && isset($aProfileInfo['PrivacyDefaultGroup']) ? $this -> getValidPrivacy((int)$aProfileInfo['PrivacyDefaultGroup']) : $this -> getValidPrivacy($iPrivacy);
+    }
+
+    protected function getValidPrivacy($iPrivacy)
+    {
+        return $iPrivacy > 1 && $iPrivacy <= 5 ? $iPrivacy : $this->_oConfig->_iDefaultPrivacyGroup;
+    }
+
+    protected function getPrivacy($iDolProfileId, $iPrivacy, $sModule = '', $sAction = '', $iDefaultPrivacy = 0){
+        if ((int)$iPrivacy == 1)
+            return $iDefaultPrivacy ? $this -> getValidPrivacy($iDefaultPrivacy) : $this -> getDefaultPrivacy($iDolProfileId, $sModule, $sAction);
+
+        return $this -> getValidPrivacy($iPrivacy);
+    }
+}
+   
+/** @} */

+ 178 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMDb.php

@@ -0,0 +1,178 @@
+<?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
+    * @return boolean if requests are successful
+	*/ 
+	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;
+	}
+
+	/**
+     * Removes Dolphin's transfer settings
+     * @return boolean if requests are successful
+     */
+    public function removeConfig()
+    {
+        $this -> query("TRUNCATE TABLE `bx_dolphin_config`");
+        $this -> query("TRUNCATE TABLE `bx_dolphin_transfers`");
+    }
+
+    /**
+	* 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 -> getOne('SELECT COUNT(*) FROM `bx_dolphin_config`');
+	 }
+	
+	/** 
+	* 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 cleanTransfersTable()
+	{
+		return $this -> query("TRUNCATE TABLE `{$this -> _sPrefix}transfers`");
+	}
+
+	public function isFinished($aElements){
+	    if (empty($aElements))
+	        return false;
+
+	    $sList = implode("','", $aElements);
+	    return $this -> getOne("SELECT COUNT(*) FROM `{$this -> _sPrefix}transfers` WHERE `module` IN (:list) AND `status` != 'finished'", array('list' => $sList)) == 0;
+    }
+
+    public function getPrivacyList()
+    {
+        return $this -> getAll("SELECT
+                   `id`,
+                   `title`,
+                   `check`,
+                   `active`
+                FROM `sys_privacy_groups`
+                WHERE `active`='1' AND `visible`='1'");
+    }
+}
+
+/** @} */

+ 233 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMEvents.php

@@ -0,0 +1,233 @@
+<?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,
+						$this -> getPrivacy((int)$aValue['ResponsibleID'], isset($aValue['allow_view_event_to']) ? (int)$aValue['allow_view_event_to'] : 0, 'events', 'view_event'),
+						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 -> transferTags((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;
+	}
+}
+
+/** @} */

+ 168 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMFiles.php

@@ -0,0 +1,168 @@
+<?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,
+                    	$this -> getPrivacy((int)$aValue['Owner'], isset($aValue['AllowDownload']) ? (int)$aValue['AllowDownload'] : 0, 'files', 'download')
+						);			
+		
+				$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 -> transferTags((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;
+	}
+}
+
+/** @} */

+ 319 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMForum.php

@@ -0,0 +1,319 @@
+<?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/updates/9.0.4_9.0.5/source/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,
+                        $this -> getPrivacy((int)$aValue['author_id'], isset($aValue['allow_view_group_to']) ? (int)$aValue['allow_view_group_to'] : 0, 'groups', 'view_group'),
+						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 -> transferTags((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;
+	}
+}
+
+/** @} */

+ 218 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMMarket.php

@@ -0,0 +1,218 @@
+<?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,
+                        $this -> getPrivacy((int)$aValue['author_id'], isset($aValue['allow_view_product_to']) ? (int)$aValue['allow_view_product_to'] : 0, 'store', 'view_product')
+					);			
+		
+				$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 -> transferTags($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;
+	}
+}
+
+/** @} */

+ 150 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMModule.php

@@ -0,0 +1,150 @@
+<?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_finished');	
+	}
+	
+	/** 
+	* Creates date for migration
+	*/
+	public function createMigration()
+	{
+		if (is_null($this -> _oMDb)) 
+			$this -> initDb();
+
+		$this -> _oDb -> cleanTransfersTable();
+		foreach ($this -> _oConfig -> _aMigrationModules as $sName => $aModule)
+		{			
+			if ($this -> _oMDb -> isTableExists($aModule['table_name']))
+			{
+				
+				//Create transferring class object
+				require_once($aModule['migration_class'] . '.php');			
+				$oObject = new $aModule['migration_class']($this, $this -> _oMDb);			
+				
+				if ($mixedNumber = $oObject -> getTotalRecords()) 
+						$this -> _oDb -> addToTransferList($sName, $mixedNumber);				
+			}	
+		}		
+	}
+	
+	/** 
+	* Init Dolphin database connect
+	* @return mixed
+	*/	
+	public function initDb()
+    {
+        $aConfig = array(
+            'host' => $this->_oDb->getExtraParam('host'),
+            'user' => $this->_oDb->getExtraParam('user'),
+            'pwd' => $this->_oDb->getExtraParam('passwd'),
+            'name' => $this->_oDb->getExtraParam('db'),
+            'port' => $this->_oDb->getExtraParam('port'),
+            'sock' => $this->_oDb->getExtraParam('sock'),
+        );
+
+        $this->_oMDb = new BxMDb($aConfig);
+        return $this->_oMDb->connect();
+    }
+
+    public function serviceGetPrivacyGroups(){
+        $aPrivacyList = $this -> _oDb -> getPrivacyList();
+        $aValues = array();
+        foreach($aPrivacyList as $aGroup)
+            $aValues[] = array('key' => $aGroup['id'], 'value' => _t($aGroup['title']));
+
+        return $aValues;
+    }
+}
+
+/** @} */

+ 187 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMPhotoAlbums.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 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;
+		}
+
+		$sWhereCount = '';
+		if ($this -> _oConfig -> _bTransferEmpty)
+            $sWhereCount = " AND `ObjCount` <> 0";
+
+		$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' {$sWhereCount} 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,
+                                $this -> getPrivacy($aValue['Owner'], (int)$aValue['AllowAlbumView'], 'photos', 'album_view'),
+								$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, $iNewAlbumID);
+					if ($iId)
+					{ 
+                        $this -> updateFilesDate($iId, $aValue['Date']);
+						
+						$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 -> transferTags((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);
+    }
+
+    private function updateFilesDate($iId, $iDate){
+        $sQuery  = $this -> _oDb ->  prepare("UPDATE `bx_albums_files` SET `added`=? WHERE `id` = ?", $iDate, $iId);
+        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)
+			{
+				BxDolService::call('bx_albums', 'delete_entity', array($aValue['id']));
+				$iNumber++;
+			}
+		}
+
+		parent::removeContent();
+		return $iNumber;
+	}
+}
+
+/** @} */

+ 181 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/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,
+                        $this -> getPrivacy((int)$aValue['id_profile'], isset($aValue['allow_view_to']) ? (int)$aValue['allow_view_to'] : 0, 'poll', 'view'),
+						$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 -> transferTags($aValue['id_poll'], $iPollId, $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['type'], $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['keywords']);
+        }      	
+
+
+        // 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;
+	}
+}
+
+/** @} */

+ 466 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMProfiles.php

@@ -0,0 +1,466 @@
+<?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
+{
+    private $_sProfileCoverName = '';
+    private $_sProfileInfoName = '';
+
+    public function __construct(&$oMigrationModule, &$mDb)
+    {
+		parent::__construct($oMigrationModule, $mDb);
+		$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()
+	{
+        $this -> _sProfileCoverName = $this -> _mDb -> getParam('bx_photos_profile_cover_album_name');
+        $this -> _sProfileInfoName = $this -> _mDb -> getParam('sys_member_info_name');
+
+        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 -> profilesMigration();
+        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 account with the same nickname or email already exists
+	* @param string $sNickName name of the user
+	* @param string $sEmail user email
+	* @return integer account id
+     */
+	private function isAccountExisted($sNickName, $sEmail){
+        $sQuery  = $this -> _oDb -> prepare("SELECT `id` FROM `sys_accounts` WHERE `name` = ? OR `email` = ?", $sNickName, $sEmail);
+        return $this -> _oDb -> getOne($sQuery);
+	}
+
+    /**
+     * Check if profile with the same nickname already exists
+     * @param integer $iAccountId account id
+     * @param string $sFullName name of the user
+     * @return integer profile id
+     */
+    private function isProfileExisted($iAccountId, $sFullName){
+       $sQuery  = $this -> _oDb -> prepare("SELECT `p`.`id` 
+                                             FROM `bx_persons_data` as `p`
+                                             LEFT JOIN `sys_profiles` as `s` ON `s`.`id` = `p`.`author` AND `s`.`type` = 'bx_persons' 
+                                             WHERE `s`.`account_id` = ? AND `p`.`fullname` = ?", $iAccountId, $sFullName);
+        return $this -> _oDb -> getOne($sQuery);
+    }
+
+	function profilesMigration()
+    {
+			$this -> createMIdField();
+
+			// get IDs of the latest transferred profile for UNA Accounts and Dolphin Profiles
+			$iProfileID = $this -> getLastMIDField();
+			$sStart = '';
+			if ($iProfileID[$this -> _sTransferFieldIdent])
+				$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");
+			$aSex = $this -> getPreValuesBy('Sex', 'Value', 'Order');
+
+			foreach($aResult as $iKey => $aValue)
+			{
+
+				if($aValue['NickName'])
+				{
+                     $sAction = "INSERT INTO";
+                     $sWhere  = "";
+                     $bAccountExists = false;
+                     $iAccountId = $this -> isAccountExisted($aValue['NickName'], $aValue['Email']);
+                     if ($iAccountId)
+                     {
+                         if ($this -> _oConfig -> _bIsOverwrite) {
+                             $sAction = "UPDATE";
+                             $sWhere = "WHERE `id` = '{$iAccountId}'";
+                             $bAccountExists = true;
+                         }
+                         else
+                             continue;
+				     }
+
+                      $sQuery = $this -> _oDb -> prepare(
+                     "
+                     	{$sAction}
+                     		`sys_accounts`
+                     	SET
+                     		`name`   			= ?,
+                     		`email`      		= ?,
+                     		`password`   		= ?,
+                     		`salt`		   		= ?,
+							`role`				= ?,		
+                     		`lang_id`			= ?,
+							`added`				= ?,
+                     		`changed`	  		= ?,
+                     		`logged` 			= ?,
+							`email_confirmed`	= ?,
+							`receive_updates`	= ?,	
+							`receive_news`		= ?
+						{$sWhere}	
+                     ", 
+						$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 = $iAccountId ? $iAccountId : $this -> _oDb -> lastId();
+					if (!$iAccountId) 
+						continue;
+					
+					$this -> setMID($iAccountId, $aValue['ID']);
+
+                    if ($this -> _oConfig -> _bUseNickName)
+                        $sFullName = $aValue['NickName'];
+					else
+					{
+                       $sFullName = isset($aValue['FullName']) ? $aValue['FullName'] : "{$aValue['FirstName']} {$aValue['LastName']}";
+                       $sFullName = $sFullName ? $sFullName : $aValue['NickName'];
+                    }
+
+                    $sAction = "INSERT INTO";
+                    $sWhere = '';
+                    $iProfID = 0;
+                    if ($bAccountExists && ($iProfID = $this -> isProfileExisted($iAccountId, $sFullName))) {
+                        $sAction = "UPDATE";
+                        $sWhere = "WHERE `id` = '{$iProfID}'";
+                    }
+
+                    $iDateReg = strtotime($aValue['DateReg']);
+                    $iDateEdit = strtotime($aValue['DateLastEdit']);
+					$sQuery = $this -> _oDb -> prepare( 
+	                     "{$sAction}
+	                     		`bx_persons_data`
+	                     	SET
+	                     		`author`   			= 0,
+	                     		`added`      		= ?,
+	                     		`changed`   		= ?,
+								`picture`			= 0,		
+	                     		`cover`				= 0,
+								`fullname`			= ?,
+								`birthday`			= ?,
+								`gender`			= ?,
+								`allow_view_to`		= ?,
+								`featured`			= ?,
+								`views`				= ?,
+								`description`		= ?
+							{$sWhere}
+	                     ",
+                            $iDateReg ? $iDateReg : 0,
+                            $iDateEdit ? $iDateEdit : 0,
+							$sFullName,
+							isset($aValue['DateOfBirth']) ? $aValue['DateOfBirth'] : 'NULL',
+							isset($aValue['Sex']) && $aValue['Sex'] ? $aSex[$aValue['Sex']] : 1,
+                            $this -> getPrivacy($aValue['ID'], isset($aValue['allow_view_to']) ? $aValue['allow_view_to'] : 0, '', '', $aValue['PrivacyDefaultGroup']),
+							isset($aValue['Featured']) ? (int)$aValue['Featured'] : 0,
+							isset($aValue['Views']) ? (int)$aValue['Views'] : 0,
+							isset($aValue['DescriptionMe']) && $aValue['DescriptionMe'] ? nl2br(htmlspecialchars_adv($aValue['DescriptionMe'])) : ''
+							);
+						
+						$this -> _oDb -> query($sQuery);	
+						$iContentId = $iProfID ? $iProfID : $this -> _oDb -> lastId();
+
+						if (!$iProfID) {
+                            $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);
+                                if ($aValue['Role'] == 3)
+                                    BxDolAcl::getInstance()->setMembership($iProfile, MEMBERSHIP_ID_ADMINISTRATOR);
+                            }
+
+                            $sQuery = $this->_oDb->prepare("UPDATE `bx_persons_data` SET `author` = ? WHERE `id` = ?", $iProfile, $iContentId);
+                            $this->_oDb->query($sQuery);
+                        }
+
+                        $this->exportCover($aValue);
+                        $this->exportAvatar($aValue);
+                        $this->exportFriends($aValue['ID']);
+
+						$this -> _iTransferred++;
+                  }
+             }
+        }
+
+	/**
+	* Get Avatar's image  path
+	* @param array $aProfileInfo profile information
+	* @return string
+         */ 	
+	private function getProfileImage($aProfileInfo)
+	{	   
+       $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 
+					ORDER BY `obj_order` ASC, `id_object` DESC
+					LIMIT 1", array('uri' => $sAlbumName, 'id' => $aProfileInfo['ID']));
+			
+			if (!empty($aInfo) && isset($aInfo['ID']))
+				$sImagePath = $this -> _sImagePhotoFiles ."{$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 exportCover($aProfileInfo){
+	    if (!$this -> _sProfileCoverName)
+            return FALSE;
+
+        $iProfileId = $this-> getProfileId($aProfileInfo['ID']);
+        $iContentId = $this-> getContentId($aProfileInfo['ID']);
+
+        $sUserName = $aProfileInfo['NickName'];
+        switch ($this -> _sProfileInfoName) {
+                case 'sys_username':
+                    $sUserName = $aProfileInfo['NickName'];
+                    break;
+                case 'sys_full_name':
+                    $sUserName = htmlspecialchars_adv($aProfileInfo['FullName'] ? $aProfileInfo['FullName'] : $aProfileInfo['NickName']);
+                    break;
+                case 'sys_first_name':
+                    $sUserName = $aProfileInfo['FirstName'] ? $aProfileInfo['FirstName'] : $aProfileInfo['NickName'];
+                    break;
+                case 'sys_first_name_last_name':
+                    $sUserName = $aProfileInfo['FirstName'] || $aProfileInfo['LastName'] ? $aProfileInfo['FirstName'] . ' ' . $aProfileInfo['LastName'] : $aProfileInfo['NickName'];
+                    break;
+                case 'sys_last_name_firs_name':
+                    $sUserName = $aProfileInfo['FirstName'] || $aProfileInfo['LastName'] ? $aProfileInfo['LastName'] . ' ' . $aProfileInfo['FirstName'] : $aProfileInfo['NickName'];
+        }
+
+        $aReplacement = array(
+            '{nickname}' => $sUserName,
+            '{fullname}' => $aProfileInfo['NickName']
+        );
+
+       $sAlbumName = uriFilter(str_replace(array_keys($aReplacement), array_values($aReplacement), $this -> _sProfileCoverName));
+       $aCoverInfo = $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` AND `sys_albums`.`LastObjId` = `bx_photos_main`.`ID`  
+          WHERE  `bx_photos_main`.`Owner` = :owner AND `sys_albums`.`Status` ='active' AND `sys_albums`.`Type` ='bx_photos' AND `sys_albums`.`Uri` =:album", array('owner' => $aProfileInfo['ID'],'album' => $sAlbumName));
+
+       if (!empty($aCoverInfo))
+       {
+           $sImagePath = $this->_sImagePhotoFiles . "{$aCoverInfo['ID']}.{$aCoverInfo['Ext']}";
+           if (file_exists($sImagePath)) {
+               $oStorage = BxDolStorage::getObjectInstance('bx_persons_pictures');
+               $iId = $oStorage->storeFileFromPath($sImagePath, false, $iProfileId, $iContentId);
+               if ($iId) {
+                   $sQuery = $this->_oDb->prepare("UPDATE `bx_persons_data` SET `Cover` = ? WHERE `id` = ?", $iId, $iContentId);
+                   $this->_oDb->query($sQuery);
+               }
+           }
+       }
+
+       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($iUserId && $iFriendId && !$this -> isFriendExists($iUserId, $iFriendId))
+			{
+
+				   $sQuery =  $this -> _oDb -> prepare("
+						INSERT IGNORE INTO
+							`sys_profiles_conn_friends`
+						SET
+						   `initiator`	= ?,
+						   `content`    = ?,
+						   `mutual`     = ?,
+						   `added`     	= UNIX_TIMESTAMP()
+				   ", $iUserId, $iFriendId, $aValue['Check']);
+                $iResult = $this -> _oDb -> query($sQuery);
+
+				if ($iResult && (int)$aValue['Check']){
+		        $sQuery = $this->_oDb->prepare("
+						INSERT IGNORE INTO
+							`sys_profiles_conn_friends`
+						SET
+						   `initiator`	= ?,
+						   `content`    = ?,
+						   `mutual`     = ?,
+						   `added`     	= UNIX_TIMESTAMP()
+				   ", $iFriendId, $iUserId, 1);
+                    $iResult = $this->_oDb->query($sQuery);
+                }
+
+				   if($iResult <= 0) {
+					   return _t('_bx_dolphin_migration_friends_exports_error');
+				   }
+				}
+				
+		}	    
+	}
+
+	private function exportAvatar($aProfileInfo)
+    {
+       $iProfileId = $this-> getProfileId($aProfileInfo['ID']);
+       $iContentId = $this-> getContentId($aProfileInfo['ID']);
+       $sAvatarPath = $this -> getProfileImage($aProfileInfo);
+       if($sAvatarPath)
+		{
+			$oStorage = BxDolStorage::getObjectInstance('bx_persons_pictures'); 				
+			$iId = $oStorage->storeFileFromPath($sAvatarPath, false, $iProfileId, $iContentId);
+			if ($iId)
+			{
+				$sQuery = $this -> _oDb -> prepare("UPDATE `bx_persons_data` SET `Picture` = ? WHERE `id` = ?", $iId, $iContentId);
+				$this -> _oDb -> query($sQuery);
+			}
+		}
+    }
+
+	private function isFriendExists($iProfileId, $iFriendId)
+    {
+            $sQuery =  "
+            	SELECT 
+            		COUNT(*) 
+            	FROM 
+            		`sys_profiles_conn_friends` 
+            	WHERE
+            		`initiator` = {$iProfileId} AND `content` = {$iFriendId}          
+            ";
+
+            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);	
+	}
+
+	/*private function getPrivacy($aProfile){
+	    return isset($aProfile['allow_to_view']) && $aProfile['allow_to_view'] > 1 && $aProfile['allow_to_view'] <= 5 ? $aProfile['allow_to_view'] : $aProfile['PrivacyDefaultGroup'];
+    }*/
+}
+
+	
+/** @} */

+ 383 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMProfilesFields.php

@@ -0,0 +1,383 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    DolphinMigration  Dolphin Migration
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+    
+require_once('BxDolMData.php');
+bx_import('BxDolStudioLanguagesUtils');
+
+class BxDolMProfilesFields extends BxDolMData
+{
+	/**
+	 *  @var  $_aProfileFields profile fields for transfer
+	 */
+	private $_aProfileFields = array();
+	
+	/**
+	 *  @var  $_aFiltered exclude listed filed from migration list
+	 */
+	private $_aFiltered = array(
+									'ID', 'NickName', 'Email', 'Password', 
+									'Role', 'LangID', 'DateLastNav', 'DateReg', 
+									'DateLastEdit', 'DateLastLogin', 'Sex', 
+									'DateOfBirth', 'EmailNotify', 'Avatar', 'allow_view_to', 
+									'Featured', 'DescriptionMe', 'FullName'
+								);
+	/**
+	 *  @var  $_oAssocFields list of the fields from Dolphin
+	 */	
+	private $_oAssocFields = null;
+
+    public function __construct($oMigrationModule, &$mDb)
+    {
+        parent::__construct($oMigrationModule, $mDb);
+		$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)
+	{
+		$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($sKey);
+			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;
+	}
+}
+
+/** @} */

+ 97 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMQuotes.php

@@ -0,0 +1,97 @@
+<?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;
+	}
+}
+
+/** @} */

+ 130 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMShoutBox.php

@@ -0,0 +1,130 @@
+<?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;
+    private $_sMigField = 'shoutbx_id';
+	public function __construct(&$oMigrationModule, &$oDb)
+	{
+        parent::__construct($oMigrationModule, $oDb);
+		$this -> _sModuleName = 'shoutbox';
+		$this -> _sTableWithTransKey = 'bx_messenger_jots';
+    }
+	
+	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_MIG_SUCCESSFUL;
+		}	
+		
+		$this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_shoutbox'));
+		
+		$this -> createMIdField($this -> _sMigField);
+		
+		$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'], 'id', $this -> _sMigField);
+			}	
+		
+			$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_MIG_SUCCESSFUL;
+    }
+
+    public function dropMID($sIdentFieldName = '', $sTableName = '')
+    {
+        return parent::dropMID($this -> _sMigField);
+    }
+    
+	public function removeContent()
+	{
+		if (!$this -> _oDb -> isTableExists($this -> _sTableWithTransKey) || !$this -> _oDb -> isFieldExists($this -> _sTableWithTransKey, $this -> _sMigField))
+			return false;
+		
+		$aRecords = $this -> _oDb -> getAll("SELECT * FROM `{$this -> _sTableWithTransKey}` WHERE `{$this -> _sMigField}` !=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;
+	}
+	
+}
+
+/** @} */

+ 475 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMTimeline.php

@@ -0,0 +1,475 @@
+<?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')
+	{
+        $sTable = '';
+	    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 = '';
+		$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 far image"></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')  || !isset($this -> _oConfig -> _aModulesAliases[$aItemInfo['type']]))
+					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`");
+
+		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'],
+                            $this -> getValidPrivacy($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;
+	}	
+}
+
+/** @} */

+ 193 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/classes/BxDolMVideoAlbums.php

@@ -0,0 +1,193 @@
+<?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;
+	private $_sVideoMigField = 'vid_id';
+
+	public function __construct(&$oMigrationModule, &$oDb)
+	{
+        parent::__construct($oMigrationModule, $oDb);
+		$this -> _sModuleName = 'videos';
+		$this -> _sTableWithTransKey = 'bx_albums_albums';
+		$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($this -> _sVideoMigField);
+
+
+		$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'], 'id', $this -> _sVideoMigField);
+			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,
+                                $this -> getPrivacy($aValue['Owner'], (int)$aValue['AllowAlbumView'], 'videos', 'album_view'),
+								$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'], 'id', $this -> _sVideoMigField);
+				
+			}
+			
+			$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 -> transferTags((int)$aValue['ID'], $iId, $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['type'], $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['keywords']);
+					}
+				}
+			}	
+				  
+	  return $iTransferred;
+   }
+
+    public function dropMID($sIdentFieldName = '', $sTableName = '')
+    {
+        return parent::dropMID($this -> _sVideoMigField);
+    }
+
+	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 -> _sVideoMigField))
+			return false;
+		
+		$aRecords = $this -> _oDb -> getAll("SELECT * FROM `{$this -> _sTableWithTransKey}` WHERE `{$this -> _sVideoMigField}` !=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;
+	}
+}
+
+/** @} */

+ 70 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/install/config.php

@@ -0,0 +1,70 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    DolphinMigration  Dolphin Migration
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_dolphin_migration',
+    'title' => 'Dolphin Migration',
+    'note' => 'Migration Tool',
+    'version' => '9.0.5',
+    'vendor' => 'Boonex',
+	'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '9.0.0-RC13'
+    ),
+
+    /**
+     * '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(),
+);
+
+/** @} */

+ 126 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/install/langs/en.xml

@@ -0,0 +1,126 @@
+<?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, all information from table below will be lost, but it will not influence on already transferred data.]]></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[{0} 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_data_membership_levels"><![CDATA[Paid Memberships levels, Members info]]></string>
+	<string name="_bx_dolphin_migration_started_migration_membership_levels"><![CDATA[Membership levels migration was started]]></string>
+	<string name="_bx_dolphin_migration_started_migration_membership_levels_finished"><![CDATA[{0} membership levels and {1} members' info were transferred]]></string>
+	<string name="_bx_dolphin_migration_started_migration_membership_levels_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>
+	<string name="_bx_dolphin_migration_cpt_overwrite"><![CDATA[If account with the same NickName or Email already exists, then to overwrite its info.
+	<br/><b>This option is useful if you already have account on current version with the same Nickname as in Dolphin. If you enable this option all existed on UNA accounts will be updated using profiles' info from Dolphin and don't forget that info of your current logged member may be also updated and you can be logged out.</b>]]></string>
+	<string name="_bx_dolphin_migration_cpt_clean"><![CDATA[Clean]]></string>
+	<string name="_bx_dolphin_migration_cpt_use_nickname"><![CDATA[Use NickName instead of Profile's FullName]]></string>
+	<string name="_bx_dolphin_migration_cpt_empty_albums"><![CDATA[Transfer photo albums even if they are empty]]></string>
+	<string name="_bx_dolphin_migration_cpt_default_privacy"><![CDATA[This privacy group will be set in case if you have not standard privacy groups in Dolphin and transferring item's privacy doesn't exist in UNA]]></string>
+	<string name="_bx_dolphin_migration_cpt_clean_warning"><![CDATA[Path to the Dolphin root and information from table below will be lost, Continue?]]></string>
+</resources>

+ 35 - 0
modules/boonex/dolphin_migration/updates/9.0.4_9.0.5/source/install/sql/enable.sql

@@ -0,0 +1,35 @@
+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', '', '', '', 1),
+('bx_dolphin_migration_overwrite', '', @iCategId, '_bx_dolphin_migration_cpt_overwrite', 'checkbox', '', '', '', 2),
+('bx_dolphin_migration_use_nickname', '', @iCategId, '_bx_dolphin_migration_cpt_use_nickname', 'checkbox', '', '', '', 3),
+('bx_dolphin_migration_empty_albums', 'on', @iCategId, '_bx_dolphin_migration_cpt_empty_albums', 'checkbox', '', '', '', 4),
+('bx_dolphin_migration_default_privacy', '3', @iCategId, '_bx_dolphin_migration_cpt_default_privacy', 'select', '', '', 'a:2:{s:6:"module";s:20:"bx_dolphin_migration";s:6:"method";s:18:"get_privacy_groups";}', 5);
+
+-- 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);