Files
Digital-Dabei-Hamburg-Job-M…/includes/class-formidable.php

988 lines
25 KiB
PHP

<?php
/**
* Formidable Forms integration for provider registration
*
* @package DDHH_Job_Manager
*/
// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;
/**
* Handles Formidable Forms integration for provider registration
*/
class DDHH_JM_Formidable {
/**
* Form ID for provider registration
*
* @var int|null
*/
private static $registration_form_id = null;
/**
* Form ID for job submission
*
* @var int|null
*/
private static $job_submission_form_id = null;
/**
* Form ID for job edit
*
* @var int|null
*/
private static $job_edit_form_id = null;
/**
* Form ID for job deactivation
*
* @var int|null
*/
private static $job_deactivation_form_id = null;
/**
* Form ID for job application
*
* @var int|null
*/
private static $job_application_form_id = null;
/**
* Get the registration form ID
*
* @return int|null Form ID or null if not found
*/
public static function get_registration_form_id() {
if ( null !== self::$registration_form_id ) {
return self::$registration_form_id;
}
// Look up form by key
$form = FrmForm::getOne( 'provider_registration' );
if ( $form ) {
self::$registration_form_id = $form->id;
return self::$registration_form_id;
}
return null;
}
/**
* Get the job submission form ID
*
* @return int|null Form ID or null if not found
*/
public static function get_job_submission_form_id() {
if ( null !== self::$job_submission_form_id ) {
return self::$job_submission_form_id;
}
// Look up form by key
$form = FrmForm::getOne( 'job_submission' );
if ( $form ) {
self::$job_submission_form_id = $form->id;
return self::$job_submission_form_id;
}
return null;
}
/**
* Get the job edit form ID
*
* @return int|null Form ID or null if not found
*/
public static function get_job_edit_form_id() {
if ( null !== self::$job_edit_form_id ) {
return self::$job_edit_form_id;
}
// Look up form by key
$form = FrmForm::getOne( 'job_edit' );
if ( $form ) {
self::$job_edit_form_id = $form->id;
return self::$job_edit_form_id;
}
return null;
}
/**
* Get the job deactivation form ID
*
* @return int|null Form ID or null if not found
*/
public static function get_job_deactivation_form_id() {
if ( null !== self::$job_deactivation_form_id ) {
return self::$job_deactivation_form_id;
}
// Look up form by key
$form = FrmForm::getOne( 'job_deactivation' );
if ( $form ) {
self::$job_deactivation_form_id = $form->id;
return self::$job_deactivation_form_id;
}
return null;
}
/**
* Get the job application form ID
*
* @return int|null Form ID or null if not found
*/
public static function get_job_application_form_id() {
if ( null !== self::$job_application_form_id ) {
return self::$job_application_form_id;
}
// Look up form by key
$form = FrmForm::getOne( 'job_application' );
if ( $form ) {
self::$job_application_form_id = $form->id;
return self::$job_application_form_id;
}
return null;
}
/**
* Setup registration hooks
*/
public static function setup_registration_hooks() {
// Create forms on plugin activation if they don't exist
add_action( 'init', array( __CLASS__, 'create_registration_form' ), 11 );
add_action( 'init', array( __CLASS__, 'create_job_submission_form' ), 11 );
add_action( 'init', array( __CLASS__, 'create_job_edit_form' ), 11 );
add_action( 'init', array( __CLASS__, 'create_job_deactivation_form' ), 11 );
add_action( 'init', array( __CLASS__, 'create_job_application_form' ), 11 );
// Hook into Formidable form submission
add_action( 'frm_after_create_entry', array( __CLASS__, 'handle_registration_submission' ), 30, 2 );
// Hook into Formidable form validation for ownership check
add_filter( 'frm_validate_entry', array( __CLASS__, 'validate_job_ownership' ), 10, 2 );
add_filter( 'frm_validate_entry', array( __CLASS__, 'validate_job_deactivation_ownership' ), 10, 2 );
}
/**
* Create the registration form programmatically if it doesn't exist
*/
public static function create_registration_form() {
// Check if Formidable is active
if ( ! class_exists( 'FrmForm' ) ) {
return;
}
// Check if form already exists
$existing_form = FrmForm::getOne( 'provider_registration' );
if ( $existing_form ) {
self::$registration_form_id = $existing_form->id;
return;
}
// Create form
$form_values = array(
'name' => 'Provider Registration',
'form_key' => 'provider_registration',
'description' => 'Anbieter-Registrierung für Digital Dabei Hamburg',
'status' => 'published',
'options' => array(
'submit_value' => 'Registrieren',
'success_msg' => 'Registrierung erfolgreich! Sie werden weitergeleitet...',
),
);
$form_id = FrmForm::create( $form_values );
if ( ! $form_id ) {
return;
}
self::$registration_form_id = $form_id;
// Create form fields
$fields = array(
array(
'name' => 'Organisationsname',
'field_key' => 'organization_name',
'type' => 'text',
'required' => '1',
'form_id' => $form_id,
'field_order' => 1,
),
array(
'name' => 'Ansprechperson',
'field_key' => 'contact_person',
'type' => 'text',
'required' => '1',
'form_id' => $form_id,
'field_order' => 2,
),
array(
'name' => 'E-Mail',
'field_key' => 'email',
'type' => 'email',
'required' => '1',
'form_id' => $form_id,
'field_order' => 3,
'field_options' => array(
'unique' => '1',
),
),
array(
'name' => 'Passwort',
'field_key' => 'password',
'type' => 'password',
'required' => '1',
'form_id' => $form_id,
'field_order' => 4,
'field_options' => array(
'minlength' => 8,
),
),
array(
'name' => 'Passwort bestätigen',
'field_key' => 'password_confirm',
'type' => 'password',
'required' => '1',
'form_id' => $form_id,
'field_order' => 5,
'field_options' => array(
'minlength' => 8,
),
),
);
foreach ( $fields as $field ) {
FrmField::create( $field );
}
}
/**
* Handle registration form submission
*
* @param int $entry_id Entry ID.
* @param int $form_id Form ID.
*/
public static function handle_registration_submission( $entry_id, $form_id ) {
error_log('DDHH Registration: Hook fired for form ' . $form_id . ', entry ' . $entry_id);
// Only process our registration form
if ( $form_id !== self::get_registration_form_id() ) {
error_log('DDHH Registration: Wrong form ID. Expected ' . self::get_registration_form_id());
return;
}
error_log('DDHH Registration: Processing registration form');
// Get entry data
$entry = FrmEntry::getOne( $entry_id, true );
if ( ! $entry ) {
error_log('DDHH Registration: Failed to get entry');
return;
}
error_log('DDHH Registration: Entry retrieved successfully');
// Extract field values
$email = '';
$password = '';
$password_confirm = '';
$organization_name = '';
$contact_person = '';
foreach ( $entry->metas as $field_id => $value ) {
$field = FrmField::getOne( $field_id );
if ( ! $field ) {
continue;
}
switch ( $field->field_key ) {
case 'email':
$email = sanitize_email( $value );
break;
case 'password':
$password = $value;
break;
case 'password_confirm':
$password_confirm = $value;
break;
case 'organization_name':
$organization_name = sanitize_text_field( $value );
break;
case 'contact_person':
$contact_person = sanitize_text_field( $value );
break;
}
}
error_log('DDHH Registration: email=' . $email . ', org=' . $organization_name . ', contact=' . $contact_person);
// Validate required fields
if ( empty( $email ) || empty( $password ) || empty( $organization_name ) || empty( $contact_person ) ) {
error_log('DDHH Registration: Validation failed - missing required fields');
return;
}
// Validate passwords match
if ( $password !== $password_confirm ) {
error_log('DDHH Registration: Passwords do not match');
return;
}
// Check if user already exists
if ( email_exists( $email ) ) {
error_log('DDHH Registration: Email already exists');
return;
}
error_log('DDHH Registration: Validation passed, creating user...');
// Create username from email (part before @)
$username = sanitize_user( strstr( $email, '@', true ) );
// Ensure username is unique
$username_base = $username;
$counter = 1;
while ( username_exists( $username ) ) {
$username = $username_base . $counter;
$counter++;
}
// Create WordPress user
$user_id = wp_insert_user(
array(
'user_login' => $username,
'user_email' => $email,
'user_pass' => $password,
'role' => 'ddhh_provider',
'display_name' => $contact_person,
'first_name' => $contact_person,
)
);
// Check for errors
if ( is_wp_error( $user_id ) ) {
error_log('DDHH Registration: wp_insert_user failed - ' . $user_id->get_error_message());
return;
}
error_log('DDHH Registration: User created successfully with ID ' . $user_id);
// Store organization name as user meta
update_user_meta( $user_id, 'ddhh_org_name', $organization_name );
// Auto-login the user
wp_set_auth_cookie( $user_id, true );
wp_set_current_user( $user_id );
error_log('DDHH Registration: User logged in, triggering redirect...');
// Optionally redirect (handled by JavaScript or form settings)
do_action( 'ddhh_provider_registered', $user_id, $organization_name );
}
/**
* Create the job submission form programmatically if it doesn't exist
*/
public static function create_job_submission_form() {
// Check if Formidable is active
if ( ! class_exists( 'FrmForm' ) || ! class_exists( 'FrmFormActionsController' ) ) {
return;
}
// Check if form already exists
$existing_form = FrmForm::getOne( 'job_submission' );
if ( $existing_form ) {
self::$job_submission_form_id = $existing_form->id;
return;
}
// Create form
$form_values = array(
'name' => 'Stellenangebot einreichen',
'form_key' => 'job_submission',
'description' => 'Alle Felder mit * sind Pflichtfelder. Ihr Angebot wird vor Veröffentlichung geprüft.',
'status' => 'published',
'options' => array(
'submit_value' => 'Stellenangebot einreichen',
'success_msg' => 'Ihr Stellenangebot wurde zur Prüfung eingereicht!',
'success_action' => 'redirect',
'success_url' => home_url( '/anbieter-dashboard/' ),
),
);
$form_id = FrmForm::create( $form_values );
if ( ! $form_id ) {
return;
}
self::$job_submission_form_id = $form_id;
// Create form fields
$fields_data = array(
array(
'name' => 'Stellentitel',
'field_key' => 'job_title',
'type' => 'text',
'required' => '1',
'form_id' => $form_id,
'field_order' => 1,
),
array(
'name' => 'Stellenbeschreibung',
'field_key' => 'job_description',
'type' => 'textarea',
'required' => '1',
'form_id' => $form_id,
'field_order' => 2,
),
array(
'name' => 'Standort',
'field_key' => 'job_location',
'type' => 'text',
'required' => '1',
'form_id' => $form_id,
'field_order' => 3,
),
array(
'name' => 'Art',
'field_key' => 'job_type',
'type' => 'select',
'required' => '1',
'form_id' => $form_id,
'field_order' => 4,
'field_options' => array(
'options' => array(
'Vollzeit' => 'Vollzeit',
'Teilzeit' => 'Teilzeit',
'Ehrenamt' => 'Ehrenamt',
),
),
),
array(
'name' => 'Bewerbungsfrist',
'field_key' => 'job_deadline',
'type' => 'date',
'required' => '0',
'form_id' => $form_id,
'field_order' => 5,
'field_options' => array(
'format' => 'd.m.Y',
),
),
array(
'name' => 'Kontakt-E-Mail',
'field_key' => 'job_contact_email',
'type' => 'email',
'required' => '1',
'form_id' => $form_id,
'field_order' => 6,
),
array(
'name' => 'Logo',
'field_key' => 'job_logo',
'type' => 'file',
'required' => '0',
'form_id' => $form_id,
'field_order' => 7,
'field_options' => array(
'restrict' => '1',
'allowed_types' => 'image/jpeg,image/png',
'max_size' => '2',
),
),
);
// Store field IDs for form action mapping
$field_ids = array();
foreach ( $fields_data as $field ) {
$field_id = FrmField::create( $field );
if ( $field_id ) {
$field_ids[ $field['field_key'] ] = $field_id;
}
}
// Create the Create Post action
if ( ! empty( $field_ids ) ) {
$action_values = array(
'menu_order' => 1,
'post_status' => 'published',
'post_content' => array(
'post_type' => 'job_offer',
'post_status' => 'pending',
'post_title' => $field_ids['job_title'],
'post_content' => $field_ids['job_description'],
'post_author' => 'current_user',
'post_custom_fields' => array(
array(
'meta_name' => 'job_location',
'field_id' => $field_ids['job_location'],
),
array(
'meta_name' => 'job_type',
'field_id' => $field_ids['job_type'],
),
array(
'meta_name' => 'job_deadline',
'field_id' => $field_ids['job_deadline'],
),
array(
'meta_name' => 'job_contact_email',
'field_id' => $field_ids['job_contact_email'],
),
array(
'meta_name' => 'job_logo',
'field_id' => $field_ids['job_logo'],
),
),
),
);
// Create the form action using the proper API
FrmFormActionsController::create_action(
$form_id,
array(
'post_excerpt' => 'wppost',
'post_content' => $action_values,
'menu_order' => 1,
)
);
}
}
/**
* Create the job edit form programmatically if it doesn't exist
*/
public static function create_job_edit_form() {
// Check if Formidable is active
if ( ! class_exists( 'FrmForm' ) || ! class_exists( 'FrmFormActionsController' ) ) {
return;
}
// Check if form already exists
$existing_form = FrmForm::getOne( 'job_edit' );
if ( $existing_form ) {
self::$job_edit_form_id = $existing_form->id;
return;
}
// Create form
$form_values = array(
'name' => 'Stellenangebot bearbeiten',
'form_key' => 'job_edit',
'description' => 'Bearbeiten Sie Ihr Stellenangebot. Alle Felder mit * sind Pflichtfelder.',
'status' => 'published',
'options' => array(
'submit_value' => 'Änderungen speichern',
'success_msg' => 'Ihre Änderungen wurden gespeichert!',
'success_action' => 'redirect',
'success_url' => home_url( '/anbieter-dashboard/' ),
),
);
$form_id = FrmForm::create( $form_values );
if ( ! $form_id ) {
return;
}
self::$job_edit_form_id = $form_id;
// Create form fields (identical to submission form)
$fields_data = array(
array(
'name' => 'Stellentitel',
'field_key' => 'job_title',
'type' => 'text',
'required' => '1',
'form_id' => $form_id,
'field_order' => 1,
),
array(
'name' => 'Stellenbeschreibung',
'field_key' => 'job_description',
'type' => 'textarea',
'required' => '1',
'form_id' => $form_id,
'field_order' => 2,
),
array(
'name' => 'Standort',
'field_key' => 'job_location',
'type' => 'text',
'required' => '1',
'form_id' => $form_id,
'field_order' => 3,
),
array(
'name' => 'Art',
'field_key' => 'job_type',
'type' => 'select',
'required' => '1',
'form_id' => $form_id,
'field_order' => 4,
'field_options' => array(
'options' => array(
'Vollzeit' => 'Vollzeit',
'Teilzeit' => 'Teilzeit',
'Ehrenamt' => 'Ehrenamt',
),
),
),
array(
'name' => 'Bewerbungsfrist',
'field_key' => 'job_deadline',
'type' => 'date',
'required' => '0',
'form_id' => $form_id,
'field_order' => 5,
'field_options' => array(
'format' => 'd.m.Y',
),
),
array(
'name' => 'Kontakt-E-Mail',
'field_key' => 'job_contact_email',
'type' => 'email',
'required' => '1',
'form_id' => $form_id,
'field_order' => 6,
),
array(
'name' => 'Logo',
'field_key' => 'job_logo',
'type' => 'file',
'required' => '0',
'form_id' => $form_id,
'field_order' => 7,
'field_options' => array(
'restrict' => '1',
'allowed_types' => 'image/jpeg,image/png',
'max_size' => '2',
),
),
);
// Store field IDs for form action mapping
$field_ids = array();
foreach ( $fields_data as $field ) {
$field_id = FrmField::create( $field );
if ( $field_id ) {
$field_ids[ $field['field_key'] ] = $field_id;
}
}
// Create the Update Post action
if ( ! empty( $field_ids ) ) {
$action_values = array(
'menu_order' => 1,
'post_status' => 'published',
'post_content' => array(
'post_type' => 'job_offer',
'post_status' => 'pending',
'post_title' => $field_ids['job_title'],
'post_content' => $field_ids['job_description'],
'post_id' => 'id_param',
'post_custom_fields' => array(
array(
'meta_name' => 'job_location',
'field_id' => $field_ids['job_location'],
),
array(
'meta_name' => 'job_type',
'field_id' => $field_ids['job_type'],
),
array(
'meta_name' => 'job_deadline',
'field_id' => $field_ids['job_deadline'],
),
array(
'meta_name' => 'job_contact_email',
'field_id' => $field_ids['job_contact_email'],
),
array(
'meta_name' => 'job_logo',
'field_id' => $field_ids['job_logo'],
),
),
),
);
// Create the form action using the proper API
FrmFormActionsController::create_action(
$form_id,
array(
'post_excerpt' => 'wppost',
'post_content' => $action_values,
'menu_order' => 1,
)
);
}
}
/**
* Validate job ownership before allowing edit
*
* @param array $errors Validation errors.
* @param array $values Form values.
* @return array Modified errors.
*/
public static function validate_job_ownership( $errors, $values ) {
// Only validate for the job edit form
if ( absint( $values['form_id'] ) !== self::get_job_edit_form_id() ) {
return $errors;
}
// Check if job_id parameter exists
if ( ! isset( $_GET['job_id'] ) ) {
$errors[''] = 'Keine Stellenangebot-ID angegeben.';
return $errors;
}
$job_id = absint( $_GET['job_id'] );
// Verify post exists and is a job_offer
$post = get_post( $job_id );
if ( ! $post || 'job_offer' !== $post->post_type ) {
$errors[''] = 'Ungültige Stellenangebot-ID.';
return $errors;
}
// Verify post author matches current user
$current_user_id = get_current_user_id();
if ( absint( $post->post_author ) !== $current_user_id ) {
$errors[''] = 'Sie haben keine Berechtigung, dieses Stellenangebot zu bearbeiten.';
return $errors;
}
return $errors;
}
/**
* Create the job deactivation form programmatically if it doesn't exist
*/
public static function create_job_deactivation_form() {
// Check if Formidable is active
if ( ! class_exists( 'FrmForm' ) || ! class_exists( 'FrmFormActionsController' ) ) {
return;
}
// Check if form already exists
$existing_form = FrmForm::getOne( 'job_deactivation' );
if ( $existing_form ) {
self::$job_deactivation_form_id = $existing_form->id;
return;
}
// Create form
$form_values = array(
'name' => 'Stellenangebot deaktivieren',
'form_key' => 'job_deactivation',
'description' => '',
'status' => 'published',
'options' => array(
'submit_value' => 'Stellenangebot deaktivieren',
'success_msg' => 'Ihr Stellenangebot wurde deaktiviert.',
'success_action' => 'redirect',
'success_url' => home_url( '/anbieter-dashboard/' ),
),
);
$form_id = FrmForm::create( $form_values );
if ( ! $form_id ) {
return;
}
self::$job_deactivation_form_id = $form_id;
// Create form fields
$fields_data = array(
array(
'name' => 'Grund für Deaktivierung',
'description' => 'Bitte geben Sie an, warum Sie dieses Stellenangebot deaktivieren möchten',
'field_key' => 'deactivation_reason',
'type' => 'textarea',
'required' => '1',
'form_id' => $form_id,
'field_order' => 1,
),
array(
'name' => 'Job ID',
'field_key' => 'job_id',
'type' => 'hidden',
'required' => '0',
'form_id' => $form_id,
'field_order' => 2,
),
);
// Store field IDs for form action mapping
$field_ids = array();
foreach ( $fields_data as $field ) {
$field_id = FrmField::create( $field );
if ( $field_id ) {
$field_ids[ $field['field_key'] ] = $field_id;
}
}
// Create the Update Post action
if ( ! empty( $field_ids ) ) {
$action_values = array(
'menu_order' => 1,
'post_status' => 'published',
'post_content' => array(
'post_type' => 'job_offer',
'post_status' => 'draft',
'post_id' => 'id_param',
'post_custom_fields' => array(
array(
'meta_name' => 'job_deactivation_reason',
'field_id' => $field_ids['deactivation_reason'],
),
),
),
);
// Create the form action using the proper API
FrmFormActionsController::create_action(
$form_id,
array(
'post_excerpt' => 'wppost',
'post_content' => $action_values,
'menu_order' => 1,
)
);
}
}
/**
* Validate job ownership before allowing deactivation
*
* @param array $errors Validation errors.
* @param array $values Form values.
* @return array Modified errors.
*/
public static function validate_job_deactivation_ownership( $errors, $values ) {
// Only validate for the job deactivation form
if ( absint( $values['form_id'] ) !== self::get_job_deactivation_form_id() ) {
return $errors;
}
// Check if job_id parameter exists
if ( ! isset( $_GET['job_id'] ) ) {
$errors[''] = 'Keine Stellenangebot-ID angegeben.';
return $errors;
}
$job_id = absint( $_GET['job_id'] );
// Verify post exists and is a job_offer
$post = get_post( $job_id );
if ( ! $post || 'job_offer' !== $post->post_type ) {
$errors[''] = 'Ungültige Stellenangebot-ID.';
return $errors;
}
// Verify post author matches current user
$current_user_id = get_current_user_id();
if ( absint( $post->post_author ) !== $current_user_id ) {
$errors[''] = 'Sie haben keine Berechtigung, dieses Stellenangebot zu deaktivieren.';
return $errors;
}
return $errors;
}
/**
* Create the job application form programmatically if it doesn't exist
*/
public static function create_job_application_form() {
// Check if Formidable is active
if ( ! class_exists( 'FrmForm' ) ) {
return;
}
// Check if form already exists
$existing_form = FrmForm::getOne( 'job_application' );
if ( $existing_form ) {
self::$job_application_form_id = $existing_form->id;
return;
}
// Create form
$form_values = array(
'name' => 'Jetzt bewerben',
'form_key' => 'job_application',
'description' => '',
'status' => 'published',
'options' => array(
'submit_value' => 'Bewerbung absenden',
'success_msg' => 'Ihre Bewerbung wurde versendet. Der Anbieter wird sich bei Ihnen melden.',
),
);
$form_id = FrmForm::create( $form_values );
if ( ! $form_id ) {
return;
}
self::$job_application_form_id = $form_id;
// Get current user email if logged in
$current_user = wp_get_current_user();
$default_email = '';
if ( $current_user && $current_user->ID ) {
$default_email = $current_user->user_email;
}
// Create form fields
$fields_data = array(
array(
'name' => 'Name',
'field_key' => 'applicant_name',
'type' => 'text',
'required' => '1',
'form_id' => $form_id,
'field_order' => 1,
),
array(
'name' => 'E-Mail',
'field_key' => 'applicant_email',
'type' => 'email',
'required' => '1',
'form_id' => $form_id,
'field_order' => 2,
'default_value' => $default_email,
),
array(
'name' => 'Nachricht',
'description' => 'Warum interessieren Sie sich für diese Stelle?',
'field_key' => 'applicant_message',
'type' => 'textarea',
'required' => '1',
'form_id' => $form_id,
'field_order' => 3,
),
array(
'name' => 'Job ID',
'field_key' => 'job_id',
'type' => 'hidden',
'required' => '0',
'form_id' => $form_id,
'field_order' => 4,
),
);
foreach ( $fields_data as $field ) {
FrmField::create( $field );
}
}
}