%PDF- %PDF-
Direktori : /var/www/tif-dev/wp-content/plugins/gravityforms/includes/locking/ |
Current File : //var/www/tif-dev/wp-content/plugins/gravityforms/includes/locking/class-gf-locking.php |
<?php if ( ! class_exists( 'GFForms' ) ) { die(); } /** * Handles all tasks related to locking. * * - Loads the WordPress Heartbeat API and scripts & styles for GF Locking * - Provides standardized UX * * @package GFLocking * @author Rocketgenius */ abstract class GFLocking { private $_object_type; private $_object_id; private $_edit_url; private $_redirect_url; private $_capabilities; const PREFIX_EDIT_LOCK = 'lock_'; const PREFIX_EDIT_LOCK_REQUEST = 'lock_request_'; public function __construct( $object_type, $redirect_url, $edit_url = '', $capabilities = array() ) { $this->_object_type = $object_type; $this->_redirect_url = $redirect_url; $this->_capabilities = $capabilities; if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { $this->init_ajax(); } else { $this->register_scripts(); $is_locking_page = false; $is_edit_page = false; if ( $this->is_edit_page() ) { $this->init_edit_lock(); $is_locking_page = true; $is_edit_page = true; } else if ( $this->is_list_page() ) { $this->init_list_page(); $is_locking_page = true; } else if ( $this->is_view_page() ) { $this->init_view_page(); $is_locking_page = true; } if ( $is_locking_page ) { $this->_object_id = $this->get_object_id(); $this->_edit_url = $edit_url; $this->maybe_lock_object( $is_edit_page ); } } } /** * Override this method to check the condition for the edit page. * * @return bool */ protected function is_edit_page() { return false; } /** * Override this method to check the condition for the list page. * * @return bool */ protected function is_list_page() { return false; } /** * Override this method to check the condition for the view page. * * @return bool */ protected function is_view_page() { return false; } /** * Override this method to provide the class with the correct object id. * * @return bool */ protected function get_object_id() { $id = rgget( 'id' ); $id = absint( $id ); return $id; // example in the case of form id } public function init_edit_lock() { add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); } public function init_ajax() { add_filter( 'heartbeat_received', array( $this, 'heartbeat_refresh_nonces' ), 10, 3 ); add_filter( 'heartbeat_received', array( $this, 'heartbeat_check_locked_objects' ), 10, 3 ); add_filter( 'heartbeat_received', array( $this, 'heartbeat_refresh_lock' ), 10, 3 ); add_filter( 'heartbeat_received', array( $this, 'heartbeat_request_lock' ), 10, 3 ); add_filter( 'wp_ajax_gf_lock_request_' . $this->_object_type, array( $this, 'ajax_lock_request' ) ); add_filter( 'wp_ajax_gf_reject_lock_request_' . $this->_object_type, array( $this, 'ajax_reject_lock_request' ) ); } public function init_list_page() { add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_list_scripts' ) ); } public function init_view_page() { add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_view_page_scripts' ) ); } public function register_scripts() { $min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG || isset( $_GET['gform_debug'] ) ? '' : '.min'; $locking_path = GFCommon::get_base_url() . '/includes/locking/'; wp_register_script( 'gforms_locking', $locking_path . "js/locking{$min}.js", array( 'jquery', 'heartbeat' ), GFCommon::$version ); wp_register_script( 'gforms_locking_view', $locking_path . "js/locking-view{$min}.js", array( 'jquery', 'heartbeat' ), GFCommon::$version ); wp_register_script( 'gforms_locking_list', $locking_path . "js/locking-list{$min}.js", array( 'jquery', 'heartbeat' ), GFCommon::$version ); wp_register_style( 'gforms_locking_css', $locking_path . "css/locking{$min}.css", array(), GFCommon::$version ); wp_register_style( 'gforms_locking_list_css', $locking_path . "css/locking-list{$min}.css", array(), GFCommon::$version ); // No conflict scripts add_filter( 'gform_noconflict_scripts', array( $this, 'register_noconflict_scripts' ) ); add_filter( 'gform_noconflict_styles', array( $this, 'register_noconflict_styles' ) ); } public function register_noconflict_scripts( $scripts ) { $locking_scripts = array( 'gforms_locking', 'gforms_locking_list', 'gforms_locking_view' ); return array_merge( $scripts, $locking_scripts ); } public function register_noconflict_styles( $styles ) { $locking_styles = array( 'gforms_locking_css', 'gforms_locking_list_css' ); return array_merge( $styles, $locking_styles ); } public function enqueue_scripts() { wp_enqueue_script( 'gforms_locking' ); wp_enqueue_style( 'gforms_locking_css' ); $lock_user_id = $this->check_lock( $this->get_object_id() ); $strings = array( 'noResponse' => $this->get_string( 'no_response' ), 'requestAgain' => $this->get_string( 'request_again' ), 'requestError' => $this->get_string( 'request_error' ), 'gainedControl' => $this->get_string( 'gained_control' ), 'rejected' => $this->get_string( 'request_rejected' ), 'pending' => $this->get_string( 'request_pending' ) ); $vars = array( 'hasLock' => ! $lock_user_id ? 1 : 0, 'lockUI' => $this->get_lock_ui( $lock_user_id ), 'objectID' => $this->_object_id, 'objectType' => $this->_object_type, 'strings' => $strings, ); wp_localize_script( 'gforms_locking', 'gflockingVars', $vars ); } public function enqueue_list_scripts() { wp_enqueue_script( 'gforms_locking_list' ); wp_enqueue_style( 'gforms_locking_list_css' ); $vars = array( 'objectType' => $this->_object_type, ); wp_localize_script( 'gforms_locking_list', 'gflockingVars', $vars ); } public function enqueue_view_page_scripts() { wp_enqueue_script( 'gforms_locking_view' ); wp_enqueue_style( 'gforms_locking_view_css' ); $lock_user_id = $this->check_lock( $this->get_object_id() ); $vars = array( 'hasLock' => ! $lock_user_id ? 1 : 0, 'objectID' => $this->_object_id, 'objectType' => $this->_object_type, ); wp_localize_script( 'gforms_locking_view', 'gflockingVars', $vars ); } protected function get_strings() { $strings = array( 'currently_locked' => wp_strip_all_tags( __( 'This page is currently locked. Click on the "Request Control" button to let %s know you\'d like to take over.', 'gravityforms' ) ), 'accept' => wp_strip_all_tags( __( 'Accept', 'gravityforms' ) ), 'cancel' => wp_strip_all_tags( __( 'Cancel', 'gravityforms' ) ), 'currently_editing' => wp_strip_all_tags( __( '%s is currently editing', 'gravityforms' ) ), 'taken_over' => wp_strip_all_tags( __( '%s has taken over and is currently editing.', 'gravityforms' ) ), 'lock_requested' => wp_strip_all_tags( __( '%s has requested permission to take over control.', 'gravityforms' ) ), 'gained_control' => wp_strip_all_tags( __( 'You now have control', 'gravityforms' ) ), 'request_pending' => wp_strip_all_tags( __( 'Pending', 'gravityforms' ) ), 'no_response' => wp_strip_all_tags( __( 'No response', 'gravityforms' ) ), 'request_again' => wp_strip_all_tags( __( 'Request again', 'gravityforms' ) ), 'request_error' => wp_strip_all_tags( __( 'Error', 'gravityforms' ) ), 'request_rejected' => wp_strip_all_tags( __( 'Your request was rejected', 'gravityforms' ) ), ); return $strings; } public function ajax_lock_request() { $object_id = rgget( 'object_id' ); $response = $this->request_lock( $object_id ); echo json_encode( $response ); die(); } public function ajax_reject_lock_request() { $object_id = rgget( 'object_id' ); $response = $this->delete_lock_request_meta( $object_id ); echo json_encode( $response ); die(); } protected function has_lock() { return $this->check_lock( $this->get_object_id() ) ? true : false; } protected function check_lock( $object_id ) { if ( ! $user_id = $this->get_lock_meta( $object_id ) ) { return false; } if ( $user_id != get_current_user_id() ) { return $user_id; } return false; } protected function check_lock_request( $object_id ) { if ( ! $user_id = $this->get_lock_request_meta( $object_id ) ) { return false; } if ( $user_id != get_current_user_id() ) { return $user_id; } return false; } protected function set_lock( $object_id ) { if ( ! GFCommon::current_user_can_any( $this->_capabilities ) ) { return false; } if ( 0 == ( $user_id = get_current_user_id() ) ) { return false; } $this->update_lock_meta( $object_id, $user_id ); return $user_id; } protected function request_lock( $object_id ) { if ( 0 == ( $user_id = get_current_user_id() ) ) { return false; } $lock_holder_user_id = $this->check_lock( $object_id ); $result = array(); if ( ! $lock_holder_user_id ) { $this->set_lock( $object_id ); $result['html'] = __( 'You now have control', 'gravityforms' ); $result['status'] = 'lock_obtained'; } else { $user = get_userdata( $lock_holder_user_id ); $this->update_lock_request_meta( $object_id, $user_id ); $result['html'] = sprintf( __( 'Your request has been sent to %s.', 'gravityforms' ), $user->display_name ); $result['status'] = 'lock_requested'; } return $result; } protected function get_lock_request_meta( $object_id ) { return GFCache::get( self::PREFIX_EDIT_LOCK_REQUEST . $this->_object_type . '_' . $object_id ); } protected function get_lock_meta( $object_id ) { return GFCache::get( self::PREFIX_EDIT_LOCK . $this->_object_type . '_' . $object_id ); } protected function update_lock_meta( $object_id, $lock_value ) { GFCache::set( self::PREFIX_EDIT_LOCK . $this->_object_type . '_' . $object_id, $lock_value, true, 150 ); } protected function update_lock_request_meta( $object_id, $lock_request_value ) { GFCache::set( self::PREFIX_EDIT_LOCK_REQUEST . $this->_object_type . '_' . $object_id, $lock_request_value, true, 120 ); } protected function delete_lock_request_meta( $object_id ) { GFCache::delete( self::PREFIX_EDIT_LOCK_REQUEST . $this->_object_type . '_' . $object_id ); return true; } protected function delete_lock_meta( $object_id ) { GFCache::delete( self::PREFIX_EDIT_LOCK . $this->_object_type . '_' . $object_id ); return true; } public function maybe_lock_object( $is_edit_page ) { if ( isset( $_GET['get-edit-lock'] ) ) { $this->set_lock( $this->_object_id ); wp_safe_redirect( $this->_edit_url ); exit(); } else if ( isset( $_GET['release-edit-lock'] ) ) { $this->delete_lock_meta( $this->_object_id ); wp_safe_redirect( $this->_redirect_url ); exit(); } else { if ( $is_edit_page && ! $user_id = $this->check_lock( $this->_object_id ) ) { $this->set_lock( $this->_object_id ); } } } public function heartbeat_check_locked_objects( $response, $data, $screen_id ) { $checked = array(); $heartbeat_key = 'gform-check-locked-objects-' . $this->_object_type; if ( array_key_exists( $heartbeat_key, $data ) && is_array( $data[ $heartbeat_key ] ) ) { foreach ( $data[ $heartbeat_key ] as $object_id ) { if ( ( $user_id = $this->check_lock( $object_id ) ) && ( $user = get_userdata( $user_id ) ) ) { $send = array( 'text' => sprintf( __( $this->get_string( 'currently_editing' ) ), $user->display_name ) ); if ( ( $avatar = get_avatar( $user->ID, 18 ) ) && preg_match( "|src='([^']+)'|", $avatar, $matches ) ) { $send['avatar_src'] = $matches[1]; } $checked[ $object_id ] = $send; } } } if ( ! empty( $checked ) ) { $response[ $heartbeat_key ] = $checked; } return $response; } public function heartbeat_refresh_lock( $response, $data, $screen_id ) { $heartbeat_key = 'gform-refresh-lock-' . $this->_object_type; if ( array_key_exists( $heartbeat_key, $data ) ) { $received = $data[ $heartbeat_key ]; $send = array(); if ( ! isset( $received['objectID'] ) ) { return $response; } $object_id = $received['objectID']; if ( ( $user_id = $this->check_lock( $object_id ) ) && ( $user = get_userdata( $user_id ) ) ) { $error = array( 'text' => sprintf( __( $this->get_string( 'taken_over' ) ), $user->display_name ) ); if ( $avatar = get_avatar( $user->ID, 64 ) ) { if ( preg_match( "|src='([^']+)'|", $avatar, $matches ) ) { $error['avatar_src'] = $matches[1]; } } $send['lock_error'] = $error; } else { if ( $new_lock = $this->set_lock( $object_id ) ) { $send['new_lock'] = $new_lock; if ( ( $lock_requester = $this->check_lock_request( $object_id ) ) && ( $user = get_userdata( $lock_requester ) ) ) { $lock_request = array( 'text' => sprintf( __( $this->get_string( 'lock_requested' ) ), $user->display_name ) ); if ( $avatar = get_avatar( $user->ID, 64 ) ) { if ( preg_match( "|src='([^']+)'|", $avatar, $matches ) ) { $lock_request['avatar_src'] = $matches[1]; } } $send['lock_request'] = $lock_request; } } } $response[ $heartbeat_key ] = $send; } return $response; } public function heartbeat_request_lock( $response, $data, $screen_id ) { $heartbeat_key = 'gform-request-lock-' . $this->_object_type; if ( array_key_exists( $heartbeat_key, $data ) ) { $received = $data[ $heartbeat_key ]; $send = array(); if ( ! isset( $received['objectID'] ) ) { return $response; } $object_id = $received['objectID']; if ( ( $user_id = $this->check_lock( $object_id ) ) && ( $user = get_userdata( $user_id ) ) ) { if ( $this->get_lock_request_meta( $object_id ) ) { $send['status'] = 'pending'; } else { $send['status'] = 'deleted'; } } else { if ( $new_lock = $this->set_lock( $object_id ) ) { $send['status'] = 'granted'; } } $response[ $heartbeat_key ] = $send; } return $response; } public function heartbeat_refresh_nonces( $response, $data, $screen_id ) { if ( array_key_exists( 'gform-refresh-nonces', $data ) ) { $received = $data['gform-refresh-nonces']; $response['gform-refresh-nonces'] = array( 'check' => 1 ); if ( ! isset( $received['objectID'] ) ) { return $response; } $object_id = $received['objectID']; if ( ! GFCommon::current_user_can_any( $this->_capabilities ) || empty( $received['post_nonce'] ) ) { return $response; } if ( 2 === wp_verify_nonce( $received['object_nonce'], 'update-contact_' . $object_id ) ) { $response['gform-refresh-nonces'] = array( 'replace' => array( '_wpnonce' => wp_create_nonce( 'update-object_' . $object_id ), ), 'heartbeatNonce' => wp_create_nonce( 'heartbeat-nonce' ), ); } } return $response; } public function get_lock_ui( $user_id ) { $user = get_userdata( $user_id ); $locked = $user_id && $user; $edit_url = $this->_edit_url; $hidden = $locked ? '' : ' hidden'; if ( $locked ) { $message = '<div class="gform-locked-message"> <div class="gform-locked-avatar">' . get_avatar( $user->ID, 64 ) . '</div> <p class="currently-editing" tabindex="0">' . sprintf( $this->get_string( 'currently_locked' ), $user->display_name ) . '</p> <p> <a id="gform-take-over-button" style="display:none" class="button button-primary wp-tab-first" href="' . esc_url( add_query_arg( 'get-edit-lock', '1', $edit_url ) ) . '">' . __( 'Take Over', 'gravityforms' ) . '</a> <button id="gform-lock-request-button" class="button button-primary wp-tab-last">' . __( 'Request Control', 'gravityforms' ) . '</button> <a class="button" href="' . esc_url( $this->_redirect_url ) . '">' . $this->get_string( 'cancel' ) . '</a> </p> <div id="gform-lock-request-status"> <!-- placeholder --> </div> </div>'; } else { $message = '<div class="gform-taken-over"> <div class="gform-locked-avatar"></div> <p class="wp-tab-first" tabindex="0"> <span class="currently-editing"></span><br> </p> <p> <a id="gform-release-lock-button" class="button button-primary wp-tab-last" href="' . esc_url( add_query_arg( 'release-edit-lock', '1', $edit_url ) ) . '">' . $this->get_string( 'accept' ) . '</a> <button id="gform-reject-lock-request-button" style="display:none" class="button button-primary wp-tab-last">' . __( 'Reject Request', 'gravityforms' ) . '</button> </p> </div>'; } $html = '<div id="gform-lock-dialog" class="notification-dialog-wrap' . $hidden . '"> <div class="notification-dialog-background"></div> <div class="notification-dialog">'; $html .= $message; $html .= ' </div> </div>'; return $html; } public function get_string( $string_key ) { $strings = $this->get_strings(); return rgar( $strings, $string_key ); } // helper functions for the list page public function list_row_class( $object_id, $echo = true ) { $locked_class = $this->is_locked( $object_id ) ? 'wp-locked' : ''; $classes = ' gf-locking ' . $locked_class; if ( $echo ) { echo $classes; } return $classes; } public function is_locked( $object_id ) { if ( ! $user_id = GFCache::get( self::PREFIX_EDIT_LOCK . $this->_object_type . '_' . $object_id ) ) { return false; } if ( $user_id != get_current_user_id() ) { return true; } return false; } public function lock_indicator( $echo = true ) { $lock_indicator = '<div class="locked-indicator"></div>'; if ( $echo ) { echo $lock_indicator; } return $lock_indicator; } public function lock_info( $object_id, $echo = true ) { $user_id = $this->check_lock( $object_id ); if ( ! $user_id ) { return ''; } if ( $user_id && $user = get_userdata( $user_id ) ) { $locked_avatar = get_avatar( $user->ID, 18 ); $locked_text = esc_html( sprintf( $this->get_string( 'currently_editing' ), $user->display_name ) ); } else { $locked_avatar = $locked_text = ''; } $locked_info = '<div class="locked-info"><span class="locked-avatar">' . $locked_avatar . '</span> <span class="locked-text">' . $locked_text . "</span></div>\n"; if ( $echo ) { echo $locked_info; } return $locked_info; } protected function is_page( $page_name ) { return $page_name == GFForms::get_page(); } }