403Webshell
Server IP : 202.61.199.114  /  Your IP : 216.73.217.139
Web Server : nginx/1.22.1
System : Linux de.arni-solutions.de 6.1.0-49-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.174-1 (2026-05-26) x86_64
User : web20 ( 1018)
PHP Version : 8.4.23
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : ON
Directory :  /var/www/clients/client2/arni-solutions.de/web/crm/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/clients/client2/arni-solutions.de/web/crm/CONVENTIONS.md
# ArNi CRM – Entwickler-Konventionen (verbindlich)

PHP **7.3** kompatibel: KEINE Arrow-Functions (`fn() =>`), kein `match`, keine typed
properties, kein Nullsafe `?->`, kein `str_contains`. Nutze `function(){ return; }`.

## Architektur
- Front-Controller: `public/index.php`, Routing über `index.php?r=controller/action`.
- Routen werden in `app/routes.php` registriert: `'route' => ['ClassName','method']`.
- Controller erben von `Controller` (in `app/Controller.php`), liegen in `app/controllers/`.
- Models erben von `BaseModel` (in `app/models/`), Tabellen IMMER mit Prefix über `tbl('name')`.
- Views liegen in `app/views/<modul>/<name>.php`, gerendert via `$this->view('modul/name', $data)`.
- Layout ist automatisch `layouts/app` (Sidebar+Topbar). `$title` setzen für Seitentitel.

## Verfügbare Helfer (functions.php)
- `e($s)` – HTML-Escape (IMMER bei Ausgabe von Daten benutzen).
- `url($route, $params=[])` – z.B. `url('products/edit', ['id'=>5])`.
- `asset($path)` – Asset-URL.
- `redirect($url)`, `is_post()`, `post($k,$d='')`, `input($k,$d='')`.
- `csrf_field()` – verstecktes Input im Formular; `csrf_verify()` – im POST aufrufen.
- `flash('success'|'error', $msg)` setzen; Anzeige passiert automatisch im Layout.
- `set_old($_POST)` + `old($key)` für Formular-Wiederbefüllung; `clear_old()`.
- `money($n)`, `num($n)`, `fdate($d)`, `fdatetime($d)`.
- `current_user()`, `require_role('admin', ...)`, `user_can('admin')`.
- Badges: `invoice_status_label/class`, `ticket_status_label/class`, `ticket_priority_label/class`.

## BaseModel-API (statisch)
`Model::find($id)`, `Model::all($order='id DESC')`, `Model::where($col,$val)`,
`Model::insert($assoc):int`, `Model::update($id,$assoc):bool`, `Model::delete($id)`,
`Model::count($where='1',$params=[])`. Spaltennamen kommen NUR aus dem Code (nie aus Eingaben).

## Controller-Pattern (Beispiel)
```php
class FooController extends Controller {
    public function index() {
        $rows = Foo::all();
        $this->view('foo/index', ['title' => 'Foo', 'rows' => $rows]);
    }
    public function store() {
        $this->guardPost(); // prüft POST + CSRF
        $errors = $this->required(['title' => 'Titel'], $_POST);
        if ($errors) { flash('error', implode(' ', $errors)); set_old($_POST); redirect(url('foo/create')); }
        Foo::insert(['title' => trim(post('title')), 'created_at' => date('Y-m-d H:i:s')]);
        flash('success', 'Gespeichert.');
        redirect(url('foo'));
    }
}
```

## Views
- Beginnen direkt mit HTML (kein `<?php` Boilerplate nötig), nutzen `$variablen` aus `$data`.
- Seitenkopf: `<div class="crm-page-head"><h2>Titel</h2><div class="spacer"></div> ...Buttons... </div>`.
- Inhalte in `<div class="card"><div class="card-body">...</div></div>`.
- Tabellen in `<div class="crm-table-wrap"><table class="table table-hover align-middle">`.
- Pflichtfeld-Label: `<label class="form-label">Name <span class="required-star">*</span></label>`.
- Löschen-Links: `data-confirm="Wirklich löschen?"` (JS bestätigt automatisch).
- Alles über `e()` ausgeben.

## Sicherheit
- JEDES Formular: `<?= csrf_field() ?>`; jede POST-Action: `$this->guardPost()` zuerst.
- Ausgabe escapen mit `e()`. DB nur über BaseModel/Prepared Statements.

Youez - 2016 - github.com/yon3zu
LinuXploit