'POST', 'callback' => [ $this, 'filters' ], 'permission_callback' => [ $this, 'permission_callback' ], ] ); register_rest_route( 'pinova/admin/blocks', 'index', [ 'methods' => 'POST', 'callback' => [ $this, 'index' ], 'permission_callback' => [ $this, 'permission_callback' ], 'args' => [ 'identifier' => [ 'required' => false, 'sanitize_callback' => 'sanitize_text_field', ], 'from_date' => [ 'required' => false, 'sanitize_callback' => 'absint', ], 'to_date' => [ 'required' => false, 'sanitize_callback' => 'absint', ], 'blocked_by' => [ 'required' => false, 'sanitize_callback' => 'absint', ], 'page' => [ 'required' => false, 'sanitize_callback' => 'absint', 'default' => 1, ], 'per_page' => [ 'required' => false, 'sanitize_callback' => 'absint', 'default' => 20, ], ], ] ); register_rest_route( 'pinova/admin/blocks', 'add', [ 'methods' => 'POST', 'callback' => [ $this, 'add' ], 'permission_callback' => [ $this, 'permission_callback' ], 'args' => [ 'identifier' => [ 'required' => true, 'sanitize_callback' => 'sanitize_text_field', ], 'blocked_until' => [ 'required' => false, 'sanitize_callback' => 'absint', ], ], ] ); register_rest_route( 'pinova/admin/blocks', 'delete', [ 'methods' => 'POST', 'callback' => [ $this, 'delete' ], 'permission_callback' => [ $this, 'permission_callback' ], 'args' => [ 'block_id' => [ 'required' => true, 'sanitize_callback' => 'absint', ], ], ] ); } public function filters( WP_REST_Request $request ) { if ( ! function_exists( 'get_editable_roles' ) ) { require_once( ABSPATH . '/wp-admin/includes/user.php' ); } // Users $roles = []; foreach ( array_reverse( wp_roles()->roles ) as $id => $role ) { if ( $role['capabilities']['manage_options'] ?? false ) { $roles[] = $id; } } $users = new WP_User_Query( [ 'number' => - 1, 'role__in' => $roles, ] ); $users = collect( $users->get_results() ); self::response( true, null, [ 'users' => $users->pluck( 'display_name', 'ID' )->toArray(), ] ); } public function index( WP_REST_Request $request ) { $raw_identifier = $request->get_param( 'identifier' ); $blocked_by = $request->get_param( 'blocked_by' ); // @todo check it return null $blocked_by = $_POST['blocked_by'] ?? null; $from_date = $request->get_param( 'from_date' ); $to_date = $request->get_param( 'to_date' ); $page = max( 1, $request->get_param( 'page' ) ); $per_page = max( 1, $request->get_param( 'per_page' ) ); $timezone = wp_timezone_string(); if ( ! empty( $from_date ) ) { $from_date = verta() ->timestamp( intval( $from_date ) ) ->timezone( $timezone ) ->startDay() ->toCarbon() ->utc(); } if ( ! empty( $to_date ) ) { $to_date = verta() ->timestamp( intval( $to_date ) ) ->timezone( $timezone ) ->endDay() ->toCarbon() ->utc(); } /** @var Block[]|Builder $query */ $query = Block::query() ->orderByDesc( 'id' ) ->when( $raw_identifier, function ( Builder $query ) use ( $raw_identifier ) { $query->where( function ( Builder $query ) use ( $raw_identifier ) { $query->where( 'identifier', 'LIKE', "%{$raw_identifier}%" ); $identifier = new Identifier( $raw_identifier ); if ( $identifier->is_valid() ) { $query->orWhere( 'identifier', '=', $identifier->get_value() ); } } ); } ) ->when( $blocked_by, function ( Builder $query ) use ( $blocked_by ) { $users = new WP_User_Query( [ 'search' => "*{$blocked_by}*", 'fields' => 'ID', ] ); $query->where( 'blocked_by', '=', $users->get_results() ); } ) ->when( $from_date, function ( Builder $query ) use ( $from_date ) { $query->where( 'blocked_until', '>=', $from_date ); } ) ->when( $to_date, function ( Builder $query ) use ( $to_date ) { $query->where( 'blocked_until', '<=', $to_date ); } ); $total_items = $query->count(); $blocks = $query ->forPage( $page, $per_page ) ->get() ->map( [ $this, 'resource' ] ) ->toArray(); self::response( true, null, [ 'blocks' => $blocks, 'current_page' => intval( $page ), 'total_items' => intval( $total_items ), ] ); } public function add( WP_REST_Request $request ) { $raw_identifier = $request->get_param( 'identifier' ); $blocked_until = $request->get_param( 'blocked_until' ); if ( empty( $blocked_until ) ) { $blocked_until = null; } else { $timezone = wp_timezone_string(); $blocked_until = verta() ->timestamp( intval( $blocked_until ) ) ->timezone( $timezone ) ->endDay() ->toCarbon() ->utc(); if ( $blocked_until->isPast() ) { self::response( false, __( 'تاریخ مسدودیت باید در آینده باشد.', 'pinova' ) ); } } $identifier = $this->expand_identifier( $raw_identifier ); if ( empty( $identifier ) ) { self::response( false, __( 'شناسه وارد شده معتبر نمی‌باشد.', 'pinova' ) ); } /**@var Block $block */ $block = Block::query()->updateOrCreate( [ 'identifier' => $identifier, ], [ 'blocked_by' => get_current_user_id(), 'blocked_until' => $blocked_until, ] ); self::response( true, sprintf( 'شناسه %s با موفقیت مسدود شد.', $identifier ), [ 'block_id' => $block->id, 'blocks' => $this->blocks(), ] ); } public function delete( WP_REST_Request $request ) { $block_id = $request->get_param( 'block_id' ); try { /** @var Block $block */ $block = Block::query()->findOrFail( $block_id ); } catch ( \Exception $e ) { self::response( false, $e->getMessage() ); } if ( empty( $block->blocked_by ) ) { self::response( false, 'مسدودی‌های سیستمی قابل حذف نیستند.', [ 'blocks' => $this->blocks(), ] ); } $block->delete(); self::response( true, 'شناسه با موفقیت رفع مسدودی شد.', [ 'blocks' => $this->blocks(), ] ); } public function permission_callback( WP_REST_Request $request ): bool { return current_user_can( 'manage_options' ); } public function blocks(): array { return Block::query() ->orderByDesc( 'id' ) ->get() ->map( [ $this, 'resource' ] ) ->toArray(); } public function resource( Block $block ): array { return [ 'id' => $block->id, 'identifier' => $block->identifier, 'blocked_by' => $block->blocked_by_label, 'blocked_until' => $block->blocked_until ? Helper::date( $block->blocked_until, 'Y/m/d H:i' ) : null, ]; } private function expand_identifier( string $raw_identifier = '' ): ?string { if ( empty( $raw_identifier ) ) { return null; } $identifier = new Identifier( $raw_identifier ); if ( IP::is_valid( $raw_identifier ) ) { return $raw_identifier; } if ( $identifier->get_type() === 'username' ) { $user = get_user_by( 'login', $identifier->get_value() ); if ( $user instanceof WP_User ) { return $user->user_login; } return null; } // Phone/Email return $identifier->get_value(); } }