Files
rm2.pagedev.pl/.paul/phases/02-media-library-grid/02-01-PLAN.md
Jacek Pyziak 5014b9108f feat(media-folder-pro): add virtual folder system for WordPress media library
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>
2026-03-28 14:08:49 +01:00

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
01-01
wp-content/plugins/media-folder-pro/includes/class-ajax-handler.php
wp-content/plugins/media-folder-pro/includes/class-media-query.php
wp-content/plugins/media-folder-pro/assets/js/folder-tree.js
wp-content/plugins/media-folder-pro/assets/js/media-filter.js
wp-content/plugins/media-folder-pro/assets/css/admin.css
wp-content/plugins/media-folder-pro/media-folder-pro.php
true
## Goal Podlaczyc drzewko folderow do filtrowania biblioteki mediow WP oraz dodac drag & drop przypisywanie mediow do folderow. Po kliknieciu folderu — grid pokazuje tylko media z tego folderu. Przeciagniecie media na folder przypisuje je.

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
## Project Context @.paul/PROJECT.md @.paul/ROADMAP.md

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
Before declaring plan complete: - [ ] Klikniecie folderu filtruje media grid - [ ] "Wszystkie media" przywraca pelna liste - [ ] mfp_assign_media endpoint dziala z nonce verification - [ ] Drag & drop media na folder przypisuje i odswierza countery - [ ] Brak regresji: media grid dziala normalnie bez aktywnego filtra - [ ] Brak JS errors w konsoli przegladarki - [ ] Assets ladowane z poprawna kolejnoscia (media-views przed media-filter)

<success_criteria>

  • Wszystkie taski ukonczone
  • Wszystkie verification checks przeszly
  • Brak bledow PHP i JS
  • Filtrowanie + drag & drop dzialaja plynnie </success_criteria>
After completion, create `.paul/phases/02-media-library-grid/02-01-SUMMARY.md`