Skip to content

Latest commit

 

History

History
551 lines (391 loc) · 14.7 KB

File metadata and controls

551 lines (391 loc) · 14.7 KB

Hellotext WordPress Plugin - Development Guide

Overview

This guide covers development setup, testing, code standards, and contribution guidelines for the Hellotext WordPress plugin.

Table of Contents

Prerequisites

Required Software

  • PHP: 8.2.12 or higher
  • Composer: Latest version
  • WordPress: 5.0 or higher
  • WooCommerce: 5.0 or higher
  • Local Development Environment:
    • Local by Flywheel
    • MAMP/XAMPP
    • Docker (wp-env)
    • Or similar

Development Setup

1. Clone the Repository

cd wp-content/plugins/
git clone https://github.com/hellotext/hellotext-wordpress.git
cd hellotext-wordpress

2. Install Dependencies

composer install

This installs:

  • Pest (testing framework)
  • Mockery (mocking library)
  • WordPress & WooCommerce stubs (for IDE autocomplete)

3. Configure Environment

Create or modify your WordPress configuration to set environment variables.

Option A: wp-config.php

// Add before "That's all, stop editing!"
$_ENV['APP_ENV'] = 'development';
$_ENV['HELLOTEXT_API_URL'] = 'https://api-dev.hellotext.com';

Option B: .htaccess

SetEnv APP_ENV development
SetEnv HELLOTEXT_API_URL https://api-dev.hellotext.com

Option C: Server Configuration

For Local by Flywheel, add to site configuration or use .env file if supported.

4. Activate Plugin

  1. Navigate to WordPress admin → Plugins
  2. Activate "Hellotext"
  3. Configure with development Business ID and Access Token

5. Enable Debugging

In wp-config.php:

define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);

This logs errors to wp-content/debug.log.

Code Standards

PHP Standards

  • PHP Version: 8.2+
  • Namespace: Hellotext\
  • Coding Style: WordPress Coding Standards with modern PHP

Type Hints

All methods must have type hints for parameters and return types:

public function process(?int $user_id, array $data = []): void
{
    // Implementation
}

PHPDoc Comments

All classes and public methods must have PHPDoc comments:

/**
 * Create a Hellotext profile.
 *
 * @param int $user_id WordPress user ID.
 * @param array $data Additional profile data.
 * @return array Profile response from API.
 * @throws \Exception If user not found.
 */
public function create(int $user_id, array $data = []): array
{
    // Implementation
}

Constants Usage

Always use constants from the Constants class instead of magic strings:

// ✅ Good
$session = $_COOKIE[Constants::SESSION_COOKIE_NAME];
$response = Client::post(Constants::API_ENDPOINT_PROFILES, $data);

// ❌ Bad
$session = $_COOKIE['hello_session'];
$response = Client::post('/profiles', $data);

Error Handling

Use exceptions for error conditions and log appropriately:

try {
    $adapter = new ProductAdapter($product_id);
    $payload = $adapter->get();
} catch (\Exception $e) {
    error_log('Hellotext: ' . $e->getMessage());
    return;
}

Testing

The project uses Pest for testing.

Running Tests

# Run all tests
./vendor/bin/pest

# Run specific test file
./vendor/bin/pest tests/Unit/Adapters/ProductAdapterTest.php

# Run with coverage (requires Xdebug)
./vendor/bin/pest --coverage

# Run in parallel
./vendor/bin/paratest

The Composer aliases used by CI and maintainers are:

composer install
composer test
composer format:check
composer build

composer build installs production dependencies with --no-dev --optimize-autoloader. Do not use the build output for local development without reinstalling dev dependencies afterward.

Verified Local Flow

Last verified: 2026-06-11

Command Result Notes
composer install Passed Requires PHP 8.2+ and Composer 2. The local system Composer emitted PHP deprecation notices under PHP 8.4; dependencies still installed correctly.
composer test Passed Pest suite runs against WordPress/WooCommerce mocks, not a real WordPress install.
composer format:check Passed PHP CS Fixer warned when run under PHP 8.4 because the Composer platform is PHP 8.2.12. CI runs the style check on PHP 8.2.
composer build Passed Runs composer install --no-dev --optimize-autoloader and removes dev tooling from vendor/. Run composer install again afterward before continuing local development.

