init_defaults(); $this->init_options(); $this->revision = $this->default->revision; $this->init_hooks(); } private function init_defaults() { $this->default = new stdClass(); $this->default->options = array( 'auto_draft_interval' => 60000, 'max_drafts_per_page' => 3, 'is_preview_on' => 1, 'is_draft_on' => 1 ); $this->default->revision = array( 'revisionid' => 0, 'userid' => 0, 'textareaid' => '', 'postid' => 0, 'body' => '', 'created' => 0, 'version' => 0, 'email' => '', 'url' => '', ); $this->default->revision_format = array( 'revisionid' => '%d', 'userid' => '%d', 'textareaid' => '%s', 'postid' => '%d', 'body' => '%s', 'created' => '%d', 'version' => '%d', 'email' => '%s', 'url' => '%s' ); $this->default->sql_select_args = array( 'include' => array(), 'exclude' => array(), 'userids_include' => array(), 'userids_exclude' => array(), 'textareaids_include' => array(), 'textareaids_exclude' => array(), 'postids_include' => array(), 'postids_exclude' => array(), 'urls_include' => array(), 'urls_exclude' => array(), 'emails_include' => array(), 'emails_exclude' => array(), 'orderby' => 'revisionid', 'order' => 'DESC', 'offset' => null, 'row_count' => null ); } private function init_options() { $this->options = get_wpf_option( 'wpforo_revision_options', $this->default->options ); } private function init_hooks() { if( $this->options['is_preview_on'] || $this->options['is_draft_on'] ){ add_action('wpforo_editor_topic_submit_after', array($this, 'show_html_into_form')); add_action('wpforo_editor_post_submit_after', array($this, 'show_html_into_form')); add_action('wpforo_portable_editor_post_submit_after', array($this, 'show_html_into_form')); if( $this->options['is_preview_on'] ) add_action('wp_ajax_wpforo_post_preview', array($this, 'ajax_post_preview')); if( $this->options['is_draft_on'] ){ add_action( 'wpforo_after_add_topic', array( $this, 'after_submit' ) ); add_action( 'wpforo_after_add_post', array( $this, 'after_submit' ) ); add_action( 'wpforo_after_edit_topic', array( $this, 'after_submit' ) ); add_action( 'wpforo_after_edit_post', array( $this, 'after_submit' ) ); add_action('wp_ajax_wpforo_save_revision', array($this, 'ajax_save_revision')); add_action('wp_ajax_wpforo_get_revisions_history', array($this, 'ajax_get_revisions_history')); add_action('wp_ajax_wpforo_get_revision', array($this, 'ajax_get_revision')); add_action('wp_ajax_wpforo_delete_revision', array($this, 'ajax_delete_revision')); } } } private function get_current_url_query_vars_str(){ $url_query_vars_str = wpforo_get_url_query_vars_str(); $url_query_vars_str = preg_replace( '#^/?'.preg_quote(WPF()->permastruct).'#isu', '' , $url_query_vars_str, 1 ); $url_query_vars_str = preg_replace('#/?\?.*$#isu', '', $url_query_vars_str); $wpf_url_parse = array_filter( explode('/', trim($url_query_vars_str, '/')) ); $wpf_url_parse = array_reverse($wpf_url_parse); if(in_array(wpforo_get_template_slug('paged'), $wpf_url_parse)){ foreach($wpf_url_parse as $key => $value){ unset($wpf_url_parse[$key]); if( $value === wpforo_get_template_slug('paged')) break; } $wpf_url_parse = array_values($wpf_url_parse); $wpf_url_parse = array_reverse($wpf_url_parse); $url_query_vars_str = implode('/', $wpf_url_parse); } if( !$url_query_vars_str ) $url_query_vars_str = 'wpforo_home_url'; return $url_query_vars_str; } private function parse_revision( $revision ) { $revision = array_merge( $this->default->revision, $revision ); if( $revision['body'] ){ $revision['body'] = preg_replace('#[\r\n\t\s\0]*
#isu', "\r\n", $revision['body']);
			$revision['body'] = wpforo_kses(trim($revision['body']), 'post');
			$revision['body'] = stripslashes($revision['body']);
		}
		return $revision;
	}

	private function parse_args( $args ) {
		$args = wpforo_parse_args( $args, $this->default->sql_select_args );

		$args['include'] = wpforo_parse_args( $args['include'] );
		$args['exclude'] = wpforo_parse_args( $args['exclude'] );

		$args['userids_include'] = wpforo_parse_args( $args['userids_include'] );
		$args['userids_exclude'] = wpforo_parse_args( $args['userids_exclude'] );

		$args['textareaids_include'] = wpforo_parse_args( $args['textareaids_include'] );
		$args['textareaids_exclude'] = wpforo_parse_args( $args['textareaids_exclude'] );

		$args['postids_include'] = wpforo_parse_args( $args['postids_include'] );
		$args['postids_exclude'] = wpforo_parse_args( $args['postids_exclude'] );

		$args['urls_include'] = wpforo_parse_args( $args['urls_include'] );
		$args['urls_exclude'] = wpforo_parse_args( $args['urls_exclude'] );

		$args['emails_include'] = wpforo_parse_args( $args['emails_include'] );
		$args['emails_exclude'] = wpforo_parse_args( $args['emails_exclude'] );

		return $args;
	}

	private function build_sql_where ( $args ){
	    $where = '';
		$args = $this->parse_args( $args );

		$wheres = array();
		if ( ! empty( $args['include'] ) ) {
			$wheres[] = "`revisionid` IN(" . implode( ',', array_map( 'wpforo_bigintval', $args['include'] ) ) . ")";
		}
		if ( ! empty( $args['exclude'] ) ) {
			$wheres[] = "`revisionid` NOT IN(" . implode( ',', array_map( 'wpforo_bigintval', $args['exclude'] ) ) . ")";
		}

		if ( ! empty( $args['userids_include'] ) ) {
			$wheres[] = "`userid` IN(" . implode( ',', array_map( 'wpforo_bigintval', $args['userids_include'] ) ) . ")";
		}
		if ( ! empty( $args['userids_exclude'] ) ) {
			$wheres[] = "`userid` NOT IN(" . implode( ',', array_map( 'wpforo_bigintval', $args['userids_exclude'] ) ) . ")";
		}

		if ( ! empty( $args['textareaids_include'] ) ) {
			$wheres[] = "`textareaid` IN('" . implode( "','", array_map( 'trim', $args['textareaids_include'] ) ) . "')";
		}
		if ( ! empty( $args['textareaids_exclude'] ) ) {
			$wheres[] = "`textareaid` IN('" . implode( "','", array_map( 'trim', $args['textareaids_exclude'] ) ) . "')";
		}

		if ( ! empty( $args['postids_include'] ) ) {
			$wheres[] = "`postid` IN(" . implode( ',', array_map( 'wpforo_bigintval', $args['postids_include'] ) ) . ")";
		}
		if ( ! empty( $args['postids_exclude'] ) ) {
			$wheres[] = "`postid` NOT IN(" . implode( ',', array_map( 'wpforo_bigintval', $args['postids_exclude'] ) ) . ")";
		}

		if ( ! empty( $args['urls_include'] ) ) {
			$wheres[] = "`url` IN('" . implode( "','", array_map( 'trim', $args['urls_include'] ) ) . "')";
		}
		if ( ! empty( $args['urls_exclude'] ) ) {
			$wheres[] = "`url` IN('" . implode( "','", array_map( 'trim', $args['urls_exclude'] ) ) . "')";
		}

		if ( ! empty( $args['emails_include'] ) ) {
			$wheres[] = "`email` IN('" . implode( "','", array_map( 'trim', $args['emails_include'] ) ) . "')";
		}
		if ( ! empty( $args['emails_exclude'] ) ) {
			$wheres[] = "`email` IN('" . implode( "','", array_map( 'trim', $args['emails_exclude'] ) ) . "')";
		}

		if ( $wheres ) {
			$where = " WHERE " . implode( " AND ", $wheres );
		}

		return $where;
    }

	private function build_sql_select( $args ) {
		$args = $this->parse_args( $args );
		$sql = "SELECT * FROM " . WPF()->tables->post_revisions;
		$sql .= $this->build_sql_where($args);
		$sql .= " ORDER BY " . $args['orderby'] . " " . $args['order'];
		if ( $args['row_count'] ) $sql .= " LIMIT " . wpforo_bigintval( $args['offset'] ) . "," . wpforo_bigintval( $args['row_count'] );
		return $sql;
	}

	private function add( $data ) {
		if ( empty( $data ) ) return false;
		$revision = $this->parse_revision($data);
		unset( $revision['revisionid'] );

		if ( !$revision['created'] ) $revision['created'] = current_time( 'timestamp', 1 );
		if ( !$revision['url'] )     $revision['url']     = $this->get_current_url_query_vars_str();
		if ( !$revision['userid'] )  $revision['userid']  = WPF()->current_userid;
		if ( !$revision['email'] )   $revision['email']   = WPF()->current_user_email;
		if ( !$revision['textareaid'] || !$revision['url'] || !$revision['body'] || !($revision['userid'] || $revision['email']) ) return false;

		$revision = wpforo_array_ordered_intersect_key( $revision, $this->default->revision_format );
		if ( WPF()->db->insert(
			WPF()->tables->post_revisions,
			$revision,
			wpforo_array_ordered_intersect_key( $this->default->revision_format, $revision )
			)
		) {
			return WPF()->db->insert_id;
		}

		return false;
	}

	private function edit( $data, $where ) {
		if ( empty( $data ) || empty( $where ) ) return false;
		if ( is_numeric( $where ) ) $where = array( 'revisionid' => $where );
		$data  = (array) $data;
		$where = (array) $where;

		$data  = wpforo_array_ordered_intersect_key( $data,  $this->default->revision_format );
		$where = wpforo_array_ordered_intersect_key( $where, $this->default->revision_format );
		if ( false !== WPF()->db->update(
				WPF()->tables->post_revisions,
				$data,
				$where,
				wpforo_array_ordered_intersect_key( $this->default->revision_format, $data ),
				wpforo_array_ordered_intersect_key( $this->default->revision_format, $where )
			)
		) {
			return true;
		}

		return false;
	}

	private function delete( $where ) {
		if( empty($where) ) return false;
		if ( is_numeric( $where ) ) $where = array( 'revisionid' => $where );
		$where = (array) $where;

		$where = wpforo_array_ordered_intersect_key( $where, $this->default->revision_format );
		if ( false !== WPF()->db->delete(
				WPF()->tables->post_revisions,
				$where,
				wpforo_array_ordered_intersect_key( $this->default->revision_format, $where )
			)
		) {
			return true;
		}

		return false;
	}

	public function get_revision( $args ) {
		if ( empty( $args ) ) return false;

		return $this->parse_revision( WPF()->db->get_row( $this->build_sql_select( $args ), ARRAY_A ) );
	}

	public function get_revisions( $args ) {
		if ( empty($args) ) return false;

		return array_map( array( $this, 'parse_revision' ), WPF()->db->get_results( $this->build_sql_select( $args ), ARRAY_A ) );
	}

	/**
	 * @param array $args
	 *
	 * @return int
	 */
	private function get_count( $args ){
		$sql = "SELECT SQL_NO_CACHE COUNT(*) FROM " . WPF()->tables->post_revisions;
		$sql .= $this->build_sql_where($args);
		return intval( WPF()->db->get_var($sql) );
	}

	public function show_html_into_form(){
	    if( $this->options['is_draft_on'] ){
		    $args = array(
//			'textareaids_include' => (string) wpfval( $_POST, 'textareaid' ),
			    'postids_include' => wpforo_bigintval( wpfval( $_POST, 'postid' ) ),
			    'userids_include' => WPF()->current_userid,
			    'emails_include'  => WPF()->current_user_email,
			    'urls_include'    => $this->get_current_url_query_vars_str()
		    );
		    $revisions_count = $this->get_count($args);
        }else{
		    $revisions_count = null;
        }

		?>
		
show_wrap_inner_html($revisions_count); ?>
options['is_preview_on'] ){ $buttons .= sprintf(' %1$s ', wpforo_phrase('Preview', false) ); } if( $this->options['is_draft_on'] ){ $revisions_count = intval($revisions_count); $buttons .= sprintf(' %1$s ', sprintf( wpforo_phrase('%1$s Revisions', false), ''.$revisions_count.'' )) . sprintf('', wpforo_phrase('Save Draft', false)) . sprintf(' %1$s ', wpforo_phrase('Saved', false)); } $html = sprintf('
%1$s
', $buttons ); return $html; } private function show_wrap_inner_html($revisions_count = null){ echo $this->build_wrap_inner_html($revisions_count); } private function build_preview($revision){ $html = sprintf('
%3$s
%4$s
', $revision['revisionid'], $revision['created'], wpforo_phrase('Preview', false), wpforo_content($revision, false) ); return $html; } private function show_preview($revision){ echo $this->build_preview($revision); } private function build_revision($revision){ $html = sprintf( '
%3$s %4$s
%5$s  |  %6$s
%7$s
', $revision['revisionid'], $revision['created'], wpforo_phrase('Revision', false), wpforo_date($revision['created'], 'ago', false), wpforo_phrase('Restore', false), wpforo_phrase('Delete', false), wpforo_content($revision, false) ); return $html; } private function show_revision($revision){ echo $this->build_revision($revision); } public function ajax_save_revision() { $args = array( 'textareaid' => (string) wpfval($_POST, 'textareaid'), 'postid' => wpforo_bigintval( wpfval($_POST, 'postid') ), 'body' => (string) wpfval($_POST, 'body') ); $revision = $this->parse_revision($args); $revision['created'] = current_time( 'timestamp', 1 ); $revision['url'] = $this->get_current_url_query_vars_str(); $revision['userid'] = WPF()->current_userid; $revision['email'] = WPF()->current_user_email; if( $revisionid = $this->add($revision) ){ $args = array( // 'textareaids_include' => $revision['textareaid'], 'postids_include' => $revision['postid'], 'userids_include' => $revision['userid'], 'emails_include' => $revision['email'], 'urls_include' => $revision['url'] ); $revisions_count = $this->get_count($args); if( $revisions_count > $this->options['max_drafts_per_page'] ){ $sql = "DELETE FROM " . WPF()->tables->post_revisions . $this->build_sql_where($args) . " ORDER BY `revisionid` ASC LIMIT %d"; $sql = WPF()->db->prepare($sql, ($revisions_count - $this->options['max_drafts_per_page']) ); if( WPF()->db->query($sql) !== false ) $revisions_count = $this->options['max_drafts_per_page']; } }else{ $revisions_count = 0; $revisionid = 0; } $revision['revisionid'] = $revisionid; echo json_encode(array( 'revisionid' => $revisionid, 'revisions_count' => $revisions_count, 'revisionhtml' => $this->build_revision($revision) )); exit(); } public function ajax_post_preview(){ $revision = $this->parse_revision($_POST); $this->show_preview($revision); exit(); } public function ajax_get_revisions_history(){ $args = array( // 'textareaids_include' => (string) wpfval( $_POST, 'textareaid' ), 'postids_include' => wpforo_bigintval( wpfval( $_POST, 'postid' ) ), 'userids_include' => WPF()->current_userid, 'emails_include' => WPF()->current_user_email, 'urls_include' => $this->get_current_url_query_vars_str() ); $revisionhtml = ''; if( $revisions = $this->get_revisions($args) ){ foreach ($revisions as $revision) $revisionhtml .= $this->build_revision($revision); } echo json_encode(array( 'revisions_count' => count($revisions), 'revisionhtml' => $revisionhtml )); exit(); } public function ajax_get_revision(){ if( $revisionid = wpforo_bigintval( wpfval($_POST, 'revisionid') ) ){ if( $revision = $this->get_revision( array('include' => $revisionid) ) ) echo json_encode( $revision ); } exit(); } public function ajax_delete_revision(){ if( $revisionid = wpforo_bigintval( wpfval($_POST, 'revisionid') ) ){ if( $this->delete( $revisionid ) ) echo $revisionid; } exit(); } public function after_submit(){ $this->delete( array( 'userid' => WPF()->current_userid, 'email' => WPF()->current_user_email, 'url' => $this->get_current_url_query_vars_str() ) ); $sql = "SELECT EXISTS( SELECT * FROM ". WPF()->tables->post_revisions ." ) AS is_exists"; if( !WPF()->db->get_var($sql) ) WPF()->db->query("TRUNCATE " . WPF()->tables->post_revisions ); } }