<?php
/*  Copyright 2009  Carson McDonald  (carson@ioncannon.net)

    This program 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 2 of the License, or
    (at your option) any later version.

    This program 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 this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

require_once( dirname( __FILE__ ) . '/ga-lib.php' );
require_once( dirname( __FILE__ ) . '/aux-lib.php' );
require_once( dirname( __FILE__ ) . '/gauth-lib.php' );
require_once( dirname( __FILE__ ) . '/simplefilecache.php' );
require_once( dirname( __FILE__ ) . '/OAuth.php' );

require_once( dirname( __FILE__ ) . '/gad-admin-options-ui.php' );

class GADAdminOptions {
	function GADAdminOptions() {
		$this->__construct();
	}

	function __construct() {
	}

	function register_for_actions_and_filters() {
		add_action( 'wp_ajax_gad_set_preference', array( &$this, 'ajax_set_preference' ) );
		add_action( 'admin_menu', array( &$this, 'admin_plugin_menu' ) );
		add_action( 'admin_init', array( &$this, 'admin_handle_oauth_login_header' ) );
	}

	function ajax_set_preference() {
		global $current_user;
		get_currentuserinfo();

		switch ( $_POST['pi'] ) {
			case 'base-stats':
				update_usermeta( $current_user->ID, 'gad_bs_toggle', sanitize_text_field( $_POST['pv'] ) );
				break;
			case 'goal-stats':
				update_usermeta( $current_user->ID, 'gad_gs_toggle', sanitize_text_field( $_POST['pv'] ) );
				break;
			case 'extended-stats':
				update_usermeta( $current_user->ID, 'gad_es_toggle', sanitize_text_field( $_POST['pv'] ) );
				break;
			default:
				die( "alert('Unknown option.')" );
		}

		die( "" );
	}

	function admin_plugin_menu() {
		add_options_page( __( 'Google Analytics Dashboard Options' ), __( 'Google Analytics Dashboard', 'google-analytics-dashboard' ), 8, __FILE__, array( &$this, 'admin_plugin_options' ) );
	}

	function admin_plugin_options( $info_message = '' ) {
		if ( ! class_exists( 'SimpleXMLElement' ) ) {
			echo '<br/><br/><div id="message" class="updated fade"><p><strong>' . __( 'It appears that <a href="http://us3.php.net/manual/en/book.simplexml.php">SimpleXML</a> is not compiled into your version of PHP. It is required for this plugin to function correctly.', 'google-analytics-dashboard' ) . '</strong></p></div>';
		} else {
			if ( ! function_exists( 'curl_init' ) ) {
				echo '<br/><br/><div id="message" class="updated fade"><p><strong>' . __( 'It appears that <a href="http://www.php.net/manual/en/book.curl.php">CURL</a> is not compiled into your version of PHP. It is required for this plugin to function correctly.', 'google-analytics-dashboard' ) . '</strong></p></div>';
			} else {
				$gad_auth_token = get_option( 'gad_auth_token' );

				if ( isset( $gad_auth_token ) && $gad_auth_token != '' ) {
					$this->admin_handle_other_options( $info_message );
				} else {
					$this->admin_handle_login_options( $info_message );
				}
			}
		}
	}

	function admin_handle_other_options( $info_message = '' ) {
		if ( isset( $_POST['SubmitOptions'] ) ) {
			if ( function_exists( 'current_user_can' ) && ! current_user_can( 'manage_options' ) ) {
				die( __( 'Cheatin&#8217; uh?' ) );
			}

			// Verify the Nonce of the options form
			if( !wp_verify_nonce( $_REQUEST['_wpnonce'], 'update_ga_dashboard_' . get_current_user_id() ) ){
				die( __( 'Cheatin&#8217; uh?' ) );
			}

			@SimpleFileCache::clearCache();

			if ( isset( $_POST['ga_forget_pass'] ) ) {
				delete_option( 'gad_login_pass' );
			}

			if ( isset( $_POST['ga_forget_all'] ) ) {
				delete_option( 'gad_oauth_token' );
				delete_option( 'gad_oauth_secret' );
				delete_option( 'gad_account_id' );
				delete_option( 'gad_display_level' );
				delete_option( 'gad_cache_timeout' );
				delete_option( 'gad_goal_one' );
				delete_option( 'gad_goal_two' );
				delete_option( 'gad_goal_three' );
				delete_option( 'gad_goal_four' );
				delete_option( 'gad_login_email' );
				delete_option( 'gad_login_pass' );
				delete_option( 'gad_auth_token' );
				delete_option( 'gad_disable_post_stats' );
				$this->admin_plugin_options( 'Everything Reset' );

				return;
			}

			delete_option( 'gad_account_id' );
			add_option( 'gad_account_id', sanitize_text_field( $_POST['ga_account_id'] ) );

			if ( isset( $_POST['ga_forget_auth'] ) ) {
				delete_option( 'gad_oauth_token' );
				delete_option( 'gad_oauth_secret' );
				delete_option( 'gad_auth_token' );
				$this->admin_plugin_options( 'Auth Reset' );

				return;
			}

			if ( isset( $_POST['ga_display_level'] ) ) {
				delete_option( 'gad_display_level' );
				if ( $_POST['ga_display_level'] != '' ) {
					add_option( 'gad_display_level', sanitize_text_field( $_POST['ga_display_level'] ) );
				}
			}

			if ( isset( $_POST['ga_disable_post_stats'] ) ) {
				add_option( 'gad_disable_post_stats', 'true' );
			} else {
				delete_option( 'gad_disable_post_stats' );
			}

			if ( isset( $_POST['ga_cache_timeout'] ) ) {
				delete_option( 'gad_cache_timeout' );
				if ( $_POST['ga_cache_timeout'] != '' ) {
					add_option( 'gad_cache_timeout', sanitize_text_field( $_POST['ga_cache_timeout'] ) );
				}
			}

			delete_option( 'gad_goal_one' );
			delete_option( 'gad_goal_two' );
			delete_option( 'gad_goal_three' );
			delete_option( 'gad_goal_four' );

			if ( isset( $_POST['ga_goal_one'] ) ) {
				if ( $_POST['ga_goal_one'] != '' ) {
					add_option( 'gad_goal_one', sanitize_text_field( $_POST['ga_goal_one'] ) );
				}
			}

			if ( isset( $_POST['ga_goal_two'] ) ) {
				if ( $_POST['ga_goal_two'] != '' ) {
					add_option( 'gad_goal_two', sanitize_text_field( $_POST['ga_goal_two'] ) );
				}
			}

			if ( isset( $_POST['ga_goal_three'] ) ) {
				if ( $_POST['ga_goal_three'] != '' ) {
					add_option( 'gad_goal_three', sanitize_text_field( $_POST['ga_goal_three'] ) );
				}
			}

			if ( isset( $_POST['ga_goal_four'] ) ) {
				if ( $_POST['ga_goal_four'] != '' ) {
					add_option( 'gad_goal_four', sanitize_text_field( $_POST['ga_goal_four'] ) );
				}
			}

			$info_message = 'Options Saved';
		}

		if ( get_option( 'gad_auth_token' ) == 'gad_see_oauth' ) {
			$ga = new GALib( 'oauth', NULL, get_option( 'gad_oauth_token' ), get_option( 'gad_oauth_secret' ), '', get_option( 'gad_cache_timeout' ) !== false ? get_option( 'gad_cache_timeout' ) : 60 );
		} else {
			$ga = new GALib( 'client', get_option( 'gad_auth_token' ), NULL, NULL, '', get_option( 'gad_cache_timeout' ) !== false ? get_option( 'gad_cache_timeout' ) : 60 );
		}
		$account_hash = $ga->account_query();

		if ( $ga->isError() ) {
			if ( $ga->isAuthError() ) {
				delete_option( 'gad_auth_token' ); // this is removed so login will happen again
				$this->admin_plugin_options();

				return;
			} else {
				$ui                = new GADAdminOptionsUI();
				$ui->error_message = 'Error gathering analytics data from Google: ' . strip_tags( $ga->getErrorMessage() );
				$ui->display_admin_halting_error();

				return;
			}
		}

		$ui                = new GADAdminOptionsUI();
		$ui->info_message  = $info_message;
		$ui->error_message = '';
		$ui->display_admin_handle_other_options( $account_hash );
	}

	function admin_handle_login_options( $info_message = '' ) {
		$ui = new GADAdminOptionsUI();

		if ( isset( $_REQUEST['error_message'] ) ) {
			$ui->error_message = strip_tags( urldecode( $_REQUEST['error_message'] ) );
		}

		if ( isset( $_REQUEST['info_message'] ) ) {
			$ui->info_message = strip_tags( urldecode( $_REQUEST['info_message'] ) );
		} else {
			$ui->info_message = $info_message;
		}

		if ( isset( $_POST['SubmitLogin'] ) ) {
			if ( function_exists( 'current_user_can' ) && ! current_user_can( 'manage_options' ) ) {
				die( __( 'Cheatin&#8217; uh?' ) );
			}

			if ( isset( $_POST['gad_login_type'] ) && $_POST['gad_login_type'] == 'client' ) {
				if ( $this->admin_handle_clientlogin_login_options( $ui, $info_message ) ) {
					return;
				}
			}
		}

		$ui->display_admin_handle_login_options( $gauth );
	}

	function admin_handle_clientlogin_login_options( &$ui, $info_message = '' ) {
		if ( ! isset( $_POST['ga_email'] ) || trim( $_POST['ga_email'] ) == '' ) {
			$error_message = "Email is required";
		} else {
			if ( ! isset( $_POST['ga_pass'] ) || $_POST['ga_pass'] == '' ) {
				$error_message = "Password is required";
			} else {
				add_option( 'gad_login_email', sanitize_text_field( $_POST['ga_email'] ) );

				if ( isset( $_POST['ga_save_pass'] ) ) {
					add_option( 'gad_login_pass', sanitize_text_field( $_POST['ga_pass'] ) );
				} else {
					delete_option( 'gad_login_pass', sanitize_text_field( $_POST['ga_pass'] ) );
				}

				$gauth = new GAuthLib( 'wpga-display-1.0' );
				if ( isset( $_POST['ga_captcha_token'] ) && isset( $_POST['ga_captcha'] ) ) {
					$gauth->authenticate( sanitize_text_field( $_POST['ga_email'] ), sanitize_text_field( $_POST['ga_pass'] ), get_option( 'gad_services' ), sanitize_text_field( $_POST['ga_captcha_token'] ), sanitize_text_field( $_POST['ga_captcha'] ) );
				} else {
					$gauth->authenticate( sanitize_text_field( $_POST['ga_email'] ), sanitize_text_field( $_POST['ga_pass'] ), get_option( 'gad_services' ) );
				}

				if ( $gauth->isError() ) {
					$error_message = $gauth->getErrorMessage();
				} else {
					add_option( 'gad_auth_token', $gauth->getAuthToken() );
					$this->admin_plugin_options( 'Login successful.' );

					return true;
				}
			}
		}

		$ui->info_message  = $info_message;
		$ui->error_message = $error_message;

		return false;
	}

	// We have to catch the oauth login data in admin_init so http headers can be added
	function admin_handle_oauth_login_header() {
		if ( isset( $_POST['SubmitLogin'] ) && isset( $_POST['gad_login_type'] ) && $_POST['gad_login_type'] == 'oauth' ) {
			$this->admin_handle_oauth_login_options();
		} else {
			if ( isset( $_REQUEST['oauth_return'] ) ) {
				$this->admin_handle_oauth_complete();
			}
		}
	}

	function admin_handle_oauth_login_options() {
		// Step one in the oauth login sequence is to grab an anonymous token

		delete_option( 'gad_oa_anon_token' );
		delete_option( 'gad_oa_anon_secret' );

		$signature_method = new GADOAuthSignatureMethod_HMAC_SHA1();
		$params           = array();

		$params['oauth_callback']     = gad_get_admin_url( '/options-general.php' ) . '?page=google-analytics-dashboard/gad-admin-options.php&oauth_return=true';
		$params['scope']              = 'https://www.googleapis.com/auth/analytics.readonly'; // This is a space seperated list of applications we want access to
		$params['xoauth_displayname'] = 'Analytics Dashboard';

		$consumer = new GADOAuthConsumer( 'anonymous', 'anonymous', NULL );
		$req_req  = GADOAuthRequest::from_consumer_and_token( $consumer, NULL, 'GET', 'https://www.google.com/accounts/OAuthGetRequestToken', $params );
		$req_req->sign_request( $signature_method, $consumer, NULL );

		$ch = curl_init();
		curl_setopt( $ch, CURLOPT_URL, $req_req->to_url() );
		curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 );
		curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );

		$oa_response = curl_exec( $ch );

		if ( curl_errno( $ch ) ) {
			$error_message = curl_error( $ch );
			$info_redirect = gad_get_admin_url( '/options-general.php' ) . '?page=google-analytics-dashboard/gad-admin-options.php&error_message=' . urlencode( $error_message );
			header( "Location: " . $info_redirect );
			die( "" );
		}

		$http_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE );

		if ( $http_code == 200 ) {
			$access_params = $this->split_params( $oa_response );

			add_option( 'gad_oa_anon_token', $access_params['oauth_token'] );
			add_option( 'gad_oa_anon_secret', $access_params['oauth_token_secret'] );

			header( "Location: https://www.google.com/accounts/OAuthAuthorizeToken?oauth_token=" . urlencode( $access_params['oauth_token'] ) );
		} else {
			$info_redirect = gad_get_admin_url( '/options-general.php' ) . '?page=google-analytics-dashboard/gad-admin-options.php&error_message=' . urlencode( $oa_response );
			header( "Location: " . $info_redirect );
		}

		die( "" );
	}

	function admin_handle_oauth_complete() {
		// step two in oauth login process

		if ( function_exists( 'current_user_can' ) && ! current_user_can( 'manage_options' ) ) {
			die( __( 'Cheatin&#8217; uh?' ) );
		}

		$signature_method = new GADOAuthSignatureMethod_HMAC_SHA1();
		$params           = array();

		$params['oauth_verifier'] = $_REQUEST['oauth_verifier'];

		$consumer = new GADOAuthConsumer( 'anonymous', 'anonymous', NULL );

		$upgrade_token = new GADOAuthConsumer( get_option( 'gad_oa_anon_token' ), get_option( 'gad_oa_anon_secret' ) );

		$acc_req = GADOAuthRequest::from_consumer_and_token( $consumer, $upgrade_token, 'GET', 'https://www.google.com/accounts/OAuthGetAccessToken', $params );

		$acc_req->sign_request( $signature_method, $consumer, $upgrade_token );

		$ch = curl_init();
		curl_setopt( $ch, CURLOPT_URL, $acc_req->to_url() );
		curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 );
		curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );

		$oa_response = curl_exec( $ch );

		if ( curl_errno( $ch ) ) {
			$error_message = curl_error( $ch );
			$info_redirect = gad_get_admin_url( '/options-general.php' ) . '?page=google-analytics-dashboard/gad-admin-options.php&error_message=' . urlencode( $error_message );
			header( "Location: " . $info_redirect );
			die( "" );
		}

		$http_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE );

		delete_option( 'gad_oa_anon_token' );
		delete_option( 'gad_oa_anon_secret' );

		if ( $http_code == 200 ) {
			$access_params = $this->split_params( $oa_response );

			update_option( 'gad_oauth_token', $access_params['oauth_token'] );
			update_option( 'gad_oauth_secret', $access_params['oauth_token_secret'] );
			update_option( 'gad_auth_token', 'gad_see_oauth' );

			$info_redirect = gad_get_admin_url( '/options-general.php' ) . '?page=google-analytics-dashboard/gad-admin-options.php&info_message=' . urlencode( 'Authenticated!' );
			header( "Location: " . $info_redirect );
		} else {
			$info_redirect = gad_get_admin_url( '/options-general.php' ) . '?page=google-analytics-dashboard/gad-admin-options.php&error_message=' . urlencode( $oa_response );
			header( "Location: " . $info_redirect );
		}

		die( "" );
	}

	function split_params( $response ) {
		$params      = array();
		$param_pairs = explode( '&', $response );
		foreach ( $param_pairs as $param_pair ) {
			if ( trim( $param_pair ) == '' ) {
				continue;
			}
			list( $key, $value ) = explode( '=', $param_pair );
			$params[$key] = urldecode( $value );
		}

		return $params;
	}
}
