Izartu API

Controller
in package

Route handlers for the front controller (index.php). Each handler deals with one route and returns a `[template, variables]` pair to render, or redirects and exits directly.

Table of Contents

Methods

add()  : array{0: string, 1: array}
Add bookmark (POST action): validate and create it, then return to the list the form was on. A GET redirects to the user's own page with the inline add form open (`?add`).
delete()  : array{0: string, 1: array}
Delete bookmark (POST action, the Delete button of the inline edit form), then return to the list the form was on.
edit()  : array{0: string, 1: array}
Edit bookmark (POST action): validate and save it, then return to the list the form was on. A GET redirects to the user's own page with that row's inline edit form open (`?edit=ID`).
home()  : array{0: string, 1: array}
Home page: one page of the bookmark feed (`?page=N`) and the tag cloud.
login()  : array{0: string, 1: array}
Login: show the form (GET) or process it (POST).
logout()  : never
Logout: destroy the session and redirect to the home page.
notFound()  : array{0: string, 1: array}
Not found: send a 404 status and render the not-found view.
redirect()  : never
Send a redirect to the given path and stop the request.
tag()  : array{0: string, 1: array}
Tag page: the feed filtered by tag names (`/tag/NAME` or `/tag/NAME,NAME,...`, comma-separated: bookmarks carrying ALL of them), paginated.
tagError()  : string|null
Validate a bookmark's normalised tag names.
tags()  : array{0: string, 1: array}
Tag index page (`/tags`): every visible tag with its count, paginated and alphabetical; `?q=TERM` narrows it to the matching tags. The list context travels along (`?tag=NAMES` and/or `?user=NAME`), scoping the index/search to that list, exactly like the cloud.
user()  : array{0: string, 1: array}
User page: the feed filtered by one username (`/user/USERNAME`), paginated.
validate()  : array<string, string>
Validate a bookmark's user-supplied fields.
apply()  : array<string, string>
Fill a bookmark from form input and validate it (CSRF included).
feed()  : array{0: string, 1: array}
The variables every list view shares. Inline form state comes from the query string: `?edit=ID` renders that row as an in-place edit form (the template still gates it with `Auth::canManage`) and `?add` renders an empty form on top of the list. Both are view states of the list, so they live in the query string; mutations POST to the `/add`, `/edit/ID` and `/delete/ID` action routes.
isValidLink()  : bool
Whether a string is an acceptable bookmark URL.
listFromReturn()  : array{0: string, 1: array}
Rebuild the list view the submitted form was on (see `returnPath()`), to re-render it with the inline form when validation fails.
ownPage()  : string
The logged-in user's own list page (`user/USERNAME`).
page()  : int
The requested list page number (`?page=N`, 1-based).
returnPath()  : string
The list the submitted form was on, as a safe relative path: the form's hidden `return` field, accepted only when it matches a known list route plus an optional page (never an absolute URL, so it cannot be turned into an open redirect). Falls back to the user's own page.
tagNames()  : array<int, string>
Parse a comma-separated tag list into the canonical tag-name set: a comma can never be part of a tag (it is the input separator), so the names are split on it, then trimmed, lower-cased, deduplicated and sorted.
tagRoute()  : string
The list route for a set of tag names (`tag/NAME,NAME`).

Methods

add()

Add bookmark (POST action): validate and create it, then return to the list the form was on. A GET redirects to the user's own page with the inline add form open (`?add`).

public static add() : array{0: string, 1: array}

Requires a logged-in user. On invalid input the origin list is re-rendered with the inline form, the typed values and the errors.

Return values
array{0: string, 1: array}

Template name and its variables.

delete()

Delete bookmark (POST action, the Delete button of the inline edit form), then return to the list the form was on.

public static delete(string $id) : array{0: string, 1: array}

Requires a logged-in user who may manage the bookmark and a valid CSRF token; anything else (including GET requests) renders the 404 view.

Parameters
$id : string

Bookmark id from the URL (second path segment).

Return values
array{0: string, 1: array}

Template name and its variables.

edit()

Edit bookmark (POST action): validate and save it, then return to the list the form was on. A GET redirects to the user's own page with that row's inline edit form open (`?edit=ID`).

public static edit(string $id) : array{0: string, 1: array}

Requires a logged-in user who may manage the bookmark; a missing id or a foreign bookmark renders the 404 view (existence is not revealed). On invalid input the origin list is re-rendered with the inline form, the typed values and the errors.

Parameters
$id : string

Bookmark id from the URL (second path segment).

Return values
array{0: string, 1: array}

Template name and its variables.

home()

Home page: one page of the bookmark feed (`?page=N`) and the tag cloud.

public static home() : array{0: string, 1: array}
Return values
array{0: string, 1: array}

Template name and its variables.

login()

Login: show the form (GET) or process it (POST).

public static login() : array{0: string, 1: array}

On a valid POST (CSRF token plus credentials) the user is logged in and redirected to their own page. Otherwise the form is shown, with an error flag after a failed attempt.

