# Puntr WordPress Plugin

A professional provider management system for WordPress with roster scheduling, provider profiles, and calendar functionality.

## Features

- **Provider Management**: Create and manage detailed provider profiles with photos, physical details, rates, and services
- **Product-style Gallery**: Professional image gallery with main photo and thumbnail navigation
- **Roster Scheduling**: Visual calendar interface for managing provider schedules using DayPilot
- **Daily Roster Display**: Customizable shortcode for displaying daily rosters on your website
- **Provider Archive**: Enhanced archive pages showing provider attributes and quick info
- **Professional Admin Interface**: Branded admin pages with consistent styling
- **Flexible Taxonomies**: Organize providers by service categories and body types
- **REST API**: Full API access to providers and roster data
- **Extensible**: Comprehensive hooks and filters for developers
- **Security**: Built with WordPress security best practices

## Installation

1. Upload the `puntr` folder to your `/wp-content/plugins/` directory
2. Activate the plugin through the 'Plugins' menu in WordPress
3. Navigate to the Puntr menu in your WordPress admin

## Usage Guide

### Managing Providers

1. Go to **Puntr → Providers** to view all providers
2. Click **Add New Provider** to create a new profile
3. Fill in the provider details:
   - Basic information (name, age, gender, ethnicity)
   - Physical details (height, measurements, hair/eye color)
   - Pricing (30/45/60/90/120/180 minute rates)
   - Contact information
   - Set a featured image (main photo)
   - Add gallery images (additional photos)

### Managing Rosters

1. Go to **Puntr → Roster** to view the calendar
2. **Click and drag** on the calendar to create a roster entry
3. Select the provider and time slot
4. Roster entries can be:
   - Moved by dragging
   - Resized by dragging edges
   - Deleted via right-click menu
5. Use the zoom controls (+/-) to adjust the calendar view
6. Navigate weeks using the arrow buttons or date picker

### Displaying Rosters on Your Website

#### Basic Daily Roster Shortcode

```
[puntr_daily_roster]
```

Displays today's roster with default columns: Ethnicity, Provider Name, Start Time, End Time

#### Advanced Options

```
[puntr_daily_roster date="2025-07-20" show_photo="true" photo_size="60" columns="photo,name,age,location,start,end"]
```

**Available Parameters:**

- `date` - Specific date to display (YYYY-MM-DD format)
- `show_photo` - Display provider photos (true/false)
- `photo_size` - Size of photos in pixels (default: 50)
- `show_age` - Include age column (true/false)
- `show_height` - Include height column (true/false)
- `show_dress_size` - Include dress size column (true/false)
- `show_bust` - Include bust size column (true/false)
- `show_location` - Include location column (true/false)
- `show_services` - Include services column (true/false)
- `show_rates` - Include rates column (true/false)
- `columns` - Comma-separated list of columns to display

**Available Columns:**

- `photo` - Provider photo
- `ethnicity` - Provider ethnicity
- `name` - Provider name (linked to profile)
- `age` - Provider age
- `height` - Height in cm
- `dress_size` - Dress size
- `bust` - Bust size
- `location` - City/location
- `services` - Service categories
- `rates` - Incall/Outcall rates
- `start` - Start time
- `end` - End time

#### Example Configurations

**Photo Gallery Style:**

```
[puntr_daily_roster show_photo="true" photo_size="80" columns="photo,name,start,end"]
```

**Detailed Information:**

```
[puntr_daily_roster show_photo="true" show_age="true" show_height="true" show_rates="true" columns="photo,name,age,height,rates,start,end"]
```

**Minimal Display:**

```
[puntr_daily_roster columns="name,start,end"]
```

### Calendar Shortcode

To embed the full roster calendar on a page:

```
[puntr_roster_calendar height="700"]
```

## Settings

Navigate to **Puntr → Settings** to configure:

- Providers per page on archive
- Display options (show/hide pricing, physical details)

## REST API Endpoints

Puntr includes a comprehensive REST API for external integrations. All endpoints are available under the `/wp-json/puntr/v1/` namespace.

### Authentication

All endpoints are publicly accessible by default. Authentication can be implemented using the `puntr_api_authentication` filter.

### Endpoints

#### Get Providers List

**GET** `/wp-json/puntr/v1/providers`

Get a paginated list of providers.

**Parameters:**
- `per_page` (integer) - Number of providers per page (default: 10)
- `page` (integer) - Page number (default: 1)
- `service` (string) - Filter by service category slug
- `active_only` (boolean) - Only show active providers (default: true)

**Example Request:**
```
GET /wp-json/puntr/v1/providers?per_page=20&page=1&service=massage
```

**Example Response:**
```json
{
  "providers": [
    {
      "id": 123,
      "name": "Provider Name",
      "slug": "provider-name",
      "url": "https://site.com/puntr_provider/provider-name/",
      "excerpt": "Provider description...",
      "featured_image": "https://site.com/wp-content/uploads/image.jpg",
      "is_active": true
    }
  ],
  "total": 50,
  "pages": 3,
  "page": 1
}
```

#### Get Single Provider

