HEX
Server: nginx/1.18.0
System: Linux test-ipsremont 5.4.0-214-generic #234-Ubuntu SMP Fri Mar 14 23:50:27 UTC 2025 x86_64
User: ips (1000)
PHP: 8.0.30
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /var/www/limestate-api/Models/Sync.php
<?php

class Sync extends Db_Model {
    static $strict = false;

    public static function numLine( $i, $string ) {
        Output::rewrite( ' - ' . ( $i + 1 ) . '. ' . $string );
    }

    public static function complexes() {
        Complex::update( [
            'published' => 0,
        ], null );

        $updated   = $created = 0;
        $complexes = BitrixApi::getComplexes();

        Output::title( 'Синхронизируем данные по комплексам' );
        Output::write( 'Найдено: ' . $complexes->totalCount );

        Output::write( '' );
        foreach ( $complexes->objects as $i => $complex ) {
            self::numLine($i, 'ищем запись');
            $complexRecord = Complex::getByOldId($complex->ID);

            $name = strip_tags($complex->name);
            Output::write($name);
            Output::write('');
            self::numLine($i, 'получаем имя');


            $beautification = unserialize($complex->beautification);
            if (is_array($beautification)) {
                $beautification = strip_tags($beautification['TEXT']);
                $beautification = empty($beautification) ? '' : Typograf::clear($beautification);
            } else {
                $beautification = '';
            }
            self::numLine( $i, 'получаем благоустройство' );

            $infrastructure = unserialize( $complex->infrastructure );
            if (is_array($infrastructure)) {
                $infrastructure = strip_tags($infrastructure['TEXT']);
                $infrastructure = empty($infrastructure) ? '' : Typograf::clear($infrastructure);
            } else {
                $infrastructure = '';
            }
            self::numLine( $i, 'получаем инфраструктуру' );

            $metroId = self::getMetroId($complex->station);
            $cityDistrictId = self::getCityDistrictId($complex->city_district);
            $developerId = self::getDeveloperId($complex->developer);

            $isCompleted = 0;
            if ( $complex->deadline == 'сдан' ) {
                $isCompleted = 1;
            } else {
                if ( is_numeric( $complex->deadline ) && is_numeric( $complex->quarter ) ) {
                    $currentQuarter = ceil( date( 'n' ) / 3 );
                    if ( date( 'Y' ) > $complex->deadline ||
                         ( $currentQuarter > $complex->quarter && date( 'Y' ) == $complex->deadline ) ) {
                        $isCompleted = 1;
                    }
                }
            }

            $complexData = [
                'old_ID'            => $complex->ID,
                'name'              => $name,
                'alias'             => $complex->code,
                'description'       => Typograf::clear( $complex->description ),
                'beautification'    => $beautification,
                'infrastructure'    => $infrastructure,
                'city_district_id'  => $cityDistrictId,
                'metro_id'          => $metroId,
                'developer_id'      => $developerId,
                'completed_year'    => is_numeric( $complex->deadline ) ? $complex->deadline : null,
                'completed_quarter' => is_numeric( $complex->quarter ) ? $complex->quarter : null,
                'is_completed'      => $isCompleted,
                'latlng'            => $complex->coord,
                'published'         => 1,
                'category_id'       => 1, // Элитная недвижимость
                'city_id'           => 1,
                'region_id'         => 1
            ];

            if ( $complexRecord ) {
                self::numLine( $i, 'обновляем запись' );
                $complexId = $complexRecord->id;
                Complex::update($complexData , [
                    'id' => $complexId
                ] );
                $updated ++;
            } else {
                self::numLine( $i, 'создаём запись' );
                $complexId = Complex::create($complexData);
                $created ++;
            }

            // StreetName
            ComplexStreets::rewrite($complex->address, $complexId);

            // Gallery
            $bitrixData = BitrixApi::getComplex( $complex->ID );
            self::numLine( $i, 'обновляем галерею' );
            //Attachment::clear('Complex', $complexId, 'photo');
            $ids = [];
            if ( ! empty( $bitrixData ) ) {
                $gallery = self::fixUrl($bitrixData->gallery_huge);
            } else {
                $gallery = [];
            }
            foreach ( $gallery as $url ) {
                $attachmentId = Attachment::getId( $url, 'Complex', $complexId );
                $pathInfo     = pathinfo( $url );
                if ( empty( $attachmentId ) ) {
                    $attachmentId = Attachment::createWithThumbnail([
                        'file'              => $url,
                        'file_type'         => 'photo',
                        'attachable_id'     => $complexId,
                        'attachable_type'   => 'Complex',
                        'original_filename' => $pathInfo['basename'],
                        'created_at'        => date( 'Y-m-d H:i:s' ),
                        'is_external'       => 1
                    ] );
                }
                $ids[] = $attachmentId;
            }
            Attachment::clearWithout('Complex', $complexId, 'photo', $ids);
        }

        Output::rewrite( '' );

        Output::write( 'обновлены: ' . $updated );
        Output::write( 'созданы: ' . $created );
        Output::success( 'данные успешно синхронизированы' );
    }

