<?php
if (!defined('SECRET_KEY')){ header("HTTP/1.0 404 Not Found"); exit; }

###
### General DB class
###

if ( !class_exists('recipeDB') ) :

### Default Settings
require_once('config.php');

class recipeDB {

	var $rSdb;
	var $connection		= false;
	var $_version 		= '1.4.3'; // check also lib-recipe-core-class.php, lib-db-class.php, lib-iphone-class.php
	var $_version_check	= false;
	var $_upateErr      = false;

	var $prefix;
    var $DBrecipes;
    var $DBobjects;

	var $all_recipies	= false;
    var $emails 		= false;

    var $last_error 	= '';

	### Init
	function recipeDB() {
		global $table_prefix, $user;

        $this->connection = @mysql_connect(DB_HOST,DB_USER,DB_PASSWORD) or $this->InitErr(__("Unable to connect to database server",'recipeshelf'));
        @mysql_select_db(DB_NAME, $this->connection) or $this->InitErr(__("Unable to select database",'recipeshelf'));

        $r = mysql_query("SET CHARACTER SET ".DB_CHARSET,$this->connection);

		$this->prefix	 = $table_prefix;
		$this->DBrecipes = $this->prefix . 'rs_recipes';
		$this->DBobjects = $this->prefix . 'rs_objects';
	}

	### Tables exist?
	function InstallCheck() {
		return ($this->fetchVal("SHOW TABLES LIKE '{$this->DBobjects}'") == $this->DBobjects);
	}

	### All db-config settings
	function dbConfigCheck() {
		if(! (defined('SECRET_KEY') && defined('NONCE_KEY') && defined('NONCE_SALT')) ){
			$msg  = '<p class="title">'.__('recipeShelf Update/Configuration Note','recipeshelf').'</p>';
			$msg .= '<p class="info">'.__('Please check your settings in <br /><strong>db-config.php</strong> <br /> and ensure that they are up-to-date and include all new settings as outlined in <br /><strong>db-config-sample.php</strong>.','recipeshelf').'</p>';
			$this->dieNOW( $msg, false, '' );
		}
	}
	
	### get rS DB Version
	function getDBVersion() {
		$sql = "SELECT object FROM {$this->DBobjects} WHERE type='version'";
		$v = $this->fetchVal($sql);
		return $v ? $v : 0;
	}
	
	### Write new DB version
	function updateDBVersion($v) {
		$v = esc_sql( $v );
		
		if( $this->getDBVersion()===0 )
			$sql = "INSERT IGNORE INTO {$this->DBobjects} (type,object) VALUES ('version','".$v."')";
		else
			$sql = "UPDATE {$this->DBobjects} SET object='".$v."' WHERE type='version'";
		$r = $this->fetch($sql);
	}
	
	### set site URL
	function setSiteURL($url) {
		if( $this->getSiteURL()===0 ){
			$v = esc_sql( (string)$url );
			$sql = "INSERT IGNORE INTO {$this->DBobjects} (type,object) VALUES ('siteurl','".$v."')";
			$r = $this->fetch($sql);
		}
	}

	### get site URL
	function getSiteURL() {
		if( defined('NEW_SITE_URL') ) ### defined in config?
			return NEW_SITE_URL;

		if( ! $this->InstallCheck() ) ### no DB yet?
			return curPageURL();
			
		$sql = "SELECT object FROM {$this->DBobjects} WHERE type='siteurl'";
		$v = $this->fetchVal($sql);
		return $v ? $v : 0;
	}