**GET** `/wp-json/puntr/v1/providers/{id}`

Get detailed information about a specific provider.

**Parameters:**
- `id` (integer) - Provider ID

**Example Request:**
```
GET /wp-json/puntr/v1/providers/123
```

**Example Response:**
```json
{
  "id": 123,
  "name": "Provider Name",
  "slug": "provider-name",
  "url": "https://site.com/puntr_provider/provider-name/",
  "excerpt": "Provider description...",
  "featured_image": "https://site.com/wp-content/uploads/image.jpg",
  "is_active": true,
  "age": "25",
  "gender": "Female",
  "ethnicity": "Caucasian",
  "height": "170",
  "weight": "60",
  "hair_color": "Blonde",
  "eye_color": "Blue",
  "bust_size": "36C",
  "waist_size": "26",
  "hip_size": "36",
  "dress_size": "8",
  "shoe_size": "7",
  "incall_rate": "200",
  "outcall_rate": "250",
  "city": "New York",
  "languages": "English, Spanish",
  "content": "<p>Full HTML content...</p>",
  "services": [
    {
      "term_id": 5,
      "name": "Massage",
      "slug": "massage"
    }
  ]
}
```

#### Get Roster Events

**GET** `/wp-json/puntr/v1/roster`

Get roster events within a date range.

**Parameters:**
- `start_date` (string) - Start date in YYYY-MM-DD format (required)
- `end_date` (string) - End date in YYYY-MM-DD format (required)
- `provider_id` (integer) - Filter by specific provider

**Example Request:**
```
GET /wp-json/puntr/v1/roster?start_date=2025-01-01&end_date=2025-01-07&provider_id=123
```

**Example Response:**
```json
[
  {
    "id": 456,
    "provider": {
      "id": 123,
      "name": "Provider Name",
      "url": "https://site.com/provider/provider-name/"
    },
    "start": "2025-01-01 09:00:00",
    "end": "2025-01-01 17:00:00",
    "status": "confirmed",
    "notes": "Available for outcalls only"
  }
]
```

#### Get Daily Roster

**GET** `/wp-json/puntr/v1/daily-roster`

Get roster entries for a specific day, including overnight shifts.

**Parameters:**
- `date` (string) - Date in YYYY-MM-DD format (default: today)

**Example Request:**
```
GET /wp-json/puntr/v1/daily-roster?date=2025-01-15
```

**Example Response:**
```json
{
  "date": "2025-01-15",
  "roster": [
    {
      "id": 789,
      "provider": {
        "id": 123,
        "name": "Provider Name",
        "url": "https://site.com/puntr_provider/provider-name/",
        "ethnicity": "Caucasian",
        "age": "25",
        "location": "New York"
      },
      "start_time": "9:00 AM",
      "end_time": "5:00 PM",
      "start_datetime": "2025-01-15 09:00:00",
      "end_datetime": "2025-01-15 17:00:00",
      "is_overnight": false,
      "status": "confirmed"
    }
  ],
  "total": 5
}
```

### Error Responses

All endpoints return standard HTTP status codes:

- `200 OK` - Request successful
- `404 Not Found` - Resource not found
- `400 Bad Request` - Invalid parameters

Error response format:
```json
{
  "code": "not_found",
  "message": "Provider not found",
  "data": {
    "status": 404
  }
}
```

### Extending the API

You can modify API responses using these filters:

```php
// Modify provider fields in API
add_filter('puntr_api_provider_fields', function($fields) {
    $fields['custom_field'] = get_post_meta($provider_id, '_custom_field', true);
    return $fields;
});

// Add custom authentication
add_filter('puntr_api_authentication', function($authenticated, $request) {
    // Your authentication logic
    return $authenticated;
}, 10, 2);

// Add custom endpoints
add_filter('puntr_api_endpoints', function($endpoints) {
    $endpoints['custom'] = array(
        'callback' => 'my_custom_callback',
        'methods' => 'GET'
    );
    return $endpoints;
});
```

## Template System

The plugin includes a template override system that allows you to customize the display of providers in your theme.

### Available Templates

- `archive-provider.php` - Provider archive/listing page
- `single-provider.php` - Single provider page
- `content-provider.php` - Provider item in lists

### How to Override Templates

1. Create a folder named `puntr` in your theme directory
2. Copy any template from `plugins/puntr/templates/` to `yourtheme/puntr/`
3. Modify the template as needed

### Example: Customizing Provider List Items

Copy `plugins/puntr/templates/content-provider.php` to `yourtheme/puntr/content-provider.php` and modify:

```php
<article id="provider-<?php the_ID(); ?>" <?php post_class('my-custom-class'); ?>>
    <!-- Your custom layout here -->
    <h3><?php the_title(); ?></h3>
    <?php the_excerpt(); ?>
</article>
```

The templates use minimal styling and inherit your theme's styles naturally.

## Hooks and Filters

The plugin provides numerous hooks and filters for developers to extend functionality:

### Provider Hooks