    public static function fixUrl($url) {
        $url = str_replace('https://limestate.ru', 'https://bitrix.limestate.ru', $url);
        $url = str_replace('http://limestate.ru', 'https://bitrix.limestate.ru', $url);

        return $url;
    }

    public static function buildings($complexId = null) {

        $toFlush = [
            'category_id' => 1,
            'published' => 1,
        ];

        if (!empty($complexId)) {
            $toFlush['complex_id'] = $complexId;
        }

        Building::update( [
            'published' => 0
        ], $toFlush );

        Output::title( 'Синхронизируем данные по домам' );

        $complexes = Complex::$db->select('id', 'name', 'old_ID')->from(Complex::$table_name . ' c')
            ->where('published = ?', 1);

        if (!empty($complexId)) {
            $complexes->where('c.id = ?', $complexId);
        }

        $complexes = $complexes->fetchAll();
        Output::write( 'Комплексов: ' . count($complexes));
        Output::write( '' );

        $updated   = $created = 0;
        foreach($complexes as $complex) {
            Output::log($complex->name . '(' . $complex->old_ID . ')');
            $buildings = BitrixApi::getBuildings($complex->old_ID);

            Output::write( 'Найдено: ' . count($buildings));

            Output::write( '' );
            $i = 1;
            $buildingsList = [];
            foreach ( $buildings as $building ) {
                self::numLine( $i, 'ищем запись' );
                $buildingRecord = Building::getByOldId( $building->id );

                $metroId = self::getMetroId($building->metro);
                $cityDistrictId = self::getCityDistrictId($building->city_district);
                $developerId = self::getDeveloperId($building->developer);
                $streetTypeId = self::getStreetTypeId($building->street_type);
                $finishingTypeId = self::getFinishingTypeId($building->finishing_type);
                $houseTypeId = self::getHouseTypeId($building->house_type);

                $isCompleted = 0;
                if ( mb_strtolower(trim($building->completed_year)) == 'сдан' || $building->completed_year == 'cдан') {
                    $isCompleted = 1;
                    $building->completed_year = null;
                    $building->completed_quarter = null;
                } else {
                    if ( is_numeric( $building->completed_year ) && is_numeric( $building->completed_quarter ) ) {
                        $currentQuarter = ceil( date( 'n' ) / 3 );
                        if ( date( 'Y' ) > $building->completed_year ||
                             ( $currentQuarter > $building->completed_quarter && date( 'Y' ) == $building->completed_year ) ) {
                            $isCompleted = 1;
                        }
                    }
                }

                $floors = array_map(function($item) {
                    return (int)$item;
                }, explode('-', $building->floors));

                $maxFloor = count($floors) > 1 ? max($floors) : $floors[0];

                $buildingData = [
                    'name' => $building->name,
                    'alias' => Helper::puntoSwitcher( $building->name, 'T->eng' ),
                    'old_ID' => $building->id,
                    'street_name' => $building->street_name,
                    'floors' => $maxFloor,
                    'floors_info' => $building->floors ?? '',
                    'region_id' => 1,
                    'metro_id' => $metroId,
                    'city_id' => 1,
                    'city_district_id' => $cityDistrictId,
                    'started_year' => (int)$building->started_year,
                    'started_quarter' => (int)$building->started_quarter,
                    'is_completed' => (int)$isCompleted,
                    'completed_year' => (int)$building->completed_year,
                    'completed_quarter' => (int)$building->completed_quarter,
                    'developer_id' => (int)$developerId,
                    'complex_id' => (int)$complex->id,
                    'latlng' => $building->latlng,
                    'housing_number' => $building->housing_number,
                    'category_id' => 1,  // Элитная недвижимость
                    'street_type_id' => $streetTypeId,
                    'flats_count' => $building->flats_count,
                    'rooms_count' => $building->rooms_count,
                    'finishing_type_id' => $finishingTypeId,
                    'house_type_id' => $houseTypeId,
                    'published' => (int)($building->active == 'Y'),
                    'block_number' => $building->block_number ? $building->block_number : 1,
                ];

                if ( $buildingRecord ) {
                    self::numLine( $i, 'обновляем запись' );
                    $buildingData['updated_at'] = date('Y-m-d H:i:s');
                    $buildingId = $buildingRecord->id;
                    Building::update($buildingData , [
                        'id' => $buildingId
                    ] );
                    $updated++;
                } else {
                    self::numLine( $i, 'создаём запись' );
                    $buildingData['updated_at'] = date('Y-m-d H:i:s');
                    $buildingData['created_at'] = date('Y-m-d H:i:s');
                    $buildingId = Building::create($buildingData);
                    $created++;
                }

                $buildingsList[] = $buildingId;

                $buildingRawData = BitrixApi::getBuilding($buildingData['old_ID']);
                // Floors plans
                //Attachment::clear('Building', $buildingId, 'floor-plan');
                $ids = [];
                if (!empty($buildingRawData[0]->floors_plans)) {
                    foreach($buildingRawData[0]->floors_plans as $floorNumber => $url) {
                        $attachmentId = Attachment::getId( $url, 'Building', $buildingId );
                        if ( empty( $attachmentId ) ) {
                            $attachmentId = Attachment::create( [
                                'file'              => $url,
                                'file_type'         => 'floor-plan',
                                'attachable_id'     => $buildingId,
                                'attachable_type'   => 'Building',
                                'original_filename' => $floorNumber,
                                'created_at'        => date( 'Y-m-d H:i:s' ),
                                'is_external'       => 1
                            ] );
                        }

                        $ids[] = $attachmentId;
                    }
                }
                Attachment::clearWithout('Building', $buildingId, 'floor-plan', $ids);

                //Attachment::clear('Building', $buildingId, 'photo');
                $ids = [];
                if (!empty($buildingRawData[0]->gallery_huge)) {
                    foreach($buildingRawData[0]->gallery_huge as $url) {
                        $attachmentId = Attachment::getId( $url, 'Building', $buildingId );
                        $pathInfo = pathinfo( $url );
                        if ( empty( $attachmentId ) ) {
                            $attachmentId = Attachment::createWithThumbnail([
                                'file'              => $url,
                                'file_type'         => 'photo',
                                'attachable_id'     => $buildingId,
                                'attachable_type'   => 'Building',
                                'original_filename' => $pathInfo['basename'],
                                'created_at'        => date( 'Y-m-d H:i:s' ),
                                'is_external'       => 1
                            ] );
                        }

                        $ids[] = $attachmentId;
                    }
                }
                Attachment::clearWithout('Building', $buildingId, 'photo', $ids);

                $i++;
            }

            if (!empty($buildingsList)) {
                Building::$db->query( 'DELETE FROM ' . Building::$table_name
                  . ' WHERE complex_id = ' . $complex->id
                  . ' AND id NOT IN (' . implode(',', $buildingsList) . ')');
            } else {
                Building::$db->delete(Building::$table_name, [
                    'complex_id' => $complex->id
                ]);
            }
        }

        Output::rewrite( '' );

        Output::write( 'обновлены: ' . $updated );
        Output::write( 'созданы: ' . $created );
        Output::success( 'данные успешно синхронизированы' );
    }