	### DB Update required?
	function VersionCheck() {
	    global $user;

		### migrate v0.9 > 1.0
		if( version_compare($this->getDBVersion(), '1.0') < 0 ) {

		    if( $user->_readonly ){
		    	$user->logout(true);
		    	$this->loginAsRoot('(-> 1.0)');
			}

		    if( isset($_POST['doneupgrade']) ){
		    	$user->logout(true);
				return;
			}

			if( !$user->_logged_in ){
		    	$this->loginAsRoot('(-> 1.0)');
			}


		    if( !isset($_POST['confirmUpgrade']) ){
		    	$this->confirmUpgrade('(-> 1.0)');
			}else{

				$results = $this->migrateDB();
				$this->migrateFaves();

				$this->updateDBVersion('1.0');
				
				$this->updateDBInfo($results);

			}
		}
		
		### add SITE URL + upgrade custom cats to DB for _nonce
		if( version_compare($this->getDBVersion(), '1.3') < 0 ) {

		    if( $user->_readonly ){
		    	$user->logout(true);
		    	$this->loginAsRoot('(-> 1.3)');
			}

		    if( isset($_POST['doneupgrade']) ){
		    	$user->logout(true);
				return;
			}

		   if( !$user->_logged_in ){
		    	$this->loginAsRoot('(-> 1.3)');
			}

		    if( !isset($_POST['confirmUpgrade']) ){
		    	$this->confirmUpgrade('(-> 1.3)');
			}else{
				### Upgrade cats
				$storedoptions = $this->get_option("recipeShelf_options");

				if( array_key_exists('rS_custom', $storedoptions) && count($storedoptions['rS_custom'])>0 ){
					foreach( array_keys($storedoptions['rS_custom']) as $k ){
						$md5k = md5($k);
						$storedoptions['rS_custom'][$md5k] = $storedoptions['rS_custom'][$k];
						unset($storedoptions['rS_custom'][$k]);
						
						###fix recipe data/references
						$sql = "UPDATE IGNORE {$this->DBrecipes} SET options=(REPLACE(options,'-{$k}-','-{$md5k}-')) WHERE options LIKE '%-{$k}-%'";
						$r = $this->fetch($sql);
					}
				}
				$this->update_option("recipeShelf_options",$storedoptions); 

				### SITEURL
				$this->setSiteURL( esc_url( curPageURL() ,false) );
				$this->updateDBVersion('1.3');

				# force logout
		    	$user->logout(true);
		    	$this->loginAsRoot('');
			}
		}
		
		### add SITE URL + upgrade custom cats to DB for _nonce
		if( version_compare($this->getDBVersion(), '1.4.3') < 0 ) {
		    if( $user->_readonly ){
		    	$user->logout(true);
		    	$this->loginAsRoot('(-> 1.4.3)');
			}

		    if( isset($_POST['doneupgrade']) ){
		    	$user->logout(true);
				return;
			}

			if( !$user->_logged_in ){
		    	$this->loginAsRoot('(-> 1.4.3)');
			}


		    if( !isset($_POST['confirmUpgrade']) ){
		    	$this->confirmUpgrade('(-> 1.4.3)');
			}else{
				
				### add full text searches
				$sql = "ALTER TABLE {$this->DBrecipes} ADD FULLTEXT (name)";
				$r = $this->fetch($sql);
				$result .= 'ALTER TABLE ADD FULLTEXT INDEX object: ' . $this->affected_rows() . $this->insertUpgradeErr($sql);
				$this->_upateErr = $this->_upateErr || ($this->affected_rows()<0);
				
				$sql = "ALTER TABLE {$this->DBrecipes} ADD FULLTEXT (description)";
				$r = $this->fetch($sql);
				$result .= 'ALTER TABLE ADD FULLTEXT INDEX object: ' . $this->affected_rows() . $this->insertUpgradeErr($sql);
				$this->_upateErr = $this->_upateErr || ($this->affected_rows()<0);

				$sql = "ALTER TABLE {$this->DBrecipes} ADD FULLTEXT (tags)";
				$r = $this->fetch($sql);
				$result .= 'ALTER TABLE ADD FULLTEXT INDEX object: ' . $this->affected_rows() . $this->insertUpgradeErr($sql);
				$this->_upateErr = $this->_upateErr || ($this->affected_rows()<0);

				$sql = "ALTER TABLE {$this->DBrecipes} ADD FULLTEXT (ingredients)";
				$r = $this->fetch($sql);
				$result .= 'ALTER TABLE ADD FULLTEXT INDEX object: ' . $this->affected_rows() . $this->insertUpgradeErr($sql);
				$this->_upateErr = $this->_upateErr || ($this->affected_rows()<0);								
			}
		}		
		
		### add SITE URL + upgrade custom cats to DB for _nonce
		if( version_compare($this->getDBVersion(), '1.4.3') < 0 ) {
			$this->updateDBVersion('1.4.3');
		}
		
	}


