Class for an access control to restrict based on author identification.
Description
Source
File: src/modules/access-controls/user-identification.php
class User_Identification extends Access_Control implements Submission_Modifier_Access_Control_Interface { /** * Bootstraps the submodule by setting properties. * * @since 1.0.0 */ protected function bootstrap() { $this->slug = 'user_identification'; $this->title = __( 'User Identification', 'torro-forms' ); // $this->description = __( 'Allows you to restrict this form based on the user who wants to access it.', 'torro-forms' ); } /** * Checks whether the access control is enabled for a specific form. * * @since 1.0.0 * * @param Form $form Form object to check. * @return bool True if the access control is enabled, false otherwise. */ public function enabled( $form ) { return true; } /** * Determines whether the current user can access a specific form or submission. * * @since 1.0.0 * * @param Form $form Form object. * @param Submission|null $submission Submission object, or null if no submission is set. * @return bool|WP_Error True if the form or submission can be accessed, false or error object otherwise. */ public function can_access( $form, $submission = null ) { if ( $this->get_form_option( $form->id, 'prevent_edit_others_submission', true ) && $submission ) { $others_submission_error = new WP_Error( 'others_submission', __( 'You do not have access to this form submission.', 'torro-forms' ) ); if ( is_user_logged_in() && ! empty( $submission->user_id ) && get_current_user_id() !== $submission->user_id ) { return $others_submission_error; } $skip_further_checks = false; if ( ! empty( $submission->user_key ) ) { if ( ! empty( $_COOKIE['torro_identity'] ) ) { if ( esc_attr( wp_unslash( $_COOKIE['torro_identity'] ) ) !== $submission->user_key ) { return $others_submission_error; } else { $skip_further_checks = true; } } } if ( ! $skip_further_checks && ! empty( $submission->remote_addr ) ) { if ( ! empty( $_SERVER['REMOTE_ADDR'] ) ) { if ( $_SERVER['REMOTE_ADDR'] !== $submission->remote_addr ) { return $others_submission_error; } else { $skip_further_checks = true; } } } if ( ! $skip_further_checks && ( empty( $submission->user_key ) || ! isset( $_SESSION ) || empty( $_SESSION['torro_identity'] ) || $_SESSION['torro_identity'] !== $submission->user_key ) ) { return $others_submission_error; } } if ( $this->get_form_option( $form->id, 'prevent_multiple_submissions' ) ) { // Always allow access to already completed submissions. if ( $submission && 'completed' === $submission->status ) { return true; } $identification_modes = $this->get_form_option( $form->id, 'identification_modes', array() ); // Back-compat: Check for whether an old cookie is still set. if ( in_array( 'cookie', $identification_modes, true ) && isset( $_COOKIE[ 'torro_has_participated_form_' . $form->id ] ) && 'yes' === $_COOKIE[ 'torro_has_participated_form_' . $form->id ] ) { $message = $this->get_form_option( $form->id, 'already_submitted_message' ); if ( empty( $message ) ) { $message = $this->get_default_already_submitted_message(); } return new WP_Error( 'already_submitted', $message ); } $query_args = array( 'number' => 1, 'fields' => 'ids', 'status' => 'completed', ); $valid_args = false; if ( is_user_logged_in() ) { $query_args['user_id'] = get_current_user_id(); } else { $identification_args = array(); if ( in_array( 'ip_address', $identification_modes, true ) && ! empty( $_SERVER['REMOTE_ADDR'] ) ) { $validated_ip = filter_var( $_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP ); if ( ! empty( $validated_ip ) ) { $identification_args['remote_addr'] = $validated_ip; } } if ( in_array( 'cookie', $identification_modes, true ) && ! empty( $_COOKIE['torro_identity'] ) ) { $identification_args['user_key'] = esc_attr( wp_unslash( $_COOKIE['torro_identity'] ) ); } elseif( isset( $_SESSION ) && ! empty( $_SESSION['torro_identity'] ) ) { $identification_args['user_key'] = esc_attr( wp_unslash( $_SESSION['torro_identity'] ) ); } if ( ! empty( $identification_args ) ) { $query_args['user_identification'] = $identification_args; } } if ( count( $query_args ) === 4 ) { $submissions = $form->get_submissions( $query_args ); if ( count( $submissions ) > 0 ) { $message = $this->get_form_option( $form->id, 'already_submitted_message' ); if ( empty( $message ) ) { $message = $this->get_default_already_submitted_message(); } return new WP_Error( 'already_submitted', $message ); } } } return true; } /** * Sets additional data for a submission when it is created. * * @since 1.0.0 * * @param Submission $submission New submission object. * @param Form $form Form object the submission belongs to. * @param array $data Submission POST data. */ public function set_submission_data( $submission, $form, $data ) { $identification_modes = $this->get_form_option( $form->id, 'identification_modes', array() ); if ( in_array( 'ip_address', $identification_modes, true ) ) { if ( ! empty( $_SERVER['REMOTE_ADDR'] ) ) { $validated_ip = filter_var( $_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP ); if ( ! empty( $validated_ip ) ) { $submission->remote_addr = $validated_ip; } } } if ( in_array( 'cookie', $identification_modes, true ) ) { if ( ! isset( $_COOKIE['torro_identity'] ) ) { setcookie( 'torro_identity', $submission->user_key, current_time( 'timestamp' ) + 3 * YEAR_IN_SECONDS ); } } } /** * Returns the available meta fields for the submodule. * * @since 1.0.0 * * @return array Associative array of `$field_slug => $field_args` pairs. */ public function get_meta_fields() { $meta_fields = parent::get_meta_fields(); unset( $meta_fields['enabled'] ); $meta_fields['prevent_edit_others_submission'] = array( 'type' => 'checkbox', 'label' => __( 'Prevent users from accessing someone else's submission?', 'torro-forms' ), 'description' => __( 'Click the checkbox to ensure that participants cannot access other participants' submissions.', 'torro-forms' ), 'default' => true, 'wrap_classes' => array( 'has-torro-tooltip-description' ), 'visual_label' => __( 'User per submission', 'torro-forms' ), ); $meta_fields['prevent_multiple_submissions'] = array( 'type' => 'checkbox', 'label' => __( 'Prevent multiple submissions by a single user?', 'torro-forms' ), 'description' => __( 'Click the checkbox to ensure that participants may only submit this form once.', 'torro-forms' ), 'wrap_classes' => array( 'has-torro-tooltip-description' ), 'visual_label' => __( 'Single submission', 'torro-forms' ), ); $meta_fields['identification_modes'] = array( 'type' => 'multibox', 'label' => __( 'Identification Modes', 'torro-forms' ), 'description' => __( 'For non logged-in users, by default PHP sessions are used to identity them. You can enable further modes here to improve accuracy.', 'torro-forms' ), 'choices' => array( 'ip_address' => __( 'IP address', 'torro-forms' ), 'cookie' => __( 'Cookie', 'torro-forms' ), ), ); $meta_fields['already_submitted_message'] = array( 'type' => 'text', 'label' => __( '“Already submitted” Message', 'torro-forms' ), 'description' => __( 'Enter the message to show to the user when they have already submitted this form.', 'torro-forms' ), 'default' => $this->get_default_already_submitted_message(), 'input_classes' => array( 'regular-text' ), 'wrap_classes' => array( 'has-torro-tooltip-description' ), 'dependencies' => array( array( 'prop' => 'display', 'callback' => 'get_data_by_condition_true', 'fields' => array( 'prevent_multiple_submissions' ), 'args' => array(), ), ), ); return $meta_fields; } /** * Returns the default message to display when the user is not logged in. * * @since 1.0.0 * * @return string Message to display. */ protected function get_default_already_submitted_message() { return __( 'You already submitted this form.', 'torro-forms' ); } }
Changelog
Version | Description |
---|---|
1.0.0 | Introduced. |
Methods
- set_submission_data — Sets additional data for a submission when it is created.