Setup assumptions:

  • PHP 8.2 or newer is available locally.
  • Composer can install from the checked-in composer.lock.
  • Tests do not require a real WordPress, WooCommerce, database, or Hellotext API connection.
  • Outbound HTTP in tests is mocked through WordPress HTTP function stubs.

Writing Tests

Unit Tests

Unit tests are located in tests/Unit/. Each test file corresponds to a source file.

Example: Testing an Adapter

<?php

use Hellotext\Adapters\ProductAdapter;

beforeEach(function () {
    $this->product = Mockery::mock('WC_Product');
    $this->product->shouldReceive('get_id')->andReturn(123);
    $this->product->shouldReceive('get_name')->andReturn('Test Product');
    // ... more mocks
});

test('ProductAdapter transforms product correctly', function () {
    $adapter = new ProductAdapter($this->product);
    $result = $adapter->get();

    expect($result)
        ->toHaveKey('reference', 123)
        ->toHaveKey('name', 'Test Product')
        ->toHaveKey('source', 'woo');
});

test('ProductAdapter throws exception for invalid product', function () {
    $adapter = new ProductAdapter(99999);
    $adapter->get(); // Should throw
})->throws(\Exception::class);

Test Structure

Use Pest's modern syntax:

// Arrange
$data = ['key' => 'value'];

// Act
$result = (new Service())->process($data);

// Assert
expect($result)->toBe('expected');

Mocking

Use Mockery for mocking WordPress and WooCommerce functions:

beforeEach(function () {
    // Mock WordPress functions
    Mockery::mock('function:get_option')
        ->shouldReceive('get_option')
        ->with('hellotext_business_id')
        ->andReturn('test_business_id');
});

afterEach(function () {
    Mockery::close();
});

Test Coverage Goals

  • Unit Tests: All Adapters and Services
  • Integration Tests: Key user flows (order placement, profile creation)
  • Coverage Target: 80%+ for critical paths

Debugging

Debug Logging

Enable WordPress debug logging and use error_log():

error_log('Hellotext Debug: ' . print_r($data, true));

Logs appear in wp-content/debug.log.

API Debugging

To inspect API requests/responses:

$response = Client::post('/profiles', $data);
error_log('API Response: ' . print_r($response, true));

Event Tracking Debugging

To verify events are being tracked:

add_filter('hellotext_event_payload', function($payload) {
    error_log('Event Payload: ' . print_r($payload, true));
    return $payload;
});

WordPress Hooks Debug

Use add_action() to monitor hook execution:

add_action('all', function($hook) {
    if (strpos($hook, 'woocommerce') !== false) {
        error_log('Hook fired: ' . $hook);
    }
});

Build & Release

Version Bump

  1. Update version in hellotext.php header comment
  2. Update changelog.txt with changes
  3. Commit changes
/**
 * Version: 1.3.0
 */

Pre-Release Checklist

  • Confirm the version in hellotext.php matches the release tag.
  • Update changelog.txt with user-facing changes, compatibility notes, and any known limitations.
  • Review open dependency PRs and confirm there are no urgent security/runtime updates pending.
  • Run composer install from a clean checkout.
  • Run composer test and confirm all tests pass.
  • Run composer format:check and confirm no style diff is reported.
  • Run composer build and confirm production dependencies install with --no-dev --optimize-autoloader.
  • Inspect the production vendor/ tree enough to confirm dev-only packages such as Pest, Mockery, stubs, PHPUnit, and PHP CS Fixer are not included in the release build.
  • Verify .distignore excludes development files from the release zip: .github/, tests/, composer.json, composer.lock, DEVELOPMENT.md, and API.md.
  • Smoke test the plugin zip in a clean WordPress/WooCommerce site.
  • Confirm settings save correctly: Business ID, access token, webchat ID, placement, and behavior.
  • Confirm script/webchat injection renders on the storefront when configured.
  • Smoke test tracking for product view, cart add/remove, coupon redemption, checkout/order placement, order status change, refund, user registration, plugin activation, and plugin deactivation.
  • Smoke test classic template pages and WooCommerce Cart/Checkout blocks separately for product, cart, and checkout coverage.
  • Smoke test order placement, order status, and refund flows with WooCommerce HPOS enabled and disabled.
  • Record WooCommerce API/HPOS compatibility notes in the release description if anything changed.
  • Run composer install again after build validation to restore dev dependencies before more local work.