Return values
array{0: string, 1: array}

Template name and its variables.

logout()

Logout: destroy the session and redirect to the home page.

public static logout() : never
Return values
never

notFound()

Not found: send a 404 status and render the not-found view.

public static notFound() : array{0: string, 1: array}
Return values
array{0: string, 1: array}

Template name and its variables.

redirect()

Send a redirect to the given path and stop the request.

public static redirect(string $path) : never
Parameters
$path : string

Absolute URL path to redirect to.

Return values
never

tag()

Tag page: the feed filtered by tag names (`/tag/NAME` or `/tag/NAME,NAME,...`, comma-separated: bookmarks carrying ALL of them), paginated.

public static tag(string $segment) : array{0: string, 1: array}

An unknown tag renders an empty page rather than a 404, so the response does not reveal whether a (possibly private) tag exists.

Parameters
$segment : string

Tag name(s) from the URL (second path segment, encoded).

Return values
array{0: string, 1: array}

Template name and its variables.

tagError()

Validate a bookmark's normalised tag names.

public static tagError(array<int, string> $names) : string|null
Parameters
$names : array<int, string>

Parsed tag names (see Bookmark::parseTags()).

Return values
string|null

An error message, or null when the tags are fine.

tags()

Tag index page (`/tags`): every visible tag with its count, paginated and alphabetical; `?q=TERM` narrows it to the matching tags. The list context travels along (`?tag=NAMES` and/or `?user=NAME`), scoping the index/search to that list, exactly like the cloud.

public static tags() : array{0: string, 1: array}
Return values
array{0: string, 1: array}

Template name and its variables.

user()

User page: the feed filtered by one username (`/user/USERNAME`), paginated.

public static user(string $name) : array{0: string, 1: array}

/user/me is a reserved alias (see User::RESERVED) that redirects to the logged-in user's own page. An unknown username renders an empty page rather than a 404, so the response does not reveal whether an account exists.

Parameters
$name : string

Username from the URL (second path segment, encoded).

Return values
array{0: string, 1: array}

Template name and its variables.

validate()

Validate a bookmark's user-supplied fields.

public static validate(Bookmark $bookmark) : array<string, string>
Parameters
$bookmark : Bookmark

The bookmark to check (already filled).

Return values
array<string, string>

Error message per invalid field; empty if valid.

apply()

Fill a bookmark from form input and validate it (CSRF included).

private static apply(Bookmark $bookmark, array<string, mixed> $input) : array<string, string>
Parameters
$bookmark : Bookmark

The bookmark to fill.

$input : array<string, mixed>

The submitted form fields ($_POST).

Return values
array<string, string>

Error message per invalid field; empty if valid.

feed()

The variables every list view shares. Inline form state comes from the query string: `?edit=ID` renders that row as an in-place edit form (the template still gates it with `Auth::canManage`) and `?add` renders an empty form on top of the list. Both are view states of the list, so they live in the query string; mutations POST to the `/add`, `/edit/ID` and `/delete/ID` action routes.

private static feed(int $page, array<string|int, mixed> $tagNames, string|null $userName, string $route) : array{0: string, 1: array}
Parameters
$page : int
$tagNames : array<string|int, mixed>
$userName : string|null
$route : string
Return values
array{0: string, 1: array}

Template name and its variables.

Whether a string is an acceptable bookmark URL.

private static isValidLink(string $url) : bool

Accepts only http/https, requires a host, and rejects embedded whitespace/control characters and userinfo (user:pass@, a phishing vector). Host shape is left permissive on purpose (IPs, localhost and intranet hosts are valid targets for a self-hosted instance).

Parameters
$url : string

The URL to check.

Return values
bool

listFromReturn()

Rebuild the list view the submitted form was on (see `returnPath()`), to re-render it with the inline form when validation fails.

private static listFromReturn() : array{0: string, 1: array}
Return values
array{0: string, 1: array}

Template name and its variables.

ownPage()

The logged-in user's own list page (`user/USERNAME`).

private static ownPage() : string
Return values
string

page()

The requested list page number (`?page=N`, 1-based).

private static page() : int
Return values
int

returnPath()

The list the submitted form was on, as a safe relative path: the form's hidden `return` field, accepted only when it matches a known list route plus an optional page (never an absolute URL, so it cannot be turned into an open redirect). Falls back to the user's own page.

private static returnPath() : string
Return values
string

tagNames()

Parse a comma-separated tag list into the canonical tag-name set: a comma can never be part of a tag (it is the input separator), so the names are split on it, then trimmed, lower-cased, deduplicated and sorted.

private static tagNames(string $list) : array<int, string>
Parameters
$list : string

The comma-separated tag names (already decoded).

Return values
array<int, string>

The tag names; empty if none survive.

tagRoute()

The list route for a set of tag names (`tag/NAME,NAME`).

private static tagRoute(array<int, string> $names) : string
Parameters
$names : array<int, string>

The tag names.

Return values
string
On this page

Search results