Haki klasy src/Narzedzie.php
Klasa haków to Narzedzia\<Pascal>\Narzedzie extends App\Narzedzia\Narzedzie w pliku src/Narzedzie.php (albo klasa z pola klasa w manifeście, też podklasa App\Narzedzia\Narzedzie). Nadpisujecie tylko to, czego moduł używa. Każdy hak portal woła w try: błąd w module trafia do logu, portal działa dalej.
<?php
namespace Narzedzia\FakturyKosztowe;
use App\Models\User;
use App\Narzedzia\Narzedzie as Baza;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Http\Request;
class Narzedzie extends Baza
{
// ... haki opisane niżej
}rekordyWMenu#
public function rekordyWMenu(User $user): arrayRekordy, które osoba przypięła do menu po lewej. Zwracacie listę [['url' => ..., 'nazwa' => ...]]. Ikona = ikona_svg z manifestu.
public function rekordyWMenu(User $user): array
{
return Faktura::where('user_id', $user->id)->where('w_menu', true)->orderBy('nazwa')->get()
->map(fn ($f) => ['url' => route('faktury_kosztowe.show', $f), 'nazwa' => $f->nazwa])
->all();
}blokPromptu#
public function blokPromptu(int $userId): arrayLinie tekstu dopisywane do promptu każdej tury czatu tej osoby. Tak moduł mówi czatowi, co może zrobić dla użytkownika. Pusta tablica = nic. Trzymajcie to krótko: te linie idą z każdą wiadomością.
public function blokPromptu(int $userId): array
{
$ile = Faktura::where('user_id', $userId)->where('status', 'nowa')->count();
if ($ile === 0) {
return [];
}
return ["Użytkownik ma {$ile} nowych faktur kosztowych w module Faktury kosztowe (adres: /narzedzia/faktury-kosztowe)."];
}uzycie#
public function uzycie(): ?arraySkąd karta modułu w Modułach liczy „kto i kiedy korzystał”. null = nie liczymy.
public function uzycie(): ?array
{
return [
'tabela' => 'faktury_kosztowe', // własna tabela modułu
'czas' => 'created_at', // kolumna z datą
'co' => 'faktur', // „12 faktur”
'kto' => 'user_id', // kolumna z id autora, domyślnie user_id
// 'warunek' => ['status' => 'zatwierdzona'],
];
}modeleAdresow#
public function modeleAdresow(): arrayModele z kolumną adres, które zajmują krótkie adresy /<adres> we wspólnej przestrzeni portalu. Dzięki temu AdresyPubliczne::zajety() nie wyda tego samego adresu dwóm modułom.
public function modeleAdresow(): array
{
return [Oferta::class];
}pokazAdres#
public function pokazAdres(Request $request, string $adres): mixedWejście na https://<instancja>/<adres> metodą GET, bez logowania. Portal pyta po kolei włączone moduły. Zwracacie odpowiedź albo null, gdy adres nie jest Wasz. O tym, kto może zobaczyć rekord, decydujecie sami.
public function pokazAdres(Request $request, string $adres): mixed
{
$oferta = Oferta::where('adres', $adres)->first();
if (! $oferta) {
return null;
}
abort_unless($oferta->opublikowana, 404);
return view('faktury_kosztowe::oferta', compact('oferta'));
}wyslijNaAdres#
public function wyslijNaAdres(Request $request, string $adres): mixedWysłanie na /<adres> metodą POST, bez logowania, z limitem 10 wysłań na minutę. Zwracacie odpowiedź albo null. Walidujcie wszystko, co przychodzi.
public function wyslijNaAdres(Request $request, string $adres): mixed
{
$oferta = Oferta::where('adres', $adres)->where('opublikowana', true)->first();
if (! $oferta) {
return null;
}
$dane = $request->validate(['email' => 'required|email|max:190', 'pytanie' => 'required|string|max:5000']);
$oferta->pytania()->create($dane);
return back()->with('status', 'Dziękujemy, odpowiemy mailem.');
}harmonogram#
public function harmonogram(Schedule $schedule): voidZadania cykliczne. Portal woła ten hak tylko dla włączonych modułów.
public function harmonogram(Schedule $schedule): void
{
$schedule->command('faktury-kosztowe:importuj')->dailyAt('06:00')->withoutOverlapping();
}Komendę artisan piszecie w src/ i wpisujecie jej klasę w komendy manifestu. Nazwę komendy zacznijcie od klucza modułu.
Ostatnia zmiana dokumentacji: 29.09.2026. Pytania: m@redai.pl.