Download the PHP package milpa/admin without Composer

On this page you can find all versions of the php package milpa/admin. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package admin

Milpa

# Milpa Admin > The **administration panel** of the Milpa PHP framework — the surface where a human leaves the house ready for the agent. Composed of Milpa Components, event-driven, and extended by declaration: every installed plugin adds its own section without the panel knowing its name. [![CI](https://github.com/getmilpa/admin/actions/workflows/ci.yml/badge.svg)](https://github.com/getmilpa/admin/actions/workflows/ci.yml) [![Packagist](https://img.shields.io/packagist/v/milpa/admin)](https://packagist.org/packages/milpa/admin) [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE) ## What it is Milpa is a framework a human administers and an **agent operates**. Everything the agent can do is a governed operation; everything the human sees is a projection of the same operations. The admin panel is the human's projection: install capabilities, read the routes and middleware every plugin declared, stand up the services the app needs, adjust configuration, read the ledgers of what the agent did. Add one plugin to `config/plugins.php` and `/milpa/admin` exists: The panel opens on **The house**, followed by **Plugins** (what the app boots, and the capabilities it can grow), **Routes** (every route the booted plugins declared, with handler and per-route middleware), **Identity** (the current request's authenticated identity and declared scopes), **Settings** (what the app declared about the panel itself, key by key, with its source), **Stack** (every backing service the booted plugins declared they need — image, ports, environment with secrets masked, the declaring plugin — and whether its port answers on loopback) and **Dev tools** (the ledgers the agent writes, read-only) — and one more per plugin that declares one. ## Identity `/milpa/admin/s/identity` shows the actor authenticated for the current request and its declared scopes. Missing scopes are reported as unavailable; an empty list is shown as empty. Each operation still makes its own authorization decision. The section reads no private keys or enrollment files and offers no permission-changing actions. Passkey registration and sign-in links appear only when the house serves those routes, with a return to Identity. The ceremonies remain outside the panel's gate so a visitor can sign in. The terminal reports no authenticated HTTP identity. English is the default; `?lang=es` selects Spanish. ## The same panel, in a terminal A section is declared once. `/milpa/admin` paints it as a page, and `coa panel` paints the same declaration in the terminal — the sections along the bottom, one state table per section, `tab` and the digits to move: Nothing is declared twice and no plugin says a word about a terminal. The panel implements `Milpa\Console\State\SectionStateSource` **once, for everyone**: it already discovers every section every request, so it hands that same catalogue — its own sections and every guest's — to the dashboard `milpa/console` carries. A component's state IS the picture; `milpa/live-tui` turns any state array into a table, so no section writes a second renderer to gain a second surface. A section that cannot be mounted reports that in its own state and the rest of the panel stands, exactly as a component that throws paints its failure inside its own region on the page. ## The one idea: a section is a component a plugin declares The panel discovers implementers by `instanceof` over the booted plugins, **at request time** (boot order does not matter), lists each section in the sidebar under its group, routes it at `/milpa/admin/s/`, and renders it inside the shell under a header that says who declared it. A duplicate id is a loud 500 naming both plugins — never a silent "last one wins". One prop name is **reserved**: `query` — the shell hands every active section the request's query params under `props['query']`, so a section can read its own (`?session=`, a filter) without the shell interpreting it; an `AdminSection` that declares `props['query']` itself is refused at construction (`InvalidArgumentException`) rather than silently overwritten on every request. The component **names** the panel registers itself are reserved the same way — the dashboard primitives, `admin-sidebar`, `admin-section-header`: a section may *name* one (`component: 'metric-card'`), but a section that brings its own `definition` under one is refused (`ReservedComponentException`, a 500 that names the section and the name it tried to take) rather than silently repainting every section that names it, the host's header included. Two lifecycle pairs let another plugin extend a section or the shell without touching either: `admin.section.before_render` / `after_render` (props, then HTML — both mutable) and `admin.shell.before_render` / `after_render` (the composition and sidebar items, then HTML). A sidebar item a subscriber adds names its `group` like a section does (`app` when it names none). The panel **declares** those four to the dispatcher it boots with (greenhouse `decisions/0228`): when the app's dispatcher implements `Milpa\Interfaces\Event\DeclaredEvents` (`milpa/core` ≥ 0.11), `AdminPlugin::boot()` hands it `AdminEvents::declarations()` — one `EventDeclaration` per name, built from the same constants `AdminShell` dispatches with (`AdminShell::events()`): who dispatches it, when, the payload key (`section` / `shell`), the subject type (`SectionRender` / `ShellRender`) and that the subject is mutable. A dispatcher that does not implement the contract is told nothing and every event fires the same. The falsifier, `tests/TheEmitterDeclaresEveryEventItDispatchesTest.php`, renders through the real kernel with a spy dispatcher and compares what was declared against what was dispatched — names, keys, subjects, the dispatching class — and goes red when one declaration is deleted (measured before it was committed). ## Hosting a guest: what a section receives A section is a guest of the panel, and the panel is the host — it tells the guest what it knows and paints what the guest cannot know about itself (greenhouse `decisions/0210`, sharpened by the first real guest, the Desktop's **Agent** section). **The context.** Every section's component mounts with a `ComponentContext` the shell fills — the same one every component of the page gets, under that component's own id: | field | value | |---|---| | `componentId` | `milpa-admin-section-` | | `principal` | the actor the gate authenticated — the `id` of the `AuthContext` a gate left under the request attribute `milpa.auth` (`passkey:` behind app-runtime's passkey gate) — or **`null` when nobody is signed in**. It is exactly what the topbar's `signed in as …` chip shows, so a guest that decides its state by the principal (the Desktop's *signed-out* vs *live*) always agrees with the topbar | | `locale` | the language the page answers in — the app's `admin.locale`, or the request's `?lang=` when the catalog carries it | | `route` | the panel's mount point (`admin.route`, default `/milpa/admin`) — for a link back into the panel | | `meta['gate']` | the gate in effect, as the topbar chip names it: `loopback` \| `custom` \| `passkey` \| `open` \| `fallback` | | `meta['section']` | the id of the section the panel is showing | | `meta['query']` | the request's query params — how a **declared view** reads what `props['query']` gives the narrow shape | The props are the section's own `props` plus `query` (the request's query params). A guest reads the context and its props; it never reads the request, and it never reads a cookie — the panel does not either. **The header.** Above every section — the panel's own included — the host paints the section header: the title (a catalog key translated, or the literal) and the attribution, read from the catalogue's record of which plugin's `adminSections()` returned it, never from the section: The short class name is shown (`declared by DesktopAppPlugin` · `declarada por DesktopAppPlugin`), the full class travels in `data-declared-by`. A guest brings the region; the host brings the header, the sidebar and the topbar. **The sidebar.** Sections list under their `group`, one heading per distinct value, in the house order — **`admin`** (the panel's own: Plugins, Routes, Settings, Stack, Dev tools) → **`app`** (the default — a plugin's sections) → **`agent`** (the agent's own surfaces: the Desktop's Agent section) → any other group name, alphabetically — case-insensitively and in its own alphabet (`año` sorts among the a's, `Zeta` after `beta`). The headings come from the catalog (`ADMIN / APP / AGENT` · `ADMIN / APP / AGENTE`); a group the catalog does not know is headed by its own name uppercased in its own alphabet (`año` → `AÑO`). The glyph a section declares as `icon` is painted before its label. **The order.** Within a group, sections sort by `order` (lower first; ties break by `id`, alphabetically). The panel **opens** on the first section in that same (`order`, `id`) order across every group, so the convention matters: the panel's own take **10..40** (Plugins 10, Routes 20, Settings 25, Stack 30, Dev tools 40); a guest picks an order **after those** — greenhouse `decisions/0210` names 60 for the Desktop's Agent section — unless it means to be the page the panel opens on. A guest at order 10 named `agent` would tie with Plugins, win the tie by id, and become the front page. ## A section may declare a whole VIEW One component is the narrow case. A plugin that brings its own UI declares a **view** — a tree of components, the definitions and renderers it needs, the props per component and the signals the page must seed — and the panel mounts it inline, in its own main, under its own header, with **one runtime for the whole page** (greenhouse `decisions/0211`). No frame, no second document, no second Alpine: the panel's theme applies to the guest's region — measured in a browser, flipping `` repaints the guest's own surfaces, which an iframe could not do. One endpoint over one registry also makes a `RenderEffect` from a host component able to repaint a guest's — the mechanism is there; this slice did not exercise it. What the panel does **not** do yet is reach INTO the region: the topbar's search is the inert `dashboard-topbar` primitive and nothing wires it to a guest, so `decisions/0211`'s S3-F1 falsifier («the topbar's search reaches the composer») is **not delivered**. The constructor takes the same thing as `view:` — `AdminSection::ofView()` is the one-liner. A section declares a view **or** a component, never both, and a view carries no section `props` (its props are per component). **What the host does with it.** - **It registers the tree.** Every name in `definitions` enters the panel's registry under a **layer of its own**, labelled with the section's id. Names the panel registers itself (`metric-card`, `dashboard-*`, `admin-sidebar`, `admin-section-header`) may be NAMED but never redefined (`ReservedComponentException`), and two sections binding one name to **different** definitions throw `milpa/live`'s own `ComponentNameConflictException` naming the component and both sections — the same rule everywhere: identity or a stateless class, never a structural compare. The **renderer** is held to that same rule by the panel (`RendererConflictException`): two sections may legitimately share one definition and still each bring their own renderer, and the renderer registry resolves the last one registered — so without a rule of its own the first section's surface would be repainted by the second's renderer, silently, in the one place whose whole point is that a collision is loud. Share the instance, or name your own component. Either refusal leaves the book as it was. - **It emits one runtime.** Every renderer that implements `DeclaresClientAssets` contributes its `.css` and `.js`; the panel merges them (deduplicated by URL) and hands them to `LiveBoot::html()`, which emits — in ``, after the panel's own stylesheets — the declared styles, the boot payload, `milpa-live.js`, `milpa-live-remote.js`, the guest modules in declared order, and **Alpine last**, each `defer`, each URL once. The panel hand-writes no runtime `