/var/www/html_us/wp-content/plugins/woocommerce/src/Internal/Admin/Orders/EditLock.php


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
<?php
namespace Automattic\WooCommerce\Internal\Admin\Orders;

/**
 * This class takes care of the edit lock logic when HPOS is enabled.
 * For better interoperability with WordPress, edit locks are stored in the same format as posts. That is, as a metadata
 * in the order object (key: '_edit_lock') in the format "timestamp:user_id".
 *
 * @since 7.8.0
 */
class EditLock {

    const 
META_KEY_NAME '_edit_lock';

    
/**
     * Obtains lock information for a given order. If the lock has expired or it's assigned to an invalid user,
     * the order is no longer considered locked.
     *
     * @param \WC_Order $order Order to check.
     * @return bool|array
     */
    
public function get_lock\WC_Order $order ) {
        
$lock $order->get_metaself::META_KEY_NAMEtrue'edit' );
        if ( ! 
$lock ) {
            return 
false;
        }

        
$lock explode':'$lock );
        if ( 
!== count$lock ) ) {
            return 
false;
        }

        
$time    absint$lock[0] );
        
$user_id = isset( $lock[1] ) ? absint$lock[1] ) : 0;

        if ( ! 
$time || ! get_user_by'id'$user_id ) ) {
            return 
false;
        }

        
/** This filter is documented in WP's wp-admin/includes/ajax-actions.php */
        
$time_window apply_filters'wp_check_post_lock_window'150 ); // phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingSinceComment
        
if ( time() >= ( $time $time_window ) ) {
            return 
false;
        }

        return 
compact'time''user_id' );
    }

    
/**
     * Checks whether the order is being edited (i.e. locked) by another user.
     *
     * @param \WC_Order $order Order to check.
     * @return bool TRUE if order is locked and currently being edited by another user. FALSE otherwise.
     */
    
public function is_locked_by_another_user\WC_Order $order ) : bool {
        
$lock $this->get_lock$order );
        return 
$lock && ( get_current_user_id() !== $lock['user_id'] );
    }

    
/**
     * Checks whether the order is being edited by any user.
     *
     * @param \WC_Order $order Order to check.
     * @return boolean TRUE if order is locked and currently being edited by a user. FALSE otherwise.
     */
    
public function is_locked\WC_Order $order ) : bool {
        return (bool) 
$this->get_lock$order );
    }

    
/**
     * Assigns an order's edit lock to the current user.
     *
     * @param \WC_Order $order The order to apply the lock to.
     * @return array|bool FALSE if no user is logged-in, an array in the same format as {@see get_lock()} otherwise.
     */
    
public function lock\WC_Order $order ) {
        
$user_id get_current_user_id();

        if ( ! 
$user_id ) {
            return 
false;
        }

        
$order->update_meta_dataself::META_KEY_NAMEtime() . ':' $user_id );
        
$order->save_meta_data();

        return 
$order->get_metaself::META_KEY_NAMEtrue'edit' );
    }

    
/**
     * Hooked to 'heartbeat_received' on the edit order page to refresh the lock on an order being edited by the current user.
     *
     * @param array $response The heartbeat response to be sent.
     * @param array $data     Data sent through the heartbeat.
     * @return array Response to be sent.
     */
    
public function refresh_lock_ajax$response$data ) {
        
$order_id absint$data['wc-refresh-order-lock'] ?? );
        if ( ! 
$order_id ) {
            return 
$response;
        }

        unset( 
$response['wp-refresh-post-lock'] );

        
$order wc_get_order$order_id );
        if ( ! 
$order || ( ! current_user_canget_post_type_object$order->get_type() )->cap->edit_post$order->get_id() ) && ! current_user_can'manage_woocommerce' ) ) ) {
            return 
$response;
        }

        
$response['wc-refresh-order-lock'] = array();

        if ( ! 
$this->is_locked_by_another_user$order ) ) {
            
$response['wc-refresh-order-lock']['lock'] = $this->lock$order );
        } else {
            
$current_lock $this->get_lock$order );
            
$user         get_user_by'id'$current_lock['user_id'] );

            
$response['wc-refresh-order-lock']['error'] = array(
                
// translators: %s is a user's name.
                
'message'            => sprintf__'%s has taken over and is currently editing.''woocommerce' ), $user->display_name ),
                
'user_name'          => $user->display_name,
                
'user_avatar_src'    => get_option'show_avatars' ) ? get_avatar_url$user->ID, array( 'size' => 64 ) ) : '',
                
'user_avatar_src_2x' => get_option'show_avatars' ) ? get_avatar_url$user->ID, array( 'size' => 128 ) ) : '',
            );
        }

        return 
$response;
    }

    
/**
     * Hooked to 'heartbeat_received' on the orders screen to refresh the locked status of orders in the list table.
     *
     * @param array $response The heartbeat response to be sent.
     * @param array $data     Data sent through the heartbeat.
     * @return array Response to be sent.
     */
    
public function check_locked_orders_ajax$response$data ) {
        if ( empty( 
$data['wc-check-locked-orders'] ) || ! is_array$data['wc-check-locked-orders'] ) ) {
            return 
$response;
        }

        
$response['wc-check-locked-orders'] = array();

        
$order_ids array_uniquearray_map'absint'$data['wc-check-locked-orders'] ) );
        foreach ( 
$order_ids as $order_id ) {
            
$order wc_get_order$order_id );
            if ( ! 
$order ) {
                continue;
            }

            if ( ! 
$this->is_locked_by_another_user$order ) || ( ! current_user_canget_post_type_object$order->get_type() )->cap->edit_post$order->get_id() ) && ! current_user_can'manage_woocommerce' ) ) ) {
                continue;
            }

            
$response['wc-check-locked-orders'][ $order_id ] = true;
        }

        return 
$response;
    }

    
/**
     * Outputs HTML for the lock dialog based on the status of the lock on the order (if any).
     * Depending on who owns the lock, this could be a message with the chance to take over or a message indicating that
     * someone else has taken over the order.
     *
     * @param \WC_Order $order Order object.
     * @return void
     */
    
public function render_dialog$order ) {
        
$lock   $this->get_lock$order );
        
$user   $lock get_user_by'id'$lock['user_id'] ) : false;
        
$locked $user && ( get_current_user_id() !== $user->ID );

        
$edit_url wc_get_container()->get\Automattic\WooCommerce\Internal\Admin\Orders\PageController::class )->get_edit_url$order->get_id() );

        
$sendback_url wp_get_referer();
        if ( ! 
$sendback_url ) {
            
$sendback_url wc_get_container()->get\Automattic\WooCommerce\Internal\Admin\Orders\PageController::class )->get_base_page_url$order->get_type() );
        }

        
$sendback_text __'Go back''woocommerce' );
        
?>
        <div id="post-lock-dialog" class="notification-dialog-wrap <?php echo $locked '' 'hidden'?> order-lock-dialog">
            <div class="notification-dialog-background"></div>
            <div class="notification-dialog">
            <?php if ( $locked ) : ?>
            <div class="post-locked-message">
                <div class="post-locked-avatar"><?php echo get_avatar$user->ID64 ); ?></div>
                <p class="currently-editing wp-tab-first" tabindex="0">
                <?php
                
// translators: %s is a user's name.
                
echo esc_htmlsprintf__'%s is currently editing this order. Do you want to take over?''woocommerce' ), esc_html$user->display_name ) ) );
                
?>
                </p>
                <p>
                    <a class="button" href="<?php echo esc_url$sendback_url ); ?>"><?php echo esc_html$sendback_text ); ?></a>
                    <a class="button button-primary wp-tab-last" href="<?php echo esc_urladd_query_arg'claim-lock''1'wp_nonce_url$edit_url'claim-lock-' $order->get_id() ) ) ); ?>"><?php esc_html_e'Take over''woocommerce' ); ?></a>
                </p>
            </div>
            <?php else : ?>
            <div class="post-taken-over">
                <div class="post-locked-avatar"></div>
                <p class="wp-tab-first" tabindex="0">
                <span class="currently-editing"></span><br />
                </p>
                <p><a class="button button-primary wp-tab-last" href="<?php echo esc_url$sendback_url ); ?>"><?php echo esc_html$sendback_text ); ?></a></p>
            </div>
            <?php endif; ?>
            </div>
        </div>
        <?php
    
}

}