    public static function usedBuildings() {
        $toFlush = [
            'published' => 1,
            'category_id' => 2,
            'complex_id' => 0
        ];

        Building::update( [
            'published' => 0
        ], $toFlush );

        Output::title( 'Синхронизируем данные по домам вторички' );

        $buildings = BitrixApi::getUsedBuildings();

        Output::write( 'Найдено: ' . count($buildings));
        $updated = $created = 0;

        Output::write( '' );
        $i = 1;
        foreach ( $buildings as $building ) {
            self::numLine( $i, 'ищем запись' );
            $buildingRecord = Building::getByOldId( $building->id );

            $metroId = self::getMetroId($building->metro);
            $cityDistrictId = self::getCityDistrictId($building->city_district);
            $developerId = self::getDeveloperId($building->developer);
            $streetTypeId = self::getStreetTypeId($building->street_type);
            $finishingTypeId = self::getFinishingTypeId($building->finishing_type);
            $houseTypeId = self::getHouseTypeId($building->house_type);

            $isCompleted = 0;
            if ( trim($building->completed_year) == 'сдан' || $building->completed_year == 'cдан') {
                $isCompleted = 1;
                $building->completed_year = null;
                $building->completed_quarter = null;
            } else {
                if ( is_numeric( $building->completed_year ) && is_numeric( $building->completed_quarter ) ) {
                    $currentQuarter = ceil( date( 'n' ) / 3 );
                    if ( date( 'Y' ) > $building->completed_year ||
                         ( $currentQuarter > $building->completed_quarter && date( 'Y' ) == $building->completed_year ) ) {
                        $isCompleted = 1;
                    }
                }
            }

            $floors = array_map(function($item) {
                return (int)$item;
            }, explode('-', $building->floors));

            $maxFloor = count($floors) > 1 ? max($floors) : $floors[0];

            $buildingData = [
                'name' => $building->name,
                'alias' => Helper::puntoSwitcher( $building->name, 'T->eng' ),
                'old_ID' => $building->id,
                'street_name' => $building->street_name,
                'floors' => $maxFloor,
                'floors_info' => $building->floors ?? '',
                'region_id' => 1,
                'metro_id' => $metroId,
                'city_id' => 1,
                'city_district_id' => $cityDistrictId,
                'started_year' => $building->started_year,
                'started_quarter' => $building->started_quarter,
                'is_completed' => $isCompleted,
                'completed_year' => (int)$building->completed_year,
                'completed_quarter' => (int)$building->completed_quarter,
                'developer_id' => $developerId,
                'complex_id' => 0,
                'latlng' => $building->latlng,
                'housing_number' => $building->housing_number,
                'category_id' => 2,  // Вторичная недвижимость
                'street_type_id' => $streetTypeId,
                'flats_count' => $building->flats_count,
                'rooms_count' => $building->rooms_count,
                'finishing_type_id' => $finishingTypeId,
                'house_type_id' => $houseTypeId,
                'published' => 1,
                'block_number' => 1
            ];

            if ( $buildingRecord ) {
                self::numLine( $i, 'обновляем запись' );
                $buildingData['updated_at'] = date('Y-m-d H:i:s');
                $buildingId = $buildingRecord->id;
                Building::update($buildingData , [
                    'id' => $buildingId
                ] );
                $updated++;
            } else {
                self::numLine( $i, 'создаём запись' );
                $buildingData['updated_at'] = date('Y-m-d H:i:s');
                $buildingData['created_at'] = date('Y-m-d H:i:s');
                $buildingId = Building::create($buildingData);
                $created++;
            }

            $i++;
        }

        Output::rewrite( '' );

        Output::write( 'обновлены: ' . $updated );
        Output::write( 'созданы: ' . $created );
        Output::success( 'данные успешно синхронизированы' );
    }

