<?php

class MainWP_BackUp_WordPress_DB {

	private $mainwp_backup_wp_db_version = '1.3';
	private $table_prefix;
	//Singleton
	private static $instance = null;

	static function get_instance() {
		if ( null == MainWP_BackUp_WordPress_DB::$instance ) {
			MainWP_BackUp_WordPress_DB::$instance = new MainWP_BackUp_WordPress_DB();
		}
		return MainWP_BackUp_WordPress_DB::$instance;
	}

	//Constructor
	function __construct() {
		global $wpdb;
		$this->table_prefix = $wpdb->prefix . 'mainwp_';
	}

	function table_name( $suffix ) {
		return $this->table_prefix . $suffix;
	}

	//Support old & new versions of wordpress (3.9+)
	public static function use_mysqli() {
		/** @var $wpdb wpdb */
		if ( ! function_exists( 'mysqli_connect' ) ) {
			return false; }

		global $wpdb;
		return ($wpdb->dbh instanceof mysqli);
	}

	//Installs new DB
	function install() {
		global $wpdb;
		$currentVersion = get_site_option( 'mainwp_backup_wp_db_version' );
		if ( $currentVersion == $this->mainwp_backup_wp_db_version ) {
			return; }

		$charset_collate = $wpdb->get_charset_collate();
		$sql = array();

		$tbl = 'CREATE TABLE `' . $this->table_name( 'backupwordpress' ) . '` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`site_id` int(11) NOT NULL,
`is_premium` tinyint(1) NOT NULL DEFAULT 0,
`lasttime_backup` int(11) NOT NULL,
`backups_path` text NOT NULL,
`schedules` longtext NOT NULL DEFAULT "",
`override` tinyint(1) NOT NULL DEFAULT 0';
		if ( '' == $currentVersion ) {
			$tbl .= ',
PRIMARY KEY  (`id`)  '; }
		$tbl .= ') ' . $charset_collate;
		$sql[] = $tbl;

		require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
		foreach ( $sql as $query ) {
			dbDelta( $query );
		}

		//        global $wpdb;
		//        echo $wpdb->last_error;
		//        exit();
		update_option( 'mainwp_backup_wp_db_version', $this->mainwp_backup_wp_db_version );
	}

	public function update_backupwp_schedule( $site_id, $schedule_id, $data ) {
		if ( empty( $site_id ) || empty( $schedule_id ) || ! is_array( $data ) ) {
			return false;
		} else {
			$current = $this->get_backupwp_by( 'site_id', $site_id );
		}

		if ( empty( $current ) ) {
			$current_schedules = $value = array();
		} else {
			$current_schedules = unserialize( base64_decode( $current->schedules ) );
			if ( ! is_array( $current_schedules ) ) {
				$current_schedules = $value = array();
			} else {
				$value = isset( $current_schedules[ $schedule_id ] ) ? $current_schedules[ $schedule_id ] : array();
				if ( ! is_array( $value ) ) {
					$value = array(); }
			}
		}

		MainWP_BackUp_WordPress::get_instance()->map_data_fields( $value, $data );

		$current_schedules[ $schedule_id ] = $value;

		return $this->update_backupwp(array(
			'site_id' => $site_id,
					'schedules' => base64_encode( serialize( $current_schedules ) ),
		));
	}

	public function sync_backupwp_schedule($site_id, $schedule_ids = array()) {
//		if (!is_array($schedule_ids) || count($schedule_ids) == 0)
//			return;
//		$current = $this->get_backupwp_by( 'site_id', $site_id );
//
//		if ( empty( $current ) ) {
//			return true;
//		}
//
//		$schedules = unserialize( base64_decode( $current->schedules ) );
//
//		error_log(print_r($schedule_ids, true));
//		error_log(print_r($schedules, true));
//
//
//		if ( ! is_array( $schedules ) ) {
//			return true;
//		}
//		$new_schedules = array();
//		foreach ($schedules as $sch_id => $sch) {
//			if (in_array($sch_id, $schedule_ids))
//				$new_schedules[$sch_id] = $sch;
//		}
//		$update = array(
//			'site_id' => $site_id,
//			'schedules' => base64_encode( serialize( $new_schedules ) ),
//		);
//		return $this->update_backupwp( $update );
	}

	public function delete_backup_schedule( $site_id, $schedule_id ) {
		if ( empty( $site_id ) || empty( $schedule_id ) ) {
			return false; }

		$current = $this->get_backupwp_by( 'site_id', $site_id );

		if ( empty( $current ) ) {
			return true; }

		$schedules = unserialize( base64_decode( $current->schedules ) );
		if ( ! is_array( $schedules ) || ! isset( $schedules[ $schedule_id ] ) ) {
			return true; }

		unset( $schedules[ $schedule_id ] );
		$update = array(
		'site_id' => $site_id,
			'schedules' => base64_encode( serialize( $schedules ) ),
		);
		return $this->update_backupwp( $update );
	}


	public function delete_schedule_data_of_site( $site_id, $data_fields ) {
		if ( empty( $site_id ) ) {
			return false; }

		$current = $this->get_backupwp_by( 'site_id', $site_id );

		if ( empty( $current ) ) {
			return true; }

		$schedules = unserialize( base64_decode( $current->schedules ) );
		if ( ! is_array( $schedules ) ) {
			return true; }

		if ( 'backups_html' == $data_fields ) { // to support delete backups_html data only
			foreach ( $schedules as $schedule_id => $sch_data ) {
				$schedules[ $schedule_id ]['backups_html'] = '';
				$schedules[ $schedule_id ]['backups_count'] = 0;
			}
		}

		$update = array(
		'site_id' => $site_id,
			'schedules' => base64_encode( serialize( $schedules ) ),
		);
		return $this->update_backupwp( $update );
	}

	public function delete_backupwp( $by = 'id', $value = null ) {
		global $wpdb;
		if ( empty( $by ) ) {
			return null; }
		$sql = '';
		if ( 'id' == $by ) {
			$sql = $wpdb->prepare( 'DELETE FROM ' . $this->table_name( 'backupwordpress' ) . ' WHERE `id`=%d ', $value );
		} else if ( 'site_id' == $by ) {
			$sql = $wpdb->prepare( 'DELETE FROM ' . $this->table_name( 'backupwordpress' ) . ' WHERE `site_id` = %d ', $value );
		}

		if ( ! empty( $sql ) ) {
			$wpdb->query( $sql ); }

		return true;
	}

	public function update_backupwp( $setting ) {
		/** @var $wpdb wpdb */
		global $wpdb;
		$id = isset( $setting['id'] ) ? $setting['id'] : 0;
		$site_id = isset( $setting['site_id'] ) ? $setting['site_id'] : 0;

		if ( $id ) {
			if ( $wpdb->update( $this->table_name( 'backupwordpress' ), $setting, array( 'id' => intval( $id ) ) ) ) {
				return $this->get_backupwp_by( 'id', $id ); }
		} else if ( $site_id ) {
			$current = $this->get_backupwp_by( 'site_id', $site_id );
			if ( $current ) {
				if ( $wpdb->update( $this->table_name( 'backupwordpress' ), $setting, array( 'site_id' => intval( $site_id ) ) ) ) {
					return $this->get_backupwp_by( 'site_id', $site_id );
				}
			} else {
				if ( $wpdb->insert( $this->table_name( 'backupwordpress' ), $setting ) ) {
					return $this->get_backupwp_by( 'id', $wpdb->insert_id ); }
			}
		} else if ( $wpdb->insert( $this->table_name( 'backupwordpress' ), $setting ) ) {
			return $this->get_backupwp_by( 'id', $wpdb->insert_id );
		}
		return false;
	}

	public function get_backupwp_by( $by = 'id', $value = null, $fields = '', $output = OBJECT ) {
		global $wpdb;

		if ( empty( $by ) || empty( $value ) ) {
			return null; }

		if ( empty( $fields ) ) {
			$fields = '*'; }

		$sql = '';
		if ( 'id' == $by ) {
			$sql = $wpdb->prepare( "SELECT {$fields} FROM " . $this->table_name( 'backupwordpress' ) . ' WHERE `id`=%d ', $value );
		} else if ( 'site_id' == $by ) {
			$sql = $wpdb->prepare( "SELECT {$fields} FROM " . $this->table_name( 'backupwordpress' ) . ' WHERE `site_id` = %d ', $value );
		}

		if ( ! empty( $sql ) ) {
			return $wpdb->get_row( $sql, $output ); }

		return null;
	}

	public function get_schedules( $site_ids = array() ) {
		global $wpdb;
		$str_ids = '';
		if ( is_array( $site_ids ) && count( $site_ids ) > 0 ) {
			$str_ids = implode( ',', $site_ids );
		}
		
		if ( ! empty( $str_ids ) ) {
			$sql = 'SELECT * FROM ' . $this->table_name( 'backupwordpress' ) . ' WHERE `site_id` IN (' . $str_ids . ') '; 			
		} else { 			
			$sql = 'SELECT * FROM ' . $this->table_name( 'backupwordpress' ) . ' WHERE 1 '; 				
		}
		
		return $wpdb->get_results( $sql );
	}

	public function get_backups( $site_ids = array() ) {
		$backupwps = $this->get_schedules( $site_ids );
		if ( count( $backupwps ) > 0 ) {
			$return = array();
			foreach ( $backupwps as $backupwp ) {

				$schedules = unserialize( base64_decode( $backupwp->schedules ) );
				if ( ! is_array( $schedules ) ) {
					$schedules = array(); }
				$return[ $backupwp->site_id ] = $schedules;
			}
			return $return;
		}
		return array();
	}

	public function get_backupwps_data( $site_ids = array() ) {
		$backupwps = $this->get_schedules( $site_ids );
		if ( count( $backupwps ) > 0 ) {
			$return = array();
			foreach ( $backupwps as $backupwp ) {
				$data = array();
				//$scheduled['is_premium'] = $backupwp->is_premium;
				$data['override'] = $backupwp->override;
				$data['lastbackup_gmttime'] = $backupwp->lasttime_backup;
				$return[ $backupwp->site_id ] = $data;
			}
			return $return;
		}
		return array();
	}

	protected function escape( $data ) {
		/** @var $wpdb wpdb */
		global $wpdb;
		if ( function_exists( 'esc_sql' ) ) {
			return esc_sql( $data ); } else { 			return $wpdb->escape( $data ); }
	}

	public function query( $sql ) {
		if ( null == $sql ) {
			return false; }
		/** @var $wpdb wpdb */
		global $wpdb;
		$result = @self::_query( $sql, $wpdb->dbh );

		if ( ! $result || (@self::num_rows( $result ) == 0) ) {
			return false; }
		return $result;
	}

	public static function _query( $query, $link ) {
		if ( self::use_mysqli() ) {
			return mysqli_query( $link, $query );
		} else {
			return mysql_query( $query, $link );
		}
	}

	public static function fetch_object( $result ) {
		if ( self::use_mysqli() ) {
			return mysqli_fetch_object( $result );
		} else {
			return mysql_fetch_object( $result );
		}
	}

	public static function free_result( $result ) {
		if ( self::use_mysqli() ) {
			return mysqli_free_result( $result );
		} else {
			return mysql_free_result( $result );
		}
	}

	public static function data_seek( $result, $offset ) {
		if ( self::use_mysqli() ) {
			return mysqli_data_seek( $result, $offset );
		} else {
			return mysql_data_seek( $result, $offset );
		}
	}

	public static function fetch_array( $result, $result_type = null ) {
		if ( self::use_mysqli() ) {
			return mysqli_fetch_array( $result, (null == $result_type ? MYSQLI_BOTH : $result_type) );
		} else {
			return mysql_fetch_array( $result, (null == $result_type ? MYSQL_BOTH : $result_type) );
		}
	}

	public static function num_rows( $result ) {
		if ( self::use_mysqli() ) {
			return mysqli_num_rows( $result );
		} else {
			return mysql_num_rows( $result );
		}
	}

	public static function is_result( $result ) {
		if ( self::use_mysqli() ) {
			return ($result instanceof mysqli_result);
		} else {
			return is_resource( $result );
		}
	}

	public function get_results_result( $sql ) {
		if ( null == $sql ) {
			return null; }
		/** @var $wpdb wpdb */
		global $wpdb;
		return $wpdb->get_results( $sql, OBJECT_K );
	}
}
