'tiboform_entry', 'posts_per_page' => 99, 'fields' => 'ids', 'meta_key' => '_tiboform_status', 'meta_value' => 'new' ) ) ); // phpcs:ignore WordPress.DB.SlowDBQuery $GLOBALS['tiboform_hook'] = add_menu_page( 'TiboForm', 'TiboForm' . ( $n ? ' ' . $n . '' : '' ), 'edit_pages', 'tiboform', 'tiboform_admin_page', 'dashicons-feedback', 27 ); } ); /** * Yönetim sayfası adresi; sekme/görünüm parametreleri nonce ile imzalanır. * * @param array $args Sorgu parametreleri (tab, edit, form, view, status). * @return string */ function tiboform_admin_url( $args = array() ) { $args = array_merge( array( 'page' => 'tiboform' ), $args ); if ( count( $args ) > 1 ) { $args['_tfnonce'] = wp_create_nonce( 'tiboform_nav' ); } return add_query_arg( $args, admin_url( 'admin.php' ) ); } /** * Sayfa parametresi: yalnız geçerli nonce ve yetki varsa okunur, yoksa boş döner. * * @param string $k Anahtar. * @return string */ function tiboform_query( $k ) { static $ok = null; if ( null === $ok ) { $ok = isset( $_GET['_tfnonce'] ) && current_user_can( 'edit_pages' ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_tfnonce'] ) ), 'tiboform_nav' ); } if ( ! $ok || ! isset( $_GET[ $k ] ) || ! is_scalar( $_GET[ $k ] ) ) { return ''; } return sanitize_text_field( wp_unslash( $_GET[ $k ] ) ); } /** * Bir sonraki sayfa yüklemesinde gösterilecek bilgi mesajı. * * @param string $msg Mesaj. */ function tiboform_flash( $msg ) { set_transient( 'tiboform_msg_' . get_current_user_id(), sanitize_text_field( $msg ), MINUTE_IN_SECONDS ); } /** * Sekmeler. * * @return array */ function tiboform_tabs() { $t = apply_filters( 'tiboform_admin_tabs', array( 'forms' => __( 'Forms', 'tiboform' ), 'entries' => __( 'Submissions', 'tiboform' ), ) ); if ( ! tiboform_is_pro() ) { $t['pro'] = 'Pro'; } return $t; } add_action( 'admin_enqueue_scripts', function ( $hook ) { if ( empty( $GLOBALS['tiboform_hook'] ) || $hook !== $GLOBALS['tiboform_hook'] ) { return; } wp_enqueue_style( 'tiboform-ui', TIBOFORM_URL . 'assets/ui.css', array(), TIBOFORM_VERSION ); wp_enqueue_style( 'tiboform-builder', TIBOFORM_URL . 'assets/builder.css', array( 'tiboform-ui' ), TIBOFORM_VERSION ); $edit = absint( tiboform_query( 'edit' ) ); if ( $edit ) { wp_enqueue_script( 'tiboform-builder', TIBOFORM_URL . 'assets/builder.js', array(), TIBOFORM_VERSION, true ); wp_localize_script( 'tiboform-builder', 'tiboformB', array( 'types' => tiboform_types(), 'layout' => tiboform_layout_types(), 'i18n' => array( 'label' => __( 'Label', 'tiboform' ), 'id' => __( 'Field key (for merge tags)', 'tiboform' ), 'required' => __( 'Required', 'tiboform' ), 'half' => __( 'Half width', 'tiboform' ), 'options' => __( 'Options (one per line)', 'tiboform' ), 'ph' => __( 'Placeholder', 'tiboform' ), 'min' => __( 'Minimum', 'tiboform' ), 'max' => __( 'Maximum', 'tiboform' ), 'value' => __( 'Value (use {get:utm_source} to read from the page address)', 'tiboform' ), 'remove' => __( 'Remove', 'tiboform' ), 'up' => __( 'Move up', 'tiboform' ), 'down' => __( 'Move down', 'tiboform' ), 'empty' => __( 'Add fields from the left. Drag to reorder.', 'tiboform' ), 'newField' => __( 'New field', 'tiboform' ), ), ) ); do_action( 'tiboform_builder_enqueue', $edit ); } } ); /** * Sayfa. */ function tiboform_admin_page() { if ( ! current_user_can( 'edit_pages' ) ) { return; } $tabs = tiboform_tabs(); $tab = sanitize_key( tiboform_query( 'tab' ) ); $tab = isset( $tabs[ $tab ] ) || 'new' === $tab ? $tab : 'forms'; $edit = absint( tiboform_query( 'edit' ) ); echo '