    public static function flats($buildingId = null) {
        $toFlush = [
            'published' => 1,
        ];

        if (!empty($buildingId)) {
            $toFlush['building_id'] = $buildingId;
        }

        Flat::update( [
            'published' => 0,
        ], $toFlush );

        Output::title( 'Синхронизируем данные по квартирам' );

        $buildingsSql = Building::$db->select('id', 'name', 'old_ID')->from(Building::$table_name . ' c')
             ->where('published = ?', 1);

        if (!empty($buildingId)) {
            $buildingsSql->where('id = ?', $buildingId);
        }

        $buildings = $buildingsSql->fetchAll();

        $updated   = $created = 0;
        foreach($buildings as $building) {
            Output::log($building->name . '(' . $building->old_ID . ')');
            $flats = BitrixApi::getFlats($building->old_ID);

            Output::write( 'Найдено: ' . count($flats));

            Output::write( '' );
            $i = 1;
            foreach ( $flats as $flat ) {
                self::numLine( $i, 'ищем запись' );
                $flatRecord = Flat::getByOldId( $flat->ID );

                $rooms = (int)$flat->rooms;
                $floor = (int)$flat->floor;

                $flatData = [
                    'alias' => 0,
                    'old_ID' => $flat->ID,
                    'alias' => $floor . '-' . $rooms . '-' . $flat->number,
                    'floor' => $floor,
                    'rooms' => $rooms,
                    'total_area' => $flat->total_area,
                    'living_area' => $flat->living_area,
                    'rooms_area' => self::sumString($flat->rooms_area),
                    'kitchen_area' => $flat->kitchen_area,
                    'number' => $flat->number,
                    'price' => $flat->price,
                    'base_price' => $flat->base_price,
                    'building_id' => $building->id,
                    'balcony_type_id' => BalconyType::getId($flat->balcony),
                    'bathroom_type_id' => BathroomType::getId($flat->bathroom),
                    'view_type_id' => ViewType::getId($flat->view),
                    'assignment' => (int)$flat->assignments,
                    'contractor' => (int)$flat->contractor,
                    'old_ID' => $flat->ID,
                    'published' => 1,
                    'description' => $flat->description ?: $flat->text,
                ];

                if ( $flatRecord ) {
                    self::numLine( $i, 'обновляем запись' );
                    $flatData['updated_at'] = date('Y-m-d H:i:s');
                    $flatId = $flatRecord->id;
                    Flat::update($flatData , [
                        'id' => $flatId
                    ] );
                    $updated++;
                } else {
                    self::numLine( $i, 'создаём запись' );
                    $flatData['updated_at'] = date('Y-m-d H:i:s');
                    $flatData['created_at'] = date('Y-m-d H:i:s');
                    $flatId = Flat::create($flatData);
                    $created++;
                }

                //Options
                $options = !empty($flat->options) ? explode(',', $flat->options) : [];
                FlatOptionRelation::clear($flatId);
                foreach($options as $option) {
                    $optionId = FlatOption::getId($option);
                    if (!empty($optionId)) {
                        FlatOptionRelation::create( [
                            'flat_id'   => $flatId,
                            'option_id' => $optionId
                        ] );
                    }
                }

                // Gallery
                $bitrixData = BitrixApi::getFlat( $flat->ID );

                self::numLine( $i, 'обновляем галерею' );

                if ( !empty($bitrixData) && !empty($bitrixData->flat_gallery_huge)) {
                    $gallery = $bitrixData->flat_gallery_huge;
                } else {
                    $gallery = [];
                }
                $ids = [];
                foreach ( $gallery as $url ) {
                    $attachmentId = Attachment::getId( $url, 'Flat', $flatId );
                    $pathInfo     = pathinfo( $url );
                    if ( empty( $attachmentId ) ) {
                        $attachmentId = Attachment::createWithThumbnail([
                            'file'              => $url,
                            'file_type'         => 'photo',
                            'attachable_id'     => $flatId,
                            'attachable_type'   => 'Flat',
                            'original_filename' => $pathInfo['basename'],
                            'created_at'        => date( 'Y-m-d H:i:s' ),
                            'is_external'       => 1
                        ]);
                    }
                    $ids[] = $attachmentId;
                }
                Attachment::clearWithout('Flat', $flatId, 'photo', $ids);

                // Floor plan
                //Attachment::clear('Flat', $flatId, 'floor-plan');
                $ids = [];
                if (!empty($flat->floor_plan)) {
                    $url = 'http://bitrix.limestate.ru/upload/' . $flat->floor_plan;
                    $attachmentId = Attachment::getId( $url, 'Flat', $flatId );
                    $pathInfo     = pathinfo( $url );
                    if ( empty( $attachmentId ) ) {
                        $attachmentId = Attachment::createWithThumbnail([
                            'file'              => $url,
                            'file_type'         => 'floor-plan',
                            'attachable_id'     => $flatId,
                            'attachable_type'   => 'Flat',
                            'original_filename' => $pathInfo['basename'],
                            'created_at'        => date( 'Y-m-d H:i:s' ),
                            'is_external'       => 1
                        ] );
                    }
                }
                Attachment::clearWithout('Flat', $flatId, 'floor-plan', $ids);

                // Plan
                //Attachment::clear('Flat', $flatId, 'plan');
                $ids = [];
                if (!empty( $flat->plan)) {
                    $url = 'http://bitrix.limestate.ru/upload/' . $flat->plan;
                    $attachmentId = Attachment::getId( $url, 'Flat', $flatId );
                    $pathInfo     = pathinfo( $url );
                    if ( empty( $attachmentId ) ) {
                        $attachmentId = Attachment::createWithThumbnail([
                            'file'              => $url,
                            'file_type'         => 'plan',
                            'attachable_id'     => $flatId,
                            'attachable_type'   => 'Flat',
                            'original_filename' => $pathInfo['basename'],
                            'created_at'        => date( 'Y-m-d H:i:s' ),
                            'is_external'       => 1
                        ] );
                    }
                    $ids[] = $attachmentId;
                }
                Attachment::clearWithout('Flat', $flatId, 'plan', $ids);

                $i++;
            }
        }

        Output::rewrite( '' );

        Output::write( 'обновлены: ' . $updated );
        Output::write( 'созданы: ' . $created );
        Output::success( 'данные успешно синхронизированы' );
    }