	### Document Upgrade Error
	function insertUpgradeErr($sql) {
		$col = ($this->affected_rows()<0)?'#C88989':'#4fc754';
		return '<br /><span style="display:none; color:'.$col.'">Server: "'.$this->error().'", Affected Rows: "'.$this->affected_rows().'", SQL: "'. $sql .'"</span>';
	}
	
	
	### Migrate Ideas
	function migrateDB() {
	    global $user;

		$charset_collate	= $this->getCollate();
		$result				= '';
		
		### drop index
        $sql = "ALTER TABLE {$this->DBobjects} DROP INDEX object";
		$r = $this->fetch($sql);
		$result .= 'ALTER TABLE DROP INDEX object: ' . $this->affected_rows() . $this->insertUpgradeErr($sql);
		$this->_upateErr = $this->_upateErr || ($this->affected_rows()<0);

		### new fields: UID
        $sql = "ALTER TABLE {$this->DBobjects} ADD uid VARCHAR( 50 );";
		$r = $this->fetch($sql);
		$result .= 'ALTER TABLE ADD uid: ' . $this->affected_rows() . $this->insertUpgradeErr($sql);
		$this->_upateErr = $this->_upateErr || ($this->affected_rows()<0);

		### change fields: flag > setting
        $sql = "ALTER TABLE {$this->DBobjects} CHANGE flag setting VARCHAR( 20000 );";
		$r = $this->fetch($sql);
		$result .= 'ALTER TABLE CHANGE flag > setting: ' . $this->affected_rows() . $this->insertUpgradeErr($sql);
		$this->_upateErr = $this->_upateErr || ($this->affected_rows()<0);

		### mark all IDEAS, EMAILS with main user id
        $sql = "UPDATE {$this->DBobjects} SET uid='{$user->_user_id}' WHERE type IN ('5','4')";
		$r = $this->fetch($sql);
		$result .= 'UPDATE ideas, emails with UID: ' . $this->affected_rows() . $this->insertUpgradeErr($sql);
		$this->_upateErr = $this->_upateErr || ($this->affected_rows()<0);

		### uid on all 1,2,3 objects
        $sql = "UPDATE {$this->DBobjects} SET uid='-' WHERE type IN ('1','2','3')";
		$r = $this->fetch($sql);
		$result .= 'UPDATE auto complete with UID: ' . $this->affected_rows() . $this->insertUpgradeErr($sql);
		$this->_upateErr = $this->_upateErr || ($this->affected_rows()<0);

		### user object
        $sql = "UPDATE {$this->DBobjects} SET uid=type WHERE CHAR_LENGTH(type)>20";
		$r = $this->fetch($sql);
		$result .= 'UPDATE uid = type (PW): ' . $this->affected_rows() . $this->insertUpgradeErr($sql);
		$this->_upateErr = $this->_upateErr || ($this->affected_rows()<0);

		### remove old PW's from type
        $sql = "UPDATE {$this->DBobjects} SET type='' WHERE CHAR_LENGTH(type)>20";
		$r = $this->fetch($sql);
		$result .= 'UPDATE clear type (PW): ' . $this->affected_rows() . $this->insertUpgradeErr($sql);
		$this->_upateErr = $this->_upateErr || ($this->affected_rows()<0);

		### migrate user settings type from 99 to 9
        $sql = "UPDATE {$this->DBobjects} SET type='9' WHERE type='99' AND object<>'recipeShelf_options'";
		$r = $this->fetch($sql);
		$result .= 'UPDATE type 99 > 9: ' . $this->affected_rows() . $this->insertUpgradeErr($sql);
		$this->_upateErr = $this->_upateErr || ($this->affected_rows()<0);

		### change db fields, when clean
        $sql = "ALTER TABLE {$this->DBobjects} CHANGE type type VARCHAR( 10 );";
		$r = $this->fetch($sql);
		$result .= 'ALTER TABLE CHANGE type (10): ' . $this->affected_rows() . $this->insertUpgradeErr($sql);
		$this->_upateErr = $this->_upateErr || ($this->affected_rows()<0);

		### Add new unique key
        $sql = "ALTER TABLE {$this->DBobjects} ADD UNIQUE KEY object (type,object,uid);";
		$r = $this->fetch($sql);
		$result .= 'ALTER TABLE ADD UNIQUE KEY object: ' . $this->affected_rows() . $this->insertUpgradeErr($sql);
		$this->_upateErr = $this->_upateErr || ($this->affected_rows()<0);

		return $result;
	}

	### Migrate Faves'
	function migrateFaves() {
	    global $user, $rShelf;

		$i = 0;
		$f = array();
		$recipes = $this->fetchArr("SELECT id FROM {$this->DBrecipes} WHERE rating='1' ORDER BY date_added DESC");

		if ( !is_array($recipes) || count($recipes)<=0 )
		    return;

		foreach( $recipes as $r )
		    $f[$i++] = $r->id;

		### move to user settings
		$rShelf->_user_options['rS_favorites'] = $f;
		$this->update_option( $user->_user_name."_options",$rShelf->_user_options );

		### remove from recipes
        $sql = "UPDATE {$this->DBrecipes} SET rating=NULL WHERE rating='1'";
		$r = $this->fetch($sql);
	}