- `puntr_before_save_provider` - Called before saving provider data
- `puntr_after_save_provider` - Called after saving provider data
- `puntr_provider_meta_fields` - Filter provider meta fields
- `puntr_provider_meta_boxes` - Filter provider meta boxes
- `puntr_provider_display_data` - Filter provider display data
- `puntr_provider_archive_info` - Filter provider archive information

### Roster Hooks

- `puntr_before_create_roster_event` - Called before creating roster event
- `puntr_after_create_roster_event` - Called after creating roster event
- `puntr_roster_event_data` - Filter roster event data
- `puntr_roster_table_columns` - Filter roster table columns

### Calendar Hooks

- `puntr_calendar_event_colors` - Filter calendar event colors
- `puntr_calendar_event_text` - Filter calendar event text
- `puntr_calendar_default_view` - Filter default calendar view
- `puntr_calendar_time_slots` - Filter calendar time slots

### Template Hooks - Archive Pages

- `puntr_skip_archive_provider_details` - Skip provider details on archive
- `puntr_archive_provider_data` - Filter provider data before display
- `puntr_archive_headline_html` - Filter headline HTML
- `puntr_archive_provider_attributes` - Filter attributes array
- `puntr_archive_attributes_html` - Filter attributes HTML
- `puntr_archive_services_html` - Filter services HTML
- `puntr_archive_pricing_array` - Filter pricing array
- `puntr_archive_pricing_html` - Filter pricing HTML
- `puntr_provider_archive_info` - Filter complete provider info
- `puntr_archive_content_position` - Control content position ('before' or 'after')

### Template Hooks - Single Provider Pages

- `puntr_skip_provider_gallery` - Skip gallery display
- `puntr_gallery_images` - Filter gallery images array
- `puntr_gallery_wrapper_classes` - Filter gallery wrapper CSS classes
- `puntr_gallery_html` - Filter complete gallery HTML
- `puntr_before_gallery` - Action before gallery output
- `puntr_after_gallery` - Action after gallery output
- `puntr_gallery_position` - Control gallery position ('before' or 'after')
- `puntr_skip_provider_details_box` - Skip details box (if used)
- `puntr_provider_details_meta_data` - Filter provider meta data

### Template Hooks - General

- `puntr_provider_template` - Filter provider template file
- `puntr_archive_template` - Filter archive template file
- `puntr_provider_content` - Filter provider content
- `puntr_gallery_settings` - Filter gallery settings
- `puntr_auto_add_roster` - Control automatic roster display on provider pages

### API Hooks

- `puntr_api_endpoints` - Filter API endpoints
- `puntr_api_provider_fields` - Filter API provider fields
- `puntr_api_authentication` - Filter API authentication

### Example Usage

```php
// Add custom field to provider
add_filter('puntr_provider_meta_fields', function($fields) {
    $fields['custom_field'] = '_puntr_custom_field';
    return $fields;
});

// Customize calendar colors
add_filter('puntr_calendar_event_colors', function($colors) {
    $colors['vip'] = '#FFD700'; // Gold for VIP events
    return $colors;
});

// Add action after roster event creation
add_action('puntr_after_create_roster_event', function($event_id, $event_data) {
    // Send notification email
    $provider_id = $event_data['provider_id'];
    $provider = get_post($provider_id);
    // Your custom code here
}, 10, 2);

// Customize archive display
add_filter('puntr_archive_provider_attributes', function($attributes, $provider_id) {
    // Add custom attribute
    $custom_value = get_post_meta($provider_id, '_my_custom_field', true);
    if ($custom_value) {
        $attributes[] = 'Custom: ' . $custom_value;
    }
    return $attributes;
}, 10, 2);

// Move gallery below content
add_filter('puntr_gallery_position', function($position, $provider_id) {
    return 'after';
}, 10, 2);

// Add custom CSS class to gallery
add_filter('puntr_gallery_wrapper_classes', function($classes, $provider_id) {
    return $classes . ' my-custom-gallery-class';
}, 10, 2);

// Skip provider details on specific providers
add_filter('puntr_skip_archive_provider_details', function($skip, $provider_id) {
    // Skip details for VIP providers
    $is_vip = get_post_meta($provider_id, '_is_vip', true);
    return $is_vip === 'yes';
}, 10, 2);
```

## Support

For support and feature requests, email [wordpress@puntr.me](mailto:wordpress@puntr.me)

## License

GPL v2 or later

## Changelog

### 1.2.0

- Removed venue functionality to simplify the plugin
- Fixed WordPress coding standards warnings
- Improved admin notices positioning
- Added Services taxonomy to admin menu
- Updated REST API documentation
- Fixed API endpoint issues with missing providers
- Enhanced admin UI with proper header positioning
- Removed unused API settings
- Improved error handling throughout

### 1.1.0

- Added template system with override capability
- Added hooks and filters for extensibility
- Added product-style image gallery for providers
- Improved roster display - removed status column for cleaner presentation
- Fixed duplicate roster display issue on provider pages
- Added template actions for gallery and roster placement
- Enhanced provider archive with flexible content positioning

### 1.0.0

- Initial release
- Provider management system
- Roster scheduling with DayPilot
- Daily roster shortcode
- Admin interface