TiboForm

'; $msg = get_transient( 'tiboform_msg_' . get_current_user_id() ); if ( $msg ) { delete_transient( 'tiboform_msg_' . get_current_user_id() ); echo '
' . esc_html( $msg ) . '
'; } if ( 'entries' === $tab ) { tiboform_tab_entries(); } elseif ( 'new' === $tab ) { tiboform_tab_new(); } elseif ( 'pro' === $tab ) { tiboform_tab_pro(); } elseif ( 'forms' !== $tab ) { do_action( 'tiboform_admin_tab_' . $tab ); } elseif ( $edit ) { tiboform_builder( $edit ); } else { tiboform_tab_forms(); } echo '
'; } /** * Form listesi. */ function tiboform_tab_forms() { echo '

' . esc_html__( 'Forms', 'tiboform' ) . '

+ ' . esc_html__( 'New form', 'tiboform' ) . '
'; foreach ( get_posts( array( 'post_type' => 'tiboform_form', 'posts_per_page' => 200 ) ) as $p ) { $n = count( get_posts( array( 'post_type' => 'tiboform_entry', 'post_parent' => $p->ID, 'posts_per_page' => 999, 'fields' => 'ids' ) ) ); echo ''; } echo '
' . esc_html__( 'Form', 'tiboform' ) . '' . esc_html__( 'Shortcode', 'tiboform' ) . '' . esc_html__( 'Submissions', 'tiboform' ) . '
' . esc_html( $p->post_title ) . '[tiboform id="' . absint( $p->ID ) . '"]' . absint( $n ) . '' . esc_html__( 'Edit', 'tiboform' ) . ' · ' . esc_html__( 'Delete', 'tiboform' ) . '
'; } /** * Yeni form: şablon seçimi. */ function tiboform_tab_new() { echo '

' . esc_html__( 'Choose a template', 'tiboform' ) . '

'; foreach ( tiboform_templates() as $k => $t ) { $labels = array(); foreach ( $t['fields'] as $f ) { if ( ! in_array( $f['type'], tiboform_layout_types(), true ) && 'kvkk' !== $f['type'] ) { $labels[] = wp_strip_all_tags( $f['label'] ); } } echo '' . esc_html( $t['title'] ) . '' . esc_html( $t['desc'] ) . '' . esc_html( implode( ' · ', array_slice( $labels, 0, 6 ) ) ) . ''; } echo '' . esc_html__( 'Blank form', 'tiboform' ) . '' . esc_html__( 'Start from scratch.', 'tiboform' ) . '
'; } /** * Pro sekmesi (yalnız bilgi). */ function tiboform_tab_pro() { $f = array( __( 'File uploads stored in a protected folder', 'tiboform' ), __( 'Conditional logic: show or hide fields based on answers', 'tiboform' ), __( 'Multi-step forms with a progress bar', 'tiboform' ), __( 'Webhooks for Zapier, Make, n8n and Google Sheets', 'tiboform' ), __( 'Cloudflare Turnstile and Google reCAPTCHA v3', 'tiboform' ), __( 'SMS notifications through Netgsm or İleti Merkezi', 'tiboform' ), __( 'Form scheduling, submission limits and one entry per person', 'tiboform' ), __( 'Calculation fields, HTML email template and conditional recipients', 'tiboform' ), __( 'Export with date range and field selection', 'tiboform' ), ); echo '

TiboForm Pro