	### Update notice
	function updateDBInfo($txt) {
		$msg  = '<p class="title">'.__('DB Update','recipeshelf').'</p>';
		$msg .= '<p class="info">'.__('Your recipeShelf Database has been updated.','recipeshelf').'</p>'.
				'<p class="info updateTXT">'.$txt.'</p>'.
				'<form action="" method="post" name="db-update">'.
				'<p class="continue aligncenter">'.
				(  ($this->_upateErr)?'<a href="" title="" class="rSbutton" id="upgradeShowErr">'.__('Show Errors','recipeshelf').'</a>':''  ) .
				'<input type="submit" name="upgradedone" class="rSbutton" value="'. __('Continue','recipeshelf') . '"/>'.
				'</p>'.
                '</form>';
    	$this->dieNOW( $msg, false, '' );
	}


	### Update notice
	function confirmUpgrade($v) {
		$msg  = '<p class="title">'.__('Backup First!','recipeshelf').' <strong>'.$v.'</strong></p>';
		$msg .= '<p class="info">'.__('Before you confirm the DB upgrade, please make a backup of your existing recipeShelf data. You have two options:','recipeshelf').'</p>'.
				'<ul class="backupoptions">'.
				'<li>'.__('click on the below Backup button (for standard web servers this should work)','recipeshelf').'</li>'.
				'<li>'.__('ask you administrator to run a SQL backup of your database','recipeshelf').'</li>'.
				'</ul>'.
				'<p class="info">'.__('This is merely a precaution in the odd case something does go wrong.','recipeshelf').'</p>'.
				'<form action="" method="post" name="db-update">'.
				'<p class="continue aligncenter"><span id="admin-res">&nbsp;</span>'.
				'<a href="" title="" class="rSbutton" id="upgradeBackup">'.__('Backup to file','recipeshelf').'</a><input id="confirmUpgrade" type="submit" name="confirmUpgrade" class="rSbutton" value="'. __('Confirm','recipeshelf') . '"/>'.
				'</p>'.
                '</form>';
    	$this->dieNOW( $msg, false, '' );
	}


	### After Upgrade Note
	function loginAsRoot($v='') {
		$msg  = '<p class="title">'.__('DB Update','recipeshelf').' <strong>'.$v.'</strong></p>';
		$msg .= '<p class="info">'.__('Please login as the main user after updating recipeShelf!','recipeshelf').'</p>'.
				'<form action="" method="post" name="db-update">'.
				'<p class="continue aligncenter"><input type="submit" name="doneupgrade" class="rSbutton" value="'. __('Continue','recipeshelf') . '"/></p>'.
                '</form>';
    	$this->dieNOW( $msg, false, 'db-error' );
	}


	function InitErr($err) {
		$msg  = '<p class="title">'.__('ERROR','recipeshelf').'</p>';
		$msg .= '<p class="info">'.$err.'</p>';
		$msg .= $this->dbInfo();
		$msg .= '<p class="info">'.__('Please check your <strong>db-config.php</strong> file and settings therein!','recipeshelf').'</p>';
    	$this->dieNOW( $msg, true, 'db-error' );
	}

	function InitForm() {
		$msg  = '<p class="title">'.__('Welcome to ','recipeshelf').' recipeShelf</p>';
		$msg .= '<p class="info">'. __('Installing recipeShelf is a simple one click action. Please provide your email adress below and continue.','recipeshelf') . '</p>';
		$msg .= '<form action="" method="post" name="install" id="rsinstall">'.
				rS_nonce_field( 'firstinstall' ).
		        '<p class="alignleft">'.
                '<label for="admin-login">'. __('Username','recipeshelf') . '</label><br /><input type="text" name="user" id="admin-login" value=""/>'.
                '</p>'.
		        '<p class="alignleft">'.
                '<label for="admin-email">'. __('User Email Address','recipeshelf') . '</label><br /><input type="text" name="email" id="admin-email" value=""/>'.
                '</p>'.
                '<p class="continue"><input type="submit" name="continue" class="rSbutton" value="'. __('Continue','recipeshelf') . '"/></p>'.
                '</form>';
    	$this->dieNOW( $msg, false, 'db-welcome' );
	}