Creating a Release

  1. Tag the release:
git tag -a v1.3.0 -m "Release version 1.3.0"
git push origin v1.3.0
  1. Build release package:
# Remove dev dependencies
composer install --no-dev

3. **Verify the generated release:**
   - Download the release zip from GitHub.
   - Confirm files excluded by `.distignore` are not included: `.github/`, `tests/`, `composer.json`, `composer.lock`, `DEVELOPMENT.md`, and `API.md`.
   - Confirm runtime files are included: `hellotext.php`, `src/`, `vendor/`, `README.md`, and `changelog.txt` if present.
   - Install the zip in a clean WordPress/WooCommerce site.
   - Confirm the release asset installs and activates without PHP warnings in `debug.log`.

### Post-Release

1. Reinstall dev dependencies: `composer install`
2. Announce release to team
3. Monitor error logs for issues

### Dependency Update Triage

Use this checklist before merging dependency-only PRs:

- Confirm the diff is limited to dependency metadata or the expected workflow file.
- Confirm GitHub reports the PR as mergeable.
- Confirm required CI checks pass.
- Prefer merging patch/minor test stub updates independently from runtime code changes.
- For GitHub Action major updates, inspect the action release notes before merging.

Dependency PRs reviewed during this maintenance pass:

- Keep dependency-only lockfile refreshes separate from runtime compatibility changes.
- Prefer one broad lock refresh over multiple older overlapping Dependabot PRs when it carries newer compatible versions and CI passes.
- For GitHub Action major updates, inspect the action release notes and verify the generated zip on the next tagged release because release publishing only runs on tags.

See also [WooCommerce Compatibility and API Audit](docs/WOOCOMMERCE-AUDIT.md) for hook, HPOS, and release compatibility notes.

## Contributing

### Workflow

1. **Fork & Clone**

```bash
git clone https://github.com/YOUR_USERNAME/hellotext-wordpress.git
cd hellotext-wordpress
composer install
  1. Create Feature Branch
git checkout -b feature/my-new-feature
  1. Make Changes

    • Write code
    • Add tests
    • Update documentation
  2. Run Tests

./vendor/bin/pest
  1. Commit
git add .
git commit -m "feat: add new feature"

Use Conventional Commits:

  • feat: - New feature
  • fix: - Bug fix
  • docs: - Documentation
  • test: - Tests
  • refactor: - Code refactoring
  1. Push & PR
git push origin feature/my-new-feature

Then create a Pull Request on GitHub.

Code Review Checklist

  • Code follows WordPress coding standards
  • All functions have type hints
  • PHPDoc comments present and accurate
  • Tests written and passing
  • No hardcoded strings (use Constants)
  • Proper error handling
  • WordPress/WooCommerce hooks used correctly
  • Security best practices followed

Common Development Tasks

Adding a New Event

  1. Create event file in src/Events/
  2. Hook into appropriate WooCommerce action
  3. Use Event class to track
  4. Add event constant to Constants.php
  5. Write test in tests/Unit/Events/

Example:

<?php
use Hellotext\Api\Event;
use Hellotext\Constants;

add_action('woocommerce_new_action', 'hellotext_track_new_action');

function hellotext_track_new_action($data): void {
    $event = new Event();
    $event->track(Constants::EVENT_NEW_ACTION, [
        'object_parameters' => $data
    ]);
}

Adding a New Adapter

  1. Create adapter file in src/Adapters/
  2. Implement get(): array method
  3. Write comprehensive test
  4. Document in API.md

Adding Configuration Option

  1. Add constant to Constants.php
  2. Add field to Settings.php admin page
  3. Use get_option(Constants::OPTION_NAME) to retrieve

Troubleshooting

Tests Failing

Issue: Mockery errors or WordPress function not found

Solution: Ensure WordPress and WooCommerce stubs are installed:

composer require --dev php-stubs/wordpress-stubs php-stubs/woocommerce-stubs

Session Cookie Not Setting

Issue: hello_session cookie not being created

Solution: Check that session_start() is called early in plugin load and cookie settings (domain, path) are correct.

API Requests Failing

Issue: 401 Unauthorized errors

Solution: Verify Business ID and Access Token are set correctly in WordPress admin → Extensions → Hellotext.

Resources

License

GPL v2 - See LICENSE file.

Support