' . esc_html__( 'Learn more', 'tiboform' ) . '
'; } add_action( 'admin_post_tiboform_new', function () { check_admin_referer( 'tiboform_new' ); if ( ! current_user_can( 'edit_pages' ) ) { wp_die( esc_html__( 'Not allowed.', 'tiboform' ) ); } $t = isset( $_GET['template'] ) ? sanitize_key( wp_unslash( $_GET['template'] ) ) : 'contact'; if ( 'blank' === $t ) { $id = wp_insert_post( array( 'post_type' => 'tiboform_form', 'post_status' => 'publish', 'post_title' => __( 'New form', 'tiboform' ), 'post_content' => wp_slash( wp_json_encode( tiboform_clean_schema( array( 'fields' => array(), 'settings' => tiboform_default_settings() ) ) ) ) ) ); } else { $id = tiboform_create_form( $t ); } wp_safe_redirect( tiboform_admin_url( array( 'edit' => (int) $id ) ) ); exit; } ); add_action( 'admin_post_tiboform_del_form', function () { $id = isset( $_GET['id'] ) ? absint( $_GET['id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Verified by check_admin_referer() on the next line; the ID is part of the nonce action. check_admin_referer( 'tiboform_del_form_' . $id ); if ( ! current_user_can( 'edit_pages' ) || 'tiboform_form' !== get_post_type( $id ) ) { wp_die( esc_html__( 'Not allowed.', 'tiboform' ) ); } foreach ( get_posts( array( 'post_type' => 'tiboform_entry', 'post_parent' => $id, 'posts_per_page' => -1, 'fields' => 'ids' ) ) as $e ) { wp_delete_post( $e, true ); } wp_delete_post( $id, true ); wp_safe_redirect( tiboform_admin_url() ); exit; } ); /** * Ayar giriş kutusu. * * @param array $s Ayarlar. * @param string $k Anahtar. * @param string $l Etiket. * @param string $type Tür. * @param string $ph Yer tutucu. */ function tiboform_setting_input( $s, $k, $l, $type = 'text', $ph = '' ) { echo '
'; } /** * Oluşturucu. * * @param int $id Form. */ function tiboform_builder( $id ) { $f = tiboform_form( $id ); if ( ! $f ) { echo '

' . esc_html__( 'Form not found.', 'tiboform' ) . '

'; return; } $s = $f['settings']; echo '
'; wp_nonce_field( 'tiboform_save_' . $id ); echo ''; echo '
[tiboform id="' . absint( $id ) . '"]
'; echo '
'; do_action( 'tiboform_builder_field_settings', $f ); echo '

' . esc_html__( 'Notification email', 'tiboform' ) . '

' . esc_html__( 'Merge tags: {field_key} for any field, {form_adi}, {tarih}, {tum_alanlar} (all fields).', 'tiboform' ) . '

'; tiboform_setting_input( $s, 'to', __( 'Send notifications to (comma separated)', 'tiboform' ) ); tiboform_setting_input( $s, 'subject', __( 'Notification subject', 'tiboform' ) ); echo '
'; echo '

' . esc_html__( 'After sending', 'tiboform' ) . '

'; tiboform_setting_input( $s, 'button', __( 'Button text', 'tiboform' ) ); tiboform_setting_input( $s, 'success', __( 'Success message', 'tiboform' ) ); tiboform_setting_input( $s, 'redirect', __( 'Redirect to a page instead (URL, optional)', 'tiboform' ), 'url', 'https://' ); tiboform_setting_input( $s, 'kvkk_url', __( 'Privacy notice (KVKK) page URL', 'tiboform' ), 'url' ); tiboform_setting_input( $s, 'keep_days', __( 'Delete submissions after (days, 0 = keep)', 'tiboform' ), 'number' ); tiboform_setting_input( $s, 'color', __( 'Accent color (empty = theme color)', 'tiboform' ), 'text', '#2563eb' ); echo '
'; tiboform_setting_input( $s, 'reply_subject', __( 'Reply subject', 'tiboform' ) ); echo '
'; do_action( 'tiboform_builder_settings', $f ); echo '
'; } add_action( 'admin_post_tiboform_save', function () { $id = isset( $_POST['id'] ) ? absint( $_POST['id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Verified by check_admin_referer() on the next line; the ID is part of the nonce action. check_admin_referer( 'tiboform_save_' . $id ); if ( ! current_user_can( 'edit_pages' ) || 'tiboform_form' !== get_post_type( $id ) ) { wp_die( esc_html__( 'Not allowed.', 'tiboform' ) ); } $old = tiboform_form( $id ); // JSON metni çözülür çözülmez her değer temizlenir; tiboform_clean_schema() alan bazında ayrıca doğrular. $json = isset( $_POST['schema'] ) && is_string( $_POST['schema'] ) ? wp_unslash( $_POST['schema'] ) : '{}'; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- JSON metni; çözüldüğü satırın hemen ardından tiboform_sanitize_deep() ile temizlenir. $raw = json_decode( $json, true ); $raw = is_array( $raw ) ? tiboform_sanitize_deep( $raw, true ) : array(); $raw['settings'] = isset( $_POST['s'] ) && is_array( $_POST['s'] ) ? tiboform_sanitize_deep( wp_unslash( $_POST['s'] ), true ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- tiboform_sanitize_deep() her değeri temizler. $clean = tiboform_clean_schema( $raw ); // Bu ekranda gönderilmeyen ayarlar (ör. Pro kapalıyken Pro ayarları) korunur. foreach ( $old['settings'] as $k => $v ) { if ( ! array_key_exists( $k, $clean['settings'] ) ) { $clean['settings'][ $k ] = $v; } } wp_update_post( array( 'ID' => $id, 'post_title' => sanitize_text_field( wp_unslash( $_POST['title'] ?? '' ) ), 'post_content' => wp_slash( wp_json_encode( $clean ) ) ) ); tiboform_flash( __( 'Form saved.', 'tiboform' ) ); wp_safe_redirect( tiboform_admin_url( array( 'edit' => $id ) ) ); exit; } ); /** * Durum rozeti. * * @param string $st Durum. * @return string */ function tiboform_status_badge( $st ) { $l = tiboform_statuses(); return '' . esc_html( isset( $l[ $st ] ) ? $l[ $st ] : $st ) . ''; } /** * Başvurular. */ function tiboform_tab_entries() { // Parametreler tiboform_query() ile yalnız geçerli nonce + yetkiyle okunur. $form = absint( tiboform_query( 'form' ) ); $view = absint( tiboform_query( 'view' ) ); $status = sanitize_key( tiboform_query( 'status' ) ); $sts = tiboform_statuses(); if ( $view && 'tiboform_entry' === get_post_type( $view ) ) { if ( 'new' === tiboform_entry_status( $view ) && current_user_can( 'edit_pages' ) ) { update_post_meta( $view, '_tiboform_status', 'read' ); } $e = get_post( $view ); $st = tiboform_entry_status( $view ); echo '

' . esc_html( $e->post_title ) . ' ' . wp_kses_post( tiboform_status_badge( $st ) ) . '

'; foreach ( (array) get_post_meta( $view, '_tiboform_data', true ) as $d ) { if ( ! is_array( $d ) || ! isset( $d['label'] ) ) { continue; } echo ''; } echo '
' . esc_html( $d['label'] ) . '' . wp_kses_post( tiboform_value_html( $d, $view, 'admin' ) ) . '
' . esc_html__( 'Page', 'tiboform' ) . '' . esc_html( (string) get_post_meta( $view, '_tiboform_page', true ) ) . '
' . esc_html__( 'Date', 'tiboform' ) . '' . esc_html( get_the_date( 'j F Y H:i', $e ) ) . '
'; do_action( 'tiboform_entry_view_after', $view, (array) get_post_meta( $view, '_tiboform_data', true ) ); echo '
'; wp_nonce_field( 'tiboform_entry_' . $view ); echo '

← ' . esc_html__( 'Back', 'tiboform' ) . ' ' . esc_html__( 'Delete', 'tiboform' ) . '

'; return; } $forms = get_posts( array( 'post_type' => 'tiboform_form', 'posts_per_page' => 200 ) ); echo '

' . esc_html__( 'Submissions', 'tiboform' ) . '

'; if ( $form ) { echo '' . esc_html__( 'Download CSV', 'tiboform' ) . ''; } echo '
'; do_action( 'tiboform_entries_toolbar', $form ); echo '
'; $q = array( 'post_type' => 'tiboform_entry', 'posts_per_page' => 100 ); if ( $form ) { $q['post_parent'] = $form; } if ( isset( $sts[ $status ] ) ) { $q['meta_query'] = array( array( 'key' => '_tiboform_status', 'value' => $status ) ); // phpcs:ignore WordPress.DB.SlowDBQuery } else { $q['meta_query'] = array( 'relation' => 'OR', array( 'key' => '_tiboform_status', 'value' => 'spam', 'compare' => '!=' ), array( 'key' => '_tiboform_status', 'compare' => 'NOT EXISTS' ) ); // phpcs:ignore WordPress.DB.SlowDBQuery } $list = get_posts( $q ); if ( ! $list ) { echo '

' . esc_html__( 'No submissions yet.', 'tiboform' ) . '

'; } else { echo ''; foreach ( $list as $e ) { $d = (array) get_post_meta( $e->ID, '_tiboform_data', true ); $sum = implode( ' · ', array_slice( array_filter( wp_list_pluck( array_filter( $d, 'is_array' ), 'value' ) ), 0, 3 ) ); $st = tiboform_entry_status( $e->ID ); echo ''; } echo '
' . esc_html__( 'Status', 'tiboform' ) . '' . esc_html__( 'Summary', 'tiboform' ) . '' . esc_html__( 'Form', 'tiboform' ) . '' . esc_html__( 'Date', 'tiboform' ) . '
' . wp_kses_post( tiboform_status_badge( $st ) ) . '' . esc_html( wp_trim_words( $sum, 16 ) ) . '' . ( get_post_meta( $e->ID, '_tiboform_note', true ) ? ' ✎' : '' ) . '' . esc_html( get_the_title( $e->post_parent ) ) . '' . esc_html( get_the_date( 'j M Y H:i', $e ) ) . '
'; } echo '
'; } add_action( 'admin_post_tiboform_entry_update', function () { $id = isset( $_POST['id'] ) ? absint( $_POST['id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Verified by check_admin_referer() on the next line; the ID is part of the nonce action. check_admin_referer( 'tiboform_entry_' . $id ); if ( ! current_user_can( 'edit_pages' ) || 'tiboform_entry' !== get_post_type( $id ) ) { wp_die( esc_html__( 'Not allowed.', 'tiboform' ) ); } $st = isset( $_POST['status'] ) ? sanitize_key( wp_unslash( $_POST['status'] ) ) : 'read'; if ( isset( tiboform_statuses()[ $st ] ) ) { update_post_meta( $id, '_tiboform_status', $st ); } update_post_meta( $id, '_tiboform_note', sanitize_textarea_field( wp_unslash( $_POST['note'] ?? '' ) ) ); do_action( 'tiboform_entry_updated', $id, $st ); tiboform_flash( __( 'Saved.', 'tiboform' ) ); wp_safe_redirect( tiboform_admin_url( array( 'tab' => 'entries', 'view' => $id ) ) ); exit; } ); add_action( 'admin_post_tiboform_del_entry', function () { $id = isset( $_GET['id'] ) ? absint( $_GET['id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Verified by check_admin_referer() on the next line; the ID is part of the nonce action. check_admin_referer( 'tiboform_del_entry_' . $id ); if ( ! current_user_can( 'edit_pages' ) || 'tiboform_entry' !== get_post_type( $id ) ) { wp_die( esc_html__( 'Not allowed.', 'tiboform' ) ); } $parent = wp_get_post_parent_id( $id ); wp_delete_post( $id, true ); wp_safe_redirect( tiboform_admin_url( array( 'tab' => 'entries', 'form' => $parent ) ) ); exit; } ); /** * CSV hücresi: Excel formül enjeksiyonuna karşı = + - @ ile başlayan hücreler kaçışlanır. * * @param string $v Değer. * @return string */ function tiboform_csv_cell( $v ) { $v = (string) $v; return preg_match( '/^[=+\-@\t\r]/', $v ) ? "'" . $v : $v; } add_action( 'admin_post_tiboform_csv', function () { $form = isset( $_GET['form'] ) ? absint( $_GET['form'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Verified by check_admin_referer() on the next line; the ID is part of the nonce action. check_admin_referer( 'tiboform_csv_' . $form ); $f = tiboform_form( $form ); if ( ! current_user_can( 'edit_pages' ) || ! $f ) { wp_die( esc_html__( 'Not allowed.', 'tiboform' ) ); } header( 'Content-Type: text/csv; charset=utf-8' ); header( 'Content-Disposition: attachment; filename="' . sanitize_file_name( $f['title'] ) . '.csv"' ); $o = fopen( 'php://output', 'w' ); // phpcs:ignore WordPress.WP.AlternativeFunctions fwrite( $o, "\xEF\xBB\xBF" ); // phpcs:ignore WordPress.WP.AlternativeFunctions $cols = array(); foreach ( $f['fields'] as $x ) { if ( ! in_array( $x['type'], tiboform_layout_types(), true ) ) { $cols[ $x['id'] ] = wp_strip_all_tags( $x['label'] ); } } $sts = tiboform_statuses(); fputcsv( $o, array_merge( array( __( 'Date', 'tiboform' ), __( 'Status', 'tiboform' ) ), array_values( $cols ) ), ';' ); foreach ( get_posts( array( 'post_type' => 'tiboform_entry', 'post_parent' => $form, 'posts_per_page' => -1 ) ) as $e ) { $d = (array) get_post_meta( $e->ID, '_tiboform_data', true ); $row = array( get_the_date( 'Y-m-d H:i', $e ), $sts[ tiboform_entry_status( $e->ID ) ] ); foreach ( array_keys( $cols ) as $k ) { $row[] = tiboform_csv_cell( isset( $d[ $k ]['value'] ) ? $d[ $k ]['value'] : '' ); } fputcsv( $o, $row, ';' ); } fclose( $o ); // phpcs:ignore WordPress.WP.AlternativeFunctions exit; } );