22

Product support

Read the plugin support instructions.

  • Added on Feb 25, 2026
  • Current version: 2.0.0
  • Platform Compatibility
    v4.x use latest
    v3.x use latest
    v2.x not tested
    v1.x not tested
  • Created by
    Bronze partner

Categories

Overview

Redmine is a full-featured integration plugin that connects your October CMS website with a Redmine project management instance. It provides a customer support desk for your frontend users and a complete API wrapper for developers.

Support Desk

The plugin includes three ready-to-use components for building a support portal:

  • Ticket List — Displays all tickets submitted by the logged-in user, with pagination, search by subject, and status filtering (open, closed, or all).
  • Ticket Detail — Shows a single ticket with its full conversation history (journals) and attachments. Users can reply and attach files directly from the frontend.
  • Ticket Create — A form for submitting new support tickets with subject, description, and file attachments.

Each component is fully configurable from the CMS editor: choose which pages to link together (detail page, list page, cancel page, redirect after creation), set items per page, and select status filters — all without writing code.

How It Works

Frontend users are mapped to Redmine accounts through an automatic user mapping system. When a user submits or views a ticket, the plugin impersonates them on the Redmine side using the X-Redmine-Switch-User header. This means tickets are created and visible under the correct Redmine user, while your admin API key handles authentication.

Requires RainLab.User for frontend authentication.

Configuration

  1. Go to Settings > Redmine in the backend.
  2. Enter your Redmine URL and API key (must have admin privileges for impersonation).
  3. Optionally set a default Project ID, Tracker ID, and Priority ID for new tickets created from the support desk.

SSL verification options can be configured via environment variables (REDMINE_VERIFY_HOST, REDMINE_VERIFY_PEER).

API Wrapper for Developers

Beyond the support desk, the plugin exposes 22 typed API endpoints through a fluent PHP interface and static facades:

Issues, Projects, Users, Uploads, Attachments, Time Entries, Memberships, Versions, Wiki Pages, News, Issue Statuses, Issue Relations, Issue Categories, Trackers, Enumerations, Queries, Roles, Groups, Custom Fields, Search, Files, and My Account.

All endpoints support named parameters, filtering, pagination, and includes. Example:

use Redmine\Facades\Issues;

$issues = Issues::all(projectId: 1, statusId: 'open', sort: 'updated_on:desc');
$issue = Issues::find(123, include: ['journals', 'attachments']);

Supported Languages

The plugin is fully translated in: English, Italian, German, French, Spanish, Portuguese, Russian, Arabic, Hindi, Japanese, and Chinese.

Requirements

  • October CMS 3.x or higher
  • PHP 8.0 or higher
  • Redmine 4.0 or higher
  • A Redmine API key with admin privileges (required for user impersonation)
Easily submit new support tickets directly from your website with the TicketCreate form.

Installation via Command Line

php artisan plugin:install DGline.Redmine

Documentation

Configuration

Go to Settings > Redmine in the October CMS backend and fill in:

Field Description
Host Your Redmine instance URL (e.g., https://redmine.example.com)
API Key A Redmine API key with admin privileges (required for user impersonation)
Project ID Default project ID for new tickets (optional)
Default Tracker ID Tracker ID assigned to tickets created from the support desk (optional)
Default Priority ID Priority ID assigned to tickets created from the support desk (optional)

Environment Variables

SSL verification can be configured via environment variables:

REDMINE_VERIFY_HOST=true
REDMINE_VERIFY_PEER=true

User Mapping

The plugin maps October CMS frontend users to Redmine accounts through the dgline_redmine_user_map database table. Each record links an October CMS user_id to a redmine_user_id and redmine_login.

When a frontend user accesses a component, the plugin resolves the mapping automatically and impersonates the Redmine user via the X-Redmine-Switch-User header. If no mapping exists for a user, it is created automatically by looking up the user's email in Redmine.

This requires the RainLab.User plugin.

Components

TicketList

Displays a paginated list of support tickets authored by the logged-in user.

Properties

Property Type Default Description
itemsPerPage string 20 Number of tickets per page
statusFilter dropdown * Filter by status: * (all), open, closed
ticketPage dropdown CMS page used to display ticket details

Page Variables

Variable Type Description
__SELF__.tickets array Ticket data for the current page (see structure below)
__SELF__.detailPage string The configured ticket detail page name
__SELF__.perPageOptions array Available page size options: [10, 20, 50, 100]

The tickets variable has the following structure:

tickets.items     - Array of Redmine issue objects
tickets.total     - Total number of matching tickets
tickets.page      - Current page number
tickets.lastPage  - Last page number
tickets.limit     - Current page size
tickets.search    - Current search query

AJAX Handlers

onChangePage — Reloads the ticket list with new pagination, search, or page size.

POST parameters:

  • page (int) — Page number (default: 1)
  • limit (int) — Items per page (default: value of itemsPerPage property)
  • search (string) — Search query to filter by subject

Example

url = "/tickets"

[ticketList]
itemsPerPage = 20
statusFilter = "open"
ticketPage = "ticket-detail"
==
{% component 'ticketList' %}

TicketDetail

Displays a single ticket with its journals (conversation history) and attachments. Users can reply to the ticket and attach files.

Only tickets authored by the logged-in user are accessible. If the ticket does not exist or belongs to another user, a 404 page is returned.

Properties

Property Type Default Description
slug string {{ :id }} URL parameter for the ticket ID
listPage dropdown CMS page for the "back to list" link

Page Variables

Variable Type Description
ticket array|null The Redmine issue object with journals and attachments included
listPage string The configured ticket list page name

The ticket variable contains the full Redmine issue data, including:

ticket.id              - Issue ID
ticket.subject         - Issue subject
ticket.description     - Issue description
ticket.status.name     - Status name
ticket.status.is_closed - Whether the status is closed
ticket.author.name     - Author display name
ticket.created_on      - Creation date (ISO 8601)
ticket.updated_on      - Last update date (ISO 8601)
ticket.journals[]      - Array of journal entries (replies)
ticket.attachments[]   - Array of file attachments

AJAX Handlers

onReply — Submits a reply to the ticket with optional file attachments.

POST parameters:

  • notes (string, required) — Reply text
  • attachments[] (files, optional) — File attachments

On success, a flash message is displayed and the ticket data is reloaded.

Example

url = "/tickets/:id"

[ticketDetail]
slug = "{{ :id }}"
listPage = "tickets"
==
{% component 'ticketDetail' %}

TicketCreate

Form for creating new support tickets with subject, description, and file attachments.

Properties

Property Type Default Description
redirectPage dropdown CMS page to redirect to after ticket creation (receives the new ticket id as URL parameter)
cancelPage dropdown CMS page for the cancel button

Page Variables

Variable Type Description
cancelPage string The configured cancel page name

AJAX Handlers

onSubmit — Creates a new ticket in Redmine.

POST parameters:

  • subject (string, required) — Ticket subject
  • description (string, optional) — Ticket description
  • attachments[] (files, optional) — File attachments

The ticket is created under the configured project with the default tracker and priority (if set in backend settings). On success, a flash message is displayed and the user is redirected to redirectPage if configured.

Example

url = "/tickets/new"

[ticketCreate]
redirectPage = "ticket-detail"
cancelPage = "tickets"
==
{% component 'ticketCreate' %}

API Usage

Static Facades

The plugin provides static facades under the Redmine\Facades namespace for quick access to all endpoints:

use Redmine\Facades\Issues;
use Redmine\Facades\Projects;
use Redmine\Facades\Users;

// List open issues
$issues = Issues::all(statusId: 'open', projectId: 1, sort: 'updated_on:desc');

// Get single issue with journals
$issue = Issues::find(123, include: ['journals', 'attachments']);

// Create issue
$newIssue = Issues::create(
    projectId: 1,
    subject: 'Bug report',
    description: 'Steps to reproduce...',
    trackerId: 1,
    priorityId: 2,
);

// Update issue
Issues::update(id: 123, statusId: 2, notes: 'Fixed in v1.2');

// Delete issue
Issues::destroy(123);

Direct Client Usage

For impersonation or more control, use the Client class directly:

use DGline\Redmine\Classes\Api\Client;

$client = new Client();

// Impersonate a user (sets X-Redmine-Switch-User header)
$client->impersonate('johndoe');
$issues = $client->issues()->all(authorId: 'me');
$client->uploads()->upload($fileContent, 'document.pdf');

// Clear impersonation
$client->impersonate(null);

Available Endpoints

All endpoints are accessible via $client->methodName() or their corresponding facade:

Client Method Facade Description
issues() Issues CRUD, watchers
projects() Projects CRUD, archive/unarchive
users() Users CRUD, current user
uploads() Uploads File upload
attachments() Attachments Download, delete
timeEntries() TimeEntries CRUD
memberships() Memberships CRUD
versions() Versions CRUD
wikiPages() WikiPages CRUD
news() News CRUD
issueStatuses() IssueStatuses List
issueRelations() IssueRelations CRUD
issueCategories() IssueCategories CRUD
trackers() Trackers List
enumerations() Enumerations Priorities, activities, categories
queries() Queries List
roles() Roles List, find
groups() Groups CRUD, members
customFields() CustomFields List
search() Search Full-text search
files() Files List, upload
myAccount() MyAccount Current user account

Issues API Reference

Filters

Parameter Description
offset Skip N issues (pagination)
limit Number of issues per page (max: 100)
sort Sort column (e.g., priority:desc, updated_on)
include Associated data: attachments, relations, journals, watchers
projectId Filter by project ID
statusId Filter by status: open, closed, *, or numeric ID
assignedToId Filter by assignee (me for current user)
authorId Filter by author ID
trackerId Filter by tracker ID
priorityId Filter by priority ID
createdOn Filter by creation date (e.g., >=2024-01-01)
updatedOn Filter by update date
customFields Array of custom field filters (e.g., ['cf_1' => 'value'])

Watchers

Issues::addWatcher(issueId: 123, userId: 5);
Issues::removeWatcher(issueId: 123, userId: 5);

Projects API Reference

Include Options

  • trackers — Project trackers
  • issue_categories — Issue categories
  • enabled_modules — Enabled modules
  • time_entry_activities — Time entry activities (Redmine 3.4+)
  • issue_custom_fields — Issue custom fields (Redmine 4.2+)

Archive/Unarchive (Redmine 5.0+)

Projects::archive('my-project');
Projects::unarchive('my-project');

Users API Reference

Status Constants

use Redmine\Facades\Users;

Users::STATUS_ACTIVE     // 1 - Can login
Users::STATUS_REGISTERED // 2 - Email not confirmed
Users::STATUS_LOCKED     // 3 - Cannot login

Error Handling

All API errors throw ApplicationException with translated messages:

use ApplicationException;

try {
    $issue = Issues::find(99999);
} catch (ApplicationException $e) {
    // "Redmine API Error: 404 - Not Found"
    Log::error($e->getMessage());
}

Console Commands

Test API Connection

php artisan redmine:test

Tests the API connection and displays issues assigned to the current user, projects, and current user information.

2.0.0

Add client impersonation support and typed endpoint usage in components

Feb 17, 2026

1.1.0

Add user-Redmine mapping table for support desk

Feb 17, 2026

1.0.1

Initialize plugin

Feb 17, 2026