Custom WordPress plugin that replaces the default flat media library with a structured folder view. Features: hierarchical folders via custom taxonomy, sidebar folder tree, drag & drop, modal integration with Elementor/builders, bulk assign, upload auto-assign, toast notifications. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
8.7 KiB
8.7 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous
| phase | plan | type | wave | depends_on | files_modified | autonomous | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 02-media-library-grid | 01 | execute | 1 |
|
|
true |
Purpose
Bez filtrowania i przypisywania foldery sa bezuzyteczne — to core feature pluginu.
Output
- Filtrowanie media grid po kliknieciu folderu w sidebar
- AJAX endpoint do przypisywania mediow do folderow
- Drag & drop mediow z grida na folder w drzewku
- Aktualizacja counterow folderow po zmianach
Prior Work
@.paul/phases/01-media-folders-plugin/01-01-SUMMARY.md
- MFP_Taxonomy z media_folder taxonomy
- MFP_Ajax_Handler z 5 CRUD endpoints
- folder-tree.js dispatches CustomEvent 'mfp-folder-selected'
- Sidebar z drzewkiem juz renderuje sie na upload.php
Source Files
@wp-content/plugins/media-folder-pro/media-folder-pro.php @wp-content/plugins/media-folder-pro/includes/class-ajax-handler.php @wp-content/plugins/media-folder-pro/includes/class-taxonomy.php @wp-content/plugins/media-folder-pro/assets/js/folder-tree.js @wp-content/plugins/media-folder-pro/assets/css/admin.css
<acceptance_criteria>
AC-1: Filtrowanie mediow po kliknieciu folderu
Given plugin aktywny, istnieja foldery z przypisanymi mediami
When uzytkownik klika folder "Zdjecia produktow" w drzewku
Then grid mediow pokazuje tylko attachmenty przypisane do tego folderu
And klikniecie "Wszystkie media" przywraca pelna liste
AC-2: Przypisywanie mediow do folderow przez AJAX
Given plugin aktywny, istnieje folder i media bez folderu
When wywolany zostaje AJAX mfp_assign_media z attachment_ids i folder_id
Then attachmenty zostaja przypisane do taxonomy term media_folder
And odpowiedz zawiera liczbe przypisanych mediow
AC-3: Drag & drop mediow na foldery
Given plugin aktywny, widoczny grid mediow i drzewko folderow
When uzytkownik przeciaga miniature media na folder w drzewku
Then media zostaje przypisane do tego folderu
And counter folderu aktualizuje sie
And grid odswieza sie jesli aktywny jest inny folder
</acceptance_criteria>
Task 1: Server-side media query filter + assign endpoint wp-content/plugins/media-folder-pro/includes/class-media-query.php, wp-content/plugins/media-folder-pro/includes/class-ajax-handler.php, wp-content/plugins/media-folder-pro/media-folder-pro.php 1. Utworzyc includes/class-media-query.php — klasa MFP_Media_Query: - Hook na 'ajax_query_attachments_args' (filtr WP uzywany przez media grid) - Jesli w $_REQUEST istnieje parametr 'media_folder' (int > 0): - Dodaj tax_query do args: taxonomy=media_folder, terms=[folder_id] - Jesli media_folder === -1 (uncategorized): - Dodaj tax_query z operator NOT EXISTS (media bez folderu) - Metoda register(): add_filter('ajax_query_attachments_args', ...)2. W class-ajax-handler.php dodac nowy endpoint mfp_assign_media:
- Parametry: attachment_ids (array int), folder_id (int, 0 = usun z folderow)
- Dla kazdego attachment_id:
- Jesli folder_id > 0: wp_set_object_terms($attachment_id, [$folder_id], 'media_folder')
- Jesli folder_id === 0: wp_set_object_terms($attachment_id, [], 'media_folder')
- Zwraca: {success: true, count: N, folder_counts: {id: count, ...}}
- folder_counts: zaktualizowane countery wszystkich folderow (dla odswiezenia UI)
- Dodac 'mfp_assign_media' do tablicy $actions w register_hooks()
3. W media-folder-pro.php:
- require_once class-media-query.php
- Utworzyc instancje MFP_Media_Query w konstruktorze
- Wywolac register() w konstruktorze (nie potrzebuje hooka init)
Avoid: Nie modyfikowac globalnego WP_Query — tylko ajax_query_attachments_args.
Avoid: Nie uzywac append=true w wp_set_object_terms — kazdy media ma dokladnie 1 folder (lub 0).
- AJAX query-attachments z parametrem media_folder=ID zwraca tylko media z tego folderu
- AJAX mfp_assign_media przypisuje media i zwraca success
- Bez parametru media_folder — zwraca wszystkie media (brak regresji)
AC-1 (server-side) + AC-2 satisfied: filtrowanie i przypisywanie dziala na backendzie
Task 2: Media filter JS + drag & drop
wp-content/plugins/media-folder-pro/assets/js/media-filter.js, wp-content/plugins/media-folder-pro/assets/js/folder-tree.js, wp-content/plugins/media-folder-pro/assets/css/admin.css, wp-content/plugins/media-folder-pro/media-folder-pro.php
1. Utworzyc assets/js/media-filter.js — integracja z WP media grid:
- Nasluchuj na 'mfp-folder-selected' CustomEvent
- Przy wyborze folderu:
- Pobierz wp.media.frame (AttachmentsBrowser) jesli istnieje
- Ustaw props modelu kolekcji: collection.props.set({media_folder: folderId})
- To wymusi AJAX reload z nowym parametrem
- Przy "Wszystkie media" (folderId === null):
- collection.props.unset('media_folder') lub set media_folder do 0
- Fallback: jesli wp.media nie istnieje (list view), uzyj window.location z query param
2. Drag & drop w media-filter.js:
- Na elementach .attachment w grid: dodaj draggable=true
- MutationObserver na kontenerze .attachments aby lapac nowo dodane elementy
- dragstart: ustaw dataTransfer z attachment ID (z data-id atrybutu)
- Dodaj klase 'mfp-dragging' na body
- dragend: usun klase 'mfp-dragging'
3. W folder-tree.js dodac obsluge drop:
- Na kazdym .mfp-folder__row: dragover (preventDefault + klasa 'mfp-drop-target')
- dragleave: usun klase 'mfp-drop-target'
- drop: odczytaj attachment ID z dataTransfer
- Wywolaj AJAX mfp_assign_media
- Po sukcesie: refreshTree() (odswiezy countery)
- Jesli aktywny folder != docelowy: refresh grid (dispatchEvent)
- Wyeksportuj refreshTree jako window.mfpRefreshTree aby media-filter.js moglo go wywolac
4. W admin.css dodac style:
- .mfp-drop-target: niebieskie podswietlenie folderu podczas drag over
- .mfp-dragging .mfp-folder__row: subtelny hover indicator
- .attachment[draggable] cursor: grab
5. W media-folder-pro.php:
- Enqueue media-filter.js z dependency ['media-views'] (WP media JS)
- Dodac i18n strings: 'assignSuccess', 'assignError'
Avoid: Nie uzywac jQuery UI Draggable/Droppable — czysty HTML5 Drag & Drop API.
Avoid: Nie modyfikowac WP core JS — tylko hookujemy sie przez props.set().
- Klikniecie folderu filtruje grid (widac tylko media z folderu)
- Klikniecie "Wszystkie media" przywraca wszystko
- Przeciagniecie miniaturki na folder przypisuje media
- Counter folderu aktualizuje sie po drop
- Brak JS errors w konsoli
AC-1 (client-side) + AC-3 satisfied: filtrowanie i drag & drop dzialaja w UI
DO NOT CHANGE
- wp-content/plugins/elementor-pro/* (nie modyfikujemy Elementora)
- wp-content/plugins/media-folder-pro/includes/class-taxonomy.php (stabilna z Phase 1)
- Zadne pliki core WordPress
SCOPE LIMITS
- Brak integracji z media modal (Phase 3)
- Brak bulk operations z UI (Phase 4)
- Brak drag & drop folderow miedzy soba (juz jest w AJAX, UI w Phase 4)
- List view (wp_list_table) — tylko grid view w tej fazie
<success_criteria>
- Wszystkie taski ukonczone
- Wszystkie verification checks przeszly
- Brak bledow PHP i JS
- Filtrowanie + drag & drop dzialaja plynnie </success_criteria>