    public static function getMetroId($stationName){
        $metroId = Metro::getId( trim($stationName) );
        if ( empty( $metroId ) && !empty( $stationName ) ) {
            if ( self::$strict ) {
                Output::log( $stationName . ' – неизвесная станция метро' );
                die( '!' );
            } else {
                $metroId = 0;
            }
        }

        return $metroId;
    }

    public static function getCityDistrictId($cityDistrict){
        $cityDistrictId = CityDistricts::getId($cityDistrict);

        if ( empty( $cityDistrictId ) ) {
            if ( self::$strict && ! empty( $cityDistrict ) ) {
                Output::error( $cityDistrict . ' – неизвесный район' );
                die( '!' );
            } else {
                $cityDistrictId = 0;
            }
        }

        return $cityDistrictId;
    }

    public static function getDeveloperId($developer) {
        $developerId = Developer::getId( $developer );
        if ( empty($developerId)) {
            if (!empty($developer)) {
                $developerId = Developer::create([
                    'name' => $developer,
                    'created_at' => date('Y-m-d H:i:s')
                ]);
            } else {
                $developerId = 0;
            }
        }

        return $developerId;
    }

    public static function getStreetTypeId($streetType) {
        $streetTypeId = StreetType::getId( $streetType );
        return $streetTypeId;
    }

