# Egyedi mezők a kurzuskészítőben

> Egyedi mezők és tartalom beillesztése a Tutor LMS kurzuskészítő előre kijelölt helyeire: mezők regisztrálása, mentés, megjelenítés, szűrők és validálás.

A Tutor LMS kurzuskészítője bővíthető: külső bővítmények egyedi mezőket és tartalmat illeszthetnek be a felület előre kijelölt helyeire (úgynevezett slotokba). A rendszer a WordPress hookjaira hasonlít.

## Hogyan működik

- A mezőket a kurzuskészítőben dinamikusan, a `registerField` függvénnyel regisztrálod.
- A mezőket konkrét slotokba teheted, így pontosan a kívánt szakaszban jelennek meg.
- Többféle mezőtípust támogat: szöveg, jelszó, többsoros szöveg, legördülő lista, rádiógomb, WPEditor, egyedi komponens és más.
- Nem csak űrlapmezőt, hanem tetszőleges tartalmat is beilleszthetsz.

## 1. Mintabővítmény

A **Tutor LMS Custom Fields** mintabővítmény referenciaszerkezetet ad, amelyet a saját beállításaidhoz alakíthatsz át. A szerkezete:

```text
tutor-lms-custom-fields/
├── custom-fields.js
└── tutor-lms-custom-fields.php
```

- `custom-fields.js`: a mezőket regisztráló JavaScript-kód a kurzuskészítő felületén.
- `tutor-lms-custom-fields.php`: a PHP-függvények, amelyek betöltik a szkripteket, mentik a mezők adatait és megjelenítik az értékeket.

## 2. Mezők létrehozása és regisztrálása

A mezőket JavaScriptben, a Tutor LMS kurzuskészítő API-ján át regisztrálod. Hozz létre egy `custom-fields.js` fájlt:

```js
document.addEventListener("DOMContentLoaded", function () {
   if (typeof Tutor !== "undefined" && Tutor.CourseBuilder) {

       // Többsoros szövegmező regisztrálása
       Tutor.CourseBuilder.Basic.registerField("after_description", {
           name: "seo_content",
           type: "textarea",
           label: "SEO-tartalom",
           placeholder: "Írj ide...",
           priority: 20,
       });

       // Számmező regisztrálása
       Tutor.CourseBuilder.Curriculum.Lesson.registerField("bottom_of_sidebar", {
           name: "lesson_duration",
           type: "number",
           label: "Lecke hossza (perc)",
           priority: 5,
       });
   }
});
```

A példában két mező szerepel: az első egy **SEO-tartalom** nevű többsoros szövegmező az **Alapok** fülön, a leírás után; a második egy **Lecke hossza (perc)** számmező a lecke oldalsávjának alján.

### A mezők beállításai

| Tulajdonság | Típus | Leírás |
|---|---|---|
| `name` | szöveg | A mező egyedi neve (kötelező). |
| `type` | szöveg | A mező típusa: `text`, `number`, `password`, `textarea`, `select`, `radio`, `checkbox`, `switch`, `date`, `time`, `image`, `video`, `uploader`, `WPEditor`. |
| `label` | szöveg | A mező felirata. |
| `placeholder` | szöveg | Helyőrző szöveg (nem kötelező). |
| `options` | tömb | A `select` és `radio` típusnál kötelező. Például: `[{ value: '1', label: '1. lehetőség' }]`. |
| `priority` | szám | A sorrendet határozza meg a slotban: a kisebb érték előrébb kerül. |
| `rules` | objektum | Validálási szabályok (React Hook Form). |

### Elérhető slotok

| Szakasz | Slotok |
|---|---|
| Alapok | `after_description`, `after_settings` |
| Tanterv, lecke | `after_description`, `bottom_of_sidebar` |
| Tanterv, kvíz | `after_question_description`, `bottom_of_question_sidebar`, `bottom_of_settings` |
| Tanterv, feladat | `after_description`, `bottom_of_sidebar` |
| További beállítások | `after_certificates`, `bottom_of_sidebar` |

A regisztráláshoz a megfelelő objektumot használd, például `Tutor.CourseBuilder.Basic` az Alapok szakaszhoz és `Tutor.CourseBuilder.Curriculum.Lesson` a leckékhez.

## 3. A szkript betöltése

A JavaScript-fájlt be kell töltened, hogy a mezők megjelenjenek a kurzuskészítőben. Hozd létre a `tutor-lms-custom-fields.php` fájlt:

```php
<?php
/**
 * Plugin Name: Tutor LMS Custom Fields
 * Description: Egyedi mezők a Tutor LMS kurzuskészítőjében.
 * Version: 1.0.0
 * Author: Saját név
 */
add_action( 'tutor_after_course_builder_load', 'tlcf_enqueue_scripts' );

/**
 * A kurzuskészítő egyedi szkriptjeinek betöltése.
 *
 * @return void
 */
function tlcf_enqueue_scripts() {
   $js_url = plugin_dir_url( __FILE__ ) . 'custom-fields.js';
   wp_enqueue_script(
       'tlcf-custom-fields-js',
       $js_url,
       array( 'tutor-course-builder' ),
       '1.0.0',
       true
   );
}
```

A függvény a `tutor_after_course_builder_load` hookra kapcsolódik, hogy a szkript csak akkor töltődjön be, amikor a kurzuskészítő aktív, és a `tutor-course-builder` szkriptre épül.

## 4. A mezők értékének mentése

A kurzus mentésekor el kell kapnod és tárolnod az egyedi mezők értékét:

```php
add_action( 'save_post_courses', 'tlcf_save_course_meta' );

/**
 * Az egyedi mező mentése a kurzus mentésekor.
 *
 * @param int $post_id A kurzus azonosítója.
 *
 * @return void
 */
function tlcf_save_course_meta( int $post_id ) {
   $seo_content = sanitize_text_field( wp_unslash( $_POST['seo_content'] ) ?? '' );
   if ( $seo_content ) {
       update_post_meta( $post_id, 'tlcf_seo_content', $seo_content );
   }
}
```

- A `save_post_courses` hook a kurzus mentési folyamatára kapcsolódik.
- A `$_POST['seo_content']` a mező értékét adja.
- A tisztítás (például `sanitize_textarea_field()`) megelőzi a biztonsági problémákat.
- Az `update_post_meta()` a megtisztított értéket a WordPress bejegyzés-metaadatai közé menti.

## 5. Az érték megjelenítése

Hogy az egyedi mező adata elérhető legyen a frontenden vagy a REST API-ban, használd a `tutor_course_details_response` szűrőt:

```php
add_filter( 'tutor_course_details_response', 'tlcf_display_custom_field_data' );

/**
 * Az egyedi mező hozzáadása a kurzus részleteihez.
 *
 * @param array $data A kurzus adatainak tömbje.
 *
 * @return array A kiegészített tömb.
 */
function tlcf_display_custom_field_data( array $data ) {
   $course_id   = $data['ID'];
   $seo_content = get_post_meta( $course_id, 'tlcf_seo_content', true );
   if ( $seo_content ) {
       $data['seo_content'] = $seo_content;
   }
   return $data;
}
```

A szűrő a kurzus részleteinek válaszát módosítja, a `get_post_meta()` kiolvassa a tárolt értéket, és a `$data['seo_content']` hozzáadja a válaszhoz.

## Hookok a kurzuskészítő bővítéséhez

Szűrők (az adatválaszokat módosítják):

```php
apply_filters( 'tutor_course_details_response', array $course_data );
apply_filters( 'tutor_quiz_details_response', WP_Post $data, int $quiz_id );
apply_filters( 'tutor_assignment_details_response', array $post, int $assignment_id );
apply_filters( 'tutor_lesson_details_response', array $post, int $lesson_id );
```

Műveletek (mentéskor futnak le):

```php
do_action( 'save_post_courses', int $post_id, WP_Post $post, bool $update );
do_action( 'save_post_lesson', int $post_id, WP_Post $post, bool $update );
do_action( 'save_post_tutor_assignments', int $post_id, WP_Post $post, bool $update );
do_action( 'save_post_tutor_quiz', int $post_id, WP_Post $post, bool $update );
```

## Gyakori kérdés: hogyan validáljam a mezőket?

A mező regisztrálásakor add meg a `rules` tulajdonságot. Példák:

Kötelező mező:

```js
const requiredRule = () => ({
    required: { value: true, message: 'Ez a mező kötelező' },
});
```

Legnagyobb hossz:

```js
const maxLimitRule = (maxLimit) => ({
    validate: (value) => {
        if (value && maxLimit < value.length) {
            return `Legfeljebb ${maxLimit} karakter engedélyezett`;
        }
        return undefined;
    },
});
```
