PluginProbe ʕ •ᴥ•ʔ
Presto Player / 4.2.1
Presto Player v4.2.1
4.3.0 4.2.4 4.2.3 4.2.2 4.2.0 4.2.1 trunk 1.10.0 1.10.1 1.10.2 1.11.0 1.12.0 1.13.0 1.14.0 1.14.1 1.5.10 1.5.11 1.5.12 1.5.13 1.5.14 1.5.15 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.10 1.6.11 1.6.12 1.6.13 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.16 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.2.0 2.2.1 2.2.2 2.2.3 2.2.3-beta1 2.3.0 2.3.1 2.3.2 2.3.3 3.0.0 3.0.0-beta1 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.1.0 3.1.1 3.1.2 3.1.3 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4
presto-player / CLAUDE.md
presto-player Last commit date
dist 1 month ago img 1 month ago inc 1 month ago languages 1 month ago src 1 month ago templates 2 months ago vendor 1 month ago CLAUDE.md 1 month ago FORCE_UI_SETUP.md 1 month ago LICENSE 5 years ago TAILWIND_SETUP.md 1 month ago index.php 4 years ago package.json 1 month ago phpinsights.php 1 month ago presto-player.php 1 month ago readme.txt 1 month ago
CLAUDE.md
361 lines
1 # CLAUDE.md
2
3 This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
5 ## Project Overview
6
7 Presto Player is a WordPress video player plugin (v4.1.0) that provides video capabilities for WordPress websites with support for multiple sources (YouTube, Vimeo, self-hosted HTML5, HLS streams, Bunny.net). It features a modern architecture combining PHP backend with React frontend, built specifically for WordPress Block Editor (Gutenberg) with extensive LMS and page builder integrations.
8
9 **Requirements:** PHP 7.3+, WordPress 5.6+
10
11 ## Context7 — Always Look Up Docs Before Writing Code
12
13 Before implementing any feature, always use Context7 (MCP) to look up the relevant library/framework documentation. This applies to **every tech stack** — not just WordPress. Use `resolve-library-id` to find the library, then `query-docs` to get current API details.
14
15 **When to use:** Any time you're about to write code that uses a library, framework, or API — WordPress hooks, React components, CSS/Tailwind utilities, PHP functions, Stencil.js, or any dependency in the project.
16
17 **Pre-resolved WordPress sources** (skip resolve step for these):
18 - **WordPress API Reference** (`/websites/developer_wordpress_reference`) — functions, general API
19 - **WordPress Classes** (`/websites/developer_wordpress_reference_classes`) — `WP_Query`, `WP_REST_*`, etc.
20 - **WordPress Hooks** (`/websites/developer_wordpress_reference_hooks`) — actions & filters
21
22 **For all other libraries** (React, Tailwind, Stencil, Force UI, HLS.js, Plyr, etc.), resolve the library ID first, then query the relevant docs before implementation.
23
24 ## Use Existing APIs First — Don't Reinvent What the Platform Provides
25
26 Before implementing any feature, check whether WordPress, Gutenberg, or the library/framework you're working with already provides it. Custom code should only exist when the platform genuinely cannot do what's needed.
27
28 **This applies to every layer of the stack:**
29
30 **PHP / Backend:**
31 1. **WP REST API**`WP_REST_Posts_Controller` already handles CRUD for any post type with `show_in_rest`. Before writing a custom REST endpoint for updating post fields (title, slug, status, date, password, taxonomies, meta), check if `/wp/v2/{rest_base}/{id}` already supports it.
32 2. **Core functions**`wp_update_post()`, `wp_insert_post()`, `wp_set_post_terms()`, `update_post_meta()` etc. already handle sanitization, capability checks, and hooks. Don't rewrite what they do.
33
34 **JavaScript / Gutenberg / Block Editor:**
35 1. **`@wordpress/data` stores**`core`, `core/editor`, `core/block-editor`, `core/notices` already expose selectors and actions for posts, blocks, settings, and UI state. Check existing stores before creating custom state management.
36 2. **`@wordpress/api-fetch`** — Already handles nonces, error parsing, and middleware. Don't build custom fetch wrappers.
37 3. **Block Editor APIs**`registerBlockType`, `InspectorControls`, `useBlockProps`, `RichText`, `InnerBlocks` etc. already solve most block UI needs. Check the Block Editor Handbook before building custom solutions.
38 4. **`@wordpress/components`** — For block editor UI (not dashboard), WordPress provides ready-made components. Don't rebuild what exists.
39
40 **The test:** Before writing custom code, ask: "Does the platform already do this?" If your code is just wrapping or proxying a built-in API with minor additions, use the built-in API directly.
41
42 ## LSP — Prefer for Code Navigation
43
44 When navigating code — finding definitions, references, implementations, or call chains — prefer the LSP tool over Grep/Glob for `.php`, `.ts`, `.js`, `.tsx`, and `.jsx` files. LSP provides accurate, type-aware results.
45
46 **Use LSP for:** `goToDefinition`, `findReferences`, `hover` (type info), `documentSymbol` (list symbols in a file), `workspaceSymbol` (search symbols across workspace), `goToImplementation`, `incomingCalls`, `outgoingCalls`.
47
48 **Fall back to Grep/Glob for:** text/string searches, pattern matching, file discovery, or when LSP returns no results.
49
50 ## Development Commands
51
52 ### Initial Setup
53 ```bash
54 # Install dependencies
55 yarn && composer install
56
57 # Bootstrap workspace packages (first-time setup)
58 yarn bootstrap
59
60 # Start development mode (includes composer install + watch)
61 yarn dev
62 ```
63
64 ### Build Commands
65 ```bash
66 # Development build and watch
67 yarn start # Watch mode with wp-scripts
68 yarn start:workspace # Watch all workspace packages
69
70 # Production build
71 yarn build # Build main plugin
72 yarn build:workspace # Build all workspace packages
73
74 # Release build (full production)
75 yarn plugin:release # Complete release: deps, i18n, build, zip
76 ```
77
78 ### Testing
79
80 **PHP Tests** (requires wp-env running):
81 ```bash
82 yarn test:php # Run all PHPUnit tests
83 yarn test:php:failing # Run only tests marked @group failing
84 composer test # Direct PHPUnit run (alternative)
85 ```
86
87 **JavaScript Tests**:
88 ```bash
89 yarn test:unit # Jest unit tests
90 ```
91
92 **E2E Tests** (requires wp-env running):
93 ```bash
94 yarn test:e2e # WordPress E2E scripts
95 yarn test:e2e:playwright # Playwright tests
96 yarn test:e2e:playwright:ui # Playwright UI mode
97 yarn test:e2e:playwright:debug # Playwright debug mode
98 yarn test:e2e:playwright:trace # Playwright with tracing
99 ```
100
101 ### WordPress Environment
102 ```bash
103 # Start/stop local WordPress environment (wp-env)
104 wp-env start # Start WordPress at :3333 (tests at :4333)
105 wp-env stop # Stop environment
106 ```
107
108 ### Linting & Formatting
109 ```bash
110 yarn lint:js # ESLint
111 yarn lint:css # Stylelint
112 yarn format # Prettier format
113
114 composer lint # PHPCS (PHP_CodeSniffer)
115 composer format # PHPCBF (PHP auto-fix)
116 ```
117
118 ### Translation
119 ```bash
120 yarn makepot # Generate .pot file from src/, inc/, templates/
121 ```
122
123 ## Architecture Overview
124
125 ### PHP Backend Architecture
126
127 **Entry Point:** `presto-player.php``Factory``Controller` → Component registration
128
129 **Dependency Injection Container:**
130 - Uses **DICE** DI container for loose coupling
131 - Configured via `inc/Factory.php` and `inc/config/app.php`
132 - Components implement `Service` interface with `register()` method
133 - Singleton services (Settings, BunnyCDN, Scripts) marked as `'shared' => true`
134
135 **Key Architectural Layers:**
136 ```
137 presto-player.php (entry)
138
139 Factory::getRules() - DI configuration
140
141 Controller::run() - Registers all components
142
143 Components (each calls register() method):
144 - Blocks (10 block types)
145 - Services (23+ services including Scripts, Settings, Menu, Shortcodes)
146 - Integrations (11 integrations: LearnDash, Elementor, Divi, etc.)
147 - Database (migrations, models)
148 - API (REST controllers)
149 ```
150
151 **Component Discovery:**
152 - All components listed in `inc/config/app.php` under `components` array
153 - Pro components added via `presto_player_pro_components` filter
154 - Factory creates instances with dependencies via DICE container
155 - Controller loops through components and calls `register()`
156
157 **Namespace:** `PrestoPlayer\` (PSR-4 autoloaded to `inc/`)
158
159 **Database:**
160 - Custom tables managed in `inc/Database/`
161 - Tables: videos, presets, audio_presets, email_collection, visits, webhooks
162 - Models in `inc/Models/` provide ORM-like interface
163 - Migrations handled via `inc/Services/Migrations.php`
164
165 ### Frontend (JavaScript/React)
166
167 **Build System:**
168 - Yarn 3.3.0 workspaces (monorepo)
169 - WordPress Scripts (Webpack, Babel)
170 - Emotion CSS-in-JS for styling
171 - React 17.0.2
172
173 **Directory Structure:**
174 ```
175 src/
176 ├── admin/ # WordPress admin React interfaces
177 ├── player/ # Player components
178 ├── router/ # Page routing
179 ├── hooks/ # React hooks
180 ├── shared/ # Shared utilities
181 ├── elementor/ # Elementor integration UI
182 └── libraries/ # Custom libraries
183
184 dist/ # Compiled assets (auto-generated)
185 ```
186
187 **Key Patterns:**
188 - Block-first design (Gutenberg blocks in `inc/Blocks/`)
189 - REST API for admin interfaces (`inc/Services/API/`)
190 - Dynamic loading for performance (scripts loaded conditionally)
191
192 ### Block Development
193
194 **Block Registration:**
195 1. Create block class in `inc/Blocks/` extending base block class
196 2. Add to `inc/config/app.php` components array
197 3. Implement `register()` method to register with WordPress
198 4. Block attributes defined in block class
199 5. React component in `src/` for editor interface
200
201 **Block Types:**
202 - Video blocks: SelfHostedBlock, YouTubeBlock, VimeoBlock
203 - Reusable: ReusableVideoBlock, MediaHubBlock
204 - Audio: AudioBlock
205 - Popup: PopupBlock, PopupTriggerBlock, PopupMediaBlock
206
207 ### Integrations
208
209 **LMS Integrations** (`inc/Integrations/`):
210 - LearnDash (video progression)
211 - TutorLMS
212 - LifterLMS
213
214 **Page Builders:**
215 - Elementor (custom widgets)
216 - Beaver Builder (custom modules)
217 - Divi (custom modules)
218 - Kadence
219
220 Each integration is a component that registers when its parent plugin is active.
221
222 ## Code Patterns & Conventions
223
224 ### PHP Patterns
225 - **PSR-4 Autoloading**: All classes under `PrestoPlayer\` namespace
226 - **Service Pattern**: Components implement `Service` interface
227 - **Singleton Pattern**: Core instance via `Core::set_instance()`
228 - **Factory Pattern**: DI container configuration in Factory class
229 - **Hook System**: WordPress hooks (`add_action`, `add_filter`)
230
231 ### JavaScript Patterns
232 - **React Components**: Functional components with hooks
233 - **CSS-in-JS**: Emotion for styling
234 - **WordPress Data**: `@wordpress/data` for state management
235 - **i18n**: WordPress i18n functions for translations
236
237 ### Namespacing
238 - PHP classes are namespaced: `PrestoPlayer\Services\Settings`
239 - Imposter plugin isolates vendor dependencies under `PrestoPlayer\` namespace
240
241 ## Security Checklist
242
243 Every REST endpoint, AJAX handler, form processor, or shortcode callback **must** pass these checks. Do not skip any — WordPress plugin reviewers and security auditors flag these as critical.
244
245 ### Authentication & Authorization
246 - **Capability check:** `current_user_can( 'edit_posts' )` (or appropriate capability) before any state-changing operation
247 - **Nonce verification:** `wp_verify_nonce()` for admin forms; REST API routes use `permission_callback` (never set to `__return_true` for write operations)
248 - **REST permission_callback:** Every `register_rest_route()` must have a `permission_callback` — use `current_user_can()` checks, not blanket `__return_true`
249
250 ### Input Sanitization (before storage/use)
251 - **Strings:** `sanitize_text_field()`, `sanitize_textarea_field()`, `sanitize_title()`
252 - **URLs:** `esc_url_raw()` (for DB storage), `esc_url()` (for output)
253 - **Integers:** `absint()`, `intval()`
254 - **HTML content:** `wp_kses_post()` (allows safe HTML), `wp_kses()` (custom allowed tags)
255 - **File paths:** `sanitize_file_name()`, validate against allowed directories
256 - **Arrays/complex data:** Sanitize each element individually — never trust `$_POST` or `$_GET` raw
257 - **REST requests:** Use `$request->get_param()` with sanitize/validate callbacks in the schema
258
259 ### Output Escaping (before rendering)
260 - **HTML context:** `esc_html()`, `esc_html__()`
261 - **Attribute context:** `esc_attr()`, `esc_attr__()`
262 - **URL context:** `esc_url()`
263 - **JavaScript context:** `esc_js()`, or better — use `wp_localize_script()` / `wp_add_inline_script()`
264 - **CSS context:** `safecss_filter_attr()`
265
266 ### Database Queries
267 - **Always use `$wpdb->prepare()`** for any query with dynamic values — no exceptions
268 - **Never concatenate** user input into SQL strings
269 - Prefer WordPress API functions (`get_post_meta()`, `WP_Query`) over raw queries when possible
270
271 ### Common Pitfalls to Avoid
272 - Never use `$_GET`, `$_POST`, `$_REQUEST` directly — access via `WP_REST_Request`, `sanitize_*()`, or `wp_unslash()` + sanitize
273 - Never use `extract()` — it creates variables from untrusted data
274 - Never use code evaluation functions or `preg_replace()` with the `e` modifier
275 - Never output unsanitized data in `wp_die()`, error messages, or admin notices
276 - `update_option()` auto-serializes — don't `json_encode()` before storing unless you need JSON specifically
277 - File uploads: validate MIME type with `wp_check_filetype()`, use `wp_handle_upload()` — never move files manually
278
279 ## Testing Strategy
280
281 **Test Locations:**
282 - PHP Unit: `tests/unit/`
283 - PHP Feature: `tests/feature/`
284 - JS Unit: `src/**/test/*.spec.js`
285 - E2E: `tests-e2e/**/*.spec.{js,ts}`
286
287 **Testing Environment:**
288 - PHP tests run in wp-env WordPress CLI environment
289 - Requires WordPress test suite
290 - E2E tests require wp-env running (ports 3333/4333)
291
292 **Test Configuration:**
293 - PHPUnit: `phpunit.xml.dist`
294 - Jest: `jest.config.unit.js`
295 - E2E (Jest): `jest.config.e2e.js`
296 - Playwright: `playwright.config.js` (if exists)
297
298 ## Key Files Reference
299
300 | Path | Purpose |
301 |------|---------|
302 | `presto-player.php` | Main plugin file (entry point) |
303 | `inc/Controller.php` | Component registration controller |
304 | `inc/Factory.php` | DI container factory and rules |
305 | `inc/config/app.php` | Component configuration array |
306 | `inc/Core.php` | Singleton core instance holder |
307 | `inc/Services/Scripts.php` | Script/style enqueueing |
308 | `inc/Services/Settings.php` | Global settings management |
309 | `inc/Services/Shortcodes.php` | Shortcode implementation |
310 | `inc/Models/` | Database models |
311 | `inc/Database/` | Table schemas and migrations |
312 | `package.json` | Root workspace config |
313 | `@presto-player/presto-player/package.json` | Workspace package config |
314 | `composer.json` | PHP dependencies and autoload |
315
316 ## Verification
317
318 After making any changes, always verify with Playwright browser testing (via MCP tools) before considering work complete. Build compiling alone does not guarantee correctness. Navigate to the relevant page and confirm changes render, function, and behave correctly — this applies to UI components, PHP backend changes, REST API responses, settings, and any other modification that affects the user-facing experience.
319
320 ## Important Notes
321
322 ### WordPress Environment (.wp-env.json)
323 - Development: `http://localhost:3333`
324 - Test environment: `http://localhost:4333`
325 - Loads both presto-player (free) and presto-player-pro plugins
326
327 ### Vendor Dependencies
328 - **DICE**: Dependency injection container
329 - **Imposter**: Namespace isolation for dependencies (critical for avoiding conflicts)
330 - Always run `composer install` after pulling changes
331
332 ### Translation Workflow
333 - Strings use WordPress i18n: `__()`, `_e()`, `esc_html__()` etc.
334 - Text domain: `presto-player`
335 - POT file: `languages/presto-player.pot`
336 - Generated from `src/`, `inc/`, and `templates/`
337
338 ### Pro Version Integration
339 - Pro plugin adds components via `presto_player_pro_components` filter
340 - Pro check: `Plugin::isPro()` method
341 - Settings constructor accepts `$isPro` parameter
342 - Pro features conditionally registered based on pro plugin activation
343
344 ### Workspace Structure
345 - Yarn workspaces used (Yarn 3+)
346 - Workspace packages in `@presto-player/presto-player/packages/*`
347 - Bootstrap command builds workspace dependencies
348 - Workspace commands run across all packages
349
350 ### Release Process
351 ```bash
352 yarn plugin:release
353 ```
354 This command:
355 1. Installs all dependencies
356 2. Generates translation files
357 3. Reinstalls composer without dev dependencies
358 4. Builds all workspace packages
359 5. Creates plugin zip
360 6. Extracts zip for distribution
361