    public static function getFinishingTypeId($finishingType) {
        $finishingTypeId = FinishingType::getId( $finishingType );
        return $finishingTypeId;
    }

    public static function getHouseTypeId($houseType) {
        $houseTypeId = HouseType::getId( $houseType );
        return $houseTypeId;
    }

    public static function sumString($string) {
        $arr = explode('+', $string);
        return array_sum($arr);
    }

    public static function prepareSync() {
        global $CFG;
        Output::log('Preparing migration ');
        $cmd = 'mysqldump -u ' . $CFG->db['write']['username'] . ' -p' . $CFG->db['write']['password']
            . (!empty($CFG->db['write']['port']) ? (' -P ' . $CFG->db['write']['port']) : '')
            . (!empty($CFG->db['write']['host']) ? (' -h ' . $CFG->db['write']['host']) : '')
            . ' --add-drop-table ' . $CFG->db['write']['database'] . ' | gzip > sync_dump.sql.gz';
        Output::write($cmd);

        exec($cmd);
        $cmd2 = 'gunzip < sync_dump.sql.gz | mysql -u ' . $CFG->temp_db['write']['username'] . ' -p' . $CFG->temp_db['write']['password']
            . (!empty($CFG->temp_db['write']['port']) ? ' -P ' . $CFG->temp_db['write']['port'] : '')
            . (!empty($CFG->temp_db['write']['host']) ? ' -h ' . $CFG->temp_db['write']['host'] : '')
            . ' ' . $CFG->temp_db['write']['database'];

        Output::write($cmd2);

        exec($cmd2);
        Db_Model::$db->init($CFG->temp_db);
        Output::success('Preparing migration: complete');
    }

    public static function completeSync() {
        global $CFG;
        Output::log('Completing migration ');
        Db_Model::$db->init($CFG->db);
        $cmd = 'mysqldump -u ' . $CFG->temp_db['write']['username'] . ' -p' . $CFG->temp_db['write']['password']
            . (!empty($CFG->temp_db['write']['port']) ? (' -P ' . $CFG->temp_db['write']['port']) : '')
            . (!empty($CFG->temp_db['write']['host']) ? (' -h ' . $CFG->temp_db['write']['host']) : '')
            . ' --add-drop-table ' . $CFG->temp_db['write']['database'] . ' | gzip > complete_dump.sql.gz';
        Output::write($cmd);
        exec($cmd);
        $cmd2 = 'gunzip < complete_dump.sql.gz | mysql -u ' . $CFG->db['write']['username'] . ' -p' . $CFG->db['write']['password']
            . (!empty($CFG->db['write']['port']) ? ' -P ' . $CFG->db['write']['port'] : '')
            . (!empty($CFG->db['write']['host']) ? ' -h ' . $CFG->db['write']['host'] : '')
            . ' ' . $CFG->db['write']['database'];
        Output::write($cmd2);
        exec($cmd2);
        Output::success('Completing migration: complete');
    }

    public static function failNotify($e) {
        Output::error($e->getMessage());
        exit;
    }
}