PHPackages                             script-development/kendo-report-tool - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. script-development/kendo-report-tool

ActiveLibrary[API Development](/categories/api)

script-development/kendo-report-tool
====================================

Laravel client library that submits user reports into a kendo project's report endpoint.

00[1 PRs](https://github.com/script-development/kendo-report-tool/pulls)PHPCI passing

Since Jun 8Pushed yesterdayCompare

[ Source](https://github.com/script-development/kendo-report-tool)[ Packagist](https://packagist.org/packages/script-development/kendo-report-tool)[ RSS](/packages/script-development-kendo-report-tool/feed)WikiDiscussions main Synced yesterday

READMEChangelogDependenciesVersions (4)Used By (0)

kendo-report-tool
=================

[](#kendo-report-tool)

[![Packagist Version](https://camo.githubusercontent.com/8d65264aaf3953b6afa104a7c0cd695b738592c5d7fb6fc92cf39a5df7eec7ad/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7363726970742d646576656c6f706d656e742f6b656e646f2d7265706f72742d746f6f6c2e737667)](https://packagist.org/packages/script-development/kendo-report-tool)[![CI](https://github.com/script-development/kendo-report-tool/actions/workflows/ci.yml/badge.svg)](https://github.com/script-development/kendo-report-tool/actions/workflows/ci.yml)[![License](https://camo.githubusercontent.com/e015407e4a34ce724be99b4dc6cfb073db555962a8f12463937fb1f584f736be/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f7363726970742d646576656c6f706d656e742f6b656e646f2d7265706f72742d746f6f6c2e737667)](LICENSE)

Laravel client library for submitting user reports/feedback into a kendo project — config, Bearer auth, multipart image upload, and a surfaced send result, installable via Composer across Script Development Laravel territories.

Why
---

[](#why)

kendo ships a reports endpoint (`POST /api/projects/{project}/reports`) that accepts machine submissions authenticated with a `report:create` project token. This library is the secure server-side transport: a consuming app's backend holds the token (which must **never** ship to the browser) and relays a report — title, description, optional author name, optional screenshots — from the app's own feedback form into the kendo project.

Unlike [`kendo-error-tracker`](https://github.com/script-development/kendo-error-tracker) (auto-captured, fire-and-forget exception telemetry), a report is an **explicit human submission**: the send is synchronous and its outcome is surfaced, so the app can tell the user whether it sent.

Installation
------------

[](#installation)

```
composer require script-development/kendo-report-tool
```

The `KendoReportToolServiceProvider` is auto-discovered via Laravel package discovery. Publish the config if you want to tune it:

```
php artisan vendor:publish --tag=report-tool-config
```

Configuration
-------------

[](#configuration)

Set the environment variables (the config reads `REPORT_TOOL_*`):

Env varConfig keyDescription`REPORT_TOOL_KENDO_URL``kendo_url`Base URL of your kendo tenant — `https://{tenant}.kendo.dev`.`REPORT_TOOL_PROJECT``project`The kendo **project id** that owns the reports (the `{project}` route-key; kendo binds it by id).`REPORT_TOOL_TOKEN``token`A kendo project token carrying the `report:create` ability (Bearer).`REPORT_TOOL_CONNECT_TIMEOUT``connect_timeout`Seconds to wait while connecting to the kendo host (default `2`).`REPORT_TOOL_TIMEOUT``timeout`Total seconds to wait for the POST (default `5`).`REPORT_TOOL_SWALLOW``swallow``false` (default) surfaces a failed send to the caller; `true` swallows it (telemetry mode).```
REPORT_TOOL_KENDO_URL=https://script.kendo.dev
REPORT_TOOL_PROJECT=1
REPORT_TOOL_TOKEN=your-project-token
```

Preconditions
-------------

[](#preconditions)

- The consuming kendo **project must have the `report-tool` feature active** — otherwise the endpoint rejects the submission.
- The token must be minted **under that project** and carry the `report:create` ability. A token used against a different project's route is rejected (`422`).

Minting a project token
-----------------------

[](#minting-a-project-token)

1. Open the kendo project's **API token** settings.
2. Create a project token — it carries the `report:create` ability.
3. Copy the token into `REPORT_TOOL_TOKEN`.

A submission made with a `report:create` token is recorded with `source = Api`; the human author you pass is surfaced via `author_name` (the token owner is not treated as the creator).

Usage
-----

[](#usage)

Resolve `KendoReports` from the container and call `submit()`:

```
use ScriptDevelopment\KendoReportTool\KendoReports;

$report = app(KendoReports::class)->submit(
    title: 'Checkout button unresponsive',
    description: "Clicking \"Pay\" does nothing on the cart page.",
    authorName: 'Jane Customer',     // optional — surfaced as the report's author
);

// $report is the decoded 201 body (id + fields) of the created report.
echo $report['id'];
```

### Signature

[](#signature)

```
public function submit(
    string $title,
    string $description,
    ?string $authorName = null,
    array $files = [],
): ?array
```

`submit()` POSTs a multipart request to `{kendo_url}/api/projects/{project}/reports` with the Bearer `report:create` token, then:

- **`201 Created`** → returns the decoded report body (`array` — `id` plus the report's fields).
- **any other outcome** — a non-`201` status (`401`/`403` token, `422` validation or token/project mismatch, `5xx`) or a transport-level failure (timeout, unreachable host) → throws `ScriptDevelopment\KendoReportTool\Exceptions\ReportSubmissionException`, **unless** `report-tool.swallow` (`REPORT_TOOL_SWALLOW`) is `true`, in which case the failure is logged to the local PHP `error_log` and `null` is returned.

A `null` author is omitted from the request rather than sent as an empty part.

### Attaching screenshots

[](#attaching-screenshots)

Pass `$files` as a list of `Illuminate\Http\UploadedFile` instances (e.g. straight from a feedback-form request) **or** local file paths. Each becomes a `files[]` multipart part:

```
use Illuminate\Http\Request;
use ScriptDevelopment\KendoReportTool\KendoReports;

public function store(Request $request): void
{
    app(KendoReports::class)->submit(
        title: (string) $request->input('title'),
        description: (string) $request->input('description'),
        authorName: $request->user()?->name,
        files: $request->file('screenshots', []),   // UploadedFile[] — or string paths
    );
}
```

The server accepts up to **5 image files** (jpg/jpeg/png/bmp/gif/tiff/webp, ≤3 MB each).

### Surfaced failure vs. swallow

[](#surfaced-failure-vs-swallow)

Because a report has a human waiting on confirmation, `submit()` **surfaces a failed send by default** (`swallow=false`) so the app can tell the user it did not send — contrast `kendo-error-tracker`, which always swallows. Catch the exception to drive UX:

```
use ScriptDevelopment\KendoReportTool\Exceptions\ReportSubmissionException;

try {
    app(KendoReports::class)->submit($title, $description);
    // tell the user it sent
} catch (ReportSubmissionException $e) {
    // tell the user it failed; $e->getMessage() distinguishes
    // a rejection ("HTTP ") from a transport failure.
}
```

Set `REPORT_TOOL_SWALLOW=true` to flip to telemetry-style swallow-on-failure (logs to `error_log`, returns `null`) when you do **not** want the caller to handle failures.

Contributing
------------

[](#contributing)

`composer test` · `composer phpstan` · `composer format:check` — all three gate CI on PHP 8.4 and 8.5. `main` is always release-ready; PRs update `CHANGELOG.md` under `[Unreleased]`.

###  Health Score

22

—

LowBetter than 22% of packages

Maintenance65

Regular maintenance activity

Popularity0

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity15

Early-stage or recently created project

 Bus Factor1

Top contributor holds 85.7% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/24678549?v=4)[Gerard Oosterhof](/maintainers/Goosterhof)[@Goosterhof](https://github.com/Goosterhof)

![](https://avatars.githubusercontent.com/u/68101885?v=4)[Jasper Boerhof](/maintainers/jasperboerhof)[@jasperboerhof](https://github.com/jasperboerhof)

---

Top Contributors

[![jasperboerhof](https://avatars.githubusercontent.com/u/68101885?v=4)](https://github.com/jasperboerhof "jasperboerhof (6 commits)")[![Goosterhof](https://avatars.githubusercontent.com/u/24678549?v=4)](https://github.com/Goosterhof "Goosterhof (1 commits)")

### Embed Badge

![Health badge](/badges/script-development-kendo-report-tool/health.svg)

```
[![Health](https://phpackages.com/badges/script-development-kendo-report-tool/health.svg)](https://phpackages.com/packages/script-development-kendo-report-tool)
```

###  Alternatives

[facebook/php-business-sdk

PHP SDK for Facebook Business

90923.5M35](/packages/facebook-php-business-sdk)[exsyst/swagger

A php library to manipulate Swagger specifications

35916.3M7](/packages/exsyst-swagger)[hubspot/api-client

Hubspot API client

24015.5M18](/packages/hubspot-api-client)[botman/driver-telegram

Telegram driver for BotMan

93452.6k6](/packages/botman-driver-telegram)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
