You've already forked wp-fedistream
400 lines
17 KiB
Markdown
400 lines
17 KiB
Markdown
# Wordpress Plugin to stream music over Activity Pub
|
|
|
|
**Author:** Marco Graetsch
|
|
**Author URL:** <https://src.bundespruefstelle.ch/magdev>
|
|
**Author Email:** <magdev3.0@gmail.com>
|
|
**Repository URL:** <https://src.bundespruefstelle.ch/magdev/wp-fedistream>
|
|
**Issues URL:** <https://src.bundespruefstelle.ch/magdev/wp-fedistream/issues>
|
|
|
|
## Project Overview
|
|
|
|
This plugin provides a way for Musicians or Music-Labels to cut the ties with Spotify, Youtube Music et al and build their own Streaming-Platform (optionally including selling their work using WooCommerce) base on the ActivityPub protocol. This plugin implements the management of Musicians (Single or Bands), Albums (or Releases), Tracks and Playlists.
|
|
|
|
The plugin utilizes the ActivityPub protocol to publish Releases or Tracks, share Playlists and let users create Playlist from different Wordpress instances, which use this plugin. It also employs Fediverse reactions to build comprehensive profile for Musicians and Bands (or the Label at all), including classicla Blogposts from Musicians. The Plugin should serve as a full Fediverse profile for Musicians. Everyone in the Fediverse is able to subscribe to the Label's or Musician's account.
|
|
|
|
If WooCommerce is installed, the Musician (or the Label) is allowed to sell the Music either as Album or single track utilizing special WooCommerce product types.
|
|
|
|
The goal is to create an alternative to the big tech streaming plaforms and give the musicians their freedom back and concentrate to make music. The first goal is to publish, the second goal is to monetize the platform without ripping of the users or musicians.
|
|
|
|
### Key Fact: 100% AI-Generated
|
|
|
|
This project is proudly **"vibe-coded"** using Claude.AI - the entire codebase was created through AI assistance.
|
|
|
|
## Temporary Roadmap
|
|
|
|
**Note for AI Assistants:** Clean this section after the specific features are done or new releases are made. Effective changes are tracked in `CHANGELOG.md`. Do not add completed versions here - document them in the Session History section at the end of this file.
|
|
|
|
### Version 0.1.1 (Bugfix)
|
|
|
|
### Version 0.2.0 (Minor)
|
|
|
|
## Technical Stack
|
|
|
|
- **Language:** PHP 8.3.x
|
|
- **Framework:** Latest WordPress Plugin API
|
|
- **E-commerce (optional):** WooCommerce 10.0+
|
|
- **Template Engine:** Twig 3.0 (via Composer)
|
|
- **Communication Protocol:** ActivityPub
|
|
- **Wordpress Base Theme** twentytwentyfive
|
|
- **Frontend:** Vanilla JavaScript
|
|
- **Styling:** Custom CSS
|
|
- **Dependency Management:** Composer
|
|
- **Internationalization:** WordPress i18n (.pot/.po/.mo files)
|
|
- **Canonical Plugin Name:** `wp-fedistream`
|
|
|
|
### Security Best Practices
|
|
|
|
- All user inputs are sanitized (integers for quantities/prices)
|
|
- Nonce verification on form submissions
|
|
- Output escaping in templates (`esc_attr`, `esc_html`, `esc_js`)
|
|
- Direct file access prevention via `ABSPATH` check
|
|
- XSS-safe DOM construction in JavaScript (no `innerHTML` with user data)
|
|
- SQL injection prevention using `$wpdb->prepare()` throughout
|
|
|
|
### Translation Ready
|
|
|
|
All user-facing strings use:
|
|
|
|
```php
|
|
__('Text to translate', 'wp-fedistream')
|
|
_e('Text to translate', 'wp-fedistream')
|
|
```
|
|
|
|
Text domain: `wp-fedistream`
|
|
|
|
#### Translation Template
|
|
|
|
- Base `.pot` file created: `languages/wp-fedistream.pot`
|
|
- Ready for translation to any locale
|
|
- All translatable strings properly marked with text domain
|
|
|
|
#### Available Translations
|
|
|
|
- `en_US` - English (United States) [base language - .pot template]
|
|
- `de_CH` - German (Switzerland, formal)
|
|
|
|
To compile translations to .mo files for production:
|
|
|
|
```bash
|
|
for po in languages/*.po; do msgfmt -o "${po%.po}.mo" "$po"; done
|
|
```
|
|
|
|
### Create releases
|
|
|
|
- The `vendor/` directory MUST be included in releases (Dependencies required for runtime)
|
|
- **Don't create any release files until version 0.1.x and up!**
|
|
- **CRITICAL**: Build `vendor/` for the MINIMUM supported PHP version, not the development version
|
|
- Use `composer config platform.php 8.3.0` before building release packages
|
|
- Run `composer update --no-dev --optimize-autoloader` to rebuild dependencies
|
|
- **CRITICAL**: WordPress requires plugins in a subdirectory structure
|
|
- Run zip from the `plugins/` parent directory, NOT from within the plugin directory
|
|
- Package must extract to `wp-fedistream/` subdirectory with main file at `wp-fedistream/wp-fedistream.php`
|
|
- Correct command: `cd /wp-content/plugins/ && zip -r wp-fedistream/releases/wp-fedistream-x.x.x.zip wp-fedistream ...`
|
|
- Wrong: Running zip from inside the plugin directory creates files at root level
|
|
- **CRITICAL**: Exclude symlinks explicitly - zip follows symlinks by default
|
|
- Always use `-x "wp-fedistream/wp-core" -x "wp-fedistream/wp-core/*" -x "wp-fedistream/wp-plugins" -x "wp-fedistream/wp-plugins/*"` to exclude development symlinks
|
|
- Otherwise the entire linked directory contents will be included in the package
|
|
- Exclusion patterns must match the relative path structure used in zip command
|
|
- Always verify the package structure with `unzip -l` before distribution
|
|
- Check all files are prefixed with `wp-fedistream/`
|
|
- Verify main file is at `wp-fedistream/wp-fedistream.php`
|
|
- Check for duplicate entries (indicates multiple builds in same archive)
|
|
- Test installation on the minimum supported PHP version before final deployment
|
|
- Releases are stored in `releases/` including checksums
|
|
- Track release changes in a single `CHANGELOG.md` file
|
|
- Bump the version number to either bugfix release versions or on new features minor release versions
|
|
- **CRITICAL**: WordPress reads version from TWO places - BOTH must be updated:
|
|
1. Plugin header comment `Version: x.x.x` (line ~6 in wc-licensed-product.php) - WordPress uses THIS for admin display
|
|
2. PHP constant `WP_FEDISTREAM_VERSION` (line ~28) - Used internally by the plugin
|
|
- If only the constant is updated, WordPress will show the old version in Plugins list
|
|
|
|
**Important Git Notes:**
|
|
|
|
- Default branch while development is `dev`
|
|
- Create releases from branch `main` after merging branch `dev`
|
|
- Tags should use format `vX.X.X` (e.g., `v1.1.22`), start with v0.1.0
|
|
- Use annotated tags (`-a`) not lightweight tags
|
|
- Commit messages should follow the established format with Claude Code attribution
|
|
- `.claude/settings.local.json` changes are typically local-only (stash before rebasing)
|
|
|
|
#### What Gets Released
|
|
|
|
- All plugin source files
|
|
- Compiled vendor dependencies
|
|
- Translation files (.mo compiled from .po)
|
|
- Assets (CSS, JS)
|
|
- Documentation (README, CHANGELOG, etc.)
|
|
|
|
#### What's Excluded
|
|
|
|
- Git metadata (`.git/`)
|
|
- Development files (`.vscode/`, `.claude/`, `CLAUDE.md`, `wp-core`, `wp-plugins`)
|
|
- Logs and cache files
|
|
- Previous releases
|
|
- `composer.lock` (but `vendor/` is included)
|
|
|
|
---
|
|
|
|
**For AI Assistants:**
|
|
|
|
When starting a new session on this project:
|
|
|
|
1. Read this CLAUDE.md file first
|
|
2. Semantic versioning follows the `MAJOR.MINOR.BUGFIX` pattern
|
|
3. Check git log for recent changes
|
|
4. Verify you're on the `dev` branch before making changes
|
|
5. Run `composer install` if vendor/ is missing
|
|
6. Test changes before committing
|
|
7. Follow commit message format with Claude Code attribution
|
|
8. Update this session history section with learnings
|
|
9. Never commit backup files (`*.po~`, `*.bak`, etc.) - check `git status` before committing
|
|
10. Follow markdown linting rules (see below)
|
|
|
|
Always refer to this document when starting work on this project.
|
|
|
|
### Markdown Linting Rules
|
|
|
|
When editing CLAUDE.md or other markdown files, follow these rules to avoid linting errors:
|
|
|
|
1. **MD031 - Blank lines around fenced code blocks**: Always add a blank line before and after fenced code blocks, even when they follow list items. Example of correct format:
|
|
|
|
- **Item label**:
|
|
|
|
(blank line here)
|
|
\`\`\`php
|
|
code example
|
|
\`\`\`
|
|
(blank line here)
|
|
|
|
2. **MD056 - Table column count**: Table separators must have matching column counts and proper spacing. Use consistent dash lengths that match column header widths.
|
|
|
|
3. **MD009 - No trailing spaces**: Remove trailing whitespace from lines
|
|
|
|
4. **MD012 - No multiple consecutive blank lines**: Use only single blank lines between sections
|
|
|
|
5. **MD040 - Fenced code blocks should have a language specified**: Always add a language identifier to code blocks (e.g., `txt`, `bash`, `php`). For shortcode examples, use `txt`.
|
|
|
|
6. **MD032 - Lists should be surrounded by blank lines**: Add a blank line before AND after list blocks, including after bold labels like `**Attributes:**`.
|
|
|
|
7. **MD034 - Bare URLs**: Wrap URLs in angle brackets (e.g., `<https://example.com>`) or use markdown link syntax `[text](url)`.
|
|
|
|
8. **Author section formatting**: Use a heading (`### Name`) instead of bold (`**Name**`) for the author name to maintain consistent document structure.
|
|
|
|
## Project Architecture
|
|
|
|
### Directory Structure
|
|
|
|
```txt
|
|
wp-fedistream/
|
|
├── assets/
|
|
│ ├── css/
|
|
│ │ ├── admin.css # Admin interface styles
|
|
│ │ └── frontend.css # Frontend styles
|
|
│ ├── js/
|
|
│ │ ├── admin.js # Admin interface scripts
|
|
│ │ ├── frontend.js # Frontend scripts
|
|
│ │ ├── player.js # Audio player
|
|
│ │ ├── library.js # User library page
|
|
│ │ └── notifications.js # Notification system
|
|
│ └── images/
|
|
├── includes/
|
|
│ ├── ActivityPub/
|
|
│ │ ├── Integration.php # ActivityPub plugin integration
|
|
│ │ ├── ArtistActor.php # Artist as ActivityPub actor
|
|
│ │ ├── Inbox.php # Process incoming activities
|
|
│ │ ├── Outbox.php # Publish outgoing activities
|
|
│ │ ├── RestApi.php # REST endpoints for ActivityPub
|
|
│ │ └── Transformers/ # Object transformers
|
|
│ │ ├── TrackTransformer.php
|
|
│ │ ├── AlbumTransformer.php
|
|
│ │ └── PlaylistTransformer.php
|
|
│ ├── Admin/
|
|
│ │ └── ListColumns.php # Custom list table columns
|
|
│ ├── Frontend/
|
|
│ │ ├── Ajax.php # AJAX handlers
|
|
│ │ ├── Shortcodes.php # All shortcodes
|
|
│ │ ├── TemplateLoader.php # Template loading
|
|
│ │ └── Widgets.php # Widget registration
|
|
│ ├── PostTypes/
|
|
│ │ ├── Artist.php # fedistream_artist
|
|
│ │ ├── Album.php # fedistream_album
|
|
│ │ ├── Track.php # fedistream_track
|
|
│ │ └── Playlist.php # fedistream_playlist
|
|
│ ├── Roles/
|
|
│ │ └── Capabilities.php # User roles and caps
|
|
│ ├── Taxonomies/
|
|
│ │ ├── Genre.php # fedistream_genre
|
|
│ │ ├── Mood.php # fedistream_mood
|
|
│ │ └── License.php # fedistream_license
|
|
│ ├── User/
|
|
│ │ ├── Library.php # Favorites, follows, history
|
|
│ │ ├── LibraryPage.php # Library shortcode
|
|
│ │ └── Notifications.php # Notification system
|
|
│ ├── WooCommerce/
|
|
│ │ ├── Integration.php # WooCommerce setup
|
|
│ │ ├── AlbumProduct.php # Album product type
|
|
│ │ ├── TrackProduct.php # Track product type
|
|
│ │ ├── DigitalDelivery.php # Download handling
|
|
│ │ └── StreamingAccess.php # Access control
|
|
│ ├── Installer.php # Database setup, activation
|
|
│ └── Plugin.php # Main singleton class
|
|
├── languages/
|
|
│ ├── wp-fedistream.pot # Translation template
|
|
│ └── wp-fedistream-de_CH.po # German (Switzerland)
|
|
├── templates/ # Twig templates
|
|
│ ├── admin/
|
|
│ ├── archive/
|
|
│ ├── single/
|
|
│ └── player/
|
|
├── vendor/ # Composer dependencies
|
|
├── composer.json
|
|
├── uninstall.php
|
|
└── wp-fedistream.php # Plugin entry point
|
|
```
|
|
|
|
### Database Tables
|
|
|
|
| Table | Purpose |
|
|
| ----- | ------- |
|
|
| `{prefix}_fedistream_plays` | Track play statistics |
|
|
| `{prefix}_fedistream_playlist_tracks` | Playlist-track relationships |
|
|
| `{prefix}_fedistream_followers` | ActivityPub followers |
|
|
| `{prefix}_fedistream_purchases` | WooCommerce purchase tracking |
|
|
| `{prefix}_fedistream_favorites` | User favorites |
|
|
| `{prefix}_fedistream_user_follows` | Local artist follows |
|
|
| `{prefix}_fedistream_listening_history` | Track play history |
|
|
| `{prefix}_fedistream_notifications` | User notifications |
|
|
| `{prefix}_fedistream_reactions` | Fediverse reactions |
|
|
|
|
### Custom Post Types
|
|
|
|
| Post Type | Slug | Description |
|
|
| --------- | ---- | ----------- |
|
|
| `fedistream_artist` | `/artists/` | Musicians, bands, collectives |
|
|
| `fedistream_album` | `/albums/` | Albums, EPs, singles, compilations |
|
|
| `fedistream_track` | `/tracks/` | Individual audio tracks |
|
|
| `fedistream_playlist` | `/playlists/` | Curated track collections |
|
|
|
|
### Custom Taxonomies
|
|
|
|
| Taxonomy | Type | Applied To |
|
|
| -------- | ---- | ---------- |
|
|
| `fedistream_genre` | Hierarchical | Artists, Albums, Tracks |
|
|
| `fedistream_mood` | Non-hierarchical | Tracks, Playlists |
|
|
| `fedistream_license` | Hierarchical | Albums, Tracks |
|
|
|
|
### User Roles
|
|
|
|
| Role | Slug | Capabilities |
|
|
| ---- | ---- | ------------ |
|
|
| Artist | `fedistream_artist` | Manage own content, upload files |
|
|
| Label | `fedistream_label` | Manage all content, taxonomies, stats |
|
|
|
|
### Shortcodes
|
|
|
|
| Shortcode | Description |
|
|
| --------- | ----------- |
|
|
| `[fedistream_player track_id="123"]` | Single track player |
|
|
| `[fedistream_playlist id="456"]` | Playlist display |
|
|
| `[fedistream_album id="789"]` | Album display |
|
|
| `[fedistream_artist id="101"]` | Artist profile |
|
|
| `[fedistream_recent_releases count="5"]` | Recent releases |
|
|
| `[fedistream_popular_tracks count="10"]` | Popular tracks |
|
|
| `[fedistream_library]` | User library page |
|
|
|
|
### Key Classes
|
|
|
|
- `Plugin` (singleton) - Main controller, initializes all components
|
|
- `Installer` - Database setup, activation/deactivation hooks
|
|
- `Artist`, `Album`, `Track`, `Playlist` - Post type registration and meta boxes
|
|
- `Genre`, `Mood`, `License` - Taxonomy registration with defaults
|
|
- `Capabilities` - User role and capability management
|
|
- `ActivityPubIntegration` - Integration with WordPress ActivityPub plugin
|
|
- `ArtistActor` - Artist profiles as ActivityPub Person/Group actors
|
|
- `Inbox` - Process Follow, Like, Announce, Create activities
|
|
- `Outbox` - Publish Create, Update activities to followers
|
|
- `WooCommerceIntegration` - Custom product types for albums/tracks
|
|
- `DigitalDelivery` - Secure download handling with ZIP support
|
|
- `StreamingAccess` - Purchase-based streaming control
|
|
- `Library` - User favorites, follows, listening history
|
|
- `Notifications` - In-app and email notification system
|
|
|
|
### REST API Endpoints
|
|
|
|
| Endpoint | Method | Purpose |
|
|
| -------- | ------ | ------- |
|
|
| `/wp-json/fedistream/v1/artists/{id}/actor` | GET | ActivityPub actor profile |
|
|
| `/wp-json/fedistream/v1/artists/{id}/inbox` | POST | ActivityPub inbox |
|
|
| `/wp-json/fedistream/v1/artists/{id}/outbox` | GET | ActivityPub outbox |
|
|
| `/wp-json/fedistream/v1/artists/{id}/followers` | GET | Followers collection |
|
|
| `/wp-json/fedistream/v1/artists/{id}/following` | GET | Following collection |
|
|
|
|
### AJAX Actions
|
|
|
|
| Action | Purpose |
|
|
| ------ | ------- |
|
|
| `fedistream_record_play` | Record track play |
|
|
| `fedistream_toggle_favorite` | Add/remove favorite |
|
|
| `fedistream_toggle_follow` | Follow/unfollow artist |
|
|
| `fedistream_get_library` | Get user library |
|
|
| `fedistream_get_followed_artists` | Get followed artists |
|
|
| `fedistream_get_history` | Get listening history |
|
|
| `fedistream_clear_history` | Clear listening history |
|
|
| `fedistream_get_notifications` | Get user notifications |
|
|
| `fedistream_mark_notification_read` | Mark notification read |
|
|
| `fedistream_mark_all_notifications_read` | Mark all read |
|
|
| `fedistream_delete_notification` | Delete notification |
|
|
|
|
---
|
|
|
|
## Session History
|
|
|
|
### 2026-01-28 - Initial Release v0.1.0
|
|
|
|
**Summary:** Consolidated all development phases (0.0.1 through 0.7.0) into initial release v0.1.0.
|
|
|
|
**Completed:**
|
|
|
|
- Implemented Phase 6 (WooCommerce Integration):
|
|
- Custom product types for albums and tracks
|
|
- Pricing models (Fixed, PWYW, NYP)
|
|
- Digital delivery with secure downloads
|
|
- Streaming access control based on purchases
|
|
- Implemented Phase 7 (User Interactions):
|
|
- User library with favorites, follows, history
|
|
- Notification system (in-app and email)
|
|
- Library shortcode and frontend page
|
|
- Consolidated documentation:
|
|
- Moved implementation details from PLAN.md to CLAUDE.md
|
|
- Deleted PLAN.md (no longer needed)
|
|
- Merged all changelog entries into single v0.1.0 release
|
|
- Updated README.md with current features
|
|
- Git operations:
|
|
- Created initial commit on dev branch
|
|
- Merged to main branch
|
|
- Tagged as v0.1.0
|
|
- Push pending (requires credentials)
|
|
|
|
**Files Created:**
|
|
|
|
- `includes/WooCommerce/Integration.php`
|
|
- `includes/WooCommerce/AlbumProduct.php`
|
|
- `includes/WooCommerce/TrackProduct.php`
|
|
- `includes/WooCommerce/DigitalDelivery.php`
|
|
- `includes/WooCommerce/StreamingAccess.php`
|
|
- `includes/User/Library.php`
|
|
- `includes/User/LibraryPage.php`
|
|
- `includes/User/Notifications.php`
|
|
- `assets/js/library.js`
|
|
- `assets/js/notifications.js`
|
|
|
|
**Files Deleted:**
|
|
|
|
- `PLAN.md`
|
|
|
|
**Notes:**
|
|
|
|
- Successfully pushed dev, main branches and v0.1.0 tag to origin
|
|
- Remote URL updated from HTTPS to SSH for authentication
|
|
- First release is now live at the repository
|