	function FeedbackForm() {
		$msg  = '<p class="title">'.__('That was it!').'</p>';
		$msg .= '<p class="info">'. __('Please note that a user account has been created with the following user name and password:','recipeshelf') . '</p>';
		$msg .= '<div class="done">'.
					'<span>'.__('User Name').':</span> <strong>'.esc_html(_rem_magic_quote($_POST['user'])).'</strong><br />'.
					'<span>'.__('Password').':</span> <strong>'.esc_html(_rem_magic_quote($_POST['pass'])).'</strong>'.
					'<form action="" method="post" name="install" id="done">'.
						'<p class="continue"><input type="submit" name="done" class="rSbutton" value="'. __('Continue','recipeshelf') . '"/></p>'.
					'</form>'.
				'</div>';
    	$this->dieNOW( $msg, false, 'db-welcome' );
	}

	function dbInfo() {
		$m  = '<table class="db-info">';
		$m .= '<tr><td class="db-setting">DB_NAME</td><td class="db-value">'.DB_NAME.'</td></tr>';
		$m .= '<tr><td class="db-setting">DB_USER</td><td class="db-value">'.DB_USER.'</td></tr>';
		$m .= '<tr><td class="db-setting">DB_PASSWORD</td><td class="db-value">***</td></tr>';
		$m .= '<tr><td class="db-setting">DB_HOST</td><td class="db-value">'.DB_HOST.'</td></tr>';
		$m .= '<tr><td class="db-setting">DB_COLLATE</td><td class="db-value">'.DB_COLLATE.'</td></tr>';
		$m .= '<tr><td class="db-setting">DB_CHARSET</td><td class="db-value">'.DB_CHARSET.'</td></tr>';
		$m .= '</table>';
    	return $m;
	}

	### Setup Tables
	function Init($std_alone=false) {
		
		### Check db-config.php
		$this->dbConfigCheck();
		
        if ( !$this->InstallCheck() ){

			if( !isset($_POST['user']) )
            	$this->InitForm();

			check_admin_referer( 'firstinstall' );

            $charset_collate = $this->getCollate();

			### New Tables
            $sql = "CREATE TABLE {$this->DBobjects} (
                id MEDIUMINT( 9 ) NOT NULL AUTO_INCREMENT,
                type VARCHAR( 10 ) NOT NULL,
                object VARCHAR( 50 ) NOT NULL,
                uid VARCHAR( 40 ),
                setting VARCHAR( 20000 ) NOT NULL,
                PRIMARY KEY ( id ),
                UNIQUE KEY object (type,object,uid)
            ) $charset_collate;";
			$r1 = $this->fetch($sql);

            $sql = "CREATE TABLE {$this->DBrecipes} (
                id MEDIUMINT( 9 ) NOT NULL AUTO_INCREMENT,
                date_added timestamp NOT NULL,
                creator MEDIUMINT( 9 ) NOT NULL,
                name VARCHAR( 80 ) NOT NULL ,
                description VARCHAR( 1024 ) NULL ,
                tags VARCHAR( 1024 ) NULL ,
                tips VARCHAR ( 1024 ) NULL ,
                steps mediumtext NULL ,
                notes mediumtext NULL ,
                ingredients mediumtext NULL ,
                yield VARCHAR( 40 ) NULL ,
                region VARCHAR( 20 ) NULL ,
                cookingtime VARCHAR( 50 ) NULL ,
                level VARCHAR( 20 ) NULL ,
                servewith VARCHAR( 2000 ) NULL ,
                rating INT( 1 ) NULL ,
                options VARCHAR( 10000 ) NULL ,
                cooked VARCHAR ( 3096 ) NULL ,
                urls mediumtext NULL ,
                PRIMARY KEY ( id ),
				FULLTEXT KEY name (name),
				FULLTEXT KEY description (description),
				FULLTEXT KEY tags (tags),
				FULLTEXT KEY ingredients (ingredients)
            ) $charset_collate;";
			$r2 = $this->fetch($sql);

	        if( ! ($r1 && $r2) )
				$this->InitErr('recipeShelf '.__('database tables could not be created.','recipeshelf'));
			else{

				### SITE URL
				$this->setSiteURL( esc_url( curPageURL() ,false) );
			
			    ### write current DB version
				$this->updateDBversion($this->_version);

				### main user setup
				global $user;
				$_POST['pass'] = $user->generatePassword(8,4);

			    $user->registration(); ###store new user

				### Store email
				$useroptions['rS_email'] = sanitize(_rem_magic_quote($_POST['email']),false,true);
				$this->update_option( _rem_magic_quote($_POST['user'])."_options",$useroptions );
			}

			if( !isset($_POST['done']) )
            	$this->FeedbackForm();

        } ### Installcheck
        else{

			$this->VersionCheck();

		} ### Versioncheck

    }

	### Get "Collate"
	function getCollate() {
	    $charset_collate = '';
			if ( version_compare(mysql_get_server_info($this->connection), '4.1.0', '>=') ) {
				if ( DB_CHARSET && DB_CHARSET != '' )
					$charset_collate .= ' DEFAULT CHARACTER SET ' . DB_CHARSET;
				else
					$charset_collate .= ' DEFAULT CHARACTER SET utf8';

			if ( DB_COLLATE != '' )
				$charset_collate .= ' COLLATE ' . DB_COLLATE;

			}
		return $charset_collate;
	}

	function dieNOW($t,$f=true,$c='db-error') {
        $rShelf	= new recipeShelf();
   		$browser = $_SERVER["HTTP_USER_AGENT"];
		?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US">
<head profile="http://gmpg.org/xfn/11">
	<title>recipeShelf</title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<link rel="shortcut icon" href="<?php echo RS_URL; ?>/img/favicon.ico" />
	<link rel="apple-touch-icon" href="<?php echo RS_URL; ?>/img/apple-touch-icon.png" />
	<link rel="stylesheet" href="<?php echo RS_URL; ?>/css/recipeshelf.css" type="text/css" media="screen" />
	<link rel="stylesheet" href="<?php echo RS_URL; ?>/js/CLEditor/jquery.cleditor.css" type="text/css" media="screen" />
<?php if( isset($browser) && strpos($browser, "Safari") > -1 ) : ?>
	<link rel="stylesheet" href="<?php echo RS_URL; ?>/css/recipeshelf-safari.css" type="text/css" media="screen" />
<?php endif; ?>
<?php if( isset($browser) && strpos($browser, "MSIE") > -1 ) : ?>
	<link rel="stylesheet" href="<?php echo RS_URL; ?>/css/recipeshelf-ie8.css" type="text/css" media="screen" />
<?php endif; ?>
<?php if( isset($browser) && strpos($browser, "Opera") > -1 ) : ?>
	<link rel="stylesheet" href="<?php echo RS_URL; ?>/css/recipeshelf-opera.css" type="text/css" media="screen" />
<?php endif; ?>

<?php if( isset($browser) && strpos($browser, "iPad") > -1 ) : ?>
	<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>
	<meta name="apple-mobile-web-app-capable" content="yes" />
	<meta name="apple-mobile-web-app-status-bar-style" content="black" />
	<link rel="apple-touch-icon" href="<?php echo RS_URL; ?>/img/apple-touch-icon190.png" />
	<link rel="apple-touch-startup-image" href="<?php echo RS_URL; ?>/img/startupPortrait.png" media="screen and (orientation: portrait)"/>
	<link rel="stylesheet" href="<?php echo RS_URL; ?>/css/recipeshelf-iPad.css" type="text/css" media="screen" />
<?php endif; ?>

	<script type="text/javascript" src="<?php echo RS_URL; ?>/js/jquery.js"></script>
<?php if( isset($browser) && !strpos($browser, "iPad") ) : ?>
	<script type="text/javascript" src="<?php echo RS_URL; ?>/js/CLEditor/jquery.cleditor.min.js"></script>
<?php endif; ?>
	<script type="text/javascript" src="<?php echo RS_URL; ?>/js/recipeshelf-library.min.js"></script>
	<script type="text/javascript" src="<?php echo RS_URL; ?>/js/recipeshelf.min.js"></script>
<?php if( isset($browser) && strpos($browser, "iPad") > -1 ) : ?>
	<script type="text/javascript" src="<?php echo RS_URL; ?>/js/iscroll-min.js"></script>
<?php endif; ?>
	<script type="text/javascript">
		var _ajax_nonce_messageboard='<?php echo rS_create_nonce( 'messageboard' ); ?>';
		var _ajax_nonce_backup_restore='<?php echo rS_create_nonce( 'backup-restore' ); ?>';
		var _ajax_nonce_download='<?php echo rS_create_nonce( 'download' ); ?>';
	</script>
</head>
<body>
	<input disabled="disabled" type="hidden" value="<?php _e('For recipeShelf to properly function, please turn on browser cookies.','recipeshelf'); ?>" id="rs-text-h8" name="rs-text-h8"/>

	<div id="headerbar">
	    <div id="headerbar-title"><img id="logo" src="<?php echo RS_URL; ?>/img/logo.png" alt="recipeShelf" /></div>
	</div>
	<?php $rShelf->dropFade()?>

		<?php
		echo '<div id="setup" class="centerWin '.$c.'">'.$t;
		if ($f)
			echo '<div class="sql-error-text">'.__('Server Response:','recipeshelf').'<br />'.( ($this->connection) ? $this->error():'' ).'</div>';
		echo '</div>';
		?>

        <?php
		$rShelf->language();
		$rShelf->footer(false);
    	die();
    }

	function error() {
		    return mysql_error($this->connection);
    }

	function fetch($q) {
		    return mysql_query($q,$this->connection);
    }

	function affected_rows() {
		    return mysql_affected_rows($this->connection);
    }

	function numrows($r) {
	    return mysql_numrows($r,$this->connection);
    }


	function fetchArr($q) {
        $got = array();
		//echo "** debug: SQL query={$q}";
        $result = mysql_query($q,$this->connection);

		if(!$result) { 
			return false;
		}
		
        if(mysql_num_rows($result) == 0)
            return $got;
        mysql_data_seek($result, 0);
        while ($row = mysql_fetch_object($result))
            array_push($got, $row);

        return $got;
    }

	function fetchRow($q) {
        $result = mysql_query($q);
        return mysql_fetch_object($result);
    }


	function fetchVal($q) {
        $result = mysql_query($q);
          $got = mysql_fetch_array($result);
        return $got[0];
    }

	function fetchNames() {
		return $this->fetchArr("SELECT id,name,description FROM {$this->DBrecipes}");
	}


	function isSerialized( $data ) {
	    if ( !is_string( $data ) )
	        return false;
	    $data = trim( $data );
	    if ( 'N;' == $data )
	        return true;
	    if ( !preg_match( '/^([adObis]):/', $data, $badions ) )
	        return false;
	    switch ( $badions[1] ) {
	        case 'a' :
	        case 'O' :
	        case 's' :
	            if ( preg_match( "/^{$badions[1]}:[0-9]+:.*[;}]\$/s", $data ) )
	                return true;
	            break;
	        case 'b' :
	        case 'i' :
	        case 'd' :
	            if ( preg_match( "/^{$badions[1]}:[0-9.E-]+;\$/", $data ) )
	                return true;
	            break;
	    }
	    return false;
	}

	function get_option($key) {

		$type 	= ( $key === 'recipeShelf_options' ) ? '99':'9';
        $sql	= "SELECT setting FROM {$this->DBobjects} WHERE type='{$type}' AND object='".esc_sql($key)."'";

		$r = $this->fetchArr($sql);
		
		if ( empty($r) )
			return false;

		$v = $r[0]->setting;
			
        #echo "<br>*** $sql "; //debug
		#echo '<br><pre>'.print_r($v,1).'</pre>'; //debug
		
		if( $this->isSerialized($v) ){
			#echo "<br> SERIALIZED *** ".print_r(@unserialize( $v ),1);
			if ( false !== ($rU = @unserialize( $v )) )
				return $rU;
		}
		return $v;
	}

	function update_option($key,$value) {

		$oldVal	= $this->get_option($key);
		$type 	= ( $key === 'recipeShelf_options' ) ? '99':'9';

        $_value = (is_array($value)) ? serialize($value) : $value;

        if( $oldVal === false ){
	        $sql = "INSERT IGNORE INTO {$this->DBobjects} (type,object,setting) VALUES ('".esc_sql($type)."','".esc_sql($key)."','".esc_sql($_value)."')";
        }else{
	        $_value = serialize($value);
	        $sql = "UPDATE {$this->DBobjects} SET setting='".esc_sql($_value)."' WHERE object='".esc_sql($key)."' AND type='".esc_sql($type)."'";
		}

		#echo "<br> OLDVAL=$oldVal | SQL=$sql ";
		$r = $this->fetch($sql);
        return $r;
	}

	function delete_option($key) {

		$type 	= $key=='recipeShelf_options' ? '99':'9';
        $sql	= "DELETE FROM {$this->DBobjects} WHERE object='".esc_sql($key)."' AND type='".esc_sql($type)."'";

		$r = $this->fetch($sql);
		return $r;
	}


	function backupDie($s,$t,$fn='') {
        $r = array();
		$r[0] = $s;
		$r[1] = $t;
		$r[2] = $fn;
		restore_error_handler();
		return $r;
	}

	function error_handler($errno, $errstr) {
	    $this->last_error = $errno.'|'.$errstr;
	}

	function backup() {

		$BACKUP_NAME = 'recipeShelf.'.date('Y-m-d');
		$BACKUP_TEMP = BACKUP_TEMP;
        $zipEXT = '';
        $optimized = '';

		// Check for safe mode
		if( ini_get('safe_mode') ){
			return $this->backupDie( false, '<strong>'.__('Before you can backup/restore your data, please turn off *PHP safe_mode*.','recipeshelf').'</strong>' );
		}

		set_error_handler(array(&$this, 'error_handler'));

		// set execution time limit
		if( ini_get( 'max_execution_time' ) < MAX_EXEC_TIME ) {
			set_time_limit( MAX_EXEC_TIME );
		}


		if( !file_exists( MYSQL_PATH.'/mysqldump' ) )
			return $this->backupDie( false, MYSQL_PATH.'/mysqldump '.__('not found!','recipeshelf') );


		### command line auth
		$db_auth = '--host="'.DB_HOST.'" --user="'.DB_USER.'" --password="'.DB_PASSWORD.'"';

		## $tables = $this->DBobjects;
		$tables = escapeshellcmd(DB_NAME) .' '. escapeshellcmd($this->DBrecipes) .' '. escapeshellcmd($this->DBobjects);
		$opt	= '--opt --add-drop-table';

		### dump db
		unset( $output );
		$cmd = MYSQL_PATH . "/mysqldump $db_auth $opt $tables 2>&1 >" . escapeshellcmd($BACKUP_TEMP) . "/".escapeshellcmd($BACKUP_NAME).".sql";
		#echo $cmd; // debug
		
		exec( $cmd, $output, $res);
		if( $res > 0 )
            return $this->backupDie( false, __('MySQL database dump failed.','recipeshelf') );
		else {

			if( OPTIMIZE==1 ) {
				unset( $output );
				exec( MYSQL_PATH . "/mysqlcheck ".$db_auth." --optimize $tables 2>&1", $output, $res);
				if( $res > 0 )
		            return $this->backupDie( false, __('MySQL database optimization failed.','recipeshelf') );
				else
				    $optimized = ' '.__('Database tables successfully optimized.','recipeshelf');

			} // if
		} // if


		// compress db
		unset( $output );
		if( $_POST['zip']=='zip' ) {
			exec( escapeshellcmd(ZIP) . ' ' .escapeshellcmd($BACKUP_TEMP). "/".escapeshellcmd($BACKUP_NAME).".sql.zip " .escapeshellcmd($BACKUP_TEMP). "/".escapeshellcmd($BACKUP_NAME).".sql 2>&1" , $output, $res );

			if( $res > 0 )
				return $this->backupDie( false, __('SQL data compression failed. ','recipeshelf').' ('.implode( "\n", $output).')' );
			else
				$zipEXT = '.zip';
		}

	return $this->backupDie( true, __('Recipe data succesfully backed up.','recipeshelf').$optimized, $BACKUP_NAME.'.sql'.$zipEXT );
	}

	function restore($tmp, $fn) {

		// Check for safe mode
		if( ini_get('safe_mode') ){
			return $this->backupDie( false, '<strong>'.__('Before you can backup/restore your data, please turn off *PHP safe_mode*.','recipeshelf').'</strong>' );
		}
		
		if( !file_exists( MYSQL_PATH.'/mysql' ) )
			return $this->backupDie( false, MYSQL_PATH.'/mysql '.__('not found!','recipeshelf') );

		// uncompress file
		$ext = '';
		unset( $output );
		if( ($a=strpos($fn,'.zip')) > -1 ) {

			$ext = time();
			exec( UNZIP . " $tmp > " . escapeshellcmd(BACKUP_TEMP.$ext) , $output, $res );
			if( $res > 0 )
				return $this->backupDie( false, __('SQL data unzipping failed. ','recipeshelf').' ('.implode( "\n", $output).')' );

            $tmp = BACKUP_TEMP.$ext;
		}

		$db_auth = ' --host="'.DB_HOST.'" --user="'.DB_USER.'" --password="'.DB_PASSWORD.'" -v ' . escapeshellcmd(DB_NAME);

		unset( $output );
		exec( MYSQL_PATH . "/mysql $db_auth < "  .$tmp. " 2>&1", $output, $res );


		if( $res > 0 )
			return $this->backupDie( false, __('Restore process appears to have failed. ','recipeshelf').' ('.implode( "\n", $output).')' );
		else
			return $this->backupDie( true, __('Recipe database successfully restored.','recipeshelf') );

	}

}

$rSdb	= new recipeDB();

endif;
?>