Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 163 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# GitHub Copilot Instructions for Decker WordPress Plugin

This document provides specific instructions for GitHub Copilot when working on the Decker WordPress plugin.

## Project Overview

Decker is a WordPress plugin for task management with a Kanban board interface. It's developed by Área de Tecnología Educativa (ATE) and follows WordPress coding standards.

## Coding Standards

### WordPress Coding Standards
- Follow [WordPress Coding Standards](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/) for all PHP, HTML, CSS, and JavaScript code
- Use 4 spaces for indentation (not tabs)
- Limit lines to 80 characters where possible
- Use `snake_case` for functions, methods, and variables
- Use `CamelCase` for class names
- Name files with lowercase letters and hyphens (e.g., `class-decker-admin.php`)

### PHP Specific
- All PHP functions and methods must have English PHPDoc comments
- Use proper escaping (`esc_html()`, `esc_attr()`, `esc_url()`) for all output
- Sanitize all user inputs using WordPress functions (`sanitize_text_field()`, etc.)
- Use WordPress nonces for form submissions and AJAX requests
- Prefer WordPress APIs over raw PHP functions when available

### Code Structure
- Keep the main plugin file (`decker.php`) minimal
- Place each class in its own file with pattern `class-pluginname-component.php`
- Admin functionality goes in the `admin/` directory
- Public-facing functionality goes in the `public/` directory
- Shared utilities and custom post types go in the `includes/` directory
- Tests go in the `tests/` directory

## Language Requirements

### Source Code
- Write all source code (identifiers, comments, docblocks) in **English**
- Use clear, descriptive names that self-document the code

### User-Facing Content
- All user-facing strings must be in **Spanish**
- Use WordPress translation functions: `__()`, `_e()`, `_n()`, `_x()`
- Text domain is `decker`
- **Always add Spanish translations** for every new translatable string to `languages/decker-es_ES.po` in the same commit that introduces the string
- Always verify no untranslated Spanish strings remain using `make check-untranslated`

## Development Workflow

### Test-Driven Development (TDD)
- Write tests BEFORE implementing features when possible
- Use PHPUnit for PHP tests, Jest for JavaScript tests
- Tests live under `/tests/` directory
- Use factory classes to create test fixtures
- Run tests with `make test`

### Code Quality
- Run `make lint` to check PHP code style
- Run `make fix` to auto-fix code style issues
- Ensure all linting passes before committing

### Environment
- Develop within `@wordpress/env` environment
- Start local environment with `make up`
- Access at http://localhost:8888 (admin/password)

## Security

### Input/Output Handling
- **Always** validate user inputs
- **Always** sanitize data before storing
- **Always** escape output before displaying
- Use WordPress nonces for all forms and AJAX
- Follow principle of least privilege

### Best Practices
- Avoid SQL injection by using `$wpdb->prepare()`
- Prevent XSS attacks with proper escaping
- Check user capabilities before performing privileged operations
- Validate file uploads and restrict file types

## Frontend Technologies

- Use **Bootstrap 5** for UI components
- Use **jQuery** for JavaScript interactions
- Keep frontend assets minimal
- Enqueue assets properly via `wp_enqueue_script()` and `wp_enqueue_style()`
- Use minified versions in production

## Common Patterns

### Adding a New Feature
1. Write failing test(s) first (TDD)
2. Implement minimal code to pass tests
3. Add Spanish translations for every new `__()`, `_e()`, `_n()`, `_x()` call to `languages/decker-es_ES.po`
4. Run `make lint` and `make fix`
5. Run `make test` to verify all tests pass
6. Run `make check-untranslated` to verify translations

### Creating a New Class
```php
<?php
/**
* Brief description of class purpose.
*
* @package Decker
* @subpackage Decker/includes
*/

/**
* Class description.
*
* Longer description if needed.
*
* @since 1.0.0
*/
class Decker_Component {
// Implementation
}
```

### Adding Translation
```php
// For simple strings
__( 'Spanish text here', 'decker' )

// For output
esc_html_e( 'Spanish text here', 'decker' )

// For plurals
_n( 'singular', 'plural', $count, 'decker' )
```

## Documentation

- Update PHPDoc blocks for all modified functions/classes
- Update `README.md` if user-facing features change
- Update `readme.txt` for WordPress.org compatibility
- Keep `CONVENTIONS.md` and `AGENTS.md` synchronized

## Additional Resources

- Project conventions: See `CONVENTIONS.md`
- Agent-specific guidelines: See `AGENTS.md`
- WordPress Coding Standards: https://developer.wordpress.org/coding-standards/
- WordPress Plugin Handbook: https://developer.wordpress.org/plugins/

## Quick Reference

### Makefile Commands
- `make up` - Start WordPress environment
- `make down` - Stop WordPress environment
- `make test` - Run all tests
- `make lint` - Check code style
- `make fix` - Auto-fix code style
- `make check-untranslated` - Check for untranslated Spanish strings

### Key Principles
1. **WordPress First**: Always use WordPress APIs
2. **Security First**: Validate input, sanitize storage, escape output
3. **Test First**: Write tests before implementation (TDD)
4. **Spanish UI**: All user-facing text in Spanish
5. **English Code**: All code and comments in English
6. **Minimal Changes**: Make smallest possible changes to achieve goals
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
runs-on: ubuntu-latest
steps:
# Checkout the code
- uses: actions/checkout@v5
- uses: actions/checkout@v6

