capability() ) ) { return; } $this->handle_actions(); add_screen_option( 'per_page', array( 'label' => __( 'Forms per page', 'devplugins-custom-form-builder' ), 'default' => FormsListTable::PER_PAGE_DEFAULT, 'option' => FormsListTable::PER_PAGE_OPTION, ) ); $this->list_table = new FormsListTable( $this->forms ); $this->list_table->prepare_items(); } /** * Returns the view path. */ protected function view(): string { return 'admin/forms/list'; } /** * Returns the data passed to the view. * * @return array Variables exposed to the template. */ protected function data(): array { return array( 'page_title' => $this->page_title(), 'add_new_url' => add_query_arg( array( 'page' => FormEditPage::SLUG ), admin_url( 'admin.php' ) ), 'list_table' => $this->list_table, 'notice' => $this->notice(), 'search' => Request::text( 's' ), 'page_slug' => self::SLUG, ); } /** * Dispatches the requested action. */ private function handle_actions(): void { $action = $this->requested_action(); if ( '' === $action ) { return; } $selection = Request::ids( 'forms' ); if ( array() !== $selection ) { $this->handle_bulk_action( $action, $selection ); return; } $form_id = Request::int( 'form' ); if ( 0 === $form_id ) { return; } match ( $action ) { 'delete' => $this->delete_form( $form_id ), 'duplicate' => $this->duplicate_form( $form_id ), default => null, }; } /** * Deletes a single form. * * @param int $form_id Form to delete. */ private function delete_form( int $form_id ): void { SecurityManager::verify_admin_request( self::row_nonce_action( 'delete', $form_id ), Capabilities::MANAGE_FORMS ); $deleted = $this->forms->delete( $form_id ); $this->redirect( $deleted ? 'deleted' : 'error', $deleted ? 1 : 0 ); } /** * Duplicates a single form. * * @param int $form_id Form to copy. */ private function duplicate_form( int $form_id ): void { SecurityManager::verify_admin_request( self::row_nonce_action( 'duplicate', $form_id ), Capabilities::MANAGE_FORMS ); $new_id = $this->forms->duplicate( $form_id ); $this->redirect( $new_id > 0 ? 'duplicated' : 'error', $new_id > 0 ? 1 : 0 ); } /** * Runs a bulk action over the selected forms. * * @param string $action Requested action. * @param array $selection Selected form IDs. */ private function handle_bulk_action( string $action, array $selection ): void { if ( 'delete' !== $action ) { return; } // Nonce emitted by WP_List_Table::display() for the "forms" plural. SecurityManager::verify_admin_request( 'bulk-formpilot-forms', Capabilities::MANAGE_FORMS ); $deleted = 0; foreach ( $selection as $form_id ) { if ( $this->forms->delete( $form_id ) ) { ++$deleted; } } $this->redirect( $deleted > 0 ? 'deleted' : 'error', $deleted ); } /** * Sends the browser back to a clean list URL. * * @param string $message Message key describing the outcome. * @param int $count Number of affected rows. */ private function redirect( string $message, int $count ): void { $args = array( self::MESSAGE_ARG => $message, self::COUNT_ARG => $count, ); $search = Request::text( 's' ); if ( '' !== $search ) { $args['s'] = $search; } $paged = Request::int( 'paged' ); if ( $paged > 1 ) { $args['paged'] = $paged; } wp_safe_redirect( $this->url( $args ) ); exit; } /** * Builds the notice shown after an action. * * @return array{type: string, text: string}|null The notice, or null when there is nothing to report. */ private function notice(): ?array { $message = Request::key( self::MESSAGE_ARG ); if ( '' === $message ) { return null; } $count = max( 0, Request::int( self::COUNT_ARG ) ); return match ( $message ) { 'created' => array( 'type' => 'success', 'text' => __( 'Form created.', 'devplugins-custom-form-builder' ), ), 'updated' => array( 'type' => 'success', 'text' => __( 'Form updated.', 'devplugins-custom-form-builder' ), ), 'duplicated' => array( 'type' => 'success', 'text' => __( 'Form duplicated.', 'devplugins-custom-form-builder' ), ), 'deleted' => array( 'type' => 'success', 'text' => sprintf( /* translators: %s: Number of deleted forms. */ _n( '%s form deleted.', '%s forms deleted.', $count, 'devplugins-custom-form-builder' ), number_format_i18n( $count ) ), ), 'missing' => array( 'type' => 'error', 'text' => __( 'That form no longer exists.', 'devplugins-custom-form-builder' ), ), default => array( 'type' => 'error', 'text' => __( 'The action could not be completed.', 'devplugins-custom-form-builder' ), ), }; } }