# Determine the branch name
- name: Set branch name for blueprint URL
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6

# Set up Python environment
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: 3.13
python-version: 3.14

# Install dependencies
- name: Install dependencies
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/phpmd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v5
uses: actions/checkout@v6

- name: Setup PHP
uses: shivammathur/setup-php@v2
Expand All @@ -51,7 +51,7 @@ jobs:
continue-on-error: true

- name: Upload analysis results to GitHub
uses: github/codeql-action/upload-sarif@v3
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: phpmd-results.sarif
wait-for-processing: true
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
# Checkout the code
- uses: actions/checkout@v5
- uses: actions/checkout@v6

- name: Set environment variables
run: |
Expand Down
2 changes: 1 addition & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ release:
sonarqube-check:
stage: sonarqube-check
image:
name: sonarsource/sonar-scanner-cli:11.4
name: sonarsource/sonar-scanner-cli:12.0
entrypoint: [""]
script:
- sonar-scanner
Expand Down
48 changes: 48 additions & 0 deletions admin/class-decker-admin-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,41 @@ public function allow_email_notifications_render() {
echo '<p class="description">' . esc_html__( 'This setting allows users to manage email notifications in their profile. By default, all notifications are enabled.', 'decker' ) . '</p>';
}

/**
* Render Collaborative Editing Field.
*
* Outputs the HTML for the collaborative_editing field.
*/
public function collaborative_editing_render() {
$options = get_option( 'decker_settings', array() );
$checked = isset( $options['collaborative_editing'] ) && '1' === $options['collaborative_editing'];

echo '<label>';
echo '<input type="checkbox" name="decker_settings[collaborative_editing]" value="1" ' . checked( $checked, true, false ) . '>';
echo esc_html__( 'Enable real-time collaborative editing for tasks.', 'decker' );
echo '</label>';
echo '<p class="description">' . esc_html__( 'When enabled, multiple users can edit the same task simultaneously with real-time synchronization using WebRTC.', 'decker' ) . '</p>';
}

/**
* Render Signaling Server Field.
*
* Outputs the HTML for the signaling_server field.
*/
public function signaling_server_render() {
$options = get_option( 'decker_settings', array() );
$value = isset( $options['signaling_server'] ) ? sanitize_text_field( $options['signaling_server'] ) : 'wss://signaling.yjs.dev';

echo '<input type="url" name="decker_settings[signaling_server]" class="regular-text" value="' . esc_attr( $value ) . '" placeholder="wss://signaling.yjs.dev">';
echo '<p class="description">' . esc_html__( 'WebRTC signaling server URL for collaborative editing. Leave empty to use the default public server (wss://signaling.yjs.dev).', 'decker' ) . '</p>';
echo '<p class="description"><strong>' . esc_html__( 'Public servers:', 'decker' ) . '</strong></p>';
echo '<ul class="description" style="list-style: disc; margin-left: 20px;">';
echo '<li><code>wss://signaling.yjs.dev</code> ' . esc_html__( '(Default - Global)', 'decker' ) . '</li>';
echo '<li><code>wss://y-webrtc-signaling-eu.herokuapp.com</code> ' . esc_html__( '(Europe)', 'decker' ) . '</li>';
echo '<li><code>wss://y-webrtc-signaling-us.herokuapp.com</code> ' . esc_html__( '(United States)', 'decker' ) . '</li>';
echo '</ul>';
}

/**
* Render User Profile Field.
*
Expand Down Expand Up @@ -250,6 +285,8 @@ public function settings_init() {
'task_editor_type' => __( 'Task Editor Type', 'decker' ),
'shared_key' => __( 'Shared Key', 'decker' ),
'allow_email_notifications' => __( 'Allow Email Notifications', 'decker' ),
'collaborative_editing' => __( 'Collaborative Editing', 'decker' ),
'signaling_server' => __( 'Signaling Server', 'decker' ),
'clear_all_data_button' => __( 'Clear All Data', 'decker' ),
'ignored_users' => __( 'Ignored Users', 'decker' ),

Expand Down Expand Up @@ -385,6 +422,17 @@ public function settings_validate( $input ) {
// Validate allow email notifications.
$input['allow_email_notifications'] = isset( $input['allow_email_notifications'] ) && '1' === $input['allow_email_notifications'] ? '1' : '0';

// Validate collaborative editing.
$input['collaborative_editing'] = isset( $input['collaborative_editing'] ) && '1' === $input['collaborative_editing'] ? '1' : '0';

// Validate signaling server.
if ( isset( $input['signaling_server'] ) && ! empty( $input['signaling_server'] ) ) {
// Include wss protocol for WebSocket signaling servers.
$input['signaling_server'] = esc_url_raw( $input['signaling_server'], array( 'wss', 'ws', 'https', 'http' ) );
} else {
$input['signaling_server'] = 'wss://signaling.yjs.dev';
}

// Validate alert color.
$valid_colors = array( 'success', 'danger', 'warning', 'info' );
if ( isset( $input['alert_color'] ) && ! in_array( $input['alert_color'], $valid_colors ) ) {
Expand Down
Loading