final 1.2.3 - file sh per generare zip

This commit is contained in:
2026-06-07 20:56:38 +02:00
parent f9c1268466
commit cd10d100ec
2442 changed files with 158 additions and 325423 deletions
+2 -1
View File
@@ -1,2 +1,3 @@
glastree-image.tar
glastree*.tar.gz
glastree*.tar
.env
+59 -50
View File
@@ -1,61 +1,70 @@
# 🧠 MEMORY.md — Stato Progetto
## Goal
- Risolvere login non funzionante dopo fresh install (causa: tinker senza escaping + `2>/dev/null`)
- Sostituire tinker per creazione admin con PDO prepared statement + SQL file per schema
- Implementare page-length selector su liste (Individui, Eventi, Email)
- Implementare CSV import per gruppi
- Implementare ICS import per eventi
- Creare script build-dist.sh per distribuzione
## Constraints & Preferences
- Laravel 13, PHP 8.4, AdminLTE 4, MySQL/MariaDB (install.sql solo MySQL)
- Zero placeholder, zero TODO, codice funzionante
- Compatibilità cross-DB MySQL ↔ SQLite (fallback migration per SQLite)
## Modifiche Effettuate (10 file + 3 nuovi)
## Progress
### Done
- **Creazione `database/install.sql`** — schema MySQL completo + seed data (~1059 righe):
- Tutte le 45 tabelle nello stato finale (consolidate da 58 migration)
- Seed: 119 diocesi, 54 comuni, 8 tipologie documenti, 8 tipologie eventi, 8 ruoli, 23 permessi Spatie, 2 ruoli Spatie, 3 role preset, 5 email folders, 1 riga app_settings
- **NON contiene l'admin** (creato via PDO da install.php)
- `SET FOREIGN_KEY_CHECKS=0` per ordine tabelle, riattivato alla fine
- **Riscritto `install.php`** — eliminata dipendenza da tinker per la creazione admin:
- Aggiunta funzione `createAdminUser()`: PDO prepared statement + `password_hash()` + Spatie role assignment
- Fresh Install Apache: importa `install.sql` via `mysql` CLI, poi crea admin via PDO
- Fresh Install Docker: copia `install.sql` nel container, importa via mysql CLI, crea admin via script PHP temporaneo con `var_export()` (safe)
- Restore: crea admin via PDO se non esiste
- Fallback SQLite: mantiene `php artisan migrate --seed` + tinker ma con `var_export()` per escaping
- Step 5 rinominato da "MIGRATION E SEED" a "SCHEMA DATABASE E DATI BASE"
- Step 6 usa PDO invece di tinker (MySQL)
- **Unified MySQL setup**: singolo tentativo PDO con `dbname` nel DSN — se fallisce (1044/1045/1049), passa automaticamente in root-mode: chiede password root, crea database + utente + GRANT ALL su `localhost` e `%`
- **Sostituito loop 30-retry** con connessione singola PDO (timeout 5s)
- **Fix parse error**: `\$adminName``$adminName` in `var_export()` nel ramo SQLite
- **Fix composer**: rimosso `sudo -u www-data` da composer (causa git dubious ownership + permission denied), aggiunto `COMPOSER_ROOT_VERSION=dev-main`; `vendor` aggiunto al chown finale
### File modificati
| File | Cosa |
|------|------|
| `app/Http/Controllers/IndividuoController.php` | perPage support (20 default, clamp [10,20,25,50,100]) |
| `app/Http/Controllers/EventoController.php` | perPage + importIcs/importIcsStore (Sabre\VObject) |
| `app/Http/Controllers/GruppoController.php` | import/importStore/downloadTemplate CSV gruppi |
| `app/Http/Controllers/EmailController.php` | perPage support |
| `app/Models/Evento.php` | `uid_esterno` aggiunto a $fillable (bug fix) |
| `resources/views/individui/index.blade.php` | dropdown perPage in card-footer |
| `resources/views/eventi/index.blade.php` | dropdown perPage + pulsante Importa ICS |
| `resources/views/gruppi/index.blade.php` | pulsante Importa CSV |
| `resources/views/email/index.blade.php` | dropdown perPage in card-footer |
| `routes/web.php` | route gruppi/import, gruppi/template, eventi/import |
### In Progress
- *(nessuno)*
### File nuovi
| File | Cosa |
|------|------|
| `resources/views/gruppi/import.blade.php` | form upload CSV gruppi |
| `resources/views/eventi/import.blade.php` | form upload ICS eventi |
| `build-dist.sh` | script build distribuzione |
### Blocked
- *(nessuno)*
## Feature
## Key Decisions
- **PDO > tinker**: `createAdminUser()` usa PDO prepared statement con `password_hash()`, niente interpolazione PHP in stringhe shell → zero escaping issues
- **`install.sql` > migration sequenziali**: unico file SQL per fresh install, più veloce e debuggabile (si può lanciare `mysql < install.sql` a mano)
- **`var_export()` per tinker fallback**: nei rari casi SQLite, si usa `var_export()` che produce stringhe PHP valide con escaping automatico
- **`2>/dev/null` rimosso** dal MySQL main path (non serve più, non c'è tinker)
- **Docker MySQL credenziali**: hardcoded `mysql:glastree:secret:glastree` (dal docker-compose.mysql.yml)
- **Composer senza sudo**: `COMPOSER_ROOT_VERSION=dev-main` per evitare git dubious ownership; composer eseguito come utente corrente (root), non più come www-data — dopo, `chown -R www-data vendor` per permessi lettura webserver
- **Unified MySQL setup**: PDO connect con `dbname` nel DSN → se fallisce 1044/1045/1049, root-mode: crea DB + utente + GRANT ALL su `localhost` e `%` + FLUSH
### 1. Page-length selector
- **3 pagine**: Individui, Eventi, Email
- **Valori**: 10, 20, 25, 50, 100 (default 20)
- Dropdown nel card-footer con hidden fields per preservare altri query param
## Next Steps
- *(nessuno)*
### 2. CSV Import Gruppi
- Stesso pattern di `IndividuoController` (import GET, importStore POST, downloadTemplate GET)
- Colonne: nome, descrizione, parent_id, diocesi_id, indirizzo_incontro, cap_incontro, città_incontro, sigla_provincia_incontro
- Fault-tolerant: skip righe vuote, log errori
## Critical Context
- `install.sql` è solo per MySQL. SQLite usa `php artisan migrate --seed` + `DatabaseSeeder`
- `DatabaseSeeder` crea ancora admin `admin@glastree.local / password` ma per MySQL viene cancellato dal PDO script
- `createAdminUser()` setta `is_admin=1`, `status='active'`, `permissions` completo, `role_preset_id=1`, e Spatie `model_has_roles` con role_id=1
- `password_hash($pass, PASSWORD_BCRYPT)` produce hash `$2y$...` compatibile con `Hash::check()` di Laravel
- Composer ora eseguito come utente corrente (root) con `COMPOSER_ROOT_VERSION=dev-main` per evitare git dubious ownership e permission denied su `vendor/`
- `vendor/` aggiunto al `chown` finale in entrambi i modi (Apache e Restore) per garantire leggibilità da www-data
- `ensureMysqlUserAndDb()` sanitizza input (rimuove `' " \0 \`) prima di passarli a SQL exec
### 3. ICS Import Eventi
- Usa `Sabre\VObject\Reader::read()` già in vendor/
- Mapping: SUMMARY→nome_evento, DESCRIPTION→descrizione, DTSTART→data_specifica+ora_inizio, DTEND→durata_minuti, LOCATION→luogo_indirizzo, UID→uid_esterno
- Dedup via uid_esterno
- RRULE: import come evento singolo con prima occorrenza
## Relevant Files
- `database/install.sql`: NEW — schema MySQL completo + seed data (1059 righe)
- `install.php`: MODIFIED — `createAdminUser()` + `ensureMysqlUserAndDb()` + composer fix + auto-create MySQL user
### 4. Script build-dist.sh
- Genera `glastree-YYYYMMDD_HHMM.tar.gz` (~26MB)
- Include: sorgenti, vendor (production), Dockerfile, docker-compose, install.php, install.sql
- Esclude: .git, node_modules, tests, cache, storage content, vendor/docs/tests
## Installazione su server remoto
```bash
# Estrarre
tar xzf glastree-20260607_2052.tar.gz
# Configurare
cp .env.example .env
php artisan key:generate
php artisan storage:link
# Opzione A — Docker
docker compose up -d
# Opzione B — Apache nativo (MySQL)
php install.php
```
Executable
+73
View File
@@ -0,0 +1,73 @@
#!/bin/bash
set -euo pipefail
NAME="${APP_NAME:-glastree}"
VERSION="$(date +%Y%m%d_%H%M)"
ARCHIVE="${NAME}-${VERSION}.tar.gz"
echo "==> Installazione dipendenze PHP production..."
composer install --no-dev --optimize-autoloader --no-scripts --quiet
echo " OK"
echo "==> Build asset Vite..."
if [ -f "node_modules/.package-lock.json" ] || [ -d "node_modules" ]; then
npm run build --quiet 2>/dev/null && echo " OK" || echo " (skip — node_modules non presente)"
else
echo " (skip — node_modules assente, build Vite non eseguita)"
fi
echo "==> Pulizia cache..."
rm -rf bootstrap/cache/*.php storage/framework/cache/data/* storage/framework/sessions/* storage/framework/views/* storage/logs/* 2>/dev/null || true
echo " OK"
echo "==> Creazione archivio: ${ARCHIVE}"
tar czf "${ARCHIVE}" \
--exclude='.git' \
--exclude='.gitignore' \
--exclude='.env' \
--exclude='.env.example' \
--exclude='node_modules' \
--exclude='tests' \
--exclude='vendor/bin' \
--exclude='vendor/*/tests' \
--exclude='vendor/*/test' \
--exclude='vendor/*/.git' \
--exclude='vendor/*/docs' \
--exclude='vendor/*/doc' \
--exclude='storage/app/backups' \
--exclude='storage/app/documenti' \
--exclude='storage/framework/cache' \
--exclude='storage/framework/sessions' \
--exclude='storage/framework/views' \
--exclude='storage/logs' \
--exclude='storage/debugbar' \
--exclude='bootstrap/cache/*.php' \
--exclude='public/hot' \
--exclude='*.tar.gz' \
--exclude='*.tar' \
--exclude='MEMORY.md' \
--exclude='AGENTS.md' \
--exclude='build-dist.sh' \
--exclude='Dockerfile' \
--exclude='docker-compose.yml' \
--exclude='docker-compose.mysql.yml' \
--exclude='docker-entrypoint.sh' \
--exclude='.dockerignore' \
--warning=no-file-changed \
.
echo ""
echo "============================================"
echo " Archivio creato: ${ARCHIVE}"
echo " Dimensione: $(du -h "${ARCHIVE}" | cut -f1)"
echo "============================================"
echo ""
echo "Per estrarre sul server di destinazione:"
echo " tar xzf ${ARCHIVE}"
echo ""
echo "Poi esegui:"
echo " cp .env.example .env # configura il tuo ambiente"
echo " php artisan key:generate"
echo " php artisan storage:link"
echo " php install.php # avvia installazione MySQL"
@@ -1,418 +0,0 @@
<?php $__env->startSection('title', 'Report'); ?>
<?php $__env->startSection('page_title', 'Report e Statistiche'); ?>
<?php $__env->startSection('styles'); ?>
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/select2-bootstrap4-theme@1.0.0/dist/select2-bootstrap4.min.css" rel="stylesheet" />
<style>
.select2-container--bootstrap4 .select2-selection--multiple .select2-selection__choice {
font-size: 0.8rem;
}
.card-indigo {
border-top: 3px solid #6610f2;
}
.card-indigo .card-title {
color: #6610f2;
}
.accordion .card-header .btn-link {
text-decoration: none;
font-weight: 600;
color: #495057;
}
.accordion .card-header .btn-link:hover {
color: #007bff;
}
.accordion .card-header .btn-link i {
transition: transform 0.2s ease;
width: 20px;
}
.accordion .card-header .btn-link[aria-expanded="true"] i.fa-chevron-right {
transform: rotate(90deg);
}
</style>
<?php $__env->stopSection(); ?>
<?php $__env->startSection('content'); ?>
<?php if(session('success')): ?>
<div class="alert alert-success alert-dismissible">
<button type="button" class="close" data-dismiss="alert">&times;</button>
<?php echo e(session('success')); ?>
</div>
<?php endif; ?>
<?php if(session('error')): ?>
<div class="alert alert-danger alert-dismissible">
<button type="button" class="close" data-dismiss="alert">&times;</button>
<?php echo e(session('error')); ?>
</div>
<?php endif; ?>
<div class="accordion" id="reportAccordion">
<div class="card">
<div class="card-header" id="headingOne">
<h2 class="mb-0">
<button class="btn btn-link btn-block text-left" type="button" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
<i class="fas fa-chevron-down mr-2 text-primary"></i>
<i class="fas fa-chart-bar mr-2 text-primary"></i> Panoramica Database
</button>
</h2>
</div>
<div id="collapseOne" class="collapse show" aria-labelledby="headingOne" data-parent="#reportAccordion">
<div class="card-body">
<div class="row">
<div class="col-md-2 col-4 text-center">
<div class="info-box">
<span class="info-box-icon bg-info"><i class="fas fa-users"></i></span>
<div class="info-box-content">
<span class="info-box-text">Individui</span>
<span class="info-box-number"><?php echo e(number_format($stats['individui'])); ?></span>
</div>
</div>
</div>
<div class="col-md-2 col-4 text-center">
<div class="info-box">
<span class="info-box-icon bg-warning"><i class="fas fa-folder"></i></span>
<div class="info-box-content">
<span class="info-box-text">Gruppi</span>
<span class="info-box-number"><?php echo e(number_format($stats['gruppi'])); ?></span>
</div>
</div>
</div>
<div class="col-md-2 col-4 text-center">
<div class="info-box">
<span class="info-box-icon bg-danger"><i class="fas fa-calendar"></i></span>
<div class="info-box-content">
<span class="info-box-text">Eventi</span>
<span class="info-box-number"><?php echo e(number_format($stats['eventi'])); ?></span>
</div>
</div>
</div>
<div class="col-md-2 col-4 text-center">
<div class="info-box">
<span class="info-box-icon bg-secondary"><i class="fas fa-file"></i></span>
<div class="info-box-content">
<span class="info-box-text">Documenti</span>
<span class="info-box-number"><?php echo e(number_format($stats['documenti'])); ?></span>
</div>
</div>
</div>
<div class="col-md-2 col-4 text-center">
<div class="info-box">
<span class="info-box-icon bg-purple"><i class="fas fa-list"></i></span>
<div class="info-box-content">
<span class="info-box-text">Mailing List</span>
<span class="info-box-number"><?php echo e(number_format($stats['mailing_liste'])); ?></span>
</div>
</div>
</div>
<div class="col-md-2 col-4 text-center">
<div class="info-box">
<span class="info-box-icon bg-teal"><i class="fas fa-address-book"></i></span>
<div class="info-box-content">
<span class="info-box-text">Contatti</span>
<span class="info-box-number"><?php echo e(number_format($stats['contatti'])); ?></span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-header" id="headingTwo">
<h2 class="mb-0">
<button class="btn btn-link btn-block text-left collapsed" type="button" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
<i class="fas fa-chevron-right mr-2 text-warning"></i>
<i class="fas fa-chart-pie mr-2 text-warning"></i> Report Predefiniti
<span class="badge badge-warning badge-pill ml-2"><?php echo e(count($prebuiltReports)); ?></span>
</button>
</h2>
</div>
<div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#reportAccordion">
<div class="card-body">
<div class="row">
<?php $__currentLoopData = $prebuiltReports; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $report): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<div class="col-md-4 col-lg-3 mb-3">
<?php
$cardColor = $report['colore'] === 'indigo' ? 'card-indigo' : 'card-' . $report['colore'];
$btnColor = $report['colore'] === 'indigo' ? 'primary' : $report['colore'];
?>
<div class="card <?php echo e($cardColor); ?> card-outline h-100">
<div class="card-body text-center d-flex flex-column">
<i class="fas <?php echo e($report['icona']); ?> fa-3x text-<?php echo e($btnColor); ?> mb-3"></i>
<h5><?php echo e($report['nome']); ?></h5>
<p class="text-muted small mb-3 flex-grow-1"><?php echo e($report['descrizione']); ?></p>
<?php if($report['has_tipologia_filter'] ?? false): ?>
<form action="<?php echo e(route('report.run')); ?>" method="GET" class="mb-2">
<div class="form-group mb-2">
<select name="tipologia_documento" class="form-control form-control-sm select2-tipologia" style="width: 100%;">
<option value="">Tutte le tipologie</option>
<?php $__currentLoopData = $tipologieDocumento; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $tipologia): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<option value="<?php echo e($tipologia); ?>"><?php echo e(ucfirst($tipologia)); ?></option>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</select>
</div>
<input type="hidden" name="report" value="<?php echo e($report['id']); ?>">
<div class="btn-group btn-group-sm w-100">
<button type="submit" class="btn btn-sm btn-<?php echo e($btnColor); ?>">
<i class="fas fa-play mr-1"></i> Genera
</button>
<a href="<?php echo e(route('report.export', ['report' => $report['id']])); ?>" class="btn btn-sm btn-outline-<?php echo e($btnColor); ?>">
<i class="fas fa-download mr-1"></i> CSV
</a>
</div>
</form>
<?php else: ?>
<div class="btn-group btn-group-sm w-100">
<a href="<?php echo e(route('report.run', ['report' => $report['id']])); ?>" class="btn btn-sm btn-<?php echo e($btnColor); ?>">
<i class="fas fa-play mr-1"></i> Genera
</a>
<a href="<?php echo e(route('report.export', ['report' => $report['id']])); ?>" class="btn btn-sm btn-outline-<?php echo e($btnColor); ?>">
<i class="fas fa-download mr-1"></i> CSV
</a>
</div>
<?php endif; ?>
</div>
</div>
</div>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-header" id="headingThree">
<h2 class="mb-0">
<button class="btn btn-link btn-block text-left collapsed" type="button" data-toggle="collapse" data-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
<i class="fas fa-chevron-right mr-2 text-info"></i>
<i class="fas fa-bookmark mr-2 text-info"></i> Report Personalizzati
<span class="badge badge-info badge-pill ml-2"><?php echo e($customReports->count()); ?></span>
</button>
</h2>
</div>
<div id="collapseThree" class="collapse" aria-labelledby="headingThree" data-parent="#reportAccordion">
<div class="card-body">
<div class="row">
<div class="col-md-8">
<?php if($customReports->count() > 0): ?>
<table class="table table-striped mb-0">
<thead>
<tr>
<th>Nome</th>
<th>Tipo</th>
<th>Creato il</th>
<th style="width: 140px;">Azioni</th>
</tr>
</thead>
<tbody>
<?php $__currentLoopData = $customReports; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $report): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<tr>
<td>
<i class="fas fa-chart-line text-primary mr-1"></i>
<?php echo e($report->nome); ?>
</td>
<td><span class="badge badge-info"><?php echo e(ucfirst($report->tipo_report)); ?></span></td>
<td><?php echo e($report->created_at->format('d/m/Y H:i')); ?></td>
<td>
<a href="<?php echo e(route('report.run', ['custom_id' => $report->id])); ?>" class="btn btn-xs btn-success" title="Esegui">
<i class="fas fa-play"></i>
</a>
<a href="<?php echo e(route('report.export', ['custom_id' => $report->id])); ?>" class="btn btn-xs btn-info" title="Esporta CSV">
<i class="fas fa-file-csv"></i>
</a>
<form action="<?php echo e(route('report.destroy-custom', $report->id)); ?>" method="POST" class="d-inline">
<?php echo csrf_field(); ?> <?php echo method_field('DELETE'); ?>
<button type="submit" class="btn btn-xs btn-danger" onclick="return confirm('Eliminare questo report?')" title="Elimina">
<i class="fas fa-trash"></i>
</button>
</form>
</td>
</tr>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</tbody>
</table>
<?php else: ?>
<div class="text-center text-muted py-4">
<i class="fas fa-chart-line fa-3x mb-3"></i>
<p>Nessun report personalizzato creato.</p>
</div>
<?php endif; ?>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-header bg-primary">
<h3 class="card-title text-white"><i class="fas fa-plus mr-2"></i>Crea Report Personalizzato</h3>
</div>
<div class="card-body">
<form action="<?php echo e(route('report.store-custom')); ?>" method="POST">
<?php echo csrf_field(); ?>
<div class="form-group">
<label>Nome Report *</label>
<input type="text" name="nome" class="form-control" required placeholder="Es: Individui attivi">
</div>
<div class="form-group">
<label>Descrizione</label>
<textarea name="descrizione" class="form-control" rows="2" placeholder="Descrizione opzionale..."></textarea>
</div>
<div class="form-group">
<label>Tipo Dato *</label>
<select name="tipo_report" id="tipo_report" class="form-control" required>
<option value="">Seleziona...</option>
<?php $__currentLoopData = $columnOptions; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $type => $columns): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<option value="<?php echo e($type); ?>"><?php echo e(ucfirst($type)); ?></option>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</select>
</div>
<div class="form-group">
<label>Colonne *</label>
<select name="columns[]" id="columns_select" class="form-control select2-multi" multiple style="width: 100%;">
</select>
<small class="text-muted">Seleziona le colonne da includere nel report</small>
</div>
<div class="form-group">
<label>Ordina per</label>
<select name="sort_by" id="sort_by" class="form-control">
<option value="">Nessun ordinamento</option>
</select>
</div>
<div class="form-group">
<label>Direzione ordinamento</label>
<select name="sort_direction" class="form-control">
<option value="asc">Ascendente (A-Z)</option>
<option value="desc" selected>Discendente (Z-A)</option>
</select>
</div>
<div class="form-group">
<label>Limite risultati</label>
<input type="number" name="limit" class="form-control" placeholder="Es: 100" min="1">
</div>
<button type="submit" class="btn btn-primary btn-block">
<i class="fas fa-save mr-1"></i> Salva Report
</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<?php $__env->stopSection(); ?>
<?php $__env->startSection('scripts'); ?>
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
const columnOptions = <?php echo json_encode($columnOptions, 15, 512) ?>;
let columnsSelectInitialized = false;
function initTipologiaSelect2(container) {
$(container).find('.select2-tipologia').select2({
theme: 'bootstrap4',
placeholder: 'Filtra per tipologia...',
allowClear: true,
width: '100%',
});
}
function destroyTipologiaSelect2(container) {
$(container).find('.select2-tipologia').select2('destroy');
}
function initColumnsSelect2() {
if (columnsSelectInitialized) return;
$('#columns_select').select2({
theme: 'bootstrap4',
placeholder: 'Seleziona le colonne...',
allowClear: true,
width: '100%',
});
columnsSelectInitialized = true;
}
function destroyColumnsSelect2() {
if (!columnsSelectInitialized) return;
$('#columns_select').select2('destroy');
columnsSelectInitialized = false;
}
function getSortOptions(tipoReport) {
const cols = columnOptions[tipoReport] || {};
const options = [];
for (const [key, col] of Object.entries(cols)) {
if (col.type !== 'relation') {
options.push({ value: key, label: col.label });
}
}
return options;
}
$('#collapseTwo').on('shown.bs.collapse', function () {
initTipologiaSelect2(this);
}).on('hidden.bs.collapse', function () {
destroyTipologiaSelect2(this);
});
$('#collapseThree').on('shown.bs.collapse', function () {
initColumnsSelect2();
}).on('hidden.bs.collapse', function () {
destroyColumnsSelect2();
});
if ($('#collapseTwo').hasClass('show')) {
initTipologiaSelect2(document);
}
if ($('#collapseThree').hasClass('show')) {
initColumnsSelect2();
}
$('#tipo_report').on('change', function() {
const tipo = this.value;
const $select = $('#columns_select');
if (columnsSelectInitialized) {
$select.empty().trigger('change');
}
$select.empty();
if (tipo && columnOptions[tipo]) {
const cols = columnOptions[tipo];
const fragment = document.createDocumentFragment();
for (const [key, col] of Object.entries(cols)) {
fragment.appendChild(new Option(col.label, key, false, false));
}
$select.append(fragment);
}
if (columnsSelectInitialized) {
$select.trigger('change');
}
const $sortBy = $('#sort_by');
$sortBy.empty();
$sortBy.append(new Option('Nessun ordinamento', '', false, false));
const sortOptions = getSortOptions(tipo);
sortOptions.forEach(function(opt) {
$sortBy.append(new Option(opt.label, opt.value, false, false));
});
});
if ($('#tipo_report').val()) {
$('#tipo_report').trigger('change');
}
});
</script>
<?php $__env->stopSection(); ?>
<?php echo $__env->make('layouts.adminlte', array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?><?php /**PATH /var/www/html/glastree/resources/views/report/index.blade.php ENDPATH**/ ?>
@@ -1,65 +0,0 @@
<?php $__env->startSection('title', 'Importa Gruppi'); ?>
<?php $__env->startSection('page_title', 'Importa Gruppi da CSV'); ?>
<?php $__env->startSection('content'); ?>
<div class="row">
<div class="col-md-8">
<div class="card">
<div class="card-header">
<h3 class="card-title"><i class="fas fa-upload mr-2"></i>Carica file CSV</h3>
</div>
<div class="card-body">
<form action="<?php echo e(route('gruppi.import.store')); ?>" method="POST" enctype="multipart/form-data">
<?php echo csrf_field(); ?>
<div class="form-group">
<label for="file">Seleziona file CSV *</label>
<input type="file" name="file" id="file" class="form-control" accept=".csv,.txt" required>
<small class="form-text text-muted">
Il file deve essere in formato CSV con separatore virgola.
</small>
</div>
<button type="submit" class="btn btn-primary">
<i class="fas fa-upload mr-1"></i> Importa
</button>
<a href="<?php echo e(route('gruppi.index')); ?>" class="btn btn-secondary ml-2">
Annulla
</a>
</form>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-header bg-info">
<h3 class="card-title text-white"><i class="fas fa-download mr-2"></i>Template</h3>
</div>
<div class="card-body">
<p>Scarica il template CSV per l'importazione:</p>
<a href="<?php echo e(route('gruppi.template')); ?>" class="btn btn-success btn-block">
<i class="fas fa-file-csv mr-1"></i> Scarica Template
</a>
</div>
</div>
<div class="card mt-3">
<div class="card-header">
<h3 class="card-title"><i class="fas fa-info-circle mr-2"></i>Formato CSV</h3>
</div>
<div class="card-body">
<h6>Campi:</h6>
<ul>
<li><code>nome</code> (obbligatorio)</li>
<li><code>descrizione</code></li>
<li><code>parent_id</code> (ID del gruppo padre)</li>
<li><code>diocesi_id</code> (ID della diocesi)</li>
<li><code>indirizzo_incontro</code></li>
<li><code>cap_incontro</code></li>
<li><code>città_incontro</code></li>
<li><code>sigla_provincia_incontro</code> (2 lettere)</li>
</ul>
</div>
</div>
</div>
</div>
<?php $__env->stopSection(); ?>
<?php echo $__env->make('layouts.adminlte', array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?><?php /**PATH /var/www/html/glastree/resources/views/gruppi/import.blade.php ENDPATH**/ ?>
@@ -1,371 +0,0 @@
<?php $__env->startSection('title', 'Email - ' . ucfirst($folder)); ?>
<?php $__env->startSection('page_title', 'Email'); ?>
<?php
$currentFolder = $folders->firstWhere('type', $folder);
?>
<?php $__env->startSection('content'); ?>
<div class="card">
<div class="card-header">
<h3 class="card-title"><i class="fas fa-envelope mr-2"></i>Email</h3>
<div class="card-tools">
<div class="btn-group mr-2">
<?php $__currentLoopData = $folders; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $f): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<a href="<?php echo e(route('email.index', $f->type)); ?>"
class="btn btn-xs <?php echo e($folder === $f->type ? 'btn-primary' : 'btn-default'); ?>">
<i class="fas <?php echo e($f->icon); ?>"></i>
<?php echo e($f->name); ?>
<?php if($f->type === 'inbox' && $messages->where('is_read', false)->count() > 0): ?>
<span class="badge badge-light"><?php echo e($messages->where('is_read', false)->count()); ?></span>
<?php endif; ?>
</a>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</div>
<a href="<?php echo e(route('email.compose')); ?>" class="btn btn-success btn-xs">
<i class="fas fa-plus"></i> Nuova Email
</a>
<button class="btn btn-primary btn-xs" onclick="syncEmails()" id="syncBtn">
<i class="fas fa-sync"></i> Ricevi/Invia
</button>
</div>
</div>
<div class="card-body p-0">
<div class="card-header pb-0">
<div class="row align-items-center">
<div class="col-md-6">
<div class="form-inline">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="selectAll" onchange="toggleAll(this)">
<label class="custom-control-label" for="selectAll">Seleziona tutto</label>
</div>
<span class="ml-3 text-muted" id="selectedCount">0 selezionati</span>
</div>
</div>
<div class="col-md-6">
<div class="input-group input-group-sm float-right" style="width: 220px;">
<select class="form-control" id="bulkAction">
<option value="">Azioni di massa...</option>
<?php if($folder !== 'trash'): ?>
<option value="mark_read">Marca come letto</option>
<option value="mark_unread">Marca come non letto</option>
<option value="star">Aggiungi a preferiti</option>
<option value="unstar">Rimuovi da preferiti</option>
<option value="move_trash">Sposta nel cestino</option>
<?php else: ?>
<option value="empty_trash">Svuota cestino</option>
<?php endif; ?>
</select>
<div class="input-group-append">
<button class="btn btn-secondary" type="button" onclick="executeBulkAction()">Applica</button>
</div>
</div>
</div>
</div>
</div>
<div class="table-responsive">
<table class="table table-hover table-striped">
<thead>
<tr>
<th style="width: 30px;"></th>
<th style="width: 30px;"></th>
<th style="width: 150px;">
<?php $sort = request('sort'); $dir = request('direction'); ?>
<?php if($folder === 'sent' || $folder === 'inviate'): ?>
<a href="<?php echo e(request()->fullUrlWithQuery(['sort' => 'to_email', 'direction' => $sort === 'to_email' && $dir === 'asc' ? 'desc' : 'asc'])); ?>" class="text-dark text-decoration-none">
Destinatario <?php echo $sort === 'to_email' ? ($dir === 'asc' ? '▲' : '▼') : ''; ?>
</a>
<?php else: ?>
<a href="<?php echo e(request()->fullUrlWithQuery(['sort' => 'from_email', 'direction' => $sort === 'from_email' && $dir === 'asc' ? 'desc' : 'asc'])); ?>" class="text-dark text-decoration-none">
Mittente <?php echo $sort === 'from_email' ? ($dir === 'asc' ? '▲' : '▼') : ''; ?>
</a>
<?php endif; ?>
</th>
<th>
<a href="<?php echo e(request()->fullUrlWithQuery(['sort' => 'subject', 'direction' => $sort === 'subject' && $dir === 'asc' ? 'desc' : 'asc'])); ?>" class="text-dark text-decoration-none">
Oggetto <?php echo $sort === 'subject' ? ($dir === 'asc' ? '▲' : '▼') : ''; ?>
</a>
</th>
<th style="width: 120px;">
<a href="<?php echo e(request()->fullUrlWithQuery(['sort' => 'received_at', 'direction' => $sort === 'received_at' && $dir === 'asc' ? 'desc' : 'asc'])); ?>" class="text-dark text-decoration-none">
Data <?php echo $sort === 'received_at' ? ($dir === 'asc' ? '▲' : '▼') : ''; ?>
</a>
</th>
</tr>
</thead>
<tbody>
<?php $__empty_1 = true; $__currentLoopData = $messages; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $message): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_1 = false; ?>
<tr class="<?php echo e($message->is_read ? '' : 'font-weight-bold'); ?>">
<td style="width: 30px;" onclick="event.stopPropagation()">
<input type="checkbox" class="email-checkbox" value="<?php echo e($message->id); ?>" onchange="updateCount()">
</td>
<td style="width: 30px;" onclick="event.stopPropagation(); window.location='<?php echo e(route('email.show', [$folder, $message->id])); ?>'">
<?php if($message->is_starred): ?>
<i class="fas fa-star text-warning"></i>
<?php endif; ?>
</td>
<td onclick="window.location='<?php echo e(route('email.show', [$folder, $message->id])); ?>'">
<?php echo e($message->is_sent ? 'A: ' . $message->to_email : ($message->from_name ?: $message->from_email)); ?>
</td>
<td onclick="window.location='<?php echo e(route('email.show', [$folder, $message->id])); ?>'">
<?php echo e($message->subject ?? '(senza oggetto)'); ?>
</td>
<td>
<?php if($message->received_at): ?>
<?php echo e($message->received_at->format('d/m/Y')); ?>
<?php elseif($message->sent_at): ?>
<?php echo e($message->sent_at->format('d/m/Y')); ?>
<?php endif; ?>
</td>
</tr>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); if ($__empty_1): ?>
<tr>
<td colspan="5" class="text-center text-muted py-4">
<i class="fas fa-inbox fa-2x mb-2"></i>
<p>Nessuna email</p>
</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
<div class="card-footer d-flex justify-content-between align-items-center">
<div>
<form method="GET" class="form-inline" id="perPageForm">
<label class="mr-2 small">Righe per pagina:</label>
<select name="perPage" class="form-control form-control-sm" onchange="this.form.submit()" style="width: auto;">
<?php $__currentLoopData = [10, 20, 25, 50, 100]; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $p): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<option value="<?php echo e($p); ?>" <?php echo e((int) request('perPage', 20) === $p ? 'selected' : ''); ?>><?php echo e($p); ?></option>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</select>
<?php $__currentLoopData = request()->except(['perPage', 'page']); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $key => $value): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<?php if(is_array($value)): ?>
<?php $__currentLoopData = $value; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $v): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<input type="hidden" name="<?php echo e($key); ?>[]" value="<?php echo e($v); ?>">
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
<?php else: ?>
<input type="hidden" name="<?php echo e($key); ?>" value="<?php echo e($value); ?>">
<?php endif; ?>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</form>
</div>
<div>
<?php echo e($messages->links('vendor.pagination.simple-bootstrap-4')); ?>
</div>
</div>
</div>
<?php $__env->stopSection(); ?>
<?php $__env->startPush('styles'); ?>
<style>
/* Bootstrap 4 Pagination override */
.pagination {
display: flex !important;
padding-left: 0;
list-style: none;
border-radius: 0.25rem;
margin: 0;
justify-content: center;
}
.page-item {
display: inline-block;
}
.page-link {
position: relative;
display: block;
padding: 0.5rem 0.75rem;
margin-left: -1px;
line-height: 1.25;
color: #007bff;
background-color: #fff;
border: 1px solid #dee2e6;
text-decoration: none;
font-size: 0.875rem;
}
.page-item.active .page-link {
z-index: 3;
color: #fff;
background-color: #007bff;
border-color: #007bff;
}
.page-item.disabled .page-link {
color: #6c757d;
pointer-events: none;
background-color: #fff;
border-color: #dee2e6;
}
.page-link:hover {
color: #0056b3;
background-color: #e9ecef;
border-color: #dee2e6;
}
/* Icons as text characters */
.pagination .page-link::before,
.pagination .page-link::after {
display: none;
}
</style>
<?php $__env->stopPush(); ?>
<?php if($syncInterval > 0 && $folder === 'inbox'): ?>
<?php $__env->startPush('scripts'); ?>
<script>
let syncInterval = <?php echo e($syncInterval * 60 * 1000); ?>;
let syncTimeout;
function autoSync() {
fetch('<?php echo e(url('email/sync/quick')); ?>', {
method: 'POST',
headers: {
'X-CSRF-TOKEN': '<?php echo e(csrf_token()); ?>',
'Content-Type': 'application/json'
}
}).then(() => {
console.log('Auto sync completed');
}).catch(() => {
console.log('Auto sync failed');
});
}
function startAutoSync() {
if (syncInterval > 0) {
syncTimeout = setInterval(autoSync, syncInterval);
}
}
function stopAutoSync() {
if (syncTimeout) {
clearInterval(syncTimeout);
}
}
document.addEventListener('DOMContentLoaded', function() {
startAutoSync();
document.addEventListener('visibilitychange', function() {
if (document.hidden) {
stopAutoSync();
} else {
startAutoSync();
}
});
});
</script>
<?php $__env->stopPush(); ?>
<?php endif; ?>
<?php $__env->startSection('scripts'); ?>
<script>
function toggleAll(checkbox) {
const checkboxes = document.querySelectorAll('.email-checkbox');
checkboxes.forEach(function(cb) {
cb.checked = checkbox.checked;
});
updateCount();
}
function updateCount() {
const checkboxes = document.querySelectorAll('.email-checkbox:checked');
document.getElementById('selectedCount').textContent = checkboxes.length + ' selezionati';
}
function executeBulkAction() {
const select = document.getElementById('bulkAction');
const action = select.value;
if (!action) {
alert('Seleziona un\'azione');
return;
}
if (action === 'empty_trash') {
if (!confirm('Sei sicuro di voler svuotare il cestino? Questa azione non è reversibile.')) {
return;
}
}
const checkboxes = document.querySelectorAll('.email-checkbox:checked');
if (action !== 'empty_trash' && checkboxes.length === 0) {
alert('Seleziona almeno una email');
return;
}
let ids = [];
if (action !== 'empty_trash') {
ids = Array.from(checkboxes).map(function(cb) {
return cb.value;
});
}
fetch('<?php echo e(route('email.bulk')); ?>', {
method: 'POST',
headers: {
'X-CSRF-TOKEN': '<?php echo e(csrf_token()); ?>',
'Content-Type': 'application/json'
},
body: JSON.stringify({ ids: ids, action: action })
}).then(function(response) {
return response.json();
}).then(function(data) {
if (data.success) {
// Reset checkboxes before reload to avoid ghost selection
document.querySelectorAll('.email-checkbox').forEach(function(cb) {
cb.checked = false;
});
document.getElementById('selectAll').checked = false;
updateCount();
window.location.href = window.location.href;
} else {
alert(data.message || 'Errore');
}
}).catch(function() {
alert('Errore');
});
}
function syncEmails() {
const btn = document.getElementById('syncBtn');
btn.disabled = true;
btn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Sincronizzazione...';
fetch('<?php echo e(url('email/sync/quick')); ?>', {
method: 'POST',
headers: {
'X-CSRF-TOKEN': '<?php echo e(csrf_token()); ?>',
'Content-Type': 'application/json'
}
}).then(function(response) {
return response.json();
}).then(function(data) {
if (data.success) {
location.reload();
} else {
alert(data.message || 'Errore durante la sincronizzazione');
btn.disabled = false;
btn.innerHTML = '<i class="fas fa-sync"></i> Ricevi/Invia';
}
}).catch(function(error) {
alert('Errore di connessione');
btn.disabled = false;
btn.innerHTML = '<i class="fas fa-sync"></i> Ricevi/Invia';
});
}
</script>
<?php $__env->stopSection(); ?>
<?php echo $__env->make('layouts.adminlte', array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?><?php /**PATH /var/www/html/glastree/resources/views/email/index.blade.php ENDPATH**/ ?>
@@ -1,441 +0,0 @@
<?php $__env->startSection('title', 'Gruppi'); ?>
<?php $__env->startSection('page_title', 'Elenco Gruppi'); ?>
<?php
$canWriteGruppi = Auth::user()->canManage('gruppi');
$canDeleteGruppi = Auth::user()->canDelete('gruppi');
$columnLabels = [
'nome' => 'Nome',
'descrizione' => 'Descrizione',
'diocesi' => 'Diocesi',
'livello' => 'Livello',
'padre' => 'Gruppo Padre',
'membri' => 'Membri',
'responsabili' => 'Responsabili',
'indirizzo' => 'Indirizzo',
'citta' => 'Città',
'telefono' => 'Telefono',
'email' => 'Email',
];
$vistaDefaultJson = $vista ? $vista->toJson() : 'null';
$allColumnsJson = json_encode($allColumns);
$visibleColumnsJson = json_encode($visibleColumns);
?>
<?php $__env->startSection('content'); ?>
<?php if(session('success')): ?>
<div class="alert alert-success alert-dismissible">
<button type="button" class="close" data-dismiss="alert">&times;</button>
<?php echo e(session('success')); ?>
</div>
<?php endif; ?>
<?php if(session('error')): ?>
<div class="alert alert-danger alert-dismissible">
<button type="button" class="close" data-dismiss="alert">&times;</button>
<?php echo e(session('error')); ?>
</div>
<?php endif; ?>
<div class="card">
<div class="card-header">
<h3 class="card-title"><i class="fas fa-sitemap mr-2"></i>Elenco Gruppi</h3>
<div class="card-tools">
<div class="btn-group mr-2">
<button type="button" class="btn btn-sm btn-outline-primary <?php echo e($viewMode === 'table' ? 'active' : ''); ?>" onclick="switchView('table')" id="btn-table-view">
<i class="fas fa-table mr-1"></i> Tabella
</button>
<button type="button" class="btn btn-sm btn-outline-primary <?php echo e($viewMode === 'tree' ? 'active' : ''); ?>" onclick="switchView('tree')" id="btn-tree-view">
<i class="fas fa-sitemap mr-1"></i> Albero
</button>
</div>
<button type="button" class="btn btn-primary btn-sm mr-1" onclick="showSaveVistaModal()">
<i class="fas fa-save mr-1"></i> Salva Vista
</button>
<?php if($canWriteGruppi): ?>
<a href="<?php echo e(route('gruppi.import')); ?>" class="btn btn-warning btn-sm mr-1">
<i class="fas fa-file-import mr-1"></i> Importa
</a>
<a href="<?php echo e(route('gruppi.create')); ?>" class="btn btn-success btn-sm">
<i class="fas fa-plus"></i> Nuovo Gruppo
</a>
<?php endif; ?>
</div>
</div>
<?php if($viewMode === 'table'): ?>
<div class="card-body p-0">
<table class="table table-bordered table-hover table-striped mb-0" id="gruppi-table">
<thead class="thead-light">
<tr>
<?php if(in_array('nome', $visibleColumns)): ?>
<th data-sortable="true" onclick="sortTable('nome')" style="cursor:pointer;">Nome <i class="fas fa-sort float-right text-muted"></i></th>
<?php endif; ?>
<?php if(in_array('descrizione', $visibleColumns)): ?>
<th data-sortable="true" onclick="sortTable('descrizione')" style="cursor:pointer;">Descrizione <i class="fas fa-sort float-right text-muted"></i></th>
<?php endif; ?>
<?php if(in_array('diocesi', $visibleColumns)): ?>
<th>Diocesi</th>
<?php endif; ?>
<?php if(in_array('livello', $visibleColumns)): ?>
<th style="width: 80px;">Livello</th>
<?php endif; ?>
<?php if(in_array('padre', $visibleColumns)): ?>
<th>Gruppo Padre</th>
<?php endif; ?>
<?php if(in_array('membri', $visibleColumns)): ?>
<th style="width: 100px;">Membri</th>
<?php endif; ?>
<?php if(in_array('responsabili', $visibleColumns)): ?>
<th>Responsabili</th>
<?php endif; ?>
<?php if(in_array('indirizzo', $visibleColumns)): ?>
<th>Indirizzo</th>
<?php endif; ?>
<?php if(in_array('citta', $visibleColumns)): ?>
<th>Città</th>
<?php endif; ?>
<?php if(in_array('telefono', $visibleColumns)): ?>
<th>Telefono</th>
<?php endif; ?>
<?php if(in_array('email', $visibleColumns)): ?>
<th>Email</th>
<?php endif; ?>
<th style="width: 120px;">Azioni</th>
</tr>
</thead>
<tbody id="table-body">
<?php $__currentLoopData = $gruppi; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $gruppo): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<tr data-id="<?php echo e($gruppo->id); ?>">
<?php if(in_array('nome', $visibleColumns)): ?>
<td>
<span style="padding-left: <?php echo e(($gruppo->depth ?? 0) * 20); ?>px;">
<i class="fas fa-<?php echo e($gruppo->children->count() > 0 ? 'folder' : 'folder-open'); ?> text-<?php echo e(($gruppo->depth ?? 0) == 0 ? 'warning' : 'secondary'); ?> mr-1"></i>
<a href="<?php echo e(route('gruppi.show', $gruppo->id)); ?>"><?php echo e($gruppo->nome); ?></a>
</span>
</td>
<?php endif; ?>
<?php if(in_array('descrizione', $visibleColumns)): ?>
<td><?php echo e(Str::limit($gruppo->descrizione, 50) ?: '-'); ?></td>
<?php endif; ?>
<?php if(in_array('diocesi', $visibleColumns)): ?>
<td><?php echo e($gruppo->diocesi?->nome ?? '-'); ?></td>
<?php endif; ?>
<?php if(in_array('livello', $visibleColumns)): ?>
<td><span class="badge badge-<?php echo e(($gruppo->depth ?? 0) == 0 ? 'primary' : 'secondary'); ?>"><?php echo e($gruppo->depth ?? 0); ?></span></td>
<?php endif; ?>
<?php if(in_array('padre', $visibleColumns)): ?>
<td><?php echo e($gruppo->parent?->nome ?? '-'); ?></td>
<?php endif; ?>
<?php if(in_array('membri', $visibleColumns)): ?>
<td><span class="badge badge-info"><?php echo e($gruppo->individui->count()); ?></span></td>
<?php endif; ?>
<?php if(in_array('responsabili', $visibleColumns)): ?>
<td>
<?php $resp = $gruppo->getResponsabili() ?>
<?php if($resp->count() > 0): ?>
<?php echo e($resp->pluck('cognome')->implode(', ')); ?>
<?php else: ?>
-
<?php endif; ?>
</td>
<?php endif; ?>
<?php if(in_array('indirizzo', $visibleColumns)): ?>
<td><?php echo e($gruppo->indirizzo_incontro ?: '-'); ?></td>
<?php endif; ?>
<?php if(in_array('citta', $visibleColumns)): ?>
<td><?php echo e($gruppo->città_incontro ?: '-'); ?></td>
<?php endif; ?>
<?php if(in_array('telefono', $visibleColumns)): ?>
<td>-</td>
<?php endif; ?>
<?php if(in_array('email', $visibleColumns)): ?>
<td>-</td>
<?php endif; ?>
<td>
<a href="<?php echo e(route('gruppi.show', $gruppo->id)); ?>" class="btn btn-xs btn-info" title="Visualizza">
<i class="fas fa-eye"></i>
</a>
<?php if($canWriteGruppi): ?>
<a href="<?php echo e(url('/gruppi/' . $gruppo->id . '/edit')); ?>" class="btn btn-xs btn-warning" title="Modifica">
<i class="fas fa-edit"></i>
</a>
<?php endif; ?>
<?php if($canDeleteGruppi): ?>
<form action="<?php echo e(url('/gruppi/' . $gruppo->id)); ?>" method="POST" class="d-inline">
<?php echo csrf_field(); ?> <?php echo method_field('DELETE'); ?>
<button type="submit" class="btn btn-xs btn-danger" onclick="return confirm('Confermi l\'eliminazione?')" title="Elimina">
<i class="fas fa-trash"></i>
</button>
</form>
<?php endif; ?>
</td>
</tr>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</tbody>
</table>
</div>
<?php else: ?>
<div class="card-body p-0">
<div class="tree-view" style="padding: 15px;">
<?php $rootGruppi = $gruppi->filter(fn($g) => $g->parent_id === null) ?>
<?php $__empty_1 = true; $__currentLoopData = $rootGruppi; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $gruppo): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_1 = false; ?>
<?php echo $__env->make('gruppi.partials.tree-item', ['gruppo' => $gruppo, 'isRoot' => true], array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); if ($__empty_1): ?>
<div class="text-center text-muted py-4">
<i class="fas fa-folder-open fa-2x mb-2"></i>
<p>Nessun gruppo presente.
<?php if($canWriteGruppi): ?>
<a href="<?php echo e(route('gruppi.create')); ?>">Crea il primo gruppo</a>
<?php endif; ?>
</p>
</div>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
</div>
<div class="modal fade" id="saveVistaModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><i class="fas fa-save mr-2"></i>Salva Vista</h5>
<button type="button" class="close" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label>Nome Vista *</label>
<input type="text" id="vista-nome" class="form-control" placeholder="Es. Elenco gruppi attivi">
</div>
<div class="form-group">
<label>Colonne visibili</label>
<div class="row" id="colonne-checkboxes">
<?php $__currentLoopData = $allColumns; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $col): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<div class="col-md-4 mb-2">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input col-checkbox" id="col-<?php echo e($col); ?>" value="<?php echo e($col); ?>" <?php echo e(in_array($col, $visibleColumns) ? 'checked' : ''); ?>>
<label class="custom-control-label" for="col-<?php echo e($col); ?>"><?php echo e($columnLabels[$col] ?? $col); ?></label>
</div>
</div>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</div>
</div>
<div class="form-group">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="vista-default">
<label class="custom-control-label" for="vista-default">Imposta come vista predefinita</label>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Annulla</button>
<button type="button" class="btn btn-primary" onclick="saveVista()">
<i class="fas fa-save mr-1"></i> Salva
</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="vistaListModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><i class="fas fa-bookmark mr-2"></i>Viste Salvate</h5>
<button type="button" class="close" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body">
<?php
$visteSalvate = \App\Models\VistaReport::where('user_id', Auth::id())
->where('tipo', 'gruppi')
->orderBy('is_default', 'desc')
->orderBy('nome')
->get();
?>
<?php if($visteSalvate->count() > 0): ?>
<div class="list-group">
<?php $__currentLoopData = $visteSalvate; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $v): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<div class="list-group-item d-flex justify-content-between align-items-center">
<div>
<a href="?vista_id=<?php echo e($v->id); ?>"><?php echo e($v->nome); ?></a>
<?php if($v->is_default): ?>
<span class="badge badge-success ml-1">Predefinita</span>
<?php endif; ?>
</div>
<form action="<?php echo e(route('gruppi.delete-vista', $v->id)); ?>" method="POST" class="d-inline">
<?php echo csrf_field(); ?> <?php echo method_field('DELETE'); ?>
<button type="submit" class="btn btn-xs btn-danger" onclick="return confirm('Eliminare questa vista?')">
<i class="fas fa-trash"></i>
</button>
</form>
</div>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</div>
<?php else: ?>
<p class="text-muted text-center">Nessuna vista salvata</p>
<?php endif; ?>
</div>
</div>
</div>
</div>
<?php $__env->stopSection(); ?>
<?php $__env->startSection('scripts'); ?>
<script>
function switchView(mode) {
window.location.href = '?view=' + mode;
}
function toggleItem(id) {
const el = document.getElementById('group-' + id);
const icon = document.getElementById('icon-' + id);
if (el.style.display === 'none') {
el.style.display = 'block';
icon.classList.remove('fa-chevron-right');
icon.classList.add('fa-chevron-down');
} else {
el.style.display = 'none';
icon.classList.remove('fa-chevron-down');
icon.classList.add('fa-chevron-right');
}
}
function toggleAllGroups() {
const collapsed = document.querySelectorAll('.tree-children[style*="display: none"]').length > 0;
document.querySelectorAll('.tree-children').forEach(el => {
el.style.display = collapsed ? 'block' : 'none';
});
document.querySelectorAll('.tree-toggle i').forEach(icon => {
if (collapsed) {
icon.classList.remove('fa-chevron-right');
icon.classList.add('fa-chevron-down');
} else {
icon.classList.remove('fa-chevron-down');
icon.classList.add('fa-chevron-right');
}
});
}
let sortDirection = {};
function sortTable(column) {
const tbody = document.getElementById('table-body');
const rows = Array.from(tbody.querySelectorAll('tr'));
sortDirection[column] = sortDirection[column] === 'asc' ? 'desc' : 'asc';
const dir = sortDirection[column];
rows.sort(function(a, b) {
const cellA = a.querySelector(`td:nth-child(${getColumnIndex(column)})`)?.textContent.trim() || '';
const cellB = b.querySelector(`td:nth-child(${getColumnIndex(column)})`)?.textContent.trim() || '';
if (dir === 'asc') {
return cellA.localeCompare(cellB, 'it');
}
return cellB.localeCompare(cellA, 'it');
});
rows.forEach(row => tbody.appendChild(row));
document.querySelectorAll('th i.fa-sort').forEach(icon => {
icon.className = 'fas fa-sort float-right text-muted';
});
const th = document.querySelector(`th[data-sortable][onclick="sortTable('${column}')"] i`);
if (th) {
th.className = `fas fa-sort-${dir === 'asc' ? 'up' : 'down'} float-right`;
}
}
function getColumnIndex(column) {
const th = document.querySelector(`th[onclick="sortTable('${column}')"]`);
if (th) {
return Array.from(th.parentNode.children).indexOf(th) + 1;
}
return 1;
}
function showSaveVistaModal() {
document.getElementById('vista-nome').value = '';
document.getElementById('vista-default').checked = false;
$('#saveVistaModal').modal('show');
}
function saveVista() {
const nome = document.getElementById('vista-nome').value.trim();
if (!nome) {
alert('Inserisci un nome per la vista');
return;
}
const colonneVisibili = Array.from(document.querySelectorAll('.col-checkbox:checked')).map(cb => cb.value);
const isDefault = document.getElementById('vista-default').checked;
fetch('/gruppi/save-vista', {
method: 'POST',
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: JSON.stringify({
nome: nome,
colonne_visibili: colonneVisibili,
is_default: isDefault,
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
$('#saveVistaModal').modal('hide');
window.location.reload();
} else {
alert('Errore nel salvataggio della vista');
}
})
.catch(error => {
alert('Errore: ' + error.message);
});
}
</script>
<style>
.tree-item { margin-bottom: 5px; }
.tree-children {
margin-left: 25px;
border-left: 1px dashed #dee2e6;
padding-left: 10px;
}
.tree-toggle {
cursor: pointer;
padding: 3px 8px;
border-radius: 4px;
}
.tree-toggle:hover {
background-color: #f8f9fa;
}
.tree-label {
display: inline-flex;
align-items: center;
gap: 8px;
}
.badge-level {
font-size: 0.7em;
padding: 2px 5px;
}
.btn-group .btn.active {
background-color: #007bff;
color: white;
border-color: #007bff;
}
</style>
<?php $__env->stopSection(); ?>
<?php echo $__env->make('layouts.adminlte', array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?><?php /**PATH /var/www/html/glastree/resources/views/gruppi/index.blade.php ENDPATH**/ ?>
@@ -1,44 +0,0 @@
<?php if($paginator->hasPages()): ?>
<ul class="pagination justify-content-center" role="navigation">
<?php if($paginator->onFirstPage()): ?>
<li class="page-item disabled" aria-disabled="true" aria-label="<?php echo app('translator')->get('pagination.previous'); ?>">
<span class="page-link" aria-hidden="true">&lsaquo;</span>
</li>
<?php else: ?>
<li class="page-item">
<a class="page-link" href="<?php echo e($paginator->previousPageUrl()); ?>" rel="prev" aria-label="<?php echo app('translator')->get('pagination.previous'); ?>">&lsaquo;</a>
</li>
<?php endif; ?>
<?php $__currentLoopData = $elements; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $element): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<?php if(is_string($element)): ?>
<li class="page-item disabled" aria-disabled="true"><span class="page-link"><?php echo e($element); ?></span></li>
<?php endif; ?>
<?php if(is_array($element)): ?>
<?php $__currentLoopData = $element; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $page => $url): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<?php if($page == $paginator->currentPage()): ?>
<li class="page-item active" aria-current="page"><span class="page-link"><?php echo e($page); ?></span></li>
<?php elseif($page >= $paginator->currentPage() - 2 && $page <= $paginator->currentPage() + 2): ?>
<li class="page-item"><a class="page-link" href="<?php echo e($url); ?>"><?php echo e($page); ?></a></li>
<?php endif; ?>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
<?php endif; ?>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
<?php if($paginator->hasMorePages()): ?>
<li class="page-item">
<a class="page-link" href="<?php echo e($paginator->nextPageUrl()); ?>" rel="next" aria-label="<?php echo app('translator')->get('pagination.next'); ?>">&rsaquo;</a>
</li>
<?php else: ?>
<li class="page-item disabled" aria-disabled="true" aria-label="<?php echo app('translator')->get('pagination.next'); ?>">
<span class="page-link" aria-hidden="true">&rsaquo;</span>
</li>
<?php endif; ?>
</ul>
<?php endif; ?><?php /**PATH /var/www/html/glastree/resources/views/vendor/pagination/simple-bootstrap-4.blade.php ENDPATH**/ ?>
@@ -1,103 +0,0 @@
<?php $__env->startSection('title', 'Calendario Eventi'); ?>
<?php $__env->startSection('page_title', 'Calendario Eventi'); ?>
<?php $__env->startSection('content'); ?>
<div class="row">
<div class="col-12">
<div class="card card-primary">
<div class="card-header">
<h3 class="card-title">
<i class="fas fa-calendar-alt mr-2"></i>Calendario Eventi
</h3>
<div class="card-tools">
<a href="<?php echo e(route('eventi.index')); ?>" class="btn btn-secondary btn-sm">
<i class="fas fa-list mr-1"></i> Elenco Eventi
</a>
<a href="<?php echo e(route('eventi.create')); ?>" class="btn btn-success btn-sm">
<i class="fas fa-plus mr-1"></i> Nuovo Evento
</a>
<form action="<?php echo e(route('eventi.export-selected-ics')); ?>" method="POST" class="d-inline">
<?php echo csrf_field(); ?>
<button type="submit" class="btn btn-success btn-sm">
<i class="fas fa-calendar-plus mr-1"></i> Esporta ICS
</button>
</form>
</div>
</div>
<div class="card-body">
<div id="calendar"></div>
</div>
</div>
</div>
</div>
<?php $__env->stopSection(); ?>
<?php $__env->startSection('styles'); ?>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fullcalendar@6.1.10/index.global.min.css">
<?php $__env->stopSection(); ?>
<?php $__env->startSection('scripts'); ?>
<script src="https://cdn.jsdelivr.net/npm/fullcalendar@6.1.10/index.global.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth',
locale: 'it',
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,listWeek'
},
buttonText: {
today: 'Oggi',
month: 'Mese',
week: 'Settimana',
list: 'Lista'
},
eventSources: [
{
url: '/eventi/calendar/events',
method: 'GET',
extraParams: function() {
return {
_token: document.querySelector('meta[name="csrf-token"]')?.content || ''
};
},
startParam: 'start',
endParam: 'end',
success: function(response) {
console.log('Eventi caricati:', response.length, response);
},
failure: function(error) {
console.error('Errore:', error);
console.log('XHR:', error.xhr);
alert('Errore nel caricamento degli eventi. Controlla la console per dettagli.');
}
}
],
eventClick: function(info) {
info.jsEvent.preventDefault();
window.location.href = info.event.url;
},
eventDisplay: 'block',
displayEventTime: true,
displayEventEnd: true,
nowIndicator: true,
height: 'auto',
expandRows: true,
stickyHeaderDates: true,
dayMaxEvents: true,
eventTimeFormat: {
hour: '2-digit',
minute: '2-digit',
hour12: false
}
});
calendar.render();
});
</script>
<?php $__env->stopSection(); ?>
<?php echo $__env->make('layouts.adminlte', array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?><?php /**PATH /var/www/html/glastree/resources/views/eventi/calendar.blade.php ENDPATH**/ ?>
@@ -1,373 +0,0 @@
<?php $__env->startSection('title', 'Eventi'); ?>
<?php $__env->startSection('page_title', 'Eventi'); ?>
<?php
$canWriteEventi = Auth::user()->canManage('eventi');
$canDeleteEventi = Auth::user()->canDelete('eventi');
?>
<?php $__env->startSection('content'); ?>
<?php if(session('success')): ?>
<div class="alert alert-success alert-dismissible">
<button type="button" class="close" data-dismiss="alert">&times;</button>
<?php echo e(session('success')); ?>
</div>
<?php endif; ?>
<div class="card">
<div class="card-header">
<h3 class="card-title">Tutti gli Eventi</h3>
<div class="card-tools">
<a href="/eventi/calendar" class="btn btn-sm btn-outline-primary mr-2">
<i class="fas fa-calendar-alt mr-1"></i> Calendario
</a>
<button type="button" class="btn btn-sm btn-success mr-2" onclick="exportSelectedIcs()">
<i class="fas fa-calendar-plus mr-1"></i> Esporta ICS
</button>
<?php if($canDeleteEventi): ?>
<div class="btn-group mr-2">
<button type="button" class="btn btn-sm btn-danger" onclick="deleteSelected()">
<i class="fas fa-trash mr-1"></i> Elimina Selezionati
</button>
</div>
<?php endif; ?>
<?php if($canWriteEventi): ?>
<a href="/eventi/import" class="btn btn-sm btn-warning mr-2">
<i class="fas fa-file-import mr-1"></i> Importa ICS
</a>
<a href="/eventi/create" class="btn btn-xs btn-success">
<i class="fas fa-plus mr-1"></i> Nuovo Evento
</a>
<?php endif; ?>
</div>
</div>
<div class="card-body">
<form method="GET" class="mb-3">
<div class="row">
<div class="col-md-3">
<input type="text" name="search" class="form-control" placeholder="Cerca evento..." value="<?php echo e(request('search')); ?>">
</div>
<div class="col-md-3">
<select name="gruppo_id" class="form-control" onchange="this.form.submit()">
<option value="">Tutti i gruppi</option>
<?php $__currentLoopData = $gruppi; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $g): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<option value="<?php echo e($g->id); ?>" <?php echo e(request('gruppo_id') == $g->id ? 'selected' : ''); ?>><?php echo e($g->full_path); ?></option>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</select>
</div>
<div class="col-md-2">
<select name="tipo" class="form-control" onchange="this.form.submit()">
<option value="">Tutte le ricorrenze</option>
<option value="singolo" <?php echo e(request('tipo') == 'singolo' ? 'selected' : ''); ?>>Singolo</option>
<option value="settimanale" <?php echo e(request('tipo') == 'settimanale' ? 'selected' : ''); ?>>Settimanale</option>
<option value="mensile" <?php echo e(request('tipo') == 'mensile' ? 'selected' : ''); ?>>Mensile</option>
<option value="annuale" <?php echo e(request('tipo') == 'annuale' ? 'selected' : ''); ?>>Annuale</option>
</select>
</div>
<div class="col-md-2">
<button type="submit" class="btn btn-primary"><i class="fas fa-search mr-1"></i> Cerca</button>
<a href="/eventi" class="btn btn-secondary"><i class="fas fa-times"></i></a>
</div>
</div>
</form>
<table class="table table-bordered table-hover">
<thead class="thead-light">
<tr>
<th style="width: 40px;">
<?php if($canDeleteEventi): ?>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="select-all" onchange="toggleSelectAll(this)">
<label class="custom-control-label" for="select-all"></label>
</div>
<?php endif; ?>
</th>
<th>
<a href="<?php echo e(request()->fullUrlWithQuery(['sort' => 'nome_evento', 'direction' => request('sort') === 'nome_evento' && request('direction') === 'asc' ? 'desc' : 'asc'])); ?>" class="text-dark">
Nome Evento
<?php if(request('sort') === 'nome_evento'): ?>
<i class="fas fa-sort-<?php echo e(request('direction') === 'asc' ? 'up' : 'down'); ?> ml-1"></i>
<?php else: ?>
<i class="fas fa-sort ml-1 text-muted"></i>
<?php endif; ?>
</a>
</th>
<th>
<a href="<?php echo e(request()->fullUrlWithQuery(['sort' => 'descrizione_evento', 'direction' => request('sort') === 'descrizione_evento' && request('direction') === 'asc' ? 'desc' : 'asc'])); ?>" class="text-dark">
Descrizione
<?php if(request('sort') === 'descrizione_evento'): ?>
<i class="fas fa-sort-<?php echo e(request('direction') === 'asc' ? 'up' : 'down'); ?> ml-1"></i>
<?php else: ?>
<i class="fas fa-sort ml-1 text-muted"></i>
<?php endif; ?>
</a>
</th>
<th>
<a href="<?php echo e(request()->fullUrlWithQuery(['sort' => 'tipo_evento', 'direction' => request('sort') === 'tipo_evento' && request('direction') === 'asc' ? 'desc' : 'asc'])); ?>" class="text-dark">
Tipologia
<?php if(request('sort') === 'tipo_evento'): ?>
<i class="fas fa-sort-<?php echo e(request('direction') === 'asc' ? 'up' : 'down'); ?> ml-1"></i>
<?php else: ?>
<i class="fas fa-sort ml-1 text-muted"></i>
<?php endif; ?>
</a>
</th>
<th>
<a href="<?php echo e(request()->fullUrlWithQuery(['sort' => 'tipo_recorrenza', 'direction' => request('sort') === 'tipo_recorrenza' && request('direction') === 'asc' ? 'desc' : 'asc'])); ?>" class="text-dark">
Ricorrenza
<?php if(request('sort') === 'tipo_recorrenza'): ?>
<i class="fas fa-sort-<?php echo e(request('direction') === 'asc' ? 'up' : 'down'); ?> ml-1"></i>
<?php else: ?>
<i class="fas fa-sort ml-1 text-muted"></i>
<?php endif; ?>
</a>
</th>
<th>
<a href="<?php echo e(request()->fullUrlWithQuery(['sort' => 'gruppi', 'direction' => request('sort') === 'gruppi' && request('direction') === 'asc' ? 'desc' : 'asc'])); ?>" class="text-dark">
Gruppi
<?php if(request('sort') === 'gruppi'): ?>
<i class="fas fa-sort-<?php echo e(request('direction') === 'asc' ? 'up' : 'down'); ?> ml-1"></i>
<?php else: ?>
<i class="fas fa-sort ml-1 text-muted"></i>
<?php endif; ?>
</a>
</th>
<th>
<a href="<?php echo e(request()->fullUrlWithQuery(['sort' => 'responsabili', 'direction' => request('sort') === 'responsabili' && request('direction') === 'asc' ? 'desc' : 'asc'])); ?>" class="text-dark">
Responsabili
<?php if(request('sort') === 'responsabili'): ?>
<i class="fas fa-sort-<?php echo e(request('direction') === 'asc' ? 'up' : 'down'); ?> ml-1"></i>
<?php else: ?>
<i class="fas fa-sort ml-1 text-muted"></i>
<?php endif; ?>
</a>
</th>
<th style="width: 120px;">
<a href="<?php echo e(request()->fullUrlWithQuery(['sort' => 'created_at', 'direction' => request('sort') === 'created_at' && request('direction') === 'asc' ? 'desc' : 'asc'])); ?>" class="text-dark">
Creato
<?php if(request('sort') === 'created_at'): ?>
<i class="fas fa-sort-<?php echo e(request('direction') === 'asc' ? 'up' : 'down'); ?> ml-1"></i>
<?php else: ?>
<i class="fas fa-sort ml-1 text-muted"></i>
<?php endif; ?>
</a>
</th>
<th style="width: 120px;">Azioni</th>
</tr>
</thead>
<tbody>
<?php $__empty_1 = true; $__currentLoopData = $eventi; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $evento): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_1 = false; ?>
<tr data-id="<?php echo e($evento->id); ?>">
<td>
<?php if($canDeleteEventi): ?>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input row-checkbox" id="row-checkbox-<?php echo e($evento->id); ?>" value="<?php echo e($evento->id); ?>">
<label class="custom-control-label" for="row-checkbox-<?php echo e($evento->id); ?>"></label>
</div>
<?php endif; ?>
</td>
<td>
<a href="/eventi/<?php echo e($evento->id); ?>">
<i class="fas fa-calendar mr-1 text-primary"></i>
<?php echo e($evento->nome_evento); ?>
</a>
<?php if($evento->is_incontro_gruppo): ?>
<span class="badge badge-success ml-1">Incluso</span>
<?php endif; ?>
</td>
<td><?php echo e(Str::limit($evento->descrizione_evento, 50) ?: '-'); ?></td>
<td>
<?php if($evento->tipo_evento): ?>
<?php
$tipologiaEvento = \App\Models\TipologiaEvento::where('nome', $evento->tipo_evento)->first();
?>
<?php if($tipologiaEvento): ?>
<span class="badge badge-primary"><?php echo e($tipologiaEvento->descrizione ?: $tipologiaEvento->nome); ?></span>
<?php else: ?>
<span class="badge badge-secondary"><?php echo e($evento->tipo_evento); ?></span>
<?php endif; ?>
<?php else: ?>
<span class="text-muted">-</span>
<?php endif; ?>
</td>
<td>
<?php if($evento->tipo_recorrenza && $evento->tipo_recorrenza !== 'singolo'): ?>
<span class="badge badge-info"><?php echo e($evento->periodicita_label); ?></span>
<?php else: ?>
<span class="badge badge-secondary">Singolo</span>
<?php endif; ?>
</td>
<td>
<?php $__empty_2 = true; $__currentLoopData = $evento->gruppi->take(2); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $gruppo): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_2 = false; ?>
<a href="/gruppi/<?php echo e($gruppo->id); ?>">
<span class="badge badge-warning"><?php echo e($gruppo->nome); ?></span>
</a>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); if ($__empty_2): ?>
<span class="text-muted">-</span>
<?php endif; ?>
<?php if($evento->gruppi->count() > 2): ?>
<small class="text-muted">+<?php echo e($evento->gruppi->count() - 2); ?></small>
<?php endif; ?>
</td>
<td>
<?php $__empty_2 = true; $__currentLoopData = $evento->responsabili->take(2); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $resp): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_2 = false; ?>
<small><?php echo e($resp->nome_completo); ?></small><br>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); if ($__empty_2): ?>
<span class="text-muted">-</span>
<?php endif; ?>
<?php if($evento->responsabili->count() > 2): ?>
<small class="text-muted">+<?php echo e($evento->responsabili->count() - 2); ?> altri</small>
<?php endif; ?>
</td>
<td><small class="text-muted"><?php echo e($evento->created_at->format('d/m/Y')); ?></small></td>
<td>
<a href="<?php echo e(url('/eventi/' . $evento->id)); ?>" class="btn btn-xs btn-info" title="Visualizza">
<i class="fas fa-eye"></i>
</a>
<?php if($canWriteEventi): ?>
<a href="<?php echo e(url('/eventi/' . $evento->id . '/edit')); ?>" class="btn btn-xs btn-warning" title="Modifica">
<i class="fas fa-edit"></i>
</a>
<form action="<?php echo e(url('/eventi/' . $evento->id)); ?>" method="POST" class="d-inline">
<?php echo csrf_field(); ?> <?php echo method_field('DELETE'); ?>
<button type="submit" class="btn btn-xs btn-danger" onclick="return confirm('Confermi l\'eliminazione?')" title="Elimina">
<i class="fas fa-trash"></i>
</button>
</form>
<?php endif; ?>
</td>
</tr>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); if ($__empty_1): ?>
<tr>
<td colspan="9" class="text-center text-muted py-4">
<i class="fas fa-calendar fa-2x mb-2"></i>
<p class="mb-0">Nessun evento trovato</p>
</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
<div class="card-footer d-flex justify-content-between align-items-center">
<div>
<form method="GET" class="form-inline" id="perPageForm">
<label class="mr-2 small">Righe per pagina:</label>
<select name="perPage" class="form-control form-control-sm" onchange="this.form.submit()" style="width: auto;">
<?php $__currentLoopData = [10, 20, 25, 50, 100]; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $p): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<option value="<?php echo e($p); ?>" <?php echo e((int) request('perPage', 20) === $p ? 'selected' : ''); ?>><?php echo e($p); ?></option>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</select>
<?php $__currentLoopData = request()->except(['perPage', 'page']); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $key => $value): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<?php if(is_array($value)): ?>
<?php $__currentLoopData = $value; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $v): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<input type="hidden" name="<?php echo e($key); ?>[]" value="<?php echo e($v); ?>">
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
<?php else: ?>
<input type="hidden" name="<?php echo e($key); ?>" value="<?php echo e($value); ?>">
<?php endif; ?>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</form>
</div>
<div>
<?php echo e($eventi->links()); ?>
</div>
</div>
</div>
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog">
<?php if($canDeleteEventi): ?>
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header bg-danger">
<h5 class="modal-title text-white"><i class="fas fa-trash-alt mr-2"></i>Conferma Eliminazione</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body">
<p>Stai per eliminare <strong id="delete-count">0</strong> eventi selezionati.</p>
<p class="text-muted small">Verranno eliminati anche i collegamenti con gruppi e responsabili.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Annulla</button>
<button type="button" class="btn btn-danger" onclick="confirmDelete()">Elimina</button>
</div>
</div>
</div>
<?php endif; ?>
</div>
<?php $__env->stopSection(); ?>
<?php $__env->startSection('scripts'); ?>
<script>
function toggleSelectAll(source) {
document.querySelectorAll('.row-checkbox').forEach(cb => cb.checked = source.checked);
}
function getSelectedIds() {
return Array.from(document.querySelectorAll('.row-checkbox:checked')).map(cb => cb.value);
}
function deleteSelected() {
const selectedIds = getSelectedIds();
if (selectedIds.length === 0) {
alert('Seleziona almeno un evento');
return;
}
document.getElementById('delete-count').textContent = selectedIds.length;
document.querySelector('#deleteModal .btn-danger').onclick = function() {
const form = document.createElement('form');
form.method = 'POST';
form.action = '/eventi/mass-elimina';
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.content || '<?php echo e(csrf_token()); ?>';
let html = `<input type="hidden" name="_token" value="${csrfToken}">`;
selectedIds.forEach(function(id) {
html += `<input type="hidden" name="ids[]" value="${id}">`;
});
form.innerHTML = html;
document.body.appendChild(form);
form.submit();
};
$('#deleteModal').modal('show');
}
function exportSelectedIcs() {
const selectedIds = getSelectedIds();
const form = document.createElement('form');
form.method = 'POST';
form.action = '/eventi/export-ics';
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.content || '<?php echo e(csrf_token()); ?>';
let html = `<input type="hidden" name="_token" value="${csrfToken}">`;
if (selectedIds.length > 0) {
selectedIds.forEach(function(id) {
html += `<input type="hidden" name="ids[]" value="${id}">`;
});
} else {
const params = new URLSearchParams(window.location.search);
params.forEach(function(value, key) {
if (key === 'search') html += `<input type="hidden" name="search" value="${value}">`;
if (key === 'gruppo_id') html += `<input type="hidden" name="gruppo_id" value="${value}">`;
if (key === 'tipo') html += `<input type="hidden" name="tipo" value="${value}">`;
});
}
form.innerHTML = html;
document.body.appendChild(form);
form.submit();
}
</script>
<?php $__env->stopSection(); ?>
<?php echo $__env->make('layouts.adminlte', array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?><?php /**PATH /var/www/html/glastree/resources/views/eventi/index.blade.php ENDPATH**/ ?>
@@ -1,943 +0,0 @@
<?php $__env->startSection('title', 'Individui'); ?>
<?php $__env->startSection('page_title', 'Elenco Individui'); ?>
<?php
$columnLabels = [
'codice' => 'Codice',
'cognome' => 'Cognome',
'nome' => 'Nome',
'email' => 'Email',
'telefono' => 'Telefono',
];
$vistaDefaultJson = $vista ? $vista->toJson() : 'null';
$allColumnsJson = json_encode($allColumns);
$visibleColumnsJson = json_encode($visibleColumns);
$canWriteIndividui = Auth::user()->canManage('individui');
$canDeleteIndividui = Auth::user()->canDelete('individui');
?>
<?php $__env->startSection('content'); ?>
<div class="card">
<div class="card-header">
<h3 class="card-title"><i class="fas fa-users mr-2"></i>Lista Individui</h3>
<div class="card-tools">
<button type="button" class="btn btn-info btn-sm mr-1" onclick="toggleSearchPanel()">
<i class="fas fa-search mr-1"></i> Ricerca/Filtri
</button>
<div class="btn-group mr-1">
<button type="button" class="btn btn-secondary btn-sm dropdown-toggle" data-toggle="dropdown">
<i class="fas fa-cog mr-1"></i> Azioni
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="#" onclick="exportCSV(); return false;">
<i class="fas fa-file-csv mr-2"></i>Esporta Tutti CSV
</a>
<a class="dropdown-item" href="#" onclick="exportSelectedCSV(); return false;">
<i class="fas fa-file-csv mr-2"></i>Esporta Selezionati CSV
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#" onclick="printSelected(); return false;">
<i class="fas fa-print mr-2"></i>Stampa Selezionati
</a>
<a class="dropdown-item" href="#" onclick="emailSelected(); return false;">
<i class="fas fa-envelope mr-2"></i>Email Selezionati
</a>
<?php if($canWriteIndividui): ?>
<a class="dropdown-item" href="#" onclick="showCreateMailingListModal(); return false;">
<i class="fas fa-list mr-2"></i>Crea Mailing List
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger" href="#" onclick="deleteSelected(); return false;">
<i class="fas fa-trash mr-2"></i>Elimina Selezionati
</a>
<?php endif; ?>
</div>
</div>
<button type="button" class="btn btn-primary btn-sm" onclick="showSaveVistaModal()">
<i class="fas fa-save mr-1"></i> Salva Vista
</button>
<?php if($canWriteIndividui): ?>
<a href="<?php echo e(route('individui.import')); ?>" class="btn btn-warning btn-sm ml-2">
<i class="fas fa-file-import mr-1"></i> Importa
</a>
<a href="/individui/create" class="btn btn-success btn-sm ml-2">
<i class="fas fa-plus mr-1"></i> Nuovo
</a>
<?php endif; ?>
</div>
</div>
<div id="search-panel" class="p-3 bg-light border-bottom" style="display: none;">
<div class="row">
<div class="col-md-4">
<div class="form-group mb-2">
<label class="small font-weight-bold">Cerca</label>
<input type="text" id="global-search" class="form-control form-control-sm" placeholder="Cerca in tutte le colonne..." oninput="applyGlobalSearch(this.value)">
</div>
</div>
<div class="col-md-3">
<div class="form-group mb-2">
<label class="small font-weight-bold">Colonna</label>
<select id="filter-column" class="form-control form-control-sm">
<option value="">Tutte le colonne</option>
<?php $__currentLoopData = $allColumns; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $col): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<option value="<?php echo e($col['key']); ?>"><?php echo e($col['label']); ?></option>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</select>
</div>
</div>
<div class="col-md-2">
<div class="form-group mb-2">
<label class="small font-weight-bold">Operatore</label>
<select id="filter-operator" class="form-control form-control-sm">
<option value="contains">Contiene</option>
<option value="equals">Uguale a</option>
<option value="starts">Inizia con</option>
<option value="ends">Finisce con</option>
</select>
</div>
</div>
<div class="col-md-2">
<div class="form-group mb-2">
<label class="small font-weight-bold">Valore</label>
<input type="text" id="filter-value" class="form-control form-control-sm" placeholder="Valore filtro">
</div>
</div>
<div class="col-md-1">
<label class="small">&nbsp;</label>
<div>
<button type="button" class="btn btn-xs btn-primary" onclick="applyColumnFilter()">
<i class="fas fa-filter"></i>
</button>
<button type="button" class="btn btn-xs btn-secondary" onclick="clearFilters()">
<i class="fas fa-times"></i>
</button>
</div>
</div>
</div>
<div class="mt-2">
<small class="text-muted">
<i class="fas fa-info-circle mr-1"></i>
Ordina cliccando sulle intestazioni delle colonne
</small>
</div>
</div>
<div class="card-body p-0">
<?php if($individui->count() > 0): ?>
<table class="table table-bordered table-hover table-striped mb-0" id="individui-table">
<thead class="thead-light">
<tr>
<th style="width: 40px;">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="select-all" onchange="toggleSelectAll(this)">
<label class="custom-control-label" for="select-all"></label>
</div>
</th>
<?php if(in_array('codice', $visibleColumns)): ?>
<th style="width: 100px;" data-sortable="true" data-column="codice" onclick="sortTable('codice')">Codice <i class="fas fa-sort float-right"></i></th>
<?php endif; ?>
<?php if(in_array('cognome', $visibleColumns)): ?>
<th data-sortable="true" data-column="cognome" onclick="sortTable('cognome')">Cognome <i class="fas fa-sort float-right"></i></th>
<?php endif; ?>
<?php if(in_array('nome', $visibleColumns)): ?>
<th data-sortable="true" data-column="nome" onclick="sortTable('nome')">Nome <i class="fas fa-sort float-right"></i></th>
<?php endif; ?>
<?php if(in_array('email', $visibleColumns)): ?>
<th data-sortable="true" data-column="email" onclick="sortTable('email')">Email <i class="fas fa-sort float-right"></i></th>
<?php endif; ?>
<?php if(in_array('telefono', $visibleColumns)): ?>
<th data-sortable="true" data-column="telefono" onclick="sortTable('telefono')">Telefono <i class="fas fa-sort float-right"></i></th>
<?php endif; ?>
<th style="width: 120px;">Azioni</th>
</tr>
</thead>
<tbody id="table-body">
<?php $__currentLoopData = $individui; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $ind): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<tr data-id="<?php echo e($ind->id); ?>">
<td>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input row-checkbox" id="select-<?php echo e($ind->id); ?>" value="<?php echo e($ind->id); ?>">
<label class="custom-control-label" for="select-<?php echo e($ind->id); ?>"></label>
</div>
</td>
<?php if(in_array('codice', $visibleColumns)): ?>
<td><span class="badge badge-secondary"><?php echo e($ind->codice_id); ?></span></td>
<?php endif; ?>
<?php if(in_array('cognome', $visibleColumns)): ?>
<td class="font-weight-bold">
<a href="<?php echo e(url('/individui/' . $ind->id . '/edit')); ?>"><?php echo e($ind->cognome); ?></a>
</td>
<?php endif; ?>
<?php if(in_array('nome', $visibleColumns)): ?>
<td>
<a href="<?php echo e(url('/individui/' . $ind->id . '/edit')); ?>"><?php echo e($ind->nome); ?></a>
</td>
<?php endif; ?>
<?php if(in_array('email', $visibleColumns)): ?>
<td><?php echo e($ind->getEmailPrimariaAttribute() ?: '-'); ?></td>
<?php endif; ?>
<?php if(in_array('telefono', $visibleColumns)): ?>
<td><?php echo e($ind->getTelefonoPrimarioAttribute() ?: '-'); ?></td>
<?php endif; ?>
<td>
<?php if($canWriteIndividui): ?>
<a href="<?php echo e(url('/individui/' . $ind->id . '/edit')); ?>" class="btn btn-xs btn-warning" title="Modifica">
<i class="fas fa-edit"></i>
</a>
<?php endif; ?>
<?php if($canDeleteIndividui): ?>
<button type="button" class="btn btn-xs btn-danger" onclick="showDeleteModal(<?php echo e($ind->id); ?>, '<?php echo e($ind->cognome); ?> <?php echo e($ind->nome); ?>')" title="Elimina">
<i class="fas fa-trash"></i>
</button>
<?php endif; ?>
<button type="button" class="btn btn-xs btn-secondary" onclick="printIndividuo(<?php echo e($ind->id); ?>)" title="Stampa">
<i class="fas fa-print"></i>
</button>
<button type="button" class="btn btn-xs btn-primary" onclick="exportIndividuoCSV(<?php echo e($ind->id); ?>)" title="Esporta CSV">
<i class="fas fa-download"></i>
</button>
<button type="button" class="btn btn-xs btn-info" onclick="sendEmail(<?php echo e($ind->id); ?>)" title="Invia Email">
<i class="fas fa-envelope"></i>
</button>
<button type="button" class="btn btn-xs btn-dark" onclick="generateReport(<?php echo e($ind->id); ?>)" title="Genera Report">
<i class="fas fa-chart-bar"></i>
</button>
</td>
</tr>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</tbody>
</table>
<?php else: ?>
<div class="text-center text-muted py-5">
<i class="fas fa-users fa-3x mb-3"></i>
<p>Nessun individuo presente</p>
<?php if($canWriteIndividui): ?>
<a href="/individui/create" class="btn btn-success">Crea il primo individuo</a>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
<?php if($individui->count() > 0): ?>
<div class="card-footer d-flex justify-content-between align-items-center">
<div>
<form method="GET" class="form-inline" id="perPageForm">
<label class="mr-2 small">Righe per pagina:</label>
<select name="perPage" class="form-control form-control-sm" onchange="this.form.submit()" style="width: auto;">
<?php $__currentLoopData = [10, 20, 25, 50, 100]; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $p): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<option value="<?php echo e($p); ?>" <?php echo e((int) request('perPage', 20) === $p ? 'selected' : ''); ?>><?php echo e($p); ?></option>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</select>
<?php $__currentLoopData = request()->except(['perPage', 'page']); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $key => $value): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<?php if(is_array($value)): ?>
<?php $__currentLoopData = $value; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $v): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<input type="hidden" name="<?php echo e($key); ?>[]" value="<?php echo e($v); ?>">
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
<?php else: ?>
<input type="hidden" name="<?php echo e($key); ?>" value="<?php echo e($value); ?>">
<?php endif; ?>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</form>
</div>
<div>
<?php echo e($individui->links()); ?>
</div>
</div>
<?php endif; ?>
</div>
<div class="modal fade" id="saveVistaModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><i class="fas fa-save mr-2"></i>Salva Vista</h5>
<button type="button" class="close" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label>Nome Vista *</label>
<input type="text" id="vista-nome" class="form-control" placeholder="Es. Elenco soci attivi">
</div>
<div class="form-group">
<label>Colonne visibili</label>
<div class="row" id="colonne-checkboxes">
<?php $__currentLoopData = $allColumns; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $col): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<div class="col-md-6">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input col-visibile" id="col-vis-<?php echo e($col['key']); ?>" value="<?php echo e($col['key']); ?>" <?php echo e(in_array($col['key'], $visibleColumns) ? 'checked' : ''); ?>>
<label class="custom-control-label" for="col-vis-<?php echo e($col['key']); ?>"><?php echo e($col['label']); ?></label>
</div>
</div>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</div>
</div>
<div class="form-group">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="vista-default" value="true">
<label class="custom-control-label" for="vista-default">Imposta come vista predefinita</label>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Annulla</button>
<button type="button" class="btn btn-primary" onclick="saveVista()">Salva</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="colonneModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><i class="fas fa-columns mr-2"></i>Colonne Visibili</h5>
<button type="button" class="close" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body">
<div class="row">
<?php $__currentLoopData = $allColumns; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $col): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<div class="col-md-6">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input col-toggle" id="col-toggle-<?php echo e($col['key']); ?>" value="<?php echo e($col['key']); ?>" <?php echo e(in_array($col['key'], $visibleColumns) ? 'checked' : ''); ?> onchange="toggleColumn('<?php echo e($col['key']); ?>', this.checked)">
<label class="custom-control-label" for="col-toggle-<?php echo e($col['key']); ?>"><?php echo e($col['label']); ?></label>
</div>
</div>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Chiudi</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog">
<?php if($canDeleteIndividui): ?>
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header bg-danger">
<h5 class="modal-title text-white"><i class="fas fa-trash-alt mr-2"></i>Conferma Eliminazione</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body">
<p>Stai per eliminare l'individuo: <strong id="delete-individuo-name"></strong></p>
<p class="text-muted">Seleziona gli elementi collegati da eliminare:</p>
<div class="ml-3">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="delete-contatti" checked>
<label class="custom-control-label" for="delete-contatti">Contatti (<span id="count-contatti">0</span>)</label>
</div>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="delete-gruppi">
<label class="custom-control-label" for="delete-gruppi">Gruppi (<span id="count-gruppi">0</span>) - solo scollegamento</label>
</div>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="delete-documenti" checked>
<label class="custom-control-label" for="delete-documenti">Documenti (<span id="count-documenti">0</span>)</label>
</div>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="delete-eventi">
<label class="custom-control-label" for="delete-eventi">Eventi (<span id="count-eventi">0</span>) - solo scollegamento</label>
</div>
</div>
<div class="alert alert-warning mt-3 mb-0">
<small><i class="fas fa-info-circle mr-1"></i>Se non selezionato, l'elemento verrà scollegato ma non eliminato.</small>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Annulla</button>
<button type="button" class="btn btn-danger" id="confirm-delete-btn" onclick="confirmDelete()">Elimina</button>
</div>
</div>
</div>
<?php endif; ?>
</div>
<div class="modal fade" id="createMailingListModal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header bg-info">
<h5 class="modal-title text-white"><i class="fas fa-list mr-2"></i>Crea Mailing List</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label>Nome Lista *</label>
<input type="text" id="ml-nome" class="form-control" placeholder="Es. Newsletter Maggio 2026">
</div>
<div class="form-group">
<label>Descrizione</label>
<textarea id="ml-descrizione" class="form-control" rows="2" placeholder="Descrizione opzionale"></textarea>
</div>
<div class="form-group">
<label>Contatti inclusi (<span id="ml-count">0</span>)</label>
<div class="table-responsive" style="max-height: 300px; overflow-y: auto;">
<table class="table table-bordered table-sm" id="ml-contatti-table">
<thead class="thead-light">
<tr>
<th style="width: 40px;">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="ml-select-all" onchange="toggleMlSelectAll(this)">
<label class="custom-control-label" for="ml-select-all"></label>
</div>
</th>
<th>Codice</th>
<th>Cognome</th>
<th>Nome</th>
<th>Email</th>
<th style="width: 50px;"></th>
</tr>
</thead>
<tbody id="ml-contatti-tbody">
</tbody>
</table>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Annulla</button>
<button type="button" class="btn btn-success" onclick="createMailingList()">
<i class="fas fa-save mr-1"></i> Salva Lista
</button>
</div>
</div>
</div>
</div>
<?php $__env->stopSection(); ?>
<?php $__env->startSection('scripts'); ?>
<script>
let currentSort = { column: null, direction: 'asc' };
let columnVisibility = <?php echo json_encode(array_column($allColumns, 'key')); ?>;
function toggleSearchPanel() {
const panel = document.getElementById('search-panel');
panel.style.display = panel.style.display === 'none' ? 'block' : 'none';
}
function applyGlobalSearch(value) {
const rows = document.querySelectorAll('#table-body tr');
const searchTerm = value.toLowerCase();
rows.forEach(row => {
const text = row.textContent.toLowerCase();
row.style.display = text.includes(searchTerm) ? '' : 'none';
});
}
function applyColumnFilter() {
const col = document.getElementById('filter-column').value;
const op = document.getElementById('filter-operator').value;
const val = document.getElementById('filter-value').value.toLowerCase();
if (!col || !val) return;
const rows = document.querySelectorAll('#table-body tr');
const colIndex = { codice: 1, cognome: 2, nome: 3, email: 4, telefono: 5, azioni: 6 }[col];
rows.forEach(row => {
const cells = row.querySelectorAll('td');
const cellText = cells[colIndex]?.textContent.toLowerCase() || '';
let matches = false;
switch(op) {
case 'contains': matches = cellText.includes(val); break;
case 'equals': matches = cellText === val; break;
case 'starts': matches = cellText.startsWith(val); break;
case 'ends': matches = cellText.endsWith(val); break;
}
row.style.display = matches ? '' : 'none';
});
}
function clearFilters() {
document.getElementById('global-search').value = '';
document.getElementById('filter-column').value = '';
document.getElementById('filter-value').value = '';
document.querySelectorAll('#table-body tr').forEach(row => row.style.display = '');
}
function sortTable(column) {
if (currentSort.column === column) {
currentSort.direction = currentSort.direction === 'asc' ? 'desc' : 'asc';
} else {
currentSort = { column: column, direction: 'asc' };
}
const colIndex = { codice: 0, cognome: 1, nome: 2, email: 3, telefono: 4, azioni: 5 }[column];
const tbody = document.getElementById('table-body');
const rows = Array.from(tbody.querySelectorAll('tr'));
rows.sort((a, b) => {
const aVal = a.querySelectorAll('td')[colIndex]?.textContent.trim() || '';
const bVal = b.querySelectorAll('td')[colIndex]?.textContent.trim() || '';
const cmp = aVal.localeCompare(bVal, undefined, { numeric: true });
return currentSort.direction === 'asc' ? cmp : -cmp;
});
rows.forEach(row => tbody.appendChild(row));
document.querySelectorAll('th[data-sortable]').forEach(th => {
const icon = th.querySelector('i');
if (th.dataset.column === column) {
icon.className = currentSort.direction === 'asc' ? 'fas fa-sort-up float-right' : 'fas fa-sort-down float-right';
} else {
icon.className = 'fas fa-sort float-right';
}
});
}
function toggleColumn(column, visible) {
const colIndex = { codice: 1, cognome: 2, nome: 3, email: 4, telefono: 5, azioni: 6 }[column];
const ths = document.querySelectorAll('#individui-table thead th');
const rows = document.querySelectorAll('#table-body tr');
if (visible) {
ths[colIndex].style.display = '';
rows.forEach(row => {
row.querySelectorAll('td')[colIndex].style.display = '';
});
} else {
ths[colIndex].style.display = 'none';
rows.forEach(row => {
row.querySelectorAll('td')[colIndex].style.display = 'none';
});
}
}
async function saveVista() {
let nome = document.getElementById('vista-nome').value.trim();
if (!nome) {
const now = new Date();
nome = 'Vista ' + now.toLocaleDateString('it-IT') + ' ' + now.toLocaleTimeString('it-IT', { hour: '2-digit', minute: '2-digit' });
}
const colonneVisibili = Array.from(document.querySelectorAll('#colonne-checkboxes input:checked')).map(i => i.value);
const isDefault = document.getElementById('vista-default').checked;
const data = {
nome: nome,
tipo: 'individui',
colonne_visibili: colonneVisibili,
colonne_ordinamento: currentSort.column ? [[currentSort.column, currentSort.direction]] : [],
ricerca: document.getElementById('global-search').value,
is_default: isDefault
};
try {
const response = await fetch('/viste', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.content || ''
},
body: JSON.stringify(data)
});
if (response.ok) {
alert('Vista salvata!');
$('#saveVistaModal').modal('hide');
} else {
alert('Errore salvataggio');
}
} catch(e) {
alert('Errore: ' + e.message);
}
}
function toggleSelectAll(source) {
const checkboxes = document.querySelectorAll('.row-checkbox');
checkboxes.forEach(cb => {
cb.checked = source.checked;
});
}
function exportCSV() {
window.location.href = '/individui/export';
}
function exportSelectedCSV() {
const selectedIds = getSelectedIds();
if (selectedIds.length === 0) {
alert('Seleziona almeno un individuo');
return;
}
const params = new URLSearchParams();
selectedIds.forEach(function(id) {
params.append('ids[]', id);
});
window.location.href = '/individui/export?' + params.toString();
}
let deleteIndividuoId = null;
async function showDeleteModal(id, nome) {
deleteIndividuoId = id;
document.getElementById('delete-individuo-name').textContent = nome;
document.getElementById('count-contatti').textContent = '...';
document.getElementById('count-gruppi').textContent = '...';
document.getElementById('count-documenti').textContent = '...';
document.getElementById('count-eventi').textContent = '...';
try {
const response = await fetch(`/individui/${id}/collegati`);
const data = await response.json();
document.getElementById('count-contatti').textContent = data.contatti;
document.getElementById('count-gruppi').textContent = data.gruppi;
document.getElementById('count-documenti').textContent = data.documenti;
document.getElementById('count-eventi').textContent = data.eventi;
} catch(e) {
console.error('Errore recupero dati:', e);
}
$('#deleteModal').modal('show');
}
function confirmDelete() {
const eliminaContatti = document.getElementById('delete-contatti').checked;
const eliminaDocumenti = document.getElementById('delete-documenti').checked;
const form = document.createElement('form');
form.method = 'POST';
form.action = `/individui/${deleteIndividuoId}/elimina`;
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.content || '<?php echo e(csrf_token()); ?>';
form.innerHTML = `
<input type="hidden" name="_token" value="${csrfToken}">
<input type="hidden" name="elimina_contatti" value="${eliminaContatti}">
<input type="hidden" name="elimina_documenti" value="${eliminaDocumenti}">
`;
document.body.appendChild(form);
form.submit();
}
function printIndividuo(id) {
window.open('/individui/' + id + '/report', '_blank');
}
function exportIndividuoCSV(id) {
const row = document.querySelector(`tr[data-id="${id}"]`);
if (!row) return;
const cells = Array.from(row.querySelectorAll('td'));
const data = {
codice: cells[1].textContent.trim(),
cognome: cells[2].textContent.trim(),
nome: cells[3].textContent.trim(),
email: cells[4].textContent.trim(),
telefono: cells[5].textContent.trim()
};
const csv = `Codice,Cognome,Nome,Email,Telefono\n"${data.codice}","${data.cognome}","${data.nome}","${data.email}","${data.telefono}"`;
const blob = new Blob([csv], { type: 'text/csv' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `individuo_${data.codice}.csv`;
a.click();
}
function sendEmail(id) {
window.location.href = `/mailing/nuovo?individui=${id}`;
}
function generateReport(id) {
window.open('/individui/' + id + '/report', '_blank');
}
function getSelectedIds() {
return Array.from(document.querySelectorAll('.row-checkbox:checked')).map(cb => cb.value);
}
function exportSelectedCSV() {
const selectedIds = getSelectedIds();
if (selectedIds.length === 0) {
alert('Seleziona almeno un individuo');
return;
}
const rows = [];
rows.push('Codice,Cognome,Nome,Email,Telefono');
document.querySelectorAll('#table-body tr').forEach(row => {
const checkbox = row.querySelector('.row-checkbox');
if (checkbox && checkbox.checked) {
const cells = Array.from(row.querySelectorAll('td'));
const codice = cells[1].textContent.trim();
const cognome = cells[2].textContent.trim();
const nome = cells[3].textContent.trim();
const email = cells[4].textContent.trim();
const telefono = cells[5].textContent.trim();
rows.push(`"${codice}","${cognome}","${nome}","${email}","${telefono}"`);
}
});
const blob = new Blob([rows.join('\n')], { type: 'text/csv' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `individui_selezionati_${new Date().toISOString().slice(0,10)}.csv`;
a.click();
}
function printSelected() {
const selectedIds = getSelectedIds();
if (selectedIds.length === 0) {
alert('Seleziona almeno un individuo');
return;
}
window.open(`/individui/report/stampa?ids=${selectedIds.join(',')}`, '_blank');
}
function emailSelected() {
const selectedIds = getSelectedIds();
if (selectedIds.length === 0) {
alert('Seleziona almeno un individuo');
return;
}
window.location.href = `/mailing/nuovo?individui=${selectedIds.join(',')}`;
}
function deleteSelected() {
const selectedIds = getSelectedIds();
if (selectedIds.length === 0) {
alert('Seleziona almeno un individuo');
return;
}
document.getElementById('delete-individuo-name').textContent = selectedIds.length + ' individui selezionati';
document.getElementById('count-contatti').textContent = '...';
document.getElementById('count-gruppi').textContent = '...';
document.getElementById('count-documenti').textContent = '...';
document.getElementById('count-eventi').textContent = '...';
document.getElementById('confirm-delete-btn').onclick = function() {
const eliminaContatti = document.getElementById('delete-contatti').checked;
const eliminaDocumenti = document.getElementById('delete-documenti').checked;
const form = document.createElement('form');
form.method = 'POST';
form.action = '/individui/mass-elimina';
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.content || '<?php echo e(csrf_token()); ?>';
let html = `<input type="hidden" name="_token" value="${csrfToken}">`;
html += `<input type="hidden" name="elimina_contatti" value="${eliminaContatti}">`;
html += `<input type="hidden" name="elimina_documenti" value="${eliminaDocumenti}">`;
selectedIds.forEach(function(id) {
html += `<input type="hidden" name="ids[]" value="${id}">`;
});
form.innerHTML = html;
document.body.appendChild(form);
form.submit();
};
$('#deleteModal').modal('show');
}
document.addEventListener('DOMContentLoaded', function() {
const csrfToken = document.querySelector('meta[name="csrf-token"]');
if (!csrfToken) {
const meta = document.createElement('meta');
meta.name = 'csrf-token';
meta.content = '<?php echo e(csrf_token()); ?>';
document.head.appendChild(meta);
}
const visibleCols = <?php echo $visibleColumnsJson; ?>;
const allCols = <?php echo $allColumnsJson; ?>;
allCols.forEach(function(col) {
const visibile = visibleCols.includes(col.key);
const saveCheckbox = document.querySelector(`#col-vis-${col.key}`);
const toggleCheckbox = document.querySelector(`#col-toggle-${col.key}`);
if (saveCheckbox) saveCheckbox.checked = visibile;
if (toggleCheckbox) toggleCheckbox.checked = visibile;
});
const vistaDefault = <?php echo $vistaDefaultJson; ?>;
if (vistaDefault && vistaDefault.ricerca) {
document.getElementById('global-search').value = vistaDefault.ricerca;
applyGlobalSearch(vistaDefault.ricerca);
}
});
function showCreateMailingListModal() {
document.getElementById('ml-nome').value = '';
document.getElementById('ml-descrizione').value = '';
document.getElementById('ml-contatti-tbody').innerHTML = '';
document.getElementById('ml-count').textContent = '0';
const selectedIds = getSelectedIds();
console.log('Selected IDs:', selectedIds);
if (selectedIds.length > 0) {
const url = '/individui/email-list?ids=' + selectedIds.join(',');
console.log('Fetching URL:', url);
fetch(url, {
credentials: 'include',
headers: {
'Accept': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(response => {
console.log('Response status:', response.status);
console.log('Response type:', response.headers.get('content-type'));
if (!response.ok) {
return response.text().then(text => {
console.log('Full error response:', text.substring(0, 500));
const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('application/json')) {
const json = JSON.parse(text);
throw new Error(json.message || 'Errore HTTP ' + response.status);
} else {
throw new Error('Server returned HTML (status ' + response.status + ') - probabilmente sessione scaduta. Ricarica la pagina.');
}
});
}
return response.json();
})
.then(data => {
console.log('Data:', data);
updateMlTable(data);
})
.catch(function(err) {
console.error('Error:', err);
alert('Errore caricamento contatti: ' + err.message + '\nURL: ' + url);
});
} else {
alert('Seleziona almeno un individuo dalla tabella');
}
$('#createMailingListModal').modal('show');
}
function updateMlTable(data) {
const tbody = document.getElementById('ml-contatti-tbody');
const existingIds = new Set();
document.querySelectorAll('.ml-row-checkbox').forEach(function(cb) {
existingIds.add(parseInt(cb.value));
});
data.forEach(function(item) {
if (existingIds.has(item.id)) return;
const tr = document.createElement('tr');
const checked = item.email_count === 1 ? 'checked' : '';
tr.innerHTML = `
<td>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input ml-row-checkbox" id="ml-${item.id}" value="${item.id}" data-email="${item.email || ''}" ${checked}>
<label class="custom-control-label" for="ml-${item.id}"></label>
</div>
</td>
<td><span class="badge badge-secondary">${item.codice_id}</span></td>
<td>${item.cognome}</td>
<td>${item.nome}</td>
<td>
${item.email_count === 1 ? (item.email || '-') :
'<select class="form-control form-control-sm" onchange="updateMlCheckboxEmail(' + item.id + ', this.value)">' +
'<option value="">Seleziona email...</option>' +
(item.emails || []).map(function(e) { return '<option value="' + e + '">' + e + '</option>'; }).join('') +
'</select>'}
</td>
<td>
<button type="button" class="btn btn-xs btn-danger" onclick="this.closest('tr').remove(); updateMlCount();">
<i class="fas fa-times"></i>
</button>
</td>
`;
tbody.appendChild(tr);
});
updateMlCount();
}
function updateMlCount() {
document.getElementById('ml-count').textContent = document.querySelectorAll('.ml-row-checkbox').length;
}
function toggleMlSelectAll(source) {
document.querySelectorAll('.ml-row-checkbox').forEach(function(cb) {
cb.checked = source.checked;
});
}
function updateMlCheckboxEmail(id, email) {
const checkbox = document.getElementById('ml-' + id);
if (checkbox) {
checkbox.dataset.email = email;
checkbox.checked = email !== '';
}
}
async function createMailingList() {
const nome = document.getElementById('ml-nome').value.trim();
if (!nome) {
alert('Inserisci un nome per la lista');
return;
}
const selected = [];
document.querySelectorAll('.ml-row-checkbox:checked').forEach(function(cb) {
if (cb.dataset.email) {
selected.push({
individuo_id: parseInt(cb.value),
email: cb.dataset.email
});
}
});
if (selected.length === 0) {
alert('Seleziona almeno un contatto con email');
return;
}
const data = {
nome: nome,
descrizione: document.getElementById('ml-descrizione').value.trim(),
contatti: selected
};
try {
const response = await fetch('/mailing-liste/create-from-individui', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.content || ''
},
body: JSON.stringify(data)
});
if (response.ok) {
alert('Mailing list creata con successo!');
$('#createMailingListModal').modal('hide');
} else {
alert('Errore nella creazione della lista');
}
} catch(e) {
alert('Errore: ' + e.message);
}
}
</script>
<?php $__env->stopSection(); ?>
<?php echo $__env->make('layouts.adminlte', array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?><?php /**PATH /var/www/html/glastree/resources/views/individui/index.blade.php ENDPATH**/ ?>
@@ -1,108 +0,0 @@
<?php
use App\Models\AppSetting;
$appLogo = AppSetting::getLogoUrl();
$appName = AppSetting::getAppName() ?? 'Glastree';
$appOrgName = AppSetting::getOrgName() ?? '';
?>
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Accedi - <?php echo e(e($appName)); ?></title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/admin-lte@3.2/dist/css/adminlte.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
</head>
<body class="hold-transition login-page">
<div class="login-box">
<div class="login-logo">
<a href="/">
<?php if($appLogo): ?>
<img src="<?php echo e($appLogo); ?>" alt="Logo" style="max-height: 80px; max-width: 200px;">
<?php else: ?>
<i class="fas fa-tree text-success"></i> <b><?php echo e(e($appName)); ?></b>
<?php endif; ?>
</a>
</div>
<?php if($appOrgName): ?>
<div class="text-center mb-3">
<small class="text-muted"><?php echo e(e($appOrgName)); ?></small>
</div>
<?php endif; ?>
<div class="card">
<div class="card-body login-card-body">
<p class="login-box-msg">Accedi per continuare</p>
<form action="<?php echo e(route('login')); ?>" method="POST">
<?php echo csrf_field(); ?>
<div class="input-group mb-3">
<input type="email" name="email" class="form-control <?php $__errorArgs = ['email'];
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
if ($__bag->has($__errorArgs[0])) :
if (isset($message)) { $__messageOriginal = $message; }
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
endif;
unset($__errorArgs, $__bag); ?>" placeholder="Email" required>
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-envelope"></span>
</div>
</div>
<?php $__errorArgs = ['email'];
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
if ($__bag->has($__errorArgs[0])) :
if (isset($message)) { $__messageOriginal = $message; }
$message = $__bag->first($__errorArgs[0]); ?>
<span class="invalid-feedback"><?php echo e($message); ?></span>
<?php unset($message);
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
endif;
unset($__errorArgs, $__bag); ?>
</div>
<div class="input-group mb-3">
<input type="password" name="password" class="form-control <?php $__errorArgs = ['password'];
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
if ($__bag->has($__errorArgs[0])) :
if (isset($message)) { $__messageOriginal = $message; }
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
endif;
unset($__errorArgs, $__bag); ?>" placeholder="Password" required>
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-lock"></span>
</div>
</div>
<?php $__errorArgs = ['password'];
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
if ($__bag->has($__errorArgs[0])) :
if (isset($message)) { $__messageOriginal = $message; }
$message = $__bag->first($__errorArgs[0]); ?>
<span class="invalid-feedback"><?php echo e($message); ?></span>
<?php unset($message);
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
endif;
unset($__errorArgs, $__bag); ?>
</div>
<div class="row">
<div class="col-8">
<div class="icheck-primary">
<input type="checkbox" id="remember" name="remember">
<label for="remember">Ricordami</label>
</div>
</div>
<div class="col-4">
<button type="submit" class="btn btn-success btn-block">Accedi</button>
</div>
</div>
</form>
<p class="mb-0 text-center mt-3">
<a href="<?php echo e(route('password.request')); ?>" class="text-center">Password dimenticata?</a>
</p>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html><?php /**PATH /var/www/html/glastree/resources/views/auth/login.blade.php ENDPATH**/ ?>
@@ -1,301 +0,0 @@
<?php
$appLogoSmall = \App\Models\AppSetting::getLogoSmallUrl();
$appName = \App\Models\AppSetting::getAppName() ?? 'Glastree';
?>
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="<?php echo e(csrf_token()); ?>">
<title><?php echo $__env->yieldContent('title', e($appName)); ?></title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/admin-lte@3.2/dist/css/adminlte.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@300;400;600;700&display=swap">
<?php echo $__env->yieldContent('styles'); ?>
</head>
<body class="hold-transition sidebar-mini layout-fixed">
<div class="wrapper">
<nav class="main-header navbar navbar-expand navbar-white navbar-light">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" data-widget="pushmenu" href="#" role="button"><i class="fas fa-bars"></i></a>
</li>
</ul>
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" href="<?php echo e(route('help')); ?>" title="Guida">
<i class="fas fa-question-circle"></i>
</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link" data-toggle="dropdown" href="#">
<i class="far fa-bell"></i>
<?php $unread = Auth::user()->unreadNotificheCount() ?? 0 ?>
<?php if($unread > 0): ?>
<span class="badge badge-warning navbar-badge"><?php echo e($unread); ?></span>
<?php endif; ?>
</a>
<div class="dropdown-menu dropdown-menu-right">
<span class="dropdown-header">Notifiche (<?php echo e($unread); ?>)</span>
<div class="dropdown-divider"></div>
<a href="#" class="dropdown-item">Visualizza tutte</a>
</div>
</li>
<li class="nav-item dropdown">
<a class="nav-link" data-toggle="dropdown" href="#">
<i class="fas fa-user"></i> <?php echo e(Auth::user()->name); ?>
</a>
<div class="dropdown-menu dropdown-menu-right">
<a href="<?php echo e(route('profile')); ?>" class="dropdown-item">
<i class="fas fa-user-cog mr-2"></i> Profilo
</a>
<div class="dropdown-divider"></div>
<form method="POST" action="<?php echo e(route('logout')); ?>">
<?php echo csrf_field(); ?>
<button type="submit" class="dropdown-item">
<i class="fas fa-sign-out-alt mr-2"></i> Esci
</button>
</form>
</div>
</li>
</ul>
</nav>
<?php
$appLogoSmall = \App\Models\AppSetting::getLogoSmallUrl();
$appName = \App\Models\AppSetting::getAppName() ?? 'Glastree';
?>
<aside class="main-sidebar sidebar-dark-primary elevation-4">
<a href="<?php echo e(route('dashboard')); ?>" class="brand-link">
<?php if($appLogoSmall): ?>
<img src="<?php echo e($appLogoSmall); ?>" alt="Logo" class="brand-image" style="max-height: 35px; max-width: 40px;">
<?php else: ?>
<i class="fas fa-tree brand-image ml-3 mr-2"></i>
<?php endif; ?>
<span class="brand-text font-weight-light"><?php echo e($appName); ?></span>
</a>
<div class="sidebar">
<nav class="mt-2">
<ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu">
<li class="nav-item">
<a href="<?php echo e(route('dashboard')); ?>" class="nav-link <?php echo e(request()->routeIs('dashboard') ? 'active' : ''); ?>">
<i class="nav-icon fas fa-tachometer-alt"></i>
<p>Dashboard</p>
</a>
</li>
<?php if(Auth::user()->canAccess('individui')): ?>
<li class="nav-item">
<a href="<?php echo e(route('individui.index')); ?>" class="nav-link">
<i class="nav-icon fas fa-users"></i>
<p>Individui</p>
</a>
</li>
<?php endif; ?>
<?php if(Auth::user()->canAccess('gruppi')): ?>
<li class="nav-item">
<a href="<?php echo e(route('gruppi.index')); ?>" class="nav-link">
<i class="nav-icon fas fa-folder"></i>
<p>Gruppi</p>
</a>
</li>
<?php endif; ?>
<?php if(Auth::user()->canAccess('documenti')): ?>
<li class="nav-item">
<a href="<?php echo e(route('documenti.index')); ?>" class="nav-link">
<i class="nav-icon fas fa-file"></i>
<p>Documenti</p>
</a>
</li>
<?php endif; ?>
<?php if(Auth::user()->canAccess('eventi')): ?>
<li class="nav-item has-treeview">
<a href="<?php echo e(route('eventi.calendar')); ?>" class="nav-link">
<i class="nav-icon fas fa-calendar"></i>
<p>Eventi <i class="right fas fa-angle-left" style="font-size: 0.8rem;"></i></p>
</a>
<ul class="nav nav-treeview">
<li class="nav-item">
<a href="<?php echo e(route('eventi.calendar')); ?>" class="nav-link">
<i class="nav-icon fas fa-calendar-alt"></i>
<p>Calendario</p>
</a>
</li>
<li class="nav-item">
<a href="<?php echo e(route('eventi.index')); ?>" class="nav-link">
<i class="nav-icon fas fa-list"></i>
<p>Elenco</p>
</a>
</li>
<li class="nav-item">
<a href="<?php echo e(route('eventi.create')); ?>" class="nav-link">
<i class="nav-icon fas fa-plus"></i>
<p>Nuovo Evento</p>
</a>
</li>
</ul>
</li>
<?php endif; ?>
<?php if(Auth::user()->canAccess('email') || Auth::user()->canAccess('mailing')): ?>
<li class="nav-item has-treeview">
<a href="<?php echo e(route('email.index', 'inbox')); ?>" class="nav-link">
<i class="nav-icon fas fa-envelope"></i>
<p>Email <i class="right fas fa-angle-left" style="font-size: 0.8rem;"></i></p>
</a>
<ul class="nav nav-treeview">
<?php if(Auth::user()->canAccess('email')): ?>
<li class="nav-item">
<a href="<?php echo e(route('email.compose')); ?>" class="nav-link">
<i class="nav-icon fas fa-plus"></i>
<p>Nuova Email</p>
</a>
</li>
<li class="nav-item">
<a href="<?php echo e(route('email.index', 'inbox')); ?>" class="nav-link">
<i class="nav-icon fas fa-inbox"></i>
<p>In arrivo</p>
</a>
</li>
<li class="nav-item">
<a href="<?php echo e(route('email.index', 'starred')); ?>" class="nav-link">
<i class="nav-icon fas fa-star"></i>
<p>Preferiti</p>
</a>
</li>
<li class="nav-item">
<a href="<?php echo e(route('email.index', 'sent')); ?>" class="nav-link">
<i class="nav-icon fas fa-paper-plane"></i>
<p>Inviate</p>
</a>
</li>
<li class="nav-item">
<a href="<?php echo e(route('email.index', 'drafts')); ?>" class="nav-link">
<i class="nav-icon fas fa-edit"></i>
<p>Bozze</p>
</a>
</li>
<li class="nav-item">
<a href="<?php echo e(route('email.index', 'archive')); ?>" class="nav-link">
<i class="nav-icon fas fa-archive"></i>
<p>Archivio</p>
</a>
</li>
<li class="nav-item">
<a href="<?php echo e(route('email.index', 'trash')); ?>" class="nav-link">
<i class="nav-icon fas fa-trash"></i>
<p>Cestino</p>
</a>
</li>
<?php endif; ?>
</ul>
</li>
<?php endif; ?>
<?php if(Auth::user()->canAccess('mailing')): ?>
<li class="nav-item">
<a href="<?php echo e(route('mailing-liste.index')); ?>" class="nav-link">
<i class="nav-icon fas fa-list"></i>
<p>Mailing List</p>
</a>
</li>
<?php endif; ?>
<?php if(Auth::user()->canAccess('report')): ?>
<li class="nav-item">
<a href="<?php echo e(route('report.index')); ?>" class="nav-link <?php echo e(request()->routeIs('report.*') ? 'active' : ''); ?>">
<i class="nav-icon fas fa-chart-bar"></i>
<p>Report</p>
</a>
</li>
<?php endif; ?>
<?php if(Auth::user()->canManage('settings')): ?>
<li class="nav-item">
<a href="/impostazioni" class="nav-link <?php echo e(request()->is('impostazioni*') ? 'active' : ''); ?>">
<i class="nav-icon fas fa-cog"></i>
<p>Impostazioni</p>
</a>
</li>
<li class="nav-item has-treeview <?php echo e(request()->is('admin/*') ? 'menu-open' : ''); ?>">
<a href="#" class="nav-link <?php echo e(request()->is('admin/*') ? 'active' : ''); ?>">
<i class="nav-icon fas fa-users-cog"></i>
<p>Admin <i class="right fas fa-angle-left" style="font-size: 0.8rem;"></i></p>
</a>
<ul class="nav nav-treeview">
<li class="nav-item">
<a href="/admin/utenti" class="nav-link <?php echo e(request()->routeIs('admin.utenti.*') ? 'active' : ''); ?>">
<i class="nav-icon fas fa-user-shield"></i>
<p>Utenti</p>
</a>
</li>
<li class="nav-item">
<a href="<?php echo e(route('admin.ruoli.index')); ?>" class="nav-link <?php echo e(request()->routeIs('admin.ruoli.*') ? 'active' : ''); ?>">
<i class="nav-icon fas fa-tag"></i>
<p>Ruoli</p>
</a>
</li>
<li class="nav-item">
<a href="/admin/backup" class="nav-link <?php echo e(request()->routeIs('admin.backup.*') ? 'active' : ''); ?>">
<i class="nav-icon fas fa-hdd"></i>
<p>Backup</p>
</a>
</li>
<li class="nav-item">
<a href="<?php echo e(route('admin.activity-logs.index')); ?>" class="nav-link <?php echo e(request()->routeIs('admin.activity-logs.*') ? 'active' : ''); ?>">
<i class="nav-icon fas fa-history"></i>
<p>Log Attività</p>
</a>
</li>
</ul>
</li>
<?php endif; ?>
<li class="nav-item">
<a href="<?php echo e(route('help')); ?>" class="nav-link <?php echo e(request()->routeIs('help') ? 'active' : ''); ?>">
<i class="nav-icon fas fa-question-circle"></i>
<p>Guida / Aiuto</p>
</a>
</li>
</ul>
</nav>
</div>
</aside>
<div class="content-wrapper" style="min-height: calc(100vh - 120px);">
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6">
<h1 class="m-0"><?php echo $__env->yieldContent('page_title', 'Dashboard'); ?></h1>
</div>
<div class="col-sm-6">
<ol class="breadcrumb float-sm-right">
<?php echo $__env->yieldContent('breadcrumbs'); ?>
</ol>
</div>
</div>
</div>
</div>
<div class="content">
<div class="container-fluid">
<?php echo $slot ?? ''; ?>
<?php echo $__env->yieldContent('content'); ?>
</div>
</div>
</div>
<footer class="main-footer">
<strong><?php echo e(\App\Models\AppSetting::getFooterText()); ?></strong>
<?php if(\App\Models\AppSetting::shouldShowVersion() && \App\Models\AppSetting::getAppVersion()): ?>
<span class="ml-2">v<?php echo e(\App\Models\AppSetting::getAppVersion()); ?></span>
<?php endif; ?>
</footer>
</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/admin-lte@3.2/dist/js/adminlte.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<?php echo $__env->yieldContent('scripts'); ?>
</body>
</html><?php /**PATH /var/www/html/glastree/resources/views/layouts/adminlte.blade.php ENDPATH**/ ?>
-122
View File
@@ -1,122 +0,0 @@
#!/usr/bin/env php
<?php
/**
* Proxy PHP file generated by Composer
*
* This file includes the referenced bin path (../phpunit/phpunit/phpunit)
* using a stream wrapper to prevent the shebang from being output on PHP<8
*
* @generated
*/
namespace Composer;
$GLOBALS['_composer_bin_dir'] = __DIR__;
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
$GLOBALS['__PHPUNIT_ISOLATION_EXCLUDE_LIST'] = $GLOBALS['__PHPUNIT_ISOLATION_BLACKLIST'] = array(realpath(__DIR__ . '/..'.'/phpunit/phpunit/phpunit'));
if (PHP_VERSION_ID < 80000) {
if (!class_exists('Composer\BinProxyWrapper')) {
/**
* @internal
*/
final class BinProxyWrapper
{
private $handle;
private $position;
private $realpath;
public function stream_open($path, $mode, $options, &$opened_path)
{
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
$opened_path = substr($path, 17);
$this->realpath = realpath($opened_path) ?: $opened_path;
$opened_path = 'phpvfscomposer://'.$this->realpath;
$this->handle = fopen($this->realpath, $mode);
$this->position = 0;
return (bool) $this->handle;
}
public function stream_read($count)
{
$data = fread($this->handle, $count);
if ($this->position === 0) {
$data = preg_replace('{^#!.*\r?\n}', '', $data);
}
$data = str_replace('__DIR__', var_export(dirname($this->realpath), true), $data);
$data = str_replace('__FILE__', var_export($this->realpath, true), $data);
$this->position += strlen($data);
return $data;
}
public function stream_cast($castAs)
{
return $this->handle;
}
public function stream_close()
{
fclose($this->handle);
}
public function stream_lock($operation)
{
return $operation ? flock($this->handle, $operation) : true;
}
public function stream_seek($offset, $whence)
{
if (0 === fseek($this->handle, $offset, $whence)) {
$this->position = ftell($this->handle);
return true;
}
return false;
}
public function stream_tell()
{
return $this->position;
}
public function stream_eof()
{
return feof($this->handle);
}
public function stream_stat()
{
return array();
}
public function stream_set_option($option, $arg1, $arg2)
{
return true;
}
public function url_stat($path, $flags)
{
$path = substr($path, 17);
if (file_exists($path)) {
return stat($path);
}
return false;
}
}
}
if (
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
) {
return include("phpvfscomposer://" . __DIR__ . '/..'.'/phpunit/phpunit/phpunit');
}
}
return include __DIR__ . '/..'.'/phpunit/phpunit/phpunit';
-119
View File
@@ -1,119 +0,0 @@
#!/usr/bin/env php
<?php
/**
* Proxy PHP file generated by Composer
*
* This file includes the referenced bin path (../laravel/pint/builds/pint)
* using a stream wrapper to prevent the shebang from being output on PHP<8
*
* @generated
*/
namespace Composer;
$GLOBALS['_composer_bin_dir'] = __DIR__;
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
if (PHP_VERSION_ID < 80000) {
if (!class_exists('Composer\BinProxyWrapper')) {
/**
* @internal
*/
final class BinProxyWrapper
{
private $handle;
private $position;
private $realpath;
public function stream_open($path, $mode, $options, &$opened_path)
{
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
$opened_path = substr($path, 17);
$this->realpath = realpath($opened_path) ?: $opened_path;
$opened_path = $this->realpath;
$this->handle = fopen($this->realpath, $mode);
$this->position = 0;
return (bool) $this->handle;
}
public function stream_read($count)
{
$data = fread($this->handle, $count);
if ($this->position === 0) {
$data = preg_replace('{^#!.*\r?\n}', '', $data);
}
$this->position += strlen($data);
return $data;
}
public function stream_cast($castAs)
{
return $this->handle;
}
public function stream_close()
{
fclose($this->handle);
}
public function stream_lock($operation)
{
return $operation ? flock($this->handle, $operation) : true;
}
public function stream_seek($offset, $whence)
{
if (0 === fseek($this->handle, $offset, $whence)) {
$this->position = ftell($this->handle);
return true;
}
return false;
}
public function stream_tell()
{
return $this->position;
}
public function stream_eof()
{
return feof($this->handle);
}
public function stream_stat()
{
return array();
}
public function stream_set_option($option, $arg1, $arg2)
{
return true;
}
public function url_stat($path, $flags)
{
$path = substr($path, 17);
if (file_exists($path)) {
return stat($path);
}
return false;
}
}
}
if (
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
) {
return include("phpvfscomposer://" . __DIR__ . '/..'.'/laravel/pint/builds/pint');
}
}
return include __DIR__ . '/..'.'/laravel/pint/builds/pint';
+5 -2094
View File
File diff suppressed because it is too large Load Diff
+3 -10
View File
@@ -11,11 +11,11 @@ return array(
'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php',
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
'8825ede83f2f289127722d4e842cf7e8' => $vendorDir . '/symfony/polyfill-intl-grapheme/bootstrap.php',
'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php',
'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php',
'383eaff206634a77a1be54e64e6459c7' => $vendorDir . '/sabre/uri/lib/functions.php',
'8825ede83f2f289127722d4e842cf7e8' => $vendorDir . '/symfony/polyfill-intl-grapheme/bootstrap.php',
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => $vendorDir . '/symfony/polyfill-iconv/bootstrap.php',
'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php',
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
@@ -27,15 +27,13 @@ return array(
'2203a247e6fda86070a5e4e07aed533a' => $vendorDir . '/symfony/clock/Resources/now.php',
'606a39d89246991a373564698c2d8383' => $vendorDir . '/symfony/polyfill-php85/bootstrap.php',
'a1105708a18b76903365ca1c4aa61b02' => $vendorDir . '/symfony/translation/Resources/functions.php',
'35a6ad97d21e794e7e22a17d806652e4' => $vendorDir . '/nunomaduro/termwind/src/Functions.php',
'b33e3d135e5d9e47d845c576147bda89' => $vendorDir . '/php-di/php-di/src/functions.php',
'1f87db08236948d07391152dccb70f04' => $vendorDir . '/google/apiclient-services/autoload.php',
'ebdb698ed4152ae445614b69b5e4bb6a' => $vendorDir . '/sabre/http/lib/functions.php',
'09f6b20656683369174dd6fa83b7e5fb' => $vendorDir . '/symfony/polyfill-uuid/bootstrap.php',
'a8d3953fd9959404dd22d3dfcd0a79f0' => $vendorDir . '/google/apiclient/src/aliases.php',
'23dd7ece5822da3d0100ef3deb0ef55f' => $vendorDir . '/laravel/agent-detector/src/functions.php',
'47e1160838b5e5a10346ac4084b58c23' => $vendorDir . '/laravel/prompts/src/helpers.php',
'6124b4c8570aa390c21fafd04a26c69f' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
'35a6ad97d21e794e7e22a17d806652e4' => $vendorDir . '/nunomaduro/termwind/src/Functions.php',
'801c31d8ed748cfa537fa45402288c95' => $vendorDir . '/psy/psysh/src/functions.php',
'e39a8b23c42d4e1452234d762b03835a' => $vendorDir . '/ramsey/uuid/src/functions.php',
'9d2b9fc6db0f153a0a149fefb182415e' => $vendorDir . '/symfony/polyfill-php84/bootstrap.php',
@@ -49,10 +47,5 @@ return array(
'91892b814db86b8442ad76273bb7aec5' => $vendorDir . '/laravel/framework/src/Illuminate/Reflection/helpers.php',
'493c6aea52f6009bab023b26c21a386a' => $vendorDir . '/laravel/framework/src/Illuminate/Support/functions.php',
'58571171fd5812e6e447dce228f52f4d' => $vendorDir . '/laravel/framework/src/Illuminate/Support/helpers.php',
'309cd39bb536ff667b25a3a76938cb83' => $vendorDir . '/laravel/pao/src/Autoload.php',
'c72349b1fe8d0deeedd3a52e8aa814d8' => $vendorDir . '/mockery/mockery/library/helpers.php',
'ce9671a430e4846b44e1c68c7611f9f5' => $vendorDir . '/mockery/mockery/library/Mockery.php',
'a1cfe24d14977df6878b9bf804af2d1c' => $vendorDir . '/nunomaduro/collision/src/Adapters/Phpunit/Autoload.php',
'ec07570ca5a812141189b1fa81503674' => $vendorDir . '/phpunit/phpunit/src/Framework/Assert/Functions.php',
'377b22b161c09ed6e5152de788ca020a' => $vendorDir . '/spatie/laravel-permission/src/helpers.php',
);
+3 -12
View File
@@ -10,10 +10,8 @@ return array(
'ZBateson\\StreamDecorators\\' => array($vendorDir . '/zbateson/stream-decorators/src'),
'ZBateson\\MbWrapper\\' => array($vendorDir . '/zbateson/mb-wrapper/src'),
'ZBateson\\MailMimeParser\\' => array($vendorDir . '/zbateson/mail-mime-parser/src'),
'Whoops\\' => array($vendorDir . '/filp/whoops/src/Whoops'),
'Webklex\\PHPIMAP\\' => array($vendorDir . '/webklex/php-imap/src'),
'TijsVerkoyen\\CssToInlineStyles\\' => array($vendorDir . '/tijsverkoyen/css-to-inline-styles/src'),
'Tests\\' => array($baseDir . '/tests'),
'Termwind\\' => array($vendorDir . '/nunomaduro/termwind/src'),
'Symfony\\Polyfill\\Uuid\\' => array($vendorDir . '/symfony/polyfill-uuid'),
'Symfony\\Polyfill\\Php86\\' => array($vendorDir . '/symfony/polyfill-php86'),
@@ -66,10 +64,8 @@ return array(
'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'),
'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'),
'PhpOption\\' => array($vendorDir . '/phpoption/phpoption/src/PhpOption'),
'NunoMaduro\\Collision\\' => array($vendorDir . '/nunomaduro/collision/src'),
'Nette\\' => array($vendorDir . '/nette/schema/src', $vendorDir . '/nette/utils/src'),
'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
'Mockery\\' => array($vendorDir . '/mockery/mockery/library/Mockery'),
'League\\Uri\\' => array($vendorDir . '/league/uri', $vendorDir . '/league/uri-interfaces'),
'League\\MimeTypeDetection\\' => array($vendorDir . '/league/mime-type-detection/src'),
'League\\Flysystem\\WebDAV\\' => array($vendorDir . '/league/flysystem-webdav'),
@@ -80,9 +76,6 @@ return array(
'Laravel\\Tinker\\' => array($vendorDir . '/laravel/tinker/src'),
'Laravel\\SerializableClosure\\' => array($vendorDir . '/laravel/serializable-closure/src'),
'Laravel\\Prompts\\' => array($vendorDir . '/laravel/prompts/src'),
'Laravel\\Pao\\' => array($vendorDir . '/laravel/pao/src'),
'Laravel\\Pail\\' => array($vendorDir . '/laravel/pail/src'),
'Laravel\\AgentDetector\\' => array($vendorDir . '/laravel/agent-detector/src'),
'Invoker\\' => array($vendorDir . '/php-di/invoker/src'),
'Illuminate\\Support\\' => array($vendorDir . '/laravel/framework/src/Illuminate/Macroable', $vendorDir . '/laravel/framework/src/Illuminate/Collections', $vendorDir . '/laravel/framework/src/Illuminate/Conditionable', $vendorDir . '/laravel/framework/src/Illuminate/Reflection'),
'Illuminate\\' => array($vendorDir . '/laravel/framework/src/Illuminate'),
@@ -96,7 +89,6 @@ return array(
'Google\\' => array($vendorDir . '/google/apiclient/src'),
'Fruitcake\\Cors\\' => array($vendorDir . '/fruitcake/php-cors/src'),
'Firebase\\JWT\\' => array($vendorDir . '/firebase/php-jwt/src'),
'Faker\\' => array($vendorDir . '/fakerphp/faker/src/Faker'),
'Egulias\\EmailValidator\\' => array($vendorDir . '/egulias/email-validator/src'),
'Dotenv\\' => array($vendorDir . '/vlucas/phpdotenv/src'),
'Doctrine\\Inflector\\' => array($vendorDir . '/doctrine/inflector/src'),
@@ -104,9 +96,8 @@ return array(
'DirectoryTree\\ImapEngine\\Laravel\\' => array($vendorDir . '/directorytree/imapengine-laravel/src'),
'DirectoryTree\\ImapEngine\\' => array($vendorDir . '/directorytree/imapengine/src'),
'Dflydev\\DotAccessData\\' => array($vendorDir . '/dflydev/dot-access-data/src'),
'DeepCopy\\' => array($vendorDir . '/myclabs/deep-copy/src/DeepCopy'),
'Database\\Seeders\\' => array($baseDir . '/database/seeders', $vendorDir . '/laravel/pint/database/seeders'),
'Database\\Factories\\' => array($baseDir . '/database/factories', $vendorDir . '/laravel/pint/database/factories'),
'Database\\Seeders\\' => array($baseDir . '/database/seeders'),
'Database\\Factories\\' => array($baseDir . '/database/factories'),
'DI\\' => array($vendorDir . '/php-di/php-di/src'),
'Cron\\' => array($vendorDir . '/dragonmantank/cron-expression/src/Cron'),
'Carbon\\Doctrine\\' => array($vendorDir . '/carbonphp/carbon-doctrine-types/src/Carbon/Doctrine'),
@@ -114,5 +105,5 @@ return array(
'Brick\\Math\\' => array($vendorDir . '/brick/math/src'),
'As247\\Flysystem\\GoogleDrive\\' => array($vendorDir . '/as247/flysystem-google-drive/src'),
'As247\\CloudStorages\\' => array($vendorDir . '/as247/cloud-storages/src'),
'App\\' => array($baseDir . '/app', $vendorDir . '/laravel/pint/app'),
'App\\' => array($baseDir . '/app'),
);
+8 -2152
View File
File diff suppressed because it is too large Load Diff
+2 -2405
View File
File diff suppressed because it is too large Load Diff
+3 -318
View File
@@ -3,11 +3,11 @@
'name' => 'laravel/laravel',
'pretty_version' => 'dev-main',
'version' => 'dev-main',
'reference' => 'aa4e582925ec155fa08dbeb9bf4e3a97b4751df1',
'reference' => 'f9c1268466e9f534c2f1ade6e5bb4bddfbaa56e5',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev' => true,
'dev' => false,
),
'versions' => array(
'as247/cloud-storages' => array(
@@ -46,18 +46,6 @@
'aliases' => array(),
'dev_requirement' => false,
),
'cordoval/hamcrest-php' => array(
'dev_requirement' => true,
'replaced' => array(
0 => '*',
),
),
'davedevelopment/hamcrest-php' => array(
'dev_requirement' => true,
'replaced' => array(
0 => '*',
),
),
'dflydev/dot-access-data' => array(
'pretty_version' => 'v3.0.3',
'version' => '3.0.3.0',
@@ -121,24 +109,6 @@
'aliases' => array(),
'dev_requirement' => false,
),
'fakerphp/faker' => array(
'pretty_version' => 'v1.24.1',
'version' => '1.24.1.0',
'reference' => 'e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5',
'type' => 'library',
'install_path' => __DIR__ . '/../fakerphp/faker',
'aliases' => array(),
'dev_requirement' => true,
),
'filp/whoops' => array(
'pretty_version' => '2.18.4',
'version' => '2.18.4.0',
'reference' => 'd2102955e48b9fd9ab24280a7ad12ed552752c4d',
'type' => 'library',
'install_path' => __DIR__ . '/../filp/whoops',
'aliases' => array(),
'dev_requirement' => true,
),
'firebase/php-jwt' => array(
'pretty_version' => 'v7.0.5',
'version' => '7.0.5.0',
@@ -229,15 +199,6 @@
'aliases' => array(),
'dev_requirement' => false,
),
'hamcrest/hamcrest-php' => array(
'pretty_version' => 'v2.1.1',
'version' => '2.1.1.0',
'reference' => 'f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487',
'type' => 'library',
'install_path' => __DIR__ . '/../hamcrest/hamcrest-php',
'aliases' => array(),
'dev_requirement' => true,
),
'illuminate/auth' => array(
'dev_requirement' => false,
'replaced' => array(
@@ -454,21 +415,6 @@
0 => 'v13.8.0',
),
),
'kodova/hamcrest-php' => array(
'dev_requirement' => true,
'replaced' => array(
0 => '*',
),
),
'laravel/agent-detector' => array(
'pretty_version' => 'v2.0.2',
'version' => '2.0.2.0',
'reference' => '90694b9256099591cf9e55d08c18ba7a00bf099f',
'type' => 'library',
'install_path' => __DIR__ . '/../laravel/agent-detector',
'aliases' => array(),
'dev_requirement' => true,
),
'laravel/framework' => array(
'pretty_version' => 'v13.8.0',
'version' => '13.8.0.0',
@@ -481,39 +427,12 @@
'laravel/laravel' => array(
'pretty_version' => 'dev-main',
'version' => 'dev-main',
'reference' => 'aa4e582925ec155fa08dbeb9bf4e3a97b4751df1',
'reference' => 'f9c1268466e9f534c2f1ade6e5bb4bddfbaa56e5',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev_requirement' => false,
),
'laravel/pail' => array(
'pretty_version' => 'v1.2.6',
'version' => '1.2.6.0',
'reference' => 'aa71a01c309e7f66bc2ec4fb1a59291b82eb4abf',
'type' => 'library',
'install_path' => __DIR__ . '/../laravel/pail',
'aliases' => array(),
'dev_requirement' => true,
),
'laravel/pao' => array(
'pretty_version' => 'v1.0.6',
'version' => '1.0.6.0',
'reference' => '02f62a64c2b60af44a418ee490fee193590d8269',
'type' => 'library',
'install_path' => __DIR__ . '/../laravel/pao',
'aliases' => array(),
'dev_requirement' => true,
),
'laravel/pint' => array(
'pretty_version' => 'v1.29.1',
'version' => '1.29.1.0',
'reference' => '0770e9b7fafd50d4586881d456d6eb41c9247a80',
'type' => 'project',
'install_path' => __DIR__ . '/../laravel/pint',
'aliases' => array(),
'dev_requirement' => true,
),
'laravel/prompts' => array(
'pretty_version' => 'v0.3.17',
'version' => '0.3.17.0',
@@ -613,15 +532,6 @@
'aliases' => array(),
'dev_requirement' => false,
),
'mockery/mockery' => array(
'pretty_version' => '1.6.12',
'version' => '1.6.12.0',
'reference' => '1f4efdd7d3beafe9807b08156dfcb176d18f1699',
'type' => 'library',
'install_path' => __DIR__ . '/../mockery/mockery',
'aliases' => array(),
'dev_requirement' => true,
),
'monolog/monolog' => array(
'pretty_version' => '3.10.0',
'version' => '3.10.0.0',
@@ -637,15 +547,6 @@
0 => '^1.0',
),
),
'myclabs/deep-copy' => array(
'pretty_version' => '1.13.4',
'version' => '1.13.4.0',
'reference' => '07d290f0c47959fd5eed98c95ee5602db07e0b6a',
'type' => 'library',
'install_path' => __DIR__ . '/../myclabs/deep-copy',
'aliases' => array(),
'dev_requirement' => true,
),
'nesbot/carbon' => array(
'pretty_version' => '3.11.4',
'version' => '3.11.4.0',
@@ -682,15 +583,6 @@
'aliases' => array(),
'dev_requirement' => false,
),
'nunomaduro/collision' => array(
'pretty_version' => 'v8.9.4',
'version' => '8.9.4.0',
'reference' => '716af8f95a470e9094cfca09ed897b023be191a5',
'type' => 'library',
'install_path' => __DIR__ . '/../nunomaduro/collision',
'aliases' => array(),
'dev_requirement' => true,
),
'nunomaduro/termwind' => array(
'pretty_version' => 'v2.4.0',
'version' => '2.4.0.0',
@@ -700,24 +592,6 @@
'aliases' => array(),
'dev_requirement' => false,
),
'phar-io/manifest' => array(
'pretty_version' => '2.0.4',
'version' => '2.0.4.0',
'reference' => '54750ef60c58e43759730615a392c31c80e23176',
'type' => 'library',
'install_path' => __DIR__ . '/../phar-io/manifest',
'aliases' => array(),
'dev_requirement' => true,
),
'phar-io/version' => array(
'pretty_version' => '3.2.1',
'version' => '3.2.1.0',
'reference' => '4f7fd7836c6f332bb2933569e566a0d6c4cbed74',
'type' => 'library',
'install_path' => __DIR__ . '/../phar-io/version',
'aliases' => array(),
'dev_requirement' => true,
),
'php-di/invoker' => array(
'pretty_version' => '2.3.7',
'version' => '2.3.7.0',
@@ -745,60 +619,6 @@
'aliases' => array(),
'dev_requirement' => false,
),
'phpunit/php-code-coverage' => array(
'pretty_version' => '12.5.6',
'version' => '12.5.6.0',
'reference' => '876099a072646c7745f673d7aeab5382c4439691',
'type' => 'library',
'install_path' => __DIR__ . '/../phpunit/php-code-coverage',
'aliases' => array(),
'dev_requirement' => true,
),
'phpunit/php-file-iterator' => array(
'pretty_version' => '6.0.1',
'version' => '6.0.1.0',
'reference' => '3d1cd096ef6bea4bf2762ba586e35dbd317cbfd5',
'type' => 'library',
'install_path' => __DIR__ . '/../phpunit/php-file-iterator',
'aliases' => array(),
'dev_requirement' => true,
),
'phpunit/php-invoker' => array(
'pretty_version' => '6.0.0',
'version' => '6.0.0.0',
'reference' => '12b54e689b07a25a9b41e57736dfab6ec9ae5406',
'type' => 'library',
'install_path' => __DIR__ . '/../phpunit/php-invoker',
'aliases' => array(),
'dev_requirement' => true,
),
'phpunit/php-text-template' => array(
'pretty_version' => '5.0.0',
'version' => '5.0.0.0',
'reference' => 'e1367a453f0eda562eedb4f659e13aa900d66c53',
'type' => 'library',
'install_path' => __DIR__ . '/../phpunit/php-text-template',
'aliases' => array(),
'dev_requirement' => true,
),
'phpunit/php-timer' => array(
'pretty_version' => '8.0.0',
'version' => '8.0.0.0',
'reference' => 'f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc',
'type' => 'library',
'install_path' => __DIR__ . '/../phpunit/php-timer',
'aliases' => array(),
'dev_requirement' => true,
),
'phpunit/phpunit' => array(
'pretty_version' => '12.5.24',
'version' => '12.5.24.0',
'reference' => 'd75dd30597caa80e72fad2ef7904601a30ef1046',
'type' => 'library',
'install_path' => __DIR__ . '/../phpunit/phpunit',
'aliases' => array(),
'dev_requirement' => true,
),
'psr/cache' => array(
'pretty_version' => '3.0.0',
'version' => '3.0.0.0',
@@ -1027,123 +847,6 @@
'aliases' => array(),
'dev_requirement' => false,
),
'sebastian/cli-parser' => array(
'pretty_version' => '4.2.0',
'version' => '4.2.0.0',
'reference' => '90f41072d220e5c40df6e8635f5dafba2d9d4d04',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/cli-parser',
'aliases' => array(),
'dev_requirement' => true,
),
'sebastian/comparator' => array(
'pretty_version' => '7.1.6',
'version' => '7.1.6.0',
'reference' => 'c769009dee98f494e0edc3fd4f4087501688f11e',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/comparator',
'aliases' => array(),
'dev_requirement' => true,
),
'sebastian/complexity' => array(
'pretty_version' => '5.0.0',
'version' => '5.0.0.0',
'reference' => 'bad4316aba5303d0221f43f8cee37eb58d384bbb',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/complexity',
'aliases' => array(),
'dev_requirement' => true,
),
'sebastian/diff' => array(
'pretty_version' => '7.0.0',
'version' => '7.0.0.0',
'reference' => '7ab1ea946c012266ca32390913653d844ecd085f',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/diff',
'aliases' => array(),
'dev_requirement' => true,
),
'sebastian/environment' => array(
'pretty_version' => '8.1.0',
'version' => '8.1.0.0',
'reference' => 'b121608b28a13f721e76ffbbd386d08eff58f3f6',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/environment',
'aliases' => array(),
'dev_requirement' => true,
),
'sebastian/exporter' => array(
'pretty_version' => '7.0.2',
'version' => '7.0.2.0',
'reference' => '016951ae10980765e4e7aee491eb288c64e505b7',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/exporter',
'aliases' => array(),
'dev_requirement' => true,
),
'sebastian/global-state' => array(
'pretty_version' => '8.0.2',
'version' => '8.0.2.0',
'reference' => 'ef1377171613d09edd25b7816f05be8313f9115d',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/global-state',
'aliases' => array(),
'dev_requirement' => true,
),
'sebastian/lines-of-code' => array(
'pretty_version' => '4.0.0',
'version' => '4.0.0.0',
'reference' => '97ffee3bcfb5805568d6af7f0f893678fc076d2f',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/lines-of-code',
'aliases' => array(),
'dev_requirement' => true,
),
'sebastian/object-enumerator' => array(
'pretty_version' => '7.0.0',
'version' => '7.0.0.0',
'reference' => '1effe8e9b8e068e9ae228e542d5d11b5d16db894',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/object-enumerator',
'aliases' => array(),
'dev_requirement' => true,
),
'sebastian/object-reflector' => array(
'pretty_version' => '5.0.0',
'version' => '5.0.0.0',
'reference' => '4bfa827c969c98be1e527abd576533293c634f6a',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/object-reflector',
'aliases' => array(),
'dev_requirement' => true,
),
'sebastian/recursion-context' => array(
'pretty_version' => '7.0.1',
'version' => '7.0.1.0',
'reference' => '0b01998a7d5b1f122911a66bebcb8d46f0c82d8c',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/recursion-context',
'aliases' => array(),
'dev_requirement' => true,
),
'sebastian/type' => array(
'pretty_version' => '6.0.3',
'version' => '6.0.3.0',
'reference' => 'e549163b9760b8f71f191651d22acf32d56d6d4d',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/type',
'aliases' => array(),
'dev_requirement' => true,
),
'sebastian/version' => array(
'pretty_version' => '6.0.0',
'version' => '6.0.0.0',
'reference' => '3e6ccf7657d4f0a59200564b08cead899313b53c',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/version',
'aliases' => array(),
'dev_requirement' => true,
),
'spatie/laravel-package-tools' => array(
'pretty_version' => '1.93.0',
'version' => '1.93.0.0',
@@ -1168,15 +871,6 @@
0 => '*',
),
),
'staabm/side-effects-detector' => array(
'pretty_version' => '1.0.5',
'version' => '1.0.5.0',
'reference' => 'd8334211a140ce329c13726d4a715adbddd0a163',
'type' => 'library',
'install_path' => __DIR__ . '/../staabm/side-effects-detector',
'aliases' => array(),
'dev_requirement' => true,
),
'symfony/clock' => array(
'pretty_version' => 'v8.0.8',
'version' => '8.0.8.0',
@@ -1468,15 +1162,6 @@
'aliases' => array(),
'dev_requirement' => false,
),
'theseer/tokenizer' => array(
'pretty_version' => '2.0.1',
'version' => '2.0.1.0',
'reference' => '7989e43bf381af0eac72e4f0ca5bcbfa81658be4',
'type' => 'library',
'install_path' => __DIR__ . '/../theseer/tokenizer',
'aliases' => array(),
'dev_requirement' => true,
),
'tijsverkoyen/css-to-inline-styles' => array(
'pretty_version' => 'v2.4.0',
'version' => '2.4.0.0',
-209
View File
@@ -1,209 +0,0 @@
# CHANGELOG
## [Unreleased](https://github.com/FakerPHP/Faker/compare/v1.24.0...1.24.1)
- Removed domain `gmail.com.au` from `Provider\en_AU\Internet` (#886)
## [2024-11-09, v1.24.0](https://github.com/FakerPHP/Faker/compare/v1.23.1..v1.24.0)
- Fix internal deprecations in Doctrine's populator by @gnutix in (#889)
- Fix mobile phone number pattern for France by @ker0x in (#859)
- PHP 8.4 Support by @Jubeki in (#904)
- Added support for PHP 8.4 (#904)
## [2023-09-29, v1.23.1](https://github.com/FakerPHP/Faker/compare/v1.23.0..v1.23.1)
- Fixed double `а` female lastName in `ru_RU/Person::name()` (#832)
- Fixed polish license plates (#685)
- Stopped using `static` in callables in `Provider\pt_BR\PhoneNumber` (#785)
- Fixed incorrect female name (#794)
- Stopped using the deprecated `MT_RAND_PHP` constant to seed the random generator on PHP 8.3 (#844)
## [2023-06-12, v1.23.0](https://github.com/FakerPHP/Faker/compare/v1.22.0..v1.23.0)
- Update `randomElements` to return random number of elements when no count is provided (#658)
## [2023-05-14, v1.22.0](https://github.com/FakerPHP/Faker/compare/v1.21.0..v1.22.0)
- Fixed `randomElements()` to accept empty iterator (#605)
- Added support for passing an `Enum` to `randomElement()` and `randomElements()` (#620)
- Started rejecting invalid arguments passed to `randomElement()` and `randomElements()` (#642)
## [2022-12-13, v1.21.0](https://github.com/FakerPHP/Faker/compare/v1.20.0..v1.21.0)
- Dropped support for PHP 7.1, 7.2, and 7.3 (#543)
- Added support for PHP 8.2 (#528)
## [2022-07-20, v1.20.0](https://github.com/FakerPHP/Faker/compare/v1.19.0..v1.20.0)
- Fixed typo in French phone number (#452)
- Fixed some Hungarian naming bugs (#451)
- Fixed bug where the NL-BE VAT generation was incorrect (#455)
- Improve Turkish phone numbers for E164 and added landline support (#460)
- Add Microsoft Edge User Agent (#464)
- Added option to set image formats on Faker\Provider\Image (#473)
- Added support for French color translations (#466)
- Support filtering timezones by country code (#480)
- Fixed typo in some greek names (#490)
- Marked the Faker\Provider\Image as deprecated
## [2022-02-02, v1.19.0](https://github.com/FakerPHP/Faker/compare/v1.18.0..v1.19.0)
- Added color extension to core (#442)
- Added conflict with `doctrine/persistence` below version `1.4`
- Fix for support on different Doctrine ORM versions (#414)
- Fix usage of `Doctrine\Persistence` dependency
- Fix CZ Person birthNumber docblock return type (#437)
- Fix is_IS Person docbock types (#439)
- Fix is_IS Address docbock type (#438)
- Fix regexify escape backslash in character class (#434)
- Removed UUID from Generator to be able to extend it (#441)
## [2022-01-23, v1.18.0](https://github.com/FakerPHP/Faker/compare/v1.17.0..v1.18.0)
- Deprecated UUID, use uuid3 to specify version (#427)
- Reset formatters when adding a new provider (#366)
- Helper methods to use our custom generators (#155)
- Set allow-plugins for Composer 2.2 (#405)
- Fix kk_KZ\Person::individualIdentificationNumber generation (#411)
- Allow for -> syntax to be used in parsing (#423)
- Person->name was missing string return type (#424)
- Generate a valid BE TAX number (#415)
- Added the UUID extension to Core (#427)
## [2021-12-05, v1.17.0](https://github.com/FakerPHP/Faker/compare/v1.16.0..v1.17.0)
- Partial PHP 8.1 compatibility (#373)
- Add payment provider for `ne_NP` locale (#375)
- Add Egyptian Arabic `ar_EG` locale (#377)
- Updated list of South African TLDs (#383)
- Fixed formatting of E.164 numbers (#380)
- Allow `symfony/deprecation-contracts` `^3.0` (#397)
## [2021-09-06, v1.16.0](https://github.com/FakerPHP/Faker/compare/v1.15.0..v1.16.0)
- Add Company extension
- Add Address extension
- Add Person extension
- Add PhoneNumber extension
- Add VersionExtension (#350)
- Stricter types in Extension\Container and Extension\GeneratorAwareExtension (#345)
- Fix deprecated property access in `nl_NL` (#348)
- Add support for `psr/container` >= 2.0 (#354)
- Add missing union types in Faker\Generator (#352)
## [2021-07-06, v1.15.0](https://github.com/FakerPHP/Faker/compare/v1.14.1..v1.15.0)
- Updated the generator phpdoc to help identify magic methods (#307)
- Prevent direct access and triggered deprecation warning for "word" (#302)
- Updated length on all global e164 numbers (#301)
- Updated last names from different source (#312)
- Don't generate birth number of '000' for Swedish personal identity (#306)
- Add job list for localization id_ID (#339)
## [2021-03-30, v1.14.1](https://github.com/FakerPHP/Faker/compare/v1.14.0..v1.14.1)
- Fix where randomNumber and randomFloat would return a 0 value (#291 / #292)
## [2021-03-29, v1.14.0](https://github.com/FakerPHP/Faker/compare/v1.13.0..v1.14.0)
- Fix for realText to ensure the text keeps closer to its boundaries (#152)
- Fix where regexify produces a random character instead of a literal dot (#135
- Deprecate zh_TW methods that only call base methods (#122)
- Add used extensions to composer.json as suggestion (#120)
- Moved TCNo and INN from calculator to localized providers (#108)
- Fix regex dot/backslash issue where a dot is replaced with a backslash as escape character (#206)
- Deprecate direct property access (#164)
- Added test to assert unique() behaviour (#233)
- Added RUC for the es_PE locale (#244)
- Test IBAN formats for Latin America (AR/PE/VE) (#260)
- Added VAT number for en_GB (#255)
- Added new districts for the ne_NP locale (#258)
- Fix for U.S. Area Code Generation (#261)
- Fix in numerify where a better random numeric value is guaranteed (#256)
- Fix e164PhoneNumber to only generate valid phone numbers with valid country codes (#264)
- Extract fixtures into separate classes (#234)
- Remove french domains that no longer exists (#277)
- Fix error that occurs when getting a polish title (#279)
- Use valid area codes for North America E164 phone numbers (#280)
- Adding support for extensions and PSR-11 (#154)
- Adding trait for GeneratorAwareExtension (#165)
- Added helper class for extension (#162)
- Added blood extension to core (#232)
- Added barcode extension to core (#252)
- Added number extension (#257)
- Various code style updates
- Added a note about our breaking change promise (#273)
## [2020-12-18, v1.13.0](https://github.com/FakerPHP/Faker/compare/v1.12.1..v1.13.0)
Several fixes and new additions in this release. A lot of cleanup has been done
on the codebase on both tests and consistency.
- Feature/pl pl license plate (#62)
- Fix greek phone numbers (#16)
- Move AT payment provider logic to de_AT (#72)
- Fix wiktionary links (#73)
- Fix AT person links (#74)
- Fix AT cities (#75)
- Deprecate at_AT providers (#78)
- Add Austrian `ssn()` to `Person` provider (#79)
- Fix typos in id_ID Address (#83)
- Austrian post codes (#86)
- Updated Polish data (#70)
- Improve Austrian social security number generation (#88)
- Move US phone numbers with extension to own method (#91)
- Add UK National Insurance number generator (#89)
- Fix en_SG phone number generator (#100)
- Remove usage of mt_rand (#87)
- Remove whitespace from beginning of el_GR phone numbers (#105)
- Building numbers can not be 0, 00, 000 (#107)
- Add 172.16/12 local IPv4 block (#121)
- Add JCB credit card type (#124)
- Remove json_decode from emoji generation (#123)
- Remove ro street address (#146)
## [2020-12-11, v1.12.1](https://github.com/FakerPHP/Faker/compare/v1.12.0..v1.12.1)
This is a security release that prevents a hacker to execute code on the server.
## [2020-11-23, v1.12.0](https://github.com/FakerPHP/Faker/compare/v1.11.0..v1.12.0)
- Fix ro_RO first and last day of year calculation offset (#65)
- Fix en_NG locale test namespaces that did not match PSR-4 (#57)
- Added Singapore NRIC/FIN provider (#56)
- Added provider for Lithuanian municipalities (#58)
- Added blood types provider (#61)
## [2020-11-15, v1.11.0](https://github.com/FakerPHP/Faker/compare/v1.10.1..v1.11.0)
- Added Provider for Swedish Municipalities
- Updates to person names in pt_BR
- Many code style changes
## [2020-10-28, v1.10.1](https://github.com/FakerPHP/Faker/compare/v1.10.0..v1.10.1)
- Updates the Danish addresses in dk_DK
- Removed offense company names in nl_NL
- Clarify changelog with original fork
- Standin replacement for LoremPixel to Placeholder.com (#11)
## [2020-10-27, v1.10.0](https://github.com/FakerPHP/Faker/compare/v1.9.1..v1.10.0)
- Support PHP 7.1-8.0
- Fix typo in de_DE Company Provider
- Fix dateTimeThisYear method
- Fix typo in de_DE jobTitleFormat
- Fix IBAN generation for CR
- Fix typos in greek first names
- Fix US job title typo
- Do not clear entity manager for doctrine orm populator
- Remove persian rude words
- Corrections to RU names
## 2020-10-27, v1.9.1
- Initial version. Same as `fzaninotto/Faker:v1.9.1`.
-22
View File
@@ -1,22 +0,0 @@
Copyright (c) 2011 François Zaninotto
Portions Copyright (c) 2008 Caius Durling
Portions Copyright (c) 2008 Adam Royle
Portions Copyright (c) 2008 Fiona Burrows
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-114
View File
@@ -1,114 +0,0 @@
<p style="text-align: center"><img src="https://github.com/FakerPHP/Artwork/raw/main/src/socialcard.png" alt="Social card of FakerPHP"></p>
# Faker
[![Packagist Downloads](https://img.shields.io/packagist/dm/FakerPHP/Faker)](https://packagist.org/packages/fakerphp/faker)
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/FakerPHP/Faker/Tests/main)](https://github.com/FakerPHP/Faker/actions)
[![Type Coverage](https://shepherd.dev/github/FakerPHP/Faker/coverage.svg)](https://shepherd.dev/github/FakerPHP/Faker)
[![Code Coverage](https://codecov.io/gh/FakerPHP/Faker/branch/main/graph/badge.svg)](https://codecov.io/gh/FakerPHP/Faker)
Faker is a PHP library that generates fake data for you. Whether you need to bootstrap your database, create good-looking XML documents, fill-in your persistence to stress test it, or anonymize data taken from a production service, Faker is for you.
It's heavily inspired by Perl's [Data::Faker](https://metacpan.org/pod/Data::Faker), and by Ruby's [Faker](https://rubygems.org/gems/faker).
## Getting Started
### Installation
Faker requires PHP >= 7.4.
```shell
composer require fakerphp/faker
```
### Documentation
Full documentation can be found over on [fakerphp.github.io](https://fakerphp.github.io).
### Basic Usage
Use `Faker\Factory::create()` to create and initialize a Faker generator, which can generate data by accessing methods named after the type of data you want.
```php
<?php
require_once 'vendor/autoload.php';
// use the factory to create a Faker\Generator instance
$faker = Faker\Factory::create();
// generate data by calling methods
echo $faker->name();
// 'Vince Sporer'
echo $faker->email();
// 'walter.sophia@hotmail.com'
echo $faker->text();
// 'Numquam ut mollitia at consequuntur inventore dolorem.'
```
Each call to `$faker->name()` yields a different (random) result. This is because Faker uses `__call()` magic, and forwards `Faker\Generator->$method()` calls to `Faker\Generator->format($method, $attributes)`.
```php
<?php
for ($i = 0; $i < 3; $i++) {
echo $faker->name() . "\n";
}
// 'Cyrus Boyle'
// 'Alena Cummerata'
// 'Orlo Bergstrom'
```
## Automated refactoring
If you already used this library with its properties, they are now deprecated and needs to be replaced by their equivalent methods.
You can use the provided [Rector](https://github.com/rectorphp/rector) config file to automate the work.
Run
```bash
composer require --dev rector/rector
```
to install `rector/rector`.
Run
```bash
vendor/bin/rector process src/ --config vendor/fakerphp/faker/rector-migrate.php
```
to run `rector/rector`.
*Note:* do not forget to replace `src/` with the path to your source directory.
Alternatively, import the configuration in your `rector.php` file:
```php
<?php
declare(strict_types=1);
use Rector\Config;
return static function (Config\RectorConfig $rectorConfig): void {
$rectorConfig->import('vendor/fakerphp/faker/rector-migrate.php');
};
```
## License
Faker is released under the MIT License. See [`LICENSE`](LICENSE) for details.
## Backward compatibility promise
Faker is using [Semver](https://semver.org/). This means that versions are tagged
with MAJOR.MINOR.PATCH. Only a new major version will be allowed to break backward
compatibility (BC).
Classes marked as `@experimental` or `@internal` are not included in our backward compatibility promise.
You are also not guaranteed that the value returned from a method is always the
same. You are guaranteed that the data type will not change.
PHP 8 introduced [named arguments](https://wiki.php.net/rfc/named_params), which
increased the cost and reduces flexibility for package maintainers. The names of the
arguments for methods in Faker is not included in our BC promise.
-56
View File
@@ -1,56 +0,0 @@
{
"name": "fakerphp/faker",
"type": "library",
"description": "Faker is a PHP library that generates fake data for you.",
"keywords": [
"faker",
"fixtures",
"data"
],
"license": "MIT",
"authors": [
{
"name": "François Zaninotto"
}
],
"require": {
"php": "^7.4 || ^8.0",
"psr/container": "^1.0 || ^2.0",
"symfony/deprecation-contracts": "^2.2 || ^3.0"
},
"require-dev": {
"ext-intl": "*",
"bamarni/composer-bin-plugin": "^1.4.1",
"doctrine/persistence": "^1.3 || ^2.0",
"phpunit/phpunit": "^9.5.26",
"symfony/phpunit-bridge": "^5.4.16"
},
"autoload": {
"psr-4": {
"Faker\\": "src/Faker/"
}
},
"autoload-dev": {
"psr-4": {
"Faker\\Test\\": "test/Faker/",
"Faker\\Test\\Fixture\\": "test/Fixture/"
}
},
"conflict": {
"fzaninotto/faker": "*"
},
"suggest": {
"ext-curl": "Required by Faker\\Provider\\Image to download images.",
"ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.",
"ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.",
"ext-mbstring": "Required for multibyte Unicode string functionality.",
"doctrine/orm": "Required to use Faker\\ORM\\Doctrine"
},
"config": {
"allow-plugins": {
"bamarni/composer-bin-plugin": true,
"composer/package-versions-deprecated": true
},
"sort-packages": true
}
}
-161
View File
@@ -1,161 +0,0 @@
<?php
declare(strict_types=1);
use Faker\Generator;
use Rector\Config;
use Rector\Transform;
// This file configures rector/rector to replace all deprecated property usages with their equivalent functions.
return static function (Config\RectorConfig $rectorConfig): void {
$properties = [
'address',
'amPm',
'asciify',
'biasedNumberBetween',
'boolean',
'bothify',
'buildingNumber',
'century',
'chrome',
'city',
'citySuffix',
'colorName',
'company',
'companyEmail',
'companySuffix',
'country',
'countryCode',
'countryISOAlpha3',
'creditCardDetails',
'creditCardExpirationDate',
'creditCardExpirationDateString',
'creditCardNumber',
'creditCardType',
'currencyCode',
'date',
'dateTime',
'dateTimeAD',
'dateTimeBetween',
'dateTimeInInterval',
'dateTimeThisCentury',
'dateTimeThisDecade',
'dateTimeThisMonth',
'dateTimeThisYear',
'dayOfMonth',
'dayOfWeek',
'domainName',
'domainWord',
'e164PhoneNumber',
'email',
'emoji',
'file',
'firefox',
'firstName',
'firstNameFemale',
'firstNameMale',
'freeEmail',
'freeEmailDomain',
'getDefaultTimezone',
'hexColor',
'hslColor',
'hslColorAsArray',
'iban',
'image',
'imageUrl',
'imei',
'internetExplorer',
'iosMobileToken',
'ipv4',
'ipv6',
'iso8601',
'jobTitle',
'languageCode',
'lastName',
'latitude',
'lexify',
'linuxPlatformToken',
'linuxProcessor',
'localCoordinates',
'localIpv4',
'locale',
'longitude',
'macAddress',
'macPlatformToken',
'macProcessor',
'md5',
'month',
'monthName',
'msedge',
'name',
'numerify',
'opera',
'paragraph',
'paragraphs',
'passthrough',
'password',
'phoneNumber',
'postcode',
'randomAscii',
'randomDigitNotNull',
'randomElement',
'randomElements',
'randomHtml',
'randomKey',
'randomLetter',
'realText',
'realTextBetween',
'regexify',
'rgbColor',
'rgbColorAsArray',
'rgbCssColor',
'rgbaCssColor',
'safari',
'safeColorName',
'safeEmail',
'safeEmailDomain',
'safeHexColor',
'sentence',
'sentences',
'setDefaultTimezone',
'sha1',
'sha256',
'shuffle',
'shuffleArray',
'shuffleString',
'slug',
'streetAddress',
'streetName',
'streetSuffix',
'swiftBicNumber',
'text',
'time',
'timezone',
'title',
'titleFemale',
'titleMale',
'tld',
'toLower',
'toUpper',
'unixTime',
'url',
'userAgent',
'userName',
'uuid',
'windowsPlatformToken',
'word',
'words',
'year',
];
$rectorConfig->ruleWithConfiguration(
Transform\Rector\Assign\PropertyFetchToMethodCallRector::class,
array_map(static function (string $property): Transform\ValueObject\PropertyFetchToMethodCall {
return new Transform\ValueObject\PropertyFetchToMethodCall(
Generator::class,
$property,
$property,
);
}, $properties),
);
};
-50
View File
@@ -1,50 +0,0 @@
<?php
namespace Faker\Calculator;
/**
* Utility class for validating EAN-8 and EAN-13 numbers
*/
class Ean
{
/**
* @var string EAN validation pattern
*/
public const PATTERN = '/^(?:\d{8}|\d{13})$/';
/**
* Computes the checksum of an EAN number.
*
* @see https://en.wikipedia.org/wiki/International_Article_Number
*
* @return int
*/
public static function checksum(string $digits)
{
$sequence = (strlen($digits) + 1) === 8 ? [3, 1] : [1, 3];
$sums = 0;
foreach (str_split($digits) as $n => $digit) {
$sums += ((int) $digit) * $sequence[$n % 2];
}
return (10 - $sums % 10) % 10;
}
/**
* Checks whether the provided number is an EAN compliant number and that
* the checksum is correct.
*
* @param string $ean An EAN number
*
* @return bool
*/
public static function isValid(string $ean)
{
if (!preg_match(self::PATTERN, $ean)) {
return false;
}
return self::checksum(substr($ean, 0, -1)) === (int) substr($ean, -1);
}
}
-69
View File
@@ -1,69 +0,0 @@
<?php
namespace Faker\Calculator;
class Iban
{
/**
* Generates IBAN Checksum
*
* @return string Checksum (numeric string)
*/
public static function checksum(string $iban)
{
// Move first four digits to end and set checksum to '00'
$checkString = substr($iban, 4) . substr($iban, 0, 2) . '00';
// Replace all letters with their number equivalents
$checkString = preg_replace_callback(
'/[A-Z]/',
static function (array $matches): string {
return (string) self::alphaToNumber($matches[0]);
},
$checkString,
);
// Perform mod 97 and subtract from 98
$checksum = 98 - self::mod97($checkString);
return str_pad($checksum, 2, '0', STR_PAD_LEFT);
}
/**
* Converts letter to number
*
* @return int
*/
public static function alphaToNumber(string $char)
{
return ord($char) - 55;
}
/**
* Calculates mod97 on a numeric string
*
* @param string $number Numeric string
*
* @return int
*/
public static function mod97(string $number)
{
$checksum = (int) $number[0];
for ($i = 1, $size = strlen($number); $i < $size; ++$i) {
$checksum = (10 * $checksum + (int) $number[$i]) % 97;
}
return $checksum;
}
/**
* Checks whether an IBAN has a valid checksum
*
* @return bool
*/
public static function isValid(string $iban)
{
return self::checksum($iban) === substr($iban, 2, 2);
}
}
-42
View File
@@ -1,42 +0,0 @@
<?php
namespace Faker\Calculator;
/**
* @deprecated moved to ru_RU\Company, use {@link \Faker\Provider\ru_RU\Company}.
* @see \Faker\Provider\ru_RU\Company
*/
class Inn
{
/**
* Generates INN Checksum
*
* https://ru.wikipedia.org/wiki/%D0%98%D0%B4%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BD%D0%BE%D0%BC%D0%B5%D1%80_%D0%BD%D0%B0%D0%BB%D0%BE%D0%B3%D0%BE%D0%BF%D0%BB%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%89%D0%B8%D0%BA%D0%B0
*
* @param string $inn
*
* @return string Checksum (one digit)
*
* @deprecated use {@link \Faker\Provider\ru_RU\Company::inn10Checksum()} instead
* @see \Faker\Provider\ru_RU\Company::inn10Checksum()
*/
public static function checksum($inn)
{
return \Faker\Provider\ru_RU\Company::inn10Checksum($inn);
}
/**
* Checks whether an INN has a valid checksum
*
* @param string $inn
*
* @return bool
*
* @deprecated use {@link \Faker\Provider\ru_RU\Company::inn10IsValid()} instead
* @see \Faker\Provider\ru_RU\Company::inn10IsValid()
*/
public static function isValid($inn)
{
return \Faker\Provider\ru_RU\Company::inn10IsValid($inn);
}
}
-60
View File
@@ -1,60 +0,0 @@
<?php
namespace Faker\Calculator;
/**
* Utility class for validating ISBN-10
*/
class Isbn
{
/**
* @var string ISBN-10 validation pattern
*/
public const PATTERN = '/^\d{9}[0-9X]$/';
/**
* ISBN-10 check digit
*
* @see http://en.wikipedia.org/wiki/International_Standard_Book_Number#ISBN-10_check_digits
*
* @param string $input ISBN without check-digit
*
* @throws \LengthException When wrong input length passed
*/
public static function checksum(string $input): string
{
// We're calculating check digit for ISBN-10
// so, the length of the input should be 9
$length = 9;
if (strlen($input) !== $length) {
throw new \LengthException(sprintf('Input length should be equal to %d', $length));
}
$digits = str_split($input);
array_walk(
$digits,
static function (&$digit, $position): void {
$digit = (10 - $position) * $digit;
},
);
$result = (11 - array_sum($digits) % 11) % 11;
// 10 is replaced by X
return ($result < 10) ? (string) $result : 'X';
}
/**
* Checks whether the provided number is a valid ISBN-10 number
*
* @param string $isbn ISBN to check
*/
public static function isValid(string $isbn): bool
{
if (!preg_match(self::PATTERN, $isbn)) {
return false;
}
return self::checksum(substr($isbn, 0, -1)) === substr($isbn, -1);
}
}
-72
View File
@@ -1,72 +0,0 @@
<?php
namespace Faker\Calculator;
/**
* Utility class for generating and validating Luhn numbers.
*
* Luhn algorithm is used to validate credit card numbers, IMEI numbers, and
* National Provider Identifier numbers.
*
* @see http://en.wikipedia.org/wiki/Luhn_algorithm
*/
class Luhn
{
/**
* @return int
*/
private static function checksum(string $number)
{
$number = (string) $number;
$length = strlen($number);
$sum = 0;
for ($i = $length - 1; $i >= 0; $i -= 2) {
$sum += $number[$i];
}
for ($i = $length - 2; $i >= 0; $i -= 2) {
$sum += array_sum(str_split($number[$i] * 2));
}
return $sum % 10;
}
/**
* @return string
*/
public static function computeCheckDigit(string $partialNumber)
{
$checkDigit = self::checksum($partialNumber . '0');
if ($checkDigit === 0) {
return '0';
}
return (string) (10 - $checkDigit);
}
/**
* Checks whether a number (partial number + check digit) is Luhn compliant
*
* @return bool
*/
public static function isValid(string $number)
{
return self::checksum($number) === 0;
}
/**
* Generate a Luhn compliant number.
*
* @return string
*/
public static function generateLuhnNumber(string $partialValue)
{
if (!preg_match('/^\d+$/', $partialValue)) {
throw new \InvalidArgumentException('Argument should be an integer.');
}
return $partialValue . Luhn::computeCheckDigit($partialValue);
}
}
-43
View File
@@ -1,43 +0,0 @@
<?php
namespace Faker\Calculator;
/**
* @deprecated moved to tr_TR\Person, use {@link \Faker\Provider\tr_TR\Person}.
* @see \Faker\Provider\tr_TR\Person
*/
class TCNo
{
/**
* Generates Turkish Identity Number Checksum
* Gets first 9 digit as prefix and calculates checksum
*
* https://en.wikipedia.org/wiki/Turkish_Identification_Number
*
* @param string $identityPrefix
*
* @return string Checksum (two digit)
*
* @deprecated use {@link \Faker\Provider\tr_TR\Person::tcNoChecksum()} instead
* @see \Faker\Provider\tr_TR\Person::tcNoChecksum()
*/
public static function checksum($identityPrefix)
{
return \Faker\Provider\tr_TR\Person::tcNoChecksum($identityPrefix);
}
/**
* Checks whether a TCNo has a valid checksum
*
* @param string $tcNo
*
* @return bool
*
* @deprecated use {@link \Faker\Provider\tr_TR\Person::tcNoIsValid()} instead
* @see \Faker\Provider\tr_TR\Person::tcNoIsValid()
*/
public static function isValid($tcNo)
{
return \Faker\Provider\tr_TR\Person::tcNoIsValid($tcNo);
}
}
-60
View File
@@ -1,60 +0,0 @@
<?php
namespace Faker;
use Faker\Extension\Extension;
/**
* This generator returns a default value for all called properties
* and methods. It works with Faker\Generator::optional().
*
* @mixin Generator
*/
class ChanceGenerator
{
private $generator;
private $weight;
protected $default;
/**
* @param Extension|Generator $generator
*/
public function __construct($generator, float $weight, $default = null)
{
$this->default = $default;
$this->generator = $generator;
$this->weight = $weight;
}
public function ext(string $id)
{
return new self($this->generator->ext($id), $this->weight, $this->default);
}
/**
* Catch and proxy all generator calls but return only valid values
*
* @param string $attribute
*
* @deprecated Use a method instead.
*/
public function __get($attribute)
{
trigger_deprecation('fakerphp/faker', '1.14', 'Accessing property "%s" is deprecated, use "%s()" instead.', $attribute, $attribute);
return $this->__call($attribute, []);
}
/**
* @param string $name
* @param array $arguments
*/
public function __call($name, $arguments)
{
if (mt_rand(1, 100) <= (100 * $this->weight)) {
return call_user_func_array([$this->generator, $name], $arguments);
}
return $this->default;
}
}
-139
View File
@@ -1,139 +0,0 @@
<?php
declare(strict_types=1);
namespace Faker\Container;
use Faker\Extension\Extension;
/**
* A simple implementation of a container.
*
* @experimental This class is experimental and does not fall under our BC promise
*/
final class Container implements ContainerInterface
{
/**
* @var array<string, callable|object|string>
*/
private array $definitions;
private array $services = [];
/**
* Create a container object with a set of definitions. The array value MUST
* produce an object that implements Extension.
*
* @param array<string, callable|object|string> $definitions
*/
public function __construct(array $definitions)
{
$this->definitions = $definitions;
}
/**
* Retrieve a definition from the container.
*
* @param string $id
*
* @throws \InvalidArgumentException
* @throws \RuntimeException
* @throws ContainerException
* @throws NotInContainerException
*/
public function get($id): Extension
{
if (!is_string($id)) {
throw new \InvalidArgumentException(sprintf(
'First argument of %s::get() must be string',
self::class,
));
}
if (array_key_exists($id, $this->services)) {
return $this->services[$id];
}
if (!$this->has($id)) {
throw new NotInContainerException(sprintf(
'There is not service with id "%s" in the container.',
$id,
));
}
$definition = $this->definitions[$id];
$service = $this->getService($id, $definition);
if (!$service instanceof Extension) {
throw new \RuntimeException(sprintf(
'Service resolved for identifier "%s" does not implement the %s" interface.',
$id,
Extension::class,
));
}
$this->services[$id] = $service;
return $service;
}
/**
* Get the service from a definition.
*
* @param callable|object|string $definition
*/
private function getService(string $id, $definition)
{
if (is_callable($definition)) {
try {
return $definition();
} catch (\Throwable $e) {
throw new ContainerException(
sprintf('Error while invoking callable for "%s"', $id),
0,
$e,
);
}
} elseif (is_object($definition)) {
return $definition;
} elseif (is_string($definition)) {
if (class_exists($definition)) {
try {
return new $definition();
} catch (\Throwable $e) {
throw new ContainerException(sprintf('Could not instantiate class "%s"', $id), 0, $e);
}
}
throw new ContainerException(sprintf(
'Could not instantiate class "%s". Class was not found.',
$id,
));
} else {
throw new ContainerException(sprintf(
'Invalid type for definition with id "%s"',
$id,
));
}
}
/**
* Check if the container contains a given identifier.
*
* @param string $id
*
* @throws \InvalidArgumentException
*/
public function has($id): bool
{
if (!is_string($id)) {
throw new \InvalidArgumentException(sprintf(
'First argument of %s::get() must be string',
self::class,
));
}
return array_key_exists($id, $this->definitions);
}
}
@@ -1,68 +0,0 @@
<?php
declare(strict_types=1);
namespace Faker\Container;
use Faker\Core;
use Faker\Extension;
/**
* @experimental This class is experimental and does not fall under our BC promise
*/
final class ContainerBuilder
{
/**
* @var array<string, callable|object|string>
*/
private array $definitions = [];
/**
* @param callable|object|string $definition
*
* @throws \InvalidArgumentException
*/
public function add(string $id, $definition): self
{
if (!is_string($definition) && !is_callable($definition) && !is_object($definition)) {
throw new \InvalidArgumentException(sprintf(
'First argument to "%s::add()" must be a string, callable or object.',
self::class,
));
}
$this->definitions[$id] = $definition;
return $this;
}
public function build(): ContainerInterface
{
return new Container($this->definitions);
}
private static function defaultExtensions(): array
{
return [
Extension\BarcodeExtension::class => Core\Barcode::class,
Extension\BloodExtension::class => Core\Blood::class,
Extension\ColorExtension::class => Core\Color::class,
Extension\DateTimeExtension::class => Core\DateTime::class,
Extension\FileExtension::class => Core\File::class,
Extension\NumberExtension::class => Core\Number::class,
Extension\UuidExtension::class => Core\Uuid::class,
Extension\VersionExtension::class => Core\Version::class,
];
}
public static function withDefaultExtensions(): self
{
$instance = new self();
foreach (self::defaultExtensions() as $id => $definition) {
$instance->add($id, $definition);
}
return $instance;
}
}
@@ -1,14 +0,0 @@
<?php
declare(strict_types=1);
namespace Faker\Container;
use Psr\Container\ContainerExceptionInterface;
/**
* @experimental This class is experimental and does not fall under our BC promise
*/
final class ContainerException extends \RuntimeException implements ContainerExceptionInterface
{
}
@@ -1,9 +0,0 @@
<?php
namespace Faker\Container;
use Psr\Container\ContainerInterface as BaseContainerInterface;
interface ContainerInterface extends BaseContainerInterface
{
}
@@ -1,14 +0,0 @@
<?php
declare(strict_types=1);
namespace Faker\Container;
use Psr\Container\NotFoundExceptionInterface;
/**
* @experimental This class is experimental and does not fall under our BC promise
*/
final class NotInContainerException extends \RuntimeException implements NotFoundExceptionInterface
{
}
-52
View File
@@ -1,52 +0,0 @@
<?php
declare(strict_types=1);
namespace Faker\Core;
use Faker\Calculator;
use Faker\Extension;
/**
* @experimental This class is experimental and does not fall under our BC promise
*/
final class Barcode implements Extension\BarcodeExtension
{
private Extension\NumberExtension $numberExtension;
public function __construct(?Extension\NumberExtension $numberExtension = null)
{
$this->numberExtension = $numberExtension ?: new Number();
}
private function ean(int $length = 13): string
{
$code = Extension\Helper::numerify(str_repeat('#', $length - 1));
return sprintf('%s%s', $code, Calculator\Ean::checksum($code));
}
public function ean13(): string
{
return $this->ean();
}
public function ean8(): string
{
return $this->ean(8);
}
public function isbn10(): string
{
$code = Extension\Helper::numerify(str_repeat('#', 9));
return sprintf('%s%s', $code, Calculator\Isbn::checksum($code));
}
public function isbn13(): string
{
$code = '97' . $this->numberExtension->numberBetween(8, 9) . Extension\Helper::numerify(str_repeat('#', 9));
return sprintf('%s%s', $code, Calculator\Ean::checksum($code));
}
}
-42
View File
@@ -1,42 +0,0 @@
<?php
declare(strict_types=1);
namespace Faker\Core;
use Faker\Extension;
/**
* @experimental This class is experimental and does not fall under our BC promise
*/
final class Blood implements Extension\BloodExtension
{
/**
* @var string[]
*/
private array $bloodTypes = ['A', 'AB', 'B', 'O'];
/**
* @var string[]
*/
private array $bloodRhFactors = ['+', '-'];
public function bloodType(): string
{
return Extension\Helper::randomElement($this->bloodTypes);
}
public function bloodRh(): string
{
return Extension\Helper::randomElement($this->bloodRhFactors);
}
public function bloodGroup(): string
{
return sprintf(
'%s%s',
$this->bloodType(),
$this->bloodRh(),
);
}
}
-177
View File
@@ -1,177 +0,0 @@
<?php
declare(strict_types=1);
namespace Faker\Core;
use Faker\Extension;
use Faker\Extension\Helper;
/**
* @experimental This class is experimental and does not fall under our BC promise
*/
final class Color implements Extension\ColorExtension
{
private Extension\NumberExtension $numberExtension;
/**
* @var string[]
*/
private array $safeColorNames = [
'black', 'maroon', 'green', 'navy', 'olive',
'purple', 'teal', 'lime', 'blue', 'silver',
'gray', 'yellow', 'fuchsia', 'aqua', 'white',
];
/**
* @var string[]
*/
private array $allColorNames = [
'AliceBlue', 'AntiqueWhite', 'Aqua', 'Aquamarine',
'Azure', 'Beige', 'Bisque', 'Black', 'BlanchedAlmond',
'Blue', 'BlueViolet', 'Brown', 'BurlyWood', 'CadetBlue',
'Chartreuse', 'Chocolate', 'Coral', 'CornflowerBlue',
'Cornsilk', 'Crimson', 'Cyan', 'DarkBlue', 'DarkCyan',
'DarkGoldenRod', 'DarkGray', 'DarkGreen', 'DarkKhaki',
'DarkMagenta', 'DarkOliveGreen', 'Darkorange', 'DarkOrchid',
'DarkRed', 'DarkSalmon', 'DarkSeaGreen', 'DarkSlateBlue',
'DarkSlateGray', 'DarkTurquoise', 'DarkViolet', 'DeepPink',
'DeepSkyBlue', 'DimGray', 'DimGrey', 'DodgerBlue', 'FireBrick',
'FloralWhite', 'ForestGreen', 'Fuchsia', 'Gainsboro', 'GhostWhite',
'Gold', 'GoldenRod', 'Gray', 'Green', 'GreenYellow', 'HoneyDew',
'HotPink', 'IndianRed', 'Indigo', 'Ivory', 'Khaki', 'Lavender',
'LavenderBlush', 'LawnGreen', 'LemonChiffon', 'LightBlue', 'LightCoral',
'LightCyan', 'LightGoldenRodYellow', 'LightGray', 'LightGreen', 'LightPink',
'LightSalmon', 'LightSeaGreen', 'LightSkyBlue', 'LightSlateGray', 'LightSteelBlue',
'LightYellow', 'Lime', 'LimeGreen', 'Linen', 'Magenta', 'Maroon', 'MediumAquaMarine',
'MediumBlue', 'MediumOrchid', 'MediumPurple', 'MediumSeaGreen', 'MediumSlateBlue',
'MediumSpringGreen', 'MediumTurquoise', 'MediumVioletRed', 'MidnightBlue',
'MintCream', 'MistyRose', 'Moccasin', 'NavajoWhite', 'Navy', 'OldLace', 'Olive',
'OliveDrab', 'Orange', 'OrangeRed', 'Orchid', 'PaleGoldenRod', 'PaleGreen',
'PaleTurquoise', 'PaleVioletRed', 'PapayaWhip', 'PeachPuff', 'Peru', 'Pink', 'Plum',
'PowderBlue', 'Purple', 'Red', 'RosyBrown', 'RoyalBlue', 'SaddleBrown', 'Salmon',
'SandyBrown', 'SeaGreen', 'SeaShell', 'Sienna', 'Silver', 'SkyBlue', 'SlateBlue',
'SlateGray', 'Snow', 'SpringGreen', 'SteelBlue', 'Tan', 'Teal', 'Thistle', 'Tomato',
'Turquoise', 'Violet', 'Wheat', 'White', 'WhiteSmoke', 'Yellow', 'YellowGreen',
];
public function __construct(?Extension\NumberExtension $numberExtension = null)
{
$this->numberExtension = $numberExtension ?: new Number();
}
/**
* @example '#fa3cc2'
*/
public function hexColor(): string
{
return '#' . str_pad(dechex($this->numberExtension->numberBetween(1, 16777215)), 6, '0', STR_PAD_LEFT);
}
/**
* @example '#ff0044'
*/
public function safeHexColor(): string
{
$color = str_pad(dechex($this->numberExtension->numberBetween(0, 255)), 3, '0', STR_PAD_LEFT);
return sprintf(
'#%s%s%s%s%s%s',
$color[0],
$color[0],
$color[1],
$color[1],
$color[2],
$color[2],
);
}
/**
* @example 'array(0,255,122)'
*
* @return int[]
*/
public function rgbColorAsArray(): array
{
$color = $this->hexColor();
return [
hexdec(substr($color, 1, 2)),
hexdec(substr($color, 3, 2)),
hexdec(substr($color, 5, 2)),
];
}
/**
* @example '0,255,122'
*/
public function rgbColor(): string
{
return implode(',', $this->rgbColorAsArray());
}
/**
* @example 'rgb(0,255,122)'
*/
public function rgbCssColor(): string
{
return sprintf(
'rgb(%s)',
$this->rgbColor(),
);
}
/**
* @example 'rgba(0,255,122,0.8)'
*/
public function rgbaCssColor(): string
{
return sprintf(
'rgba(%s,%s)',
$this->rgbColor(),
$this->numberExtension->randomFloat(1, 0, 1),
);
}
/**
* @example 'blue'
*/
public function safeColorName(): string
{
return Helper::randomElement($this->safeColorNames);
}
/**
* @example 'NavajoWhite'
*/
public function colorName(): string
{
return Helper::randomElement($this->allColorNames);
}
/**
* @example '340,50,20'
*/
public function hslColor(): string
{
return sprintf(
'%s,%s,%s',
$this->numberExtension->numberBetween(0, 360),
$this->numberExtension->numberBetween(0, 100),
$this->numberExtension->numberBetween(0, 100),
);
}
/**
* @example array(340, 50, 20)
*
* @return int[]
*/
public function hslColorAsArray(): array
{
return [
$this->numberExtension->numberBetween(0, 360),
$this->numberExtension->numberBetween(0, 100),
$this->numberExtension->numberBetween(0, 100),
];
}
}
-78
View File
@@ -1,78 +0,0 @@
<?php
declare(strict_types=1);
namespace Faker\Core;
use Faker\Extension;
/**
* @experimental This class is experimental and does not fall under our BC promise
*/
final class Coordinates implements Extension\Extension
{
private Extension\NumberExtension $numberExtension;
public function __construct(?Extension\NumberExtension $numberExtension = null)
{
$this->numberExtension = $numberExtension ?: new Number();
}
/**
* @example '77.147489'
*
* @return float Uses signed degrees format (returns a float number between -90 and 90)
*/
public function latitude(float $min = -90.0, float $max = 90.0): float
{
if ($min < -90 || $max < -90) {
throw new \LogicException('Latitude cannot be less that -90.0');
}
if ($min > 90 || $max > 90) {
throw new \LogicException('Latitude cannot be greater that 90.0');
}
return $this->randomFloat(6, $min, $max);
}
/**
* @example '86.211205'
*
* @return float Uses signed degrees format (returns a float number between -180 and 180)
*/
public function longitude(float $min = -180.0, float $max = 180.0): float
{
if ($min < -180 || $max < -180) {
throw new \LogicException('Longitude cannot be less that -180.0');
}
if ($min > 180 || $max > 180) {
throw new \LogicException('Longitude cannot be greater that 180.0');
}
return $this->randomFloat(6, $min, $max);
}
/**
* @example array('77.147489', '86.211205')
*
* @return array{latitude: float, longitude: float}
*/
public function localCoordinates(): array
{
return [
'latitude' => $this->latitude(),
'longitude' => $this->longitude(),
];
}
private function randomFloat(int $nbMaxDecimals, float $min, float $max): float
{
if ($min > $max) {
throw new \LogicException('Invalid coordinates boundaries');
}
return $this->numberExtension->randomFloat($nbMaxDecimals, $min, $max);
}
}
-217
View File
@@ -1,217 +0,0 @@
<?php
namespace Faker\Core;
use Faker\Extension\DateTimeExtension;
use Faker\Extension\GeneratorAwareExtension;
use Faker\Extension\GeneratorAwareExtensionTrait;
use Faker\Extension\Helper;
/**
* @experimental This class is experimental and does not fall under our BC promise
*
* @since 1.20.0
*/
final class DateTime implements DateTimeExtension, GeneratorAwareExtension
{
use GeneratorAwareExtensionTrait;
/**
* @var string[]
*/
private array $centuries = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII', 'XIII', 'XIV', 'XV', 'XVI', 'XVII', 'XVIII', 'XIX', 'XX', 'XXI'];
private ?string $defaultTimezone = null;
/**
* Get the POSIX-timestamp of a DateTime, int or string.
*
* @param \DateTime|float|int|string $until
*
* @return false|int
*/
private function getTimestamp($until = 'now')
{
if (is_numeric($until)) {
return (int) $until;
}
if ($until instanceof \DateTime) {
return $until->getTimestamp();
}
return strtotime(empty($until) ? 'now' : $until);
}
/**
* Get a DateTime created based on a POSIX-timestamp.
*
* @param int $timestamp the UNIX / POSIX-compatible timestamp
*/
private function getTimestampDateTime(int $timestamp): \DateTime
{
return new \DateTime('@' . $timestamp);
}
private function resolveTimezone(?string $timezone): string
{
if ($timezone !== null) {
return $timezone;
}
return null === $this->defaultTimezone ? date_default_timezone_get() : $this->defaultTimezone;
}
/**
* Internal method to set the timezone on a DateTime object.
*/
private function setTimezone(\DateTime $dateTime, ?string $timezone): \DateTime
{
$timezone = $this->resolveTimezone($timezone);
return $dateTime->setTimezone(new \DateTimeZone($timezone));
}
public function dateTime($until = 'now', ?string $timezone = null): \DateTime
{
return $this->setTimezone(
$this->getTimestampDateTime($this->unixTime($until)),
$timezone,
);
}
public function dateTimeAD($until = 'now', ?string $timezone = null): \DateTime
{
$min = (PHP_INT_SIZE > 4) ? -62135597361 : -PHP_INT_MAX;
return $this->setTimezone(
$this->getTimestampDateTime($this->generator->numberBetween($min, $this->getTimestamp($until))),
$timezone,
);
}
public function dateTimeBetween($from = '-30 years', $until = 'now', ?string $timezone = null): \DateTime
{
$start = $this->getTimestamp($from);
$end = $this->getTimestamp($until);
if ($start > $end) {
throw new \InvalidArgumentException('"$from" must be anterior to "$until".');
}
$timestamp = $this->generator->numberBetween($start, $end);
return $this->setTimezone(
$this->getTimestampDateTime($timestamp),
$timezone,
);
}
public function dateTimeInInterval($from = '-30 years', string $interval = '+5 days', ?string $timezone = null): \DateTime
{
$intervalObject = \DateInterval::createFromDateString($interval);
$datetime = $from instanceof \DateTime ? $from : new \DateTime($from);
$other = (clone $datetime)->add($intervalObject);
$begin = min($datetime, $other);
$end = $datetime === $begin ? $other : $datetime;
return $this->dateTimeBetween($begin, $end, $timezone);
}
public function dateTimeThisWeek($until = 'sunday this week', ?string $timezone = null): \DateTime
{
return $this->dateTimeBetween('monday this week', $until, $timezone);
}
public function dateTimeThisMonth($until = 'last day of this month', ?string $timezone = null): \DateTime
{
return $this->dateTimeBetween('first day of this month', $until, $timezone);
}
public function dateTimeThisYear($until = 'last day of december', ?string $timezone = null): \DateTime
{
return $this->dateTimeBetween('first day of january', $until, $timezone);
}
public function dateTimeThisDecade($until = 'now', ?string $timezone = null): \DateTime
{
$year = floor(date('Y') / 10) * 10;
return $this->dateTimeBetween("first day of january $year", $until, $timezone);
}
public function dateTimeThisCentury($until = 'now', ?string $timezone = null): \DateTime
{
$year = floor(date('Y') / 100) * 100;
return $this->dateTimeBetween("first day of january $year", $until, $timezone);
}
public function date(string $format = 'Y-m-d', $until = 'now'): string
{
return $this->dateTime($until)->format($format);
}
public function time(string $format = 'H:i:s', $until = 'now'): string
{
return $this->date($format, $until);
}
public function unixTime($until = 'now'): int
{
return $this->generator->numberBetween(0, $this->getTimestamp($until));
}
public function iso8601($until = 'now'): string
{
return $this->date(\DateTime::ISO8601, $until);
}
public function amPm($until = 'now'): string
{
return $this->date('a', $until);
}
public function dayOfMonth($until = 'now'): string
{
return $this->date('d', $until);
}
public function dayOfWeek($until = 'now'): string
{
return $this->date('l', $until);
}
public function month($until = 'now'): string
{
return $this->date('m', $until);
}
public function monthName($until = 'now'): string
{
return $this->date('F', $until);
}
public function year($until = 'now'): string
{
return $this->date('Y', $until);
}
public function century(): string
{
return Helper::randomElement($this->centuries);
}
public function timezone(?string $countryCode = null): string
{
if ($countryCode) {
$timezones = \DateTimeZone::listIdentifiers(\DateTimeZone::PER_COUNTRY, $countryCode);
} else {
$timezones = \DateTimeZone::listIdentifiers();
}
return Helper::randomElement($timezones);
}
}
-564
View File
@@ -1,564 +0,0 @@
<?php
declare(strict_types=1);
namespace Faker\Core;
use Faker\Extension;
/**
* @experimental This class is experimental and does not fall under our BC promise
*/
final class File implements Extension\FileExtension
{
/**
* MIME types from the apache.org file. Some types are truncated.
*
* @var array Map of MIME types => file extension(s)
*
* @see http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
*/
private array $mimeTypes = [
'application/atom+xml' => 'atom',
'application/ecmascript' => 'ecma',
'application/emma+xml' => 'emma',
'application/epub+zip' => 'epub',
'application/java-archive' => 'jar',
'application/java-vm' => 'class',
'application/javascript' => 'js',
'application/json' => 'json',
'application/jsonml+json' => 'jsonml',
'application/lost+xml' => 'lostxml',
'application/mathml+xml' => 'mathml',
'application/mets+xml' => 'mets',
'application/mods+xml' => 'mods',
'application/mp4' => 'mp4s',
'application/msword' => ['doc', 'dot'],
'application/octet-stream' => [
'bin',
'dms',
'lrf',
'mar',
'so',
'dist',
'distz',
'pkg',
'bpk',
'dump',
'elc',
'deploy',
],
'application/ogg' => 'ogx',
'application/omdoc+xml' => 'omdoc',
'application/pdf' => 'pdf',
'application/pgp-encrypted' => 'pgp',
'application/pgp-signature' => ['asc', 'sig'],
'application/pkix-pkipath' => 'pkipath',
'application/pkixcmp' => 'pki',
'application/pls+xml' => 'pls',
'application/postscript' => ['ai', 'eps', 'ps'],
'application/pskc+xml' => 'pskcxml',
'application/rdf+xml' => 'rdf',
'application/reginfo+xml' => 'rif',
'application/rss+xml' => 'rss',
'application/rtf' => 'rtf',
'application/sbml+xml' => 'sbml',
'application/vnd.adobe.air-application-installer-package+zip' => 'air',
'application/vnd.adobe.xdp+xml' => 'xdp',
'application/vnd.adobe.xfdf' => 'xfdf',
'application/vnd.ahead.space' => 'ahead',
'application/vnd.dart' => 'dart',
'application/vnd.data-vision.rdz' => 'rdz',
'application/vnd.dece.data' => ['uvf', 'uvvf', 'uvd', 'uvvd'],
'application/vnd.dece.ttml+xml' => ['uvt', 'uvvt'],
'application/vnd.dece.unspecified' => ['uvx', 'uvvx'],
'application/vnd.dece.zip' => ['uvz', 'uvvz'],
'application/vnd.denovo.fcselayout-link' => 'fe_launch',
'application/vnd.dna' => 'dna',
'application/vnd.dolby.mlp' => 'mlp',
'application/vnd.dpgraph' => 'dpg',
'application/vnd.dreamfactory' => 'dfac',
'application/vnd.ds-keypoint' => 'kpxx',
'application/vnd.dvb.ait' => 'ait',
'application/vnd.dvb.service' => 'svc',
'application/vnd.dynageo' => 'geo',
'application/vnd.ecowin.chart' => 'mag',
'application/vnd.enliven' => 'nml',
'application/vnd.epson.esf' => 'esf',
'application/vnd.epson.msf' => 'msf',
'application/vnd.epson.quickanime' => 'qam',
'application/vnd.epson.salt' => 'slt',
'application/vnd.epson.ssf' => 'ssf',
'application/vnd.ezpix-album' => 'ez2',
'application/vnd.ezpix-package' => 'ez3',
'application/vnd.fdf' => 'fdf',
'application/vnd.fdsn.mseed' => 'mseed',
'application/vnd.fdsn.seed' => ['seed', 'dataless'],
'application/vnd.flographit' => 'gph',
'application/vnd.fluxtime.clip' => 'ftc',
'application/vnd.hal+xml' => 'hal',
'application/vnd.hydrostatix.sof-data' => 'sfd-hdstx',
'application/vnd.ibm.minipay' => 'mpy',
'application/vnd.ibm.secure-container' => 'sc',
'application/vnd.iccprofile' => ['icc', 'icm'],
'application/vnd.igloader' => 'igl',
'application/vnd.immervision-ivp' => 'ivp',
'application/vnd.kde.karbon' => 'karbon',
'application/vnd.kde.kchart' => 'chrt',
'application/vnd.kde.kformula' => 'kfo',
'application/vnd.kde.kivio' => 'flw',
'application/vnd.kde.kontour' => 'kon',
'application/vnd.kde.kpresenter' => ['kpr', 'kpt'],
'application/vnd.kde.kspread' => 'ksp',
'application/vnd.kde.kword' => ['kwd', 'kwt'],
'application/vnd.kenameaapp' => 'htke',
'application/vnd.kidspiration' => 'kia',
'application/vnd.kinar' => ['kne', 'knp'],
'application/vnd.koan' => ['skp', 'skd', 'skt', 'skm'],
'application/vnd.kodak-descriptor' => 'sse',
'application/vnd.las.las+xml' => 'lasxml',
'application/vnd.llamagraphics.life-balance.desktop' => 'lbd',
'application/vnd.llamagraphics.life-balance.exchange+xml' => 'lbe',
'application/vnd.lotus-1-2-3' => '123',
'application/vnd.lotus-approach' => 'apr',
'application/vnd.lotus-freelance' => 'pre',
'application/vnd.lotus-notes' => 'nsf',
'application/vnd.lotus-organizer' => 'org',
'application/vnd.lotus-screencam' => 'scm',
'application/vnd.mozilla.xul+xml' => 'xul',
'application/vnd.ms-artgalry' => 'cil',
'application/vnd.ms-cab-compressed' => 'cab',
'application/vnd.ms-excel' => [
'xls',
'xlm',
'xla',
'xlc',
'xlt',
'xlw',
],
'application/vnd.ms-excel.addin.macroenabled.12' => 'xlam',
'application/vnd.ms-excel.sheet.binary.macroenabled.12' => 'xlsb',
'application/vnd.ms-excel.sheet.macroenabled.12' => 'xlsm',
'application/vnd.ms-excel.template.macroenabled.12' => 'xltm',
'application/vnd.ms-fontobject' => 'eot',
'application/vnd.ms-htmlhelp' => 'chm',
'application/vnd.ms-ims' => 'ims',
'application/vnd.ms-lrm' => 'lrm',
'application/vnd.ms-officetheme' => 'thmx',
'application/vnd.ms-pki.seccat' => 'cat',
'application/vnd.ms-pki.stl' => 'stl',
'application/vnd.ms-powerpoint' => ['ppt', 'pps', 'pot'],
'application/vnd.ms-powerpoint.addin.macroenabled.12' => 'ppam',
'application/vnd.ms-powerpoint.presentation.macroenabled.12' => 'pptm',
'application/vnd.ms-powerpoint.slide.macroenabled.12' => 'sldm',
'application/vnd.ms-powerpoint.slideshow.macroenabled.12' => 'ppsm',
'application/vnd.ms-powerpoint.template.macroenabled.12' => 'potm',
'application/vnd.ms-project' => ['mpp', 'mpt'],
'application/vnd.ms-word.document.macroenabled.12' => 'docm',
'application/vnd.ms-word.template.macroenabled.12' => 'dotm',
'application/vnd.ms-works' => ['wps', 'wks', 'wcm', 'wdb'],
'application/vnd.ms-wpl' => 'wpl',
'application/vnd.ms-xpsdocument' => 'xps',
'application/vnd.mseq' => 'mseq',
'application/vnd.musician' => 'mus',
'application/vnd.oasis.opendocument.chart' => 'odc',
'application/vnd.oasis.opendocument.chart-template' => 'otc',
'application/vnd.oasis.opendocument.database' => 'odb',
'application/vnd.oasis.opendocument.formula' => 'odf',
'application/vnd.oasis.opendocument.formula-template' => 'odft',
'application/vnd.oasis.opendocument.graphics' => 'odg',
'application/vnd.oasis.opendocument.graphics-template' => 'otg',
'application/vnd.oasis.opendocument.image' => 'odi',
'application/vnd.oasis.opendocument.image-template' => 'oti',
'application/vnd.oasis.opendocument.presentation' => 'odp',
'application/vnd.oasis.opendocument.presentation-template' => 'otp',
'application/vnd.oasis.opendocument.spreadsheet' => 'ods',
'application/vnd.oasis.opendocument.spreadsheet-template' => 'ots',
'application/vnd.oasis.opendocument.text' => 'odt',
'application/vnd.oasis.opendocument.text-master' => 'odm',
'application/vnd.oasis.opendocument.text-template' => 'ott',
'application/vnd.oasis.opendocument.text-web' => 'oth',
'application/vnd.olpc-sugar' => 'xo',
'application/vnd.oma.dd2+xml' => 'dd2',
'application/vnd.openofficeorg.extension' => 'oxt',
'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'pptx',
'application/vnd.openxmlformats-officedocument.presentationml.slide' => 'sldx',
'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => 'ppsx',
'application/vnd.openxmlformats-officedocument.presentationml.template' => 'potx',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'xlsx',
'application/vnd.openxmlformats-officedocument.spreadsheetml.template' => 'xltx',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx',
'application/vnd.openxmlformats-officedocument.wordprocessingml.template' => 'dotx',
'application/vnd.pvi.ptid1' => 'ptid',
'application/vnd.quark.quarkxpress' => [
'qxd',
'qxt',
'qwd',
'qwt',
'qxl',
'qxb',
],
'application/vnd.realvnc.bed' => 'bed',
'application/vnd.recordare.musicxml' => 'mxl',
'application/vnd.recordare.musicxml+xml' => 'musicxml',
'application/vnd.rig.cryptonote' => 'cryptonote',
'application/vnd.rim.cod' => 'cod',
'application/vnd.rn-realmedia' => 'rm',
'application/vnd.rn-realmedia-vbr' => 'rmvb',
'application/vnd.route66.link66+xml' => 'link66',
'application/vnd.sailingtracker.track' => 'st',
'application/vnd.seemail' => 'see',
'application/vnd.sema' => 'sema',
'application/vnd.semd' => 'semd',
'application/vnd.semf' => 'semf',
'application/vnd.shana.informed.formdata' => 'ifm',
'application/vnd.shana.informed.formtemplate' => 'itp',
'application/vnd.shana.informed.interchange' => 'iif',
'application/vnd.shana.informed.package' => 'ipk',
'application/vnd.simtech-mindmapper' => ['twd', 'twds'],
'application/vnd.smaf' => 'mmf',
'application/vnd.stepmania.stepchart' => 'sm',
'application/vnd.sun.xml.calc' => 'sxc',
'application/vnd.sun.xml.calc.template' => 'stc',
'application/vnd.sun.xml.draw' => 'sxd',
'application/vnd.sun.xml.draw.template' => 'std',
'application/vnd.sun.xml.impress' => 'sxi',
'application/vnd.sun.xml.impress.template' => 'sti',
'application/vnd.sun.xml.math' => 'sxm',
'application/vnd.sun.xml.writer' => 'sxw',
'application/vnd.sun.xml.writer.global' => 'sxg',
'application/vnd.sun.xml.writer.template' => 'stw',
'application/vnd.sus-calendar' => ['sus', 'susp'],
'application/vnd.svd' => 'svd',
'application/vnd.symbian.install' => ['sis', 'sisx'],
'application/vnd.syncml+xml' => 'xsm',
'application/vnd.syncml.dm+wbxml' => 'bdm',
'application/vnd.syncml.dm+xml' => 'xdm',
'application/vnd.tao.intent-module-archive' => 'tao',
'application/vnd.tcpdump.pcap' => ['pcap', 'cap', 'dmp'],
'application/vnd.tmobile-livetv' => 'tmo',
'application/vnd.trid.tpt' => 'tpt',
'application/vnd.triscape.mxs' => 'mxs',
'application/vnd.trueapp' => 'tra',
'application/vnd.ufdl' => ['ufd', 'ufdl'],
'application/vnd.uiq.theme' => 'utz',
'application/vnd.umajin' => 'umj',
'application/vnd.unity' => 'unityweb',
'application/vnd.uoml+xml' => 'uoml',
'application/vnd.vcx' => 'vcx',
'application/vnd.visio' => ['vsd', 'vst', 'vss', 'vsw'],
'application/vnd.visionary' => 'vis',
'application/vnd.vsf' => 'vsf',
'application/vnd.wap.wbxml' => 'wbxml',
'application/vnd.wap.wmlc' => 'wmlc',
'application/vnd.wap.wmlscriptc' => 'wmlsc',
'application/vnd.webturbo' => 'wtb',
'application/vnd.wolfram.player' => 'nbp',
'application/vnd.wordperfect' => 'wpd',
'application/vnd.wqd' => 'wqd',
'application/vnd.wt.stf' => 'stf',
'application/vnd.xara' => 'xar',
'application/vnd.xfdl' => 'xfdl',
'application/voicexml+xml' => 'vxml',
'application/widget' => 'wgt',
'application/winhlp' => 'hlp',
'application/wsdl+xml' => 'wsdl',
'application/wspolicy+xml' => 'wspolicy',
'application/x-7z-compressed' => '7z',
'application/x-bittorrent' => 'torrent',
'application/x-blorb' => ['blb', 'blorb'],
'application/x-bzip' => 'bz',
'application/x-cdlink' => 'vcd',
'application/x-cfs-compressed' => 'cfs',
'application/x-chat' => 'chat',
'application/x-chess-pgn' => 'pgn',
'application/x-conference' => 'nsc',
'application/x-cpio' => 'cpio',
'application/x-csh' => 'csh',
'application/x-debian-package' => ['deb', 'udeb'],
'application/x-dgc-compressed' => 'dgc',
'application/x-director' => [
'dir',
'dcr',
'dxr',
'cst',
'cct',
'cxt',
'w3d',
'fgd',
'swa',
],
'application/x-font-ttf' => ['ttf', 'ttc'],
'application/x-font-type1' => ['pfa', 'pfb', 'pfm', 'afm'],
'application/x-font-woff' => 'woff',
'application/x-freearc' => 'arc',
'application/x-futuresplash' => 'spl',
'application/x-gca-compressed' => 'gca',
'application/x-glulx' => 'ulx',
'application/x-gnumeric' => 'gnumeric',
'application/x-gramps-xml' => 'gramps',
'application/x-gtar' => 'gtar',
'application/x-hdf' => 'hdf',
'application/x-install-instructions' => 'install',
'application/x-iso9660-image' => 'iso',
'application/x-java-jnlp-file' => 'jnlp',
'application/x-latex' => 'latex',
'application/x-lzh-compressed' => ['lzh', 'lha'],
'application/x-mie' => 'mie',
'application/x-mobipocket-ebook' => ['prc', 'mobi'],
'application/x-ms-application' => 'application',
'application/x-ms-shortcut' => 'lnk',
'application/x-ms-wmd' => 'wmd',
'application/x-ms-wmz' => 'wmz',
'application/x-ms-xbap' => 'xbap',
'application/x-msaccess' => 'mdb',
'application/x-msbinder' => 'obd',
'application/x-mscardfile' => 'crd',
'application/x-msclip' => 'clp',
'application/x-msdownload' => ['exe', 'dll', 'com', 'bat', 'msi'],
'application/x-msmediaview' => [
'mvb',
'm13',
'm14',
],
'application/x-msmetafile' => ['wmf', 'wmz', 'emf', 'emz'],
'application/x-rar-compressed' => 'rar',
'application/x-research-info-systems' => 'ris',
'application/x-sh' => 'sh',
'application/x-shar' => 'shar',
'application/x-shockwave-flash' => 'swf',
'application/x-silverlight-app' => 'xap',
'application/x-sql' => 'sql',
'application/x-stuffit' => 'sit',
'application/x-stuffitx' => 'sitx',
'application/x-subrip' => 'srt',
'application/x-sv4cpio' => 'sv4cpio',
'application/x-sv4crc' => 'sv4crc',
'application/x-t3vm-image' => 't3',
'application/x-tads' => 'gam',
'application/x-tar' => 'tar',
'application/x-tcl' => 'tcl',
'application/x-tex' => 'tex',
'application/x-tex-tfm' => 'tfm',
'application/x-texinfo' => ['texinfo', 'texi'],
'application/x-tgif' => 'obj',
'application/x-ustar' => 'ustar',
'application/x-wais-source' => 'src',
'application/x-x509-ca-cert' => ['der', 'crt'],
'application/x-xfig' => 'fig',
'application/x-xliff+xml' => 'xlf',
'application/x-xpinstall' => 'xpi',
'application/x-xz' => 'xz',
'application/x-zmachine' => 'z1',
'application/xaml+xml' => 'xaml',
'application/xcap-diff+xml' => 'xdf',
'application/xenc+xml' => 'xenc',
'application/xhtml+xml' => ['xhtml', 'xht'],
'application/xml' => ['xml', 'xsl'],
'application/xml-dtd' => 'dtd',
'application/xop+xml' => 'xop',
'application/xproc+xml' => 'xpl',
'application/xslt+xml' => 'xslt',
'application/xspf+xml' => 'xspf',
'application/xv+xml' => ['mxml', 'xhvml', 'xvml', 'xvm'],
'application/yang' => 'yang',
'application/yin+xml' => 'yin',
'application/zip' => 'zip',
'audio/adpcm' => 'adp',
'audio/basic' => ['au', 'snd'],
'audio/midi' => ['mid', 'midi', 'kar', 'rmi'],
'audio/mp4' => 'mp4a',
'audio/mpeg' => [
'mpga',
'mp2',
'mp2a',
'mp3',
'm2a',
'm3a',
],
'audio/ogg' => ['oga', 'ogg', 'spx'],
'audio/vnd.dece.audio' => ['uva', 'uvva'],
'audio/vnd.rip' => 'rip',
'audio/webm' => 'weba',
'audio/x-aac' => 'aac',
'audio/x-aiff' => ['aif', 'aiff', 'aifc'],
'audio/x-caf' => 'caf',
'audio/x-flac' => 'flac',
'audio/x-matroska' => 'mka',
'audio/x-mpegurl' => 'm3u',
'audio/x-ms-wax' => 'wax',
'audio/x-ms-wma' => 'wma',
'audio/x-pn-realaudio' => ['ram', 'ra'],
'audio/x-pn-realaudio-plugin' => 'rmp',
'audio/x-wav' => 'wav',
'audio/xm' => 'xm',
'image/bmp' => 'bmp',
'image/cgm' => 'cgm',
'image/g3fax' => 'g3',
'image/gif' => 'gif',
'image/ief' => 'ief',
'image/jpeg' => ['jpeg', 'jpg', 'jpe'],
'image/ktx' => 'ktx',
'image/png' => 'png',
'image/prs.btif' => 'btif',
'image/sgi' => 'sgi',
'image/svg+xml' => ['svg', 'svgz'],
'image/tiff' => ['tiff', 'tif'],
'image/vnd.adobe.photoshop' => 'psd',
'image/vnd.dece.graphic' => ['uvi', 'uvvi', 'uvg', 'uvvg'],
'image/vnd.dvb.subtitle' => 'sub',
'image/vnd.djvu' => ['djvu', 'djv'],
'image/vnd.dwg' => 'dwg',
'image/vnd.dxf' => 'dxf',
'image/vnd.fastbidsheet' => 'fbs',
'image/vnd.fpx' => 'fpx',
'image/vnd.fst' => 'fst',
'image/vnd.fujixerox.edmics-mmr' => 'mmr',
'image/vnd.fujixerox.edmics-rlc' => 'rlc',
'image/vnd.ms-modi' => 'mdi',
'image/vnd.ms-photo' => 'wdp',
'image/vnd.net-fpx' => 'npx',
'image/vnd.wap.wbmp' => 'wbmp',
'image/vnd.xiff' => 'xif',
'image/webp' => 'webp',
'image/x-3ds' => '3ds',
'image/x-cmu-raster' => 'ras',
'image/x-cmx' => 'cmx',
'image/x-freehand' => ['fh', 'fhc', 'fh4', 'fh5', 'fh7'],
'image/x-icon' => 'ico',
'image/x-mrsid-image' => 'sid',
'image/x-pcx' => 'pcx',
'image/x-pict' => ['pic', 'pct'],
'image/x-portable-anymap' => 'pnm',
'image/x-portable-bitmap' => 'pbm',
'image/x-portable-graymap' => 'pgm',
'image/x-portable-pixmap' => 'ppm',
'image/x-rgb' => 'rgb',
'image/x-tga' => 'tga',
'image/x-xbitmap' => 'xbm',
'image/x-xpixmap' => 'xpm',
'image/x-xwindowdump' => 'xwd',
'message/rfc822' => ['eml', 'mime'],
'model/iges' => ['igs', 'iges'],
'model/mesh' => ['msh', 'mesh', 'silo'],
'model/vnd.collada+xml' => 'dae',
'model/vnd.dwf' => 'dwf',
'model/vnd.gdl' => 'gdl',
'model/vnd.gtw' => 'gtw',
'model/vnd.mts' => 'mts',
'model/vnd.vtu' => 'vtu',
'model/vrml' => ['wrl', 'vrml'],
'model/x3d+binary' => 'x3db',
'model/x3d+vrml' => 'x3dv',
'model/x3d+xml' => 'x3d',
'text/cache-manifest' => 'appcache',
'text/calendar' => ['ics', 'ifb'],
'text/css' => 'css',
'text/csv' => 'csv',
'text/html' => ['html', 'htm'],
'text/n3' => 'n3',
'text/plain' => [
'txt',
'text',
'conf',
'def',
'list',
'log',
'in',
],
'text/prs.lines.tag' => 'dsc',
'text/richtext' => 'rtx',
'text/sgml' => ['sgml', 'sgm'],
'text/tab-separated-values' => 'tsv',
'text/troff' => [
't',
'tr',
'roff',
'man',
'me',
'ms',
],
'text/turtle' => 'ttl',
'text/uri-list' => ['uri', 'uris', 'urls'],
'text/vcard' => 'vcard',
'text/vnd.curl' => 'curl',
'text/vnd.curl.dcurl' => 'dcurl',
'text/vnd.curl.scurl' => 'scurl',
'text/vnd.curl.mcurl' => 'mcurl',
'text/vnd.dvb.subtitle' => 'sub',
'text/vnd.fly' => 'fly',
'text/vnd.fmi.flexstor' => 'flx',
'text/vnd.graphviz' => 'gv',
'text/vnd.in3d.3dml' => '3dml',
'text/vnd.in3d.spot' => 'spot',
'text/vnd.sun.j2me.app-descriptor' => 'jad',
'text/vnd.wap.wml' => 'wml',
'text/vnd.wap.wmlscript' => 'wmls',
'text/x-asm' => ['s', 'asm'],
'text/x-fortran' => ['f', 'for', 'f77', 'f90'],
'text/x-java-source' => 'java',
'text/x-opml' => 'opml',
'text/x-pascal' => ['p', 'pas'],
'text/x-nfo' => 'nfo',
'text/x-setext' => 'etx',
'text/x-sfv' => 'sfv',
'text/x-uuencode' => 'uu',
'text/x-vcalendar' => 'vcs',
'text/x-vcard' => 'vcf',
'video/3gpp' => '3gp',
'video/3gpp2' => '3g2',
'video/h261' => 'h261',
'video/h263' => 'h263',
'video/h264' => 'h264',
'video/jpeg' => 'jpgv',
'video/jpm' => ['jpm', 'jpgm'],
'video/mj2' => 'mj2',
'video/mp4' => 'mp4',
'video/mpeg' => ['mpeg', 'mpg', 'mpe', 'm1v', 'm2v'],
'video/ogg' => 'ogv',
'video/quicktime' => ['qt', 'mov'],
'video/vnd.dece.hd' => ['uvh', 'uvvh'],
'video/vnd.dece.mobile' => ['uvm', 'uvvm'],
'video/vnd.dece.pd' => ['uvp', 'uvvp'],
'video/vnd.dece.sd' => ['uvs', 'uvvs'],
'video/vnd.dece.video' => ['uvv', 'uvvv'],
'video/vnd.dvb.file' => 'dvb',
'video/vnd.fvt' => 'fvt',
'video/vnd.mpegurl' => ['mxu', 'm4u'],
'video/vnd.ms-playready.media.pyv' => 'pyv',
'video/vnd.uvvu.mp4' => ['uvu', 'uvvu'],
'video/vnd.vivo' => 'viv',
'video/webm' => 'webm',
'video/x-f4v' => 'f4v',
'video/x-fli' => 'fli',
'video/x-flv' => 'flv',
'video/x-m4v' => 'm4v',
'video/x-matroska' => ['mkv', 'mk3d', 'mks'],
'video/x-mng' => 'mng',
'video/x-ms-asf' => ['asf', 'asx'],
'video/x-ms-vob' => 'vob',
'video/x-ms-wm' => 'wm',
'video/x-ms-wmv' => 'wmv',
'video/x-ms-wmx' => 'wmx',
'video/x-ms-wvx' => 'wvx',
'video/x-msvideo' => 'avi',
'video/x-sgi-movie' => 'movie',
];
public function mimeType(): string
{
return array_rand($this->mimeTypes, 1);
}
public function extension(): string
{
$extension = $this->mimeTypes[array_rand($this->mimeTypes, 1)];
return is_array($extension) ? $extension[array_rand($extension, 1)] : $extension;
}
public function filePath(): string
{
return tempnam(sys_get_temp_dir(), 'faker');
}
}
-83
View File
@@ -1,83 +0,0 @@
<?php
declare(strict_types=1);
namespace Faker\Core;
use Faker\Extension;
/**
* @experimental This class is experimental and does not fall under our BC promise
*/
final class Number implements Extension\NumberExtension
{
public function numberBetween(int $min = 0, int $max = 2147483647): int
{
$int1 = min($min, $max);
$int2 = max($min, $max);
return mt_rand($int1, $int2);
}
public function randomDigit(): int
{
return $this->numberBetween(0, 9);
}
public function randomDigitNot(int $except): int
{
$result = $this->numberBetween(0, 8);
if ($result >= $except) {
++$result;
}
return $result;
}
public function randomDigitNotZero(): int
{
return $this->numberBetween(1, 9);
}
public function randomFloat(?int $nbMaxDecimals = null, float $min = 0, ?float $max = null): float
{
if (null === $nbMaxDecimals) {
$nbMaxDecimals = $this->randomDigit();
}
if (null === $max) {
$max = $this->randomNumber();
if ($min > $max) {
$max = $min;
}
}
if ($min > $max) {
$tmp = $min;
$min = $max;
$max = $tmp;
}
return round($min + $this->numberBetween() / mt_getrandmax() * ($max - $min), $nbMaxDecimals);
}
public function randomNumber(?int $nbDigits = null, bool $strict = false): int
{
if (null === $nbDigits) {
$nbDigits = $this->randomDigitNotZero();
}
$max = 10 ** $nbDigits - 1;
if ($max > mt_getrandmax()) {
throw new \InvalidArgumentException('randomNumber() can only generate numbers up to mt_getrandmax()');
}
if ($strict) {
return $this->numberBetween(10 ** ($nbDigits - 1), $max);
}
return $this->numberBetween(0, $max);
}
}
-65
View File
@@ -1,65 +0,0 @@
<?php
namespace Faker\Core;
use Faker\Extension;
/**
* @experimental This class is experimental and does not fall under our BC promise
*/
final class Uuid implements Extension\UuidExtension
{
private Extension\NumberExtension $numberExtension;
public function __construct(?Extension\NumberExtension $numberExtension = null)
{
$this->numberExtension = $numberExtension ?: new Number();
}
public function uuid3(): string
{
// fix for compatibility with 32bit architecture; each mt_rand call is restricted to 32bit
// two such calls will cause 64bits of randomness regardless of architecture
$seed = $this->numberExtension->numberBetween(0, 2147483647) . '#' . $this->numberExtension->numberBetween(0, 2147483647);
// Hash the seed and convert to a byte array
$val = md5($seed, true);
$byte = array_values(unpack('C16', $val));
// extract fields from byte array
$tLo = ($byte[0] << 24) | ($byte[1] << 16) | ($byte[2] << 8) | $byte[3];
$tMi = ($byte[4] << 8) | $byte[5];
$tHi = ($byte[6] << 8) | $byte[7];
$csLo = $byte[9];
$csHi = $byte[8] & 0x3f | (1 << 7);
// correct byte order for big edian architecture
if (pack('L', 0x6162797A) == pack('N', 0x6162797A)) {
$tLo = (($tLo & 0x000000ff) << 24) | (($tLo & 0x0000ff00) << 8)
| (($tLo & 0x00ff0000) >> 8) | (($tLo & 0xff000000) >> 24);
$tMi = (($tMi & 0x00ff) << 8) | (($tMi & 0xff00) >> 8);
$tHi = (($tHi & 0x00ff) << 8) | (($tHi & 0xff00) >> 8);
}
// apply version number
$tHi &= 0x0fff;
$tHi |= (3 << 12);
// cast to string
return sprintf(
'%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x',
$tLo,
$tMi,
$tHi,
$csHi,
$csLo,
$byte[10],
$byte[11],
$byte[12],
$byte[13],
$byte[14],
$byte[15],
);
}
}
-69
View File
@@ -1,69 +0,0 @@
<?php
declare(strict_types=1);
namespace Faker\Core;
use Faker\Extension;
use Faker\Provider\DateTime;
/**
* @experimental This class is experimental and does not fall under our BC promise
*/
final class Version implements Extension\VersionExtension
{
private Extension\NumberExtension $numberExtension;
/**
* @var string[]
*/
private array $semverCommonPreReleaseIdentifiers = ['alpha', 'beta', 'rc'];
public function __construct(?Extension\NumberExtension $numberExtension = null)
{
$this->numberExtension = $numberExtension ?: new Number();
}
/**
* Represents v2.0.0 of the semantic versioning: https://semver.org/spec/v2.0.0.html
*/
public function semver(bool $preRelease = false, bool $build = false): string
{
return sprintf(
'%d.%d.%d%s%s',
$this->numberExtension->numberBetween(0, 9),
$this->numberExtension->numberBetween(0, 99),
$this->numberExtension->numberBetween(0, 99),
$preRelease && $this->numberExtension->numberBetween(0, 1) === 1 ? '-' . $this->semverPreReleaseIdentifier() : '',
$build && $this->numberExtension->numberBetween(0, 1) === 1 ? '+' . $this->semverBuildIdentifier() : '',
);
}
/**
* Common pre-release identifier
*/
private function semverPreReleaseIdentifier(): string
{
$ident = Extension\Helper::randomElement($this->semverCommonPreReleaseIdentifiers);
if ($this->numberExtension->numberBetween(0, 1) !== 1) {
return $ident;
}
return $ident . '.' . $this->numberExtension->numberBetween(1, 99);
}
/**
* Common random build identifier
*/
private function semverBuildIdentifier(): string
{
if ($this->numberExtension->numberBetween(0, 1) === 1) {
// short git revision syntax: https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection
return substr(sha1(Extension\Helper::lexify('??????')), 0, 7);
}
// date syntax
return DateTime::date('YmdHis');
}
}
-49
View File
@@ -1,49 +0,0 @@
<?php
namespace Faker;
/**
* This generator returns a default value for all called properties
* and methods.
*
* @mixin Generator
*
* @deprecated Use ChanceGenerator instead
*/
class DefaultGenerator
{
protected $default;
public function __construct($default = null)
{
trigger_deprecation('fakerphp/faker', '1.16', 'Class "%s" is deprecated, use "%s" instead.', __CLASS__, ChanceGenerator::class);
$this->default = $default;
}
public function ext()
{
return $this;
}
/**
* @param string $attribute
*
* @deprecated Use a method instead.
*/
public function __get($attribute)
{
trigger_deprecation('fakerphp/faker', '1.14', 'Accessing property "%s" is deprecated, use "%s()" instead.', $attribute, $attribute);
return $this->default;
}
/**
* @param string $method
* @param array $attributes
*/
public function __call($method, $attributes)
{
return $this->default;
}
}
-70
View File
@@ -1,70 +0,0 @@
<?php
namespace Faker;
class Documentor
{
protected $generator;
public function __construct(Generator $generator)
{
$this->generator = $generator;
}
/**
* @return array
*/
public function getFormatters()
{
$formatters = [];
$providers = array_reverse($this->generator->getProviders());
$providers[] = new Provider\Base($this->generator);
foreach ($providers as $provider) {
$providerClass = get_class($provider);
$formatters[$providerClass] = [];
$refl = new \ReflectionObject($provider);
foreach ($refl->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflmethod) {
if ($reflmethod->getDeclaringClass()->getName() == 'Faker\Provider\Base' && $providerClass != 'Faker\Provider\Base') {
continue;
}
$methodName = $reflmethod->name;
if ($reflmethod->isConstructor()) {
continue;
}
$parameters = [];
foreach ($reflmethod->getParameters() as $reflparameter) {
$parameter = '$' . $reflparameter->getName();
if ($reflparameter->isDefaultValueAvailable()) {
$parameter .= ' = ' . var_export($reflparameter->getDefaultValue(), true);
}
$parameters[] = $parameter;
}
$parameters = $parameters ? '(' . implode(', ', $parameters) . ')' : '';
try {
$example = $this->generator->format($methodName);
} catch (\InvalidArgumentException $e) {
$example = '';
}
if (is_array($example)) {
$example = "array('" . implode("', '", $example) . "')";
} elseif ($example instanceof \DateTime) {
$example = "DateTime('" . $example->format('Y-m-d H:i:s') . "')";
} elseif ($example instanceof Generator || $example instanceof UniqueGenerator) { // modifier
$example = '';
} else {
$example = var_export($example, true);
}
$formatters[$providerClass][$methodName . $parameters] = $example;
}
}
return $formatters;
}
}
@@ -1,39 +0,0 @@
<?php
namespace Faker\Extension;
/**
* @experimental This interface is experimental and does not fall under our BC promise
*/
interface AddressExtension extends Extension
{
/**
* @example '791 Crist Parks, Sashabury, IL 86039-9874'
*/
public function address(): string;
/**
* Randomly return a real city name.
*/
public function city(): string;
/**
* @example 86039-9874
*/
public function postcode(): string;
/**
* @example 'Crist Parks'
*/
public function streetName(): string;
/**
* @example '791 Crist Parks'
*/
public function streetAddress(): string;
/**
* Randomly return a building number.
*/
public function buildingNumber(): string;
}
@@ -1,41 +0,0 @@
<?php
namespace Faker\Extension;
/**
* @experimental This interface is experimental and does not fall under our BC promise
*/
interface BarcodeExtension extends Extension
{
/**
* Get a random EAN13 barcode.
*
* @example '4006381333931'
*/
public function ean13(): string;
/**
* Get a random EAN8 barcode.
*
* @example '73513537'
*/
public function ean8(): string;
/**
* Get a random ISBN-10 code
*
* @see http://en.wikipedia.org/wiki/International_Standard_Book_Number
*
* @example '4881416324'
*/
public function isbn10(): string;
/**
* Get a random ISBN-13 code
*
* @see http://en.wikipedia.org/wiki/International_Standard_Book_Number
*
* @example '9790404436093'
*/
public function isbn13(): string;
}
@@ -1,30 +0,0 @@
<?php
namespace Faker\Extension;
/**
* @experimental This interface is experimental and does not fall under our BC promise
*/
interface BloodExtension extends Extension
{
/**
* Get an actual blood type
*
* @example 'AB'
*/
public function bloodType(): string;
/**
* Get a random resis value
*
* @example '+'
*/
public function bloodRh(): string;
/**
* Get a full blood group
*
* @example 'AB+'
*/
public function bloodGroup(): string;
}
@@ -1,63 +0,0 @@
<?php
namespace Faker\Extension;
/**
* @experimental This interface is experimental and does not fall under our BC promise
*/
interface ColorExtension extends Extension
{
/**
* @example '#fa3cc2'
*/
public function hexColor(): string;
/**
* @example '#ff0044'
*/
public function safeHexColor(): string;
/**
* @example 'array(0,255,122)'
*
* @return int[]
*/
public function rgbColorAsArray(): array;
/**
* @example '0,255,122'
*/
public function rgbColor(): string;
/**
* @example 'rgb(0,255,122)'
*/
public function rgbCssColor(): string;
/**
* @example 'rgba(0,255,122,0.8)'
*/
public function rgbaCssColor(): string;
/**
* @example 'blue'
*/
public function safeColorName(): string;
/**
* @example 'NavajoWhite'
*/
public function colorName(): string;
/**
* @example '340,50,20'
*/
public function hslColor(): string;
/**
* @example array(340, 50, 20)
*
* @return int[]
*/
public function hslColorAsArray(): array;
}
@@ -1,21 +0,0 @@
<?php
namespace Faker\Extension;
/**
* @experimental This interface is experimental and does not fall under our BC promise
*/
interface CompanyExtension extends Extension
{
/**
* @example 'Acme Ltd'
*/
public function company(): string;
/**
* @example 'Ltd'
*/
public function companySuffix(): string;
public function jobTitle(): string;
}
@@ -1,14 +0,0 @@
<?php
namespace Faker\Extension;
/**
* @experimental This interface is experimental and does not fall under our BC promise
*/
interface CountryExtension extends Extension
{
/**
* @example 'Japan'
*/
public function country(): string;
}
@@ -1,242 +0,0 @@
<?php
namespace Faker\Extension;
/**
* FakerPHP extension for Date-related randomization.
*
* Functions accepting a date string use the `strtotime()` function internally.
*
* @experimental
*
* @since 1.20.0
*/
interface DateTimeExtension
{
/**
* Get a DateTime object between January 1, 1970, and `$until` (defaults to "now").
*
* @param \DateTime|int|string $until maximum timestamp, defaults to "now"
* @param string|null $timezone zone timezone for generated date, fallback to `DateTime::$defaultTimezone` and `date_default_timezone_get()`.
*
* @see \DateTimeZone
* @see http://php.net/manual/en/timezones.php
* @see http://php.net/manual/en/function.date-default-timezone-get.php
*
* @example DateTime('2005-08-16 20:39:21')
*/
public function dateTime($until = 'now', ?string $timezone = null): \DateTime;
/**
* Get a DateTime object for a date between January 1, 0001, and now.
*
* @param \DateTime|int|string $until maximum timestamp, defaults to "now"
* @param string|null $timezone zone timezone for generated date, fallback to `DateTime::$defaultTimezone` and `date_default_timezone_get()`.
*
* @example DateTime('1265-03-22 21:15:52')
*
* @see http://php.net/manual/en/timezones.php
* @see http://php.net/manual/en/function.date-default-timezone-get.php
*/
public function dateTimeAD($until = 'now', ?string $timezone = null): \DateTime;
/**
* Get a DateTime object a random date between `$from` and `$until`.
* Accepts date strings that can be recognized by `strtotime()`.
*
* @param \DateTime|string $from defaults to 30 years ago
* @param \DateTime|int|string $until maximum timestamp, defaults to "now"
* @param string|null $timezone zone timezone for generated date, fallback to `DateTime::$defaultTimezone` and `date_default_timezone_get()`.
*
* @see \DateTimeZone
* @see http://php.net/manual/en/timezones.php
* @see http://php.net/manual/en/function.date-default-timezone-get.php
*/
public function dateTimeBetween($from = '-30 years', $until = 'now', ?string $timezone = null): \DateTime;
/**
* Get a DateTime object based on a random date between `$from` and an interval.
* Accepts date string that can be recognized by `strtotime()`.
*
* @param \DateTime|int|string $from defaults to 30 years ago
* @param string $interval defaults to 5 days after
* @param string|null $timezone zone timezone for generated date, fallback to `DateTime::$defaultTimezone` and `date_default_timezone_get()`.
*
* @see \DateTimeZone
* @see http://php.net/manual/en/timezones.php
* @see http://php.net/manual/en/function.date-default-timezone-get.php
*/
public function dateTimeInInterval($from = '-30 years', string $interval = '+5 days', ?string $timezone = null): \DateTime;
/**
* Get a date time object somewhere inside the current week.
*
* @param \DateTime|int|string $until maximum timestamp, defaults to "now"
* @param string|null $timezone zone timezone for generated date, fallback to `DateTime::$defaultTimezone` and `date_default_timezone_get()`.
*
* @see \DateTimeZone
* @see http://php.net/manual/en/timezones.php
* @see http://php.net/manual/en/function.date-default-timezone-get.php
*/
public function dateTimeThisWeek($until = 'now', ?string $timezone = null): \DateTime;
/**
* Get a date time object somewhere inside the current month.
*
* @param \DateTime|int|string $until maximum timestamp, defaults to "now"
* @param string|null $timezone timezone for generated date, fallback to `DateTime::$defaultTimezone` and `date_default_timezone_get()`.
*
* @see \DateTimeZone
* @see http://php.net/manual/en/timezones.php
* @see http://php.net/manual/en/function.date-default-timezone-get.php
*/
public function dateTimeThisMonth($until = 'now', ?string $timezone = null): \DateTime;
/**
* Get a date time object somewhere inside the current year.
*
* @param \DateTime|int|string $until maximum timestamp, defaults to "now"
* @param string|null $timezone timezone for generated date, fallback to `DateTime::$defaultTimezone` and `date_default_timezone_get()`.
*
* @see \DateTimeZone
* @see http://php.net/manual/en/timezones.php
* @see http://php.net/manual/en/function.date-default-timezone-get.php
*/
public function dateTimeThisYear($until = 'now', ?string $timezone = null): \DateTime;
/**
* Get a date time object somewhere inside the current decade.
*
* @param \DateTime|int|string $until maximum timestamp, defaults to "now"
* @param string|null $timezone timezone for generated date, fallback to `DateTime::$defaultTimezone` and `date_default_timezone_get()`.
*
* @see \DateTimeZone
* @see http://php.net/manual/en/timezones.php
* @see http://php.net/manual/en/function.date-default-timezone-get.php
*/
public function dateTimeThisDecade($until = 'now', ?string $timezone = null): \DateTime;
/**
* Get a date time object somewhere inside the current century.
*
* @param \DateTime|int|string $until maximum timestamp, defaults to "now"
* @param string|null $timezone timezone for generated date, fallback to `DateTime::$defaultTimezone` and `date_default_timezone_get()`.
*
* @see \DateTimeZone
* @see http://php.net/manual/en/timezones.php
* @see http://php.net/manual/en/function.date-default-timezone-get.php
*/
public function dateTimeThisCentury($until = 'now', ?string $timezone = null): \DateTime;
/**
* Get a date string between January 1, 1970, and `$until`.
*
* @param string $format DateTime format
* @param \DateTime|int|string $until maximum timestamp, defaults to "now"
*
* @see https://www.php.net/manual/en/datetime.format.php
*/
public function date(string $format = 'Y-m-d', $until = 'now'): string;
/**
* Get a time string (24h format by default).
*
* @param string $format DateTime format
* @param \DateTime|int|string $until maximum timestamp, defaults to "now"
*
* @see https://www.php.net/manual/en/datetime.format.php
*/
public function time(string $format = 'H:i:s', $until = 'now'): string;
/**
* Get a UNIX (POSIX-compatible) timestamp between January 1, 1970, and `$until`.
*
* @param \DateTime|int|string $until maximum timestamp, defaults to "now"
*/
public function unixTime($until = 'now'): int;
/**
* Get a date string according to the ISO-8601 standard.
*
* @param \DateTime|int|string $until maximum timestamp, defaults to "now"
*/
public function iso8601($until = 'now'): string;
/**
* Get a string containing either "am" or "pm".
*
* @param \DateTime|int|string $until maximum timestamp, defaults to "now"
*
* @example 'am'
*/
public function amPm($until = 'now'): string;
/**
* Get a localized random day of the month.
*
* @param \DateTime|int|string $until maximum timestamp, defaults to "now"
*
* @example '16'
*/
public function dayOfMonth($until = 'now'): string;
/**
* Get a localized random day of the week.
*
* Uses internal DateTime formatting, hence PHP's internal locale will be used (change using `setlocale()`).
*
* @param \DateTime|int|string $until maximum timestamp, defaults to "now"
*
* @example 'Tuesday'
*
* @see setlocale
* @see https://www.php.net/manual/en/function.setlocale.php Set a different output language
*/
public function dayOfWeek($until = 'now'): string;
/**
* Get a random month (numbered).
*
* @param \DateTime|int|string $until maximum timestamp, defaults to "now"
*
* @example '7'
*/
public function month($until = 'now'): string;
/**
* Get a random month.
*
* @param \DateTime|int|string $until maximum timestamp, defaults to "now"
*
* @see setlocale
* @see https://www.php.net/manual/en/function.setlocale.php Set a different output language
*
* @example 'September'
*/
public function monthName($until = 'now'): string;
/**
* Get a random year between 1970 and `$until`.
*
* @param \DateTime|int|string $until maximum timestamp, defaults to "now"
*
* @example '1987'
*/
public function year($until = 'now'): string;
/**
* Get a random century, formatted as Roman numerals.
*
* @example 'XVII'
*/
public function century(): string;
/**
* Get a random timezone, uses `\DateTimeZone::listIdentifiers()` internally.
*
* @param string|null $countryCode two-letter ISO 3166-1 compatible country code
*
* @example 'Europe/Rome'
*/
public function timezone(?string $countryCode = null): string;
}
-14
View File
@@ -1,14 +0,0 @@
<?php
declare(strict_types=1);
namespace Faker\Extension;
/**
* An extension is the only way to add new functionality to Faker.
*
* @experimental This interface is experimental and does not fall under our BC promise
*/
interface Extension
{
}
@@ -1,12 +0,0 @@
<?php
declare(strict_types=1);
namespace Faker\Extension;
/**
* @experimental This class is experimental and does not fall under our BC promise
*/
final class ExtensionNotFound extends \LogicException
{
}
@@ -1,28 +0,0 @@
<?php
namespace Faker\Extension;
/**
* @experimental This interface is experimental and does not fall under our BC promise
*/
interface FileExtension extends Extension
{
/**
* Get a random MIME type
*
* @example 'video/avi'
*/
public function mimeType(): string;
/**
* Get a random file extension (without a dot)
*
* @example avi
*/
public function extension(): string;
/**
* Get a full path to a new real file on the system.
*/
public function filePath(): string;
}
@@ -1,20 +0,0 @@
<?php
declare(strict_types=1);
namespace Faker\Extension;
use Faker\Generator;
/**
* @experimental This interface is experimental and does not fall under our BC promise
*/
interface GeneratorAwareExtension extends Extension
{
/**
* This method MUST be implemented in such a way as to retain the
* immutability of the extension, and MUST return an instance that has the
* new Generator.
*/
public function withGenerator(Generator $generator): Extension;
}
@@ -1,30 +0,0 @@
<?php
declare(strict_types=1);
namespace Faker\Extension;
use Faker\Generator;
/**
* A helper trait to be used with GeneratorAwareExtension.
*/
trait GeneratorAwareExtensionTrait
{
/**
* @var Generator|null
*/
private $generator;
/**
* @return static
*/
public function withGenerator(Generator $generator): Extension
{
$instance = clone $this;
$instance->generator = $generator;
return $instance;
}
}
-106
View File
@@ -1,106 +0,0 @@
<?php
namespace Faker\Extension;
/**
* A class with some methods that may make building extensions easier.
*
* @experimental This class is experimental and does not fall under our BC promise
*/
final class Helper
{
/**
* Returns a random element from a passed array.
*/
public static function randomElement(array $array)
{
if ($array === []) {
return null;
}
return $array[array_rand($array, 1)];
}
/**
* Replaces all hash sign ('#') occurrences with a random number
* Replaces all percentage sign ('%') occurrences with a non-zero number.
*
* @param string $string String that needs to bet parsed
*/
public static function numerify(string $string): string
{
// instead of using randomDigit() several times, which is slow,
// count the number of hashes and generate once a large number
$toReplace = [];
if (($pos = strpos($string, '#')) !== false) {
for ($i = $pos, $last = strrpos($string, '#', $pos) + 1; $i < $last; ++$i) {
if ($string[$i] === '#') {
$toReplace[] = $i;
}
}
}
if ($nbReplacements = count($toReplace)) {
$maxAtOnce = strlen((string) mt_getrandmax()) - 1;
$numbers = '';
$i = 0;
while ($i < $nbReplacements) {
$size = min($nbReplacements - $i, $maxAtOnce);
$numbers .= str_pad((string) mt_rand(0, 10 ** $size - 1), $size, '0', STR_PAD_LEFT);
$i += $size;
}
for ($i = 0; $i < $nbReplacements; ++$i) {
$string[$toReplace[$i]] = $numbers[$i];
}
}
return self::replaceWildcard($string, '%', static function () {
return mt_rand(1, 9);
});
}
/**
* Replaces all question mark ('?') occurrences with a random letter.
*
* @param string $string String that needs to bet parsed
*/
public static function lexify(string $string): string
{
return self::replaceWildcard($string, '?', static function () {
return chr(mt_rand(97, 122));
});
}
/**
* Replaces hash signs ('#') and question marks ('?') with random numbers and letters
* An asterisk ('*') is replaced with either a random number or a random letter.
*
* @param string $string String that needs to bet parsed
*/
public static function bothify(string $string): string
{
$string = self::replaceWildcard($string, '*', static function () {
return mt_rand(0, 1) === 1 ? '#' : '?';
});
return self::lexify(self::numerify($string));
}
private static function replaceWildcard(string $string, string $wildcard, callable $callback): string
{
if (($pos = strpos($string, $wildcard)) === false) {
return $string;
}
for ($i = $pos, $last = strrpos($string, $wildcard, $pos) + 1; $i < $last; ++$i) {
if ($string[$i] === $wildcard) {
$string[$i] = call_user_func($callback);
}
}
return $string;
}
}
@@ -1,53 +0,0 @@
<?php
namespace Faker\Extension;
/**
* @experimental This interface is experimental and does not fall under our BC promise
*/
interface NumberExtension extends Extension
{
/**
* Returns a random number between $int1 and $int2 (any order)
*
* @param int $min default to 0
* @param int $max defaults to 32 bit max integer, ie 2147483647
*
* @example 79907610
*/
public function numberBetween(int $min, int $max): int;
/**
* Returns a random number between 0 and 9
*/
public function randomDigit(): int;
/**
* Generates a random digit, which cannot be $except
*/
public function randomDigitNot(int $except): int;
/**
* Returns a random number between 1 and 9
*/
public function randomDigitNotZero(): int;
/**
* Return a random float number
*
* @example 48.8932
*/
public function randomFloat(?int $nbMaxDecimals, float $min, ?float $max): float;
/**
* Returns a random integer with 0 to $nbDigits digits.
*
* The maximum value returned is mt_getrandmax()
*
* @param int|null $nbDigits Defaults to a random number between 1 and 9
* @param bool $strict Whether the returned number should have exactly $nbDigits
*
* @example 79907610
*/
public function randomNumber(?int $nbDigits, bool $strict): int;
}
@@ -1,52 +0,0 @@
<?php
namespace Faker\Extension;
/**
* @experimental This interface is experimental and does not fall under our BC promise
*/
interface PersonExtension extends Extension
{
public const GENDER_FEMALE = 'female';
public const GENDER_MALE = 'male';
/**
* @param string|null $gender 'male', 'female' or null for any
*
* @example 'John Doe'
*/
public function name(?string $gender = null): string;
/**
* @param string|null $gender 'male', 'female' or null for any
*
* @example 'John'
*/
public function firstName(?string $gender = null): string;
public function firstNameMale(): string;
public function firstNameFemale(): string;
/**
* @example 'Doe'
*/
public function lastName(): string;
/**
* @example 'Mrs.'
*
* @param string|null $gender 'male', 'female' or null for any
*/
public function title(?string $gender = null): string;
/**
* @example 'Mr.'
*/
public function titleMale(): string;
/**
* @example 'Mrs.'
*/
public function titleFemale(): string;
}
@@ -1,19 +0,0 @@
<?php
namespace Faker\Extension;
/**
* @experimental This interface is experimental and does not fall under our BC promise
*/
interface PhoneNumberExtension extends Extension
{
/**
* @example '555-123-546'
*/
public function phoneNumber(): string;
/**
* @example +27113456789
*/
public function e164PhoneNumber(): string;
}
@@ -1,16 +0,0 @@
<?php
namespace Faker\Extension;
/**
* @experimental This interface is experimental and does not fall under our BC promise
*/
interface UuidExtension extends Extension
{
/**
* Generate name based md5 UUID (version 3).
*
* @example '7e57d004-2b97-0e7a-b45f-5387367791cd'
*/
public function uuid3(): string;
}
@@ -1,21 +0,0 @@
<?php
namespace Faker\Extension;
/**
* @experimental This interface is experimental and does not fall under our BC promise
*/
interface VersionExtension extends Extension
{
/**
* Get a version number in semantic versioning syntax 2.0.0. (https://semver.org/spec/v2.0.0.html)
*
* @param bool $preRelease Pre release parts may be randomly included
* @param bool $build Build parts may be randomly included
*
* @example 1.0.0
* @example 1.0.0-alpha.1
* @example 1.0.0-alpha.1+b71f04d
*/
public function semver(bool $preRelease = false, bool $build = false): string;
}
-71
View File
@@ -1,71 +0,0 @@
<?php
namespace Faker;
class Factory
{
public const DEFAULT_LOCALE = 'en_US';
protected static $defaultProviders = ['Address', 'Barcode', 'Biased', 'Color', 'Company', 'DateTime', 'File', 'HtmlLorem', 'Image', 'Internet', 'Lorem', 'Medical', 'Miscellaneous', 'Payment', 'Person', 'PhoneNumber', 'Text', 'UserAgent', 'Uuid'];
/**
* Create a new generator
*
* @param string $locale
*
* @return Generator
*/
public static function create($locale = self::DEFAULT_LOCALE)
{
$generator = new Generator();
foreach (static::$defaultProviders as $provider) {
$providerClassName = self::getProviderClassname($provider, $locale);
$generator->addProvider(new $providerClassName($generator));
}
return $generator;
}
/**
* @param string $provider
* @param string $locale
*
* @return string
*/
protected static function getProviderClassname($provider, $locale = '')
{
if ($providerClass = self::findProviderClassname($provider, $locale)) {
return $providerClass;
}
// fallback to default locale
if ($providerClass = self::findProviderClassname($provider, static::DEFAULT_LOCALE)) {
return $providerClass;
}
// fallback to no locale
if ($providerClass = self::findProviderClassname($provider)) {
return $providerClass;
}
throw new \InvalidArgumentException(sprintf('Unable to find provider "%s" with locale "%s"', $provider, $locale));
}
/**
* @param string $provider
* @param string $locale
*
* @return string|null
*/
protected static function findProviderClassname($provider, $locale = '')
{
$providerClass = 'Faker\\' . ($locale ? sprintf('Provider\%s\%s', $locale, $provider) : sprintf('Provider\%s', $provider));
if (class_exists($providerClass, true)) {
return $providerClass;
}
return null;
}
}
-985
View File
@@ -1,985 +0,0 @@
<?php
namespace Faker;
use Faker\Container\ContainerInterface;
/**
* @property string $citySuffix
*
* @method string citySuffix()
*
* @property string $streetSuffix
*
* @method string streetSuffix()
*
* @property string $buildingNumber
*
* @method string buildingNumber()
*
* @property string $city
*
* @method string city()
*
* @property string $streetName
*
* @method string streetName()
*
* @property string $streetAddress
*
* @method string streetAddress()
*
* @property string $postcode
*
* @method string postcode()
*
* @property string $address
*
* @method string address()
*
* @property string $country
*
* @method string country()
*
* @property float $latitude
*
* @method float latitude($min = -90, $max = 90)
*
* @property float $longitude
*
* @method float longitude($min = -180, $max = 180)
*
* @property float[] $localCoordinates
*
* @method float[] localCoordinates()
*
* @property int $randomDigitNotNull
*
* @method int randomDigitNotNull()
*
* @property mixed $passthrough
*
* @method mixed passthrough($value)
*
* @property string $randomLetter
*
* @method string randomLetter()
*
* @property string $randomAscii
*
* @method string randomAscii()
*
* @property array $randomElements
*
* @method array randomElements($array = ['a', 'b', 'c'], $count = 1, $allowDuplicates = false)
*
* @property mixed $randomElement
*
* @method mixed randomElement($array = ['a', 'b', 'c'])
*
* @property int|string|null $randomKey
*
* @method int|string|null randomKey($array = [])
*
* @property array|string $shuffle
*
* @method array|string shuffle($arg = '')
*
* @property array $shuffleArray
*
* @method array shuffleArray($array = [])
*
* @property string $shuffleString
*
* @method string shuffleString($string = '', $encoding = 'UTF-8')
*
* @property string $numerify
*
* @method string numerify($string = '###')
*
* @property string $lexify
*
* @method string lexify($string = '????')
*
* @property string $bothify
*
* @method string bothify($string = '## ??')
*
* @property string $asciify
*
* @method string asciify($string = '****')
*
* @property string $regexify
*
* @method string regexify($regex = '')
*
* @property string $toLower
*
* @method string toLower($string = '')
*
* @property string $toUpper
*
* @method string toUpper($string = '')
*
* @property int $biasedNumberBetween
*
* @method int biasedNumberBetween($min = 0, $max = 100, $function = 'sqrt')
*
* @property string $hexColor
*
* @method string hexColor()
*
* @property string $safeHexColor
*
* @method string safeHexColor()
*
* @property array $rgbColorAsArray
*
* @method array rgbColorAsArray()
*
* @property string $rgbColor
*
* @method string rgbColor()
*
* @property string $rgbCssColor
*
* @method string rgbCssColor()
*
* @property string $rgbaCssColor
*
* @method string rgbaCssColor()
*
* @property string $safeColorName
*
* @method string safeColorName()
*
* @property string $colorName
*
* @method string colorName()
*
* @property string $hslColor
*
* @method string hslColor()
*
* @property array $hslColorAsArray
*
* @method array hslColorAsArray()
*
* @property string $company
*
* @method string company()
*
* @property string $companySuffix
*
* @method string companySuffix()
*
* @property string $jobTitle
*
* @method string jobTitle()
*
* @property int $unixTime
*
* @method int unixTime($max = 'now')
*
* @property \DateTime $dateTime
*
* @method \DateTime dateTime($max = 'now', $timezone = null)
*
* @property \DateTime $dateTimeAD
*
* @method \DateTime dateTimeAD($max = 'now', $timezone = null)
*
* @property string $iso8601
*
* @method string iso8601($max = 'now')
*
* @property string $date
*
* @method string date($format = 'Y-m-d', $max = 'now')
*
* @property string $time
*
* @method string time($format = 'H:i:s', $max = 'now')
*
* @property \DateTime $dateTimeBetween
*
* @method \DateTime dateTimeBetween($startDate = '-30 years', $endDate = 'now', $timezone = null)
*
* @property \DateTime $dateTimeInInterval
*
* @method \DateTime dateTimeInInterval($date = '-30 years', $interval = '+5 days', $timezone = null)
*
* @property \DateTime $dateTimeThisCentury
*
* @method \DateTime dateTimeThisCentury($max = 'now', $timezone = null)
*
* @property \DateTime $dateTimeThisDecade
*
* @method \DateTime dateTimeThisDecade($max = 'now', $timezone = null)
*
* @property \DateTime $dateTimeThisYear
*
* @method \DateTime dateTimeThisYear($max = 'now', $timezone = null)
*
* @property \DateTime $dateTimeThisMonth
*
* @method \DateTime dateTimeThisMonth($max = 'now', $timezone = null)
*
* @property string $amPm
*
* @method string amPm($max = 'now')
*
* @property string $dayOfMonth
*
* @method string dayOfMonth($max = 'now')
*
* @property string $dayOfWeek
*
* @method string dayOfWeek($max = 'now')
*
* @property string $month
*
* @method string month($max = 'now')
*
* @property string $monthName
*
* @method string monthName($max = 'now')
*
* @property string $year
*
* @method string year($max = 'now')
*
* @property string $century
*
* @method string century()
*
* @property string $timezone
*
* @method string timezone($countryCode = null)
*
* @property void $setDefaultTimezone
*
* @method void setDefaultTimezone($timezone = null)
*
* @property string $getDefaultTimezone
*
* @method string getDefaultTimezone()
*
* @property string $file
*
* @method string file($sourceDirectory = '/tmp', $targetDirectory = '/tmp', $fullPath = true)
*
* @property string $randomHtml
*
* @method string randomHtml($maxDepth = 4, $maxWidth = 4)
*
* @property string $imageUrl
*
* @method string imageUrl($width = 640, $height = 480, $category = null, $randomize = true, $word = null, $gray = false, string $format = 'png')
*
* @property string $image
*
* @method string image($dir = null, $width = 640, $height = 480, $category = null, $fullPath = true, $randomize = true, $word = null, $gray = false, string $format = 'png')
*
* @property string $email
*
* @method string email()
*
* @property string $safeEmail
*
* @method string safeEmail()
*
* @property string $freeEmail
*
* @method string freeEmail()
*
* @property string $companyEmail
*
* @method string companyEmail()
*
* @property string $freeEmailDomain
*
* @method string freeEmailDomain()
*
* @property string $safeEmailDomain
*
* @method string safeEmailDomain()
*
* @property string $userName
*
* @method string userName()
*
* @property string $password
*
* @method string password($minLength = 6, $maxLength = 20)
*
* @property string $domainName
*
* @method string domainName()
*
* @property string $domainWord
*
* @method string domainWord()
*
* @property string $tld
*
* @method string tld()
*
* @property string $url
*
* @method string url()
*
* @property string $slug
*
* @method string slug($nbWords = 6, $variableNbWords = true)
*
* @property string $ipv4
*
* @method string ipv4()
*
* @property string $ipv6
*
* @method string ipv6()
*
* @property string $localIpv4
*
* @method string localIpv4()
*
* @property string $macAddress
*
* @method string macAddress()
*
* @property string $word
*
* @method string word()
*
* @property array|string $words
*
* @method array|string words($nb = 3, $asText = false)
*
* @property string $sentence
*
* @method string sentence($nbWords = 6, $variableNbWords = true)
*
* @property array|string $sentences
*
* @method array|string sentences($nb = 3, $asText = false)
*
* @property string $paragraph
*
* @method string paragraph($nbSentences = 3, $variableNbSentences = true)
*
* @property array|string $paragraphs
*
* @method array|string paragraphs($nb = 3, $asText = false)
*
* @property string $text
*
* @method string text($maxNbChars = 200)
*
* @property bool $boolean
*
* @method bool boolean($chanceOfGettingTrue = 50)
*
* @property string $md5
*
* @method string md5()
*
* @property string $sha1
*
* @method string sha1()
*
* @property string $sha256
*
* @method string sha256()
*
* @property string $locale
*
* @method string locale()
*
* @property string $countryCode
*
* @method string countryCode()
*
* @property string $countryISOAlpha3
*
* @method string countryISOAlpha3()
*
* @property string $languageCode
*
* @method string languageCode()
*
* @property string $currencyCode
*
* @method string currencyCode()
*
* @property string $emoji
*
* @method string emoji()
*
* @property string $creditCardType
*
* @method string creditCardType()
*
* @property string $creditCardNumber
*
* @method string creditCardNumber($type = null, $formatted = false, $separator = '-')
*
* @property \DateTime $creditCardExpirationDate
*
* @method \DateTime creditCardExpirationDate($valid = true)
*
* @property string $creditCardExpirationDateString
*
* @method string creditCardExpirationDateString($valid = true, $expirationDateFormat = null)
*
* @property array $creditCardDetails
*
* @method array creditCardDetails($valid = true)
*
* @property string $iban
*
* @method string iban($countryCode = null, $prefix = '', $length = null)
*
* @property string $swiftBicNumber
*
* @method string swiftBicNumber()
*
* @property string $name
*
* @method string name($gender = null)
*
* @property string $firstName
*
* @method string firstName($gender = null)
*
* @property string $firstNameMale
*
* @method string firstNameMale()
*
* @property string $firstNameFemale
*
* @method string firstNameFemale()
*
* @property string $lastName
*
* @method string lastName($gender = null)
*
* @property string $title
*
* @method string title($gender = null)
*
* @property string $titleMale
*
* @method string titleMale()
*
* @property string $titleFemale
*
* @method string titleFemale()
*
* @property string $phoneNumber
*
* @method string phoneNumber()
*
* @property string $e164PhoneNumber
*
* @method string e164PhoneNumber()
*
* @property int $imei
*
* @method int imei()
*
* @property string $realText
*
* @method string realText($maxNbChars = 200, $indexSize = 2)
*
* @property string $realTextBetween
*
* @method string realTextBetween($minNbChars = 160, $maxNbChars = 200, $indexSize = 2)
*
* @property string $macProcessor
*
* @method string macProcessor()
*
* @property string $linuxProcessor
*
* @method string linuxProcessor()
*
* @property string $userAgent
*
* @method string userAgent()
*
* @property string $chrome
*
* @method string chrome()
*
* @property string $msedge
*
* @method string msedge()
*
* @property string $firefox
*
* @method string firefox()
*
* @property string $safari
*
* @method string safari()
*
* @property string $opera
*
* @method string opera()
*
* @property string $internetExplorer
*
* @method string internetExplorer()
*
* @property string $windowsPlatformToken
*
* @method string windowsPlatformToken()
*
* @property string $macPlatformToken
*
* @method string macPlatformToken()
*
* @property string $iosMobileToken
*
* @method string iosMobileToken()
*
* @property string $linuxPlatformToken
*
* @method string linuxPlatformToken()
*
* @property string $uuid
*
* @method string uuid()
*/
class Generator
{
protected $providers = [];
protected $formatters = [];
private $container;
/**
* @var UniqueGenerator
*/
private $uniqueGenerator;
public function __construct(?ContainerInterface $container = null)
{
$this->container = $container ?: Container\ContainerBuilder::withDefaultExtensions()->build();
}
/**
* @template T of Extension\Extension
*
* @param class-string<T> $id
*
* @throws Extension\ExtensionNotFound
*
* @return T
*/
public function ext(string $id): Extension\Extension
{
if (!$this->container->has($id)) {
throw new Extension\ExtensionNotFound(sprintf(
'No Faker extension with id "%s" was loaded.',
$id,
));
}
$extension = $this->container->get($id);
if ($extension instanceof Extension\GeneratorAwareExtension) {
$extension = $extension->withGenerator($this);
}
return $extension;
}
public function addProvider($provider)
{
array_unshift($this->providers, $provider);
$this->formatters = [];
}
public function getProviders()
{
return $this->providers;
}
/**
* With the unique generator you are guaranteed to never get the same two
* values.
*
* <code>
* // will never return twice the same value
* $faker->unique()->randomElement(array(1, 2, 3));
* </code>
*
* @param bool $reset If set to true, resets the list of existing values
* @param int $maxRetries Maximum number of retries to find a unique value,
* After which an OverflowException is thrown.
*
* @throws \OverflowException When no unique value can be found by iterating $maxRetries times
*
* @return self A proxy class returning only non-existing values
*/
public function unique($reset = false, $maxRetries = 10000)
{
if ($reset || $this->uniqueGenerator === null) {
$this->uniqueGenerator = new UniqueGenerator($this, $maxRetries);
}
return $this->uniqueGenerator;
}
/**
* Get a value only some percentage of the time.
*
* @param float $weight A probability between 0 and 1, 0 means that we always get the default value.
*
* @return self
*/
public function optional(float $weight = 0.5, $default = null)
{
if ($weight > 1) {
trigger_deprecation('fakerphp/faker', '1.16', 'First argument ($weight) to method "optional()" must be between 0 and 1. You passed %f, we assume you meant %f.', $weight, $weight / 100);
$weight = $weight / 100;
}
return new ChanceGenerator($this, $weight, $default);
}
/**
* To make sure the value meet some criteria, pass a callable that verifies the
* output. If the validator fails, the generator will try again.
*
* The value validity is determined by a function passed as first argument.
*
* <code>
* $values = array();
* $evenValidator = function ($digit) {
* return $digit % 2 === 0;
* };
* for ($i=0; $i < 10; $i++) {
* $values []= $faker->valid($evenValidator)->randomDigit;
* }
* print_r($values); // [0, 4, 8, 4, 2, 6, 0, 8, 8, 6]
* </code>
*
* @param ?\Closure $validator A function returning true for valid values
* @param int $maxRetries Maximum number of retries to find a valid value,
* After which an OverflowException is thrown.
*
* @throws \OverflowException When no valid value can be found by iterating $maxRetries times
*
* @return self A proxy class returning only valid values
*/
public function valid(?\Closure $validator = null, int $maxRetries = 10000)
{
return new ValidGenerator($this, $validator, $maxRetries);
}
public function seed($seed = null)
{
if ($seed === null) {
mt_srand();
} else {
mt_srand((int) $seed, self::mode());
}
}
/**
* @see https://www.php.net/manual/en/migration83.deprecated.php#migration83.deprecated.random
*/
private static function mode(): int
{
if (PHP_VERSION_ID < 80300) {
return MT_RAND_PHP;
}
return MT_RAND_MT19937;
}
public function format($format, $arguments = [])
{
return call_user_func_array($this->getFormatter($format), $arguments);
}
/**
* @param string $format
*
* @return callable
*/
public function getFormatter($format)
{
if (isset($this->formatters[$format])) {
return $this->formatters[$format];
}
if (method_exists($this, $format)) {
$this->formatters[$format] = [$this, $format];
return $this->formatters[$format];
}
// "Faker\Core\Barcode->ean13"
if (preg_match('|^([a-zA-Z0-9\\\]+)->([a-zA-Z0-9]+)$|', $format, $matches)) {
$this->formatters[$format] = [$this->ext($matches[1]), $matches[2]];
return $this->formatters[$format];
}
foreach ($this->providers as $provider) {
if (method_exists($provider, $format)) {
$this->formatters[$format] = [$provider, $format];
return $this->formatters[$format];
}
}
throw new \InvalidArgumentException(sprintf('Unknown format "%s"', $format));
}
/**
* Replaces tokens ('{{ tokenName }}') with the result from the token method call
*
* @param string $string String that needs to bet parsed
*
* @return string
*/
public function parse($string)
{
$callback = function ($matches) {
return $this->format($matches[1]);
};
return preg_replace_callback('/{{\s?(\w+|[\w\\\]+->\w+?)\s?}}/u', $callback, $string);
}
/**
* Get a random MIME type
*
* @example 'video/avi'
*/
public function mimeType()
{
return $this->ext(Extension\FileExtension::class)->mimeType();
}
/**
* Get a random file extension (without a dot)
*
* @example avi
*/
public function fileExtension()
{
return $this->ext(Extension\FileExtension::class)->extension();
}
/**
* Get a full path to a new real file on the system.
*/
public function filePath()
{
return $this->ext(Extension\FileExtension::class)->filePath();
}
/**
* Get an actual blood type
*
* @example 'AB'
*/
public function bloodType(): string
{
return $this->ext(Extension\BloodExtension::class)->bloodType();
}
/**
* Get a random resis value
*
* @example '+'
*/
public function bloodRh(): string
{
return $this->ext(Extension\BloodExtension::class)->bloodRh();
}
/**
* Get a full blood group
*
* @example 'AB+'
*/
public function bloodGroup(): string
{
return $this->ext(Extension\BloodExtension::class)->bloodGroup();
}
/**
* Get a random EAN13 barcode.
*
* @example '4006381333931'
*/
public function ean13(): string
{
return $this->ext(Extension\BarcodeExtension::class)->ean13();
}
/**
* Get a random EAN8 barcode.
*
* @example '73513537'
*/
public function ean8(): string
{
return $this->ext(Extension\BarcodeExtension::class)->ean8();
}
/**
* Get a random ISBN-10 code
*
* @see http://en.wikipedia.org/wiki/International_Standard_Book_Number
*
* @example '4881416324'
*/
public function isbn10(): string
{
return $this->ext(Extension\BarcodeExtension::class)->isbn10();
}
/**
* Get a random ISBN-13 code
*
* @see http://en.wikipedia.org/wiki/International_Standard_Book_Number
*
* @example '9790404436093'
*/
public function isbn13(): string
{
return $this->ext(Extension\BarcodeExtension::class)->isbn13();
}
/**
* Returns a random number between $int1 and $int2 (any order)
*
* @example 79907610
*/
public function numberBetween($int1 = 0, $int2 = 2147483647): int
{
return $this->ext(Extension\NumberExtension::class)->numberBetween((int) $int1, (int) $int2);
}
/**
* Returns a random number between 0 and 9
*/
public function randomDigit(): int
{
return $this->ext(Extension\NumberExtension::class)->randomDigit();
}
/**
* Generates a random digit, which cannot be $except
*/
public function randomDigitNot($except): int
{
return $this->ext(Extension\NumberExtension::class)->randomDigitNot((int) $except);
}
/**
* Returns a random number between 1 and 9
*/
public function randomDigitNotZero(): int
{
return $this->ext(Extension\NumberExtension::class)->randomDigitNotZero();
}
/**
* Return a random float number
*
* @example 48.8932
*/
public function randomFloat($nbMaxDecimals = null, $min = 0, $max = null): float
{
return $this->ext(Extension\NumberExtension::class)->randomFloat(
$nbMaxDecimals !== null ? (int) $nbMaxDecimals : null,
(float) $min,
$max !== null ? (float) $max : null,
);
}
/**
* Returns a random integer with 0 to $nbDigits digits.
*
* The maximum value returned is mt_getrandmax()
*
* @param int|null $nbDigits Defaults to a random number between 1 and 9
* @param bool $strict Whether the returned number should have exactly $nbDigits
*
* @example 79907610
*/
public function randomNumber($nbDigits = null, $strict = false): int
{
return $this->ext(Extension\NumberExtension::class)->randomNumber(
$nbDigits !== null ? (int) $nbDigits : null,
(bool) $strict,
);
}
/**
* Get a version number in semantic versioning syntax 2.0.0. (https://semver.org/spec/v2.0.0.html)
*
* @param bool $preRelease Pre release parts may be randomly included
* @param bool $build Build parts may be randomly included
*
* @example 1.0.0
* @example 1.0.0-alpha.1
* @example 1.0.0-alpha.1+b71f04d
*/
public function semver(bool $preRelease = false, bool $build = false): string
{
return $this->ext(Extension\VersionExtension::class)->semver($preRelease, $build);
}
/**
* @deprecated
*/
protected function callFormatWithMatches($matches)
{
trigger_deprecation('fakerphp/faker', '1.14', 'Protected method "callFormatWithMatches()" is deprecated and will be removed.');
return $this->format($matches[1]);
}
/**
* @param string $attribute
*
* @deprecated Use a method instead.
*/
public function __get($attribute)
{
trigger_deprecation('fakerphp/faker', '1.14', 'Accessing property "%s" is deprecated, use "%s()" instead.', $attribute, $attribute);
return $this->format($attribute);
}
/**
* @param string $method
* @param array $attributes
*/
public function __call($method, $attributes)
{
return $this->format($method, $attributes);
}
public function __destruct()
{
$this->seed();
}
public function __wakeup()
{
$this->formatters = [];
}
}
-180
View File
@@ -1,180 +0,0 @@
<?php
namespace Faker\Guesser;
use Faker\Provider\Base;
class Name
{
protected $generator;
public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}
/**
* @param string $name
* @param int|null $size Length of field, if known
*
* @return callable|null
*/
public function guessFormat($name, $size = null)
{
$name = Base::toLower($name);
$generator = $this->generator;
if (preg_match('/^is[_A-Z]/', $name)) {
return static function () use ($generator) {
return $generator->boolean();
};
}
if (preg_match('/(_a|A)t$/', $name)) {
return static function () use ($generator) {
return $generator->dateTime();
};
}
switch (str_replace('_', '', $name)) {
case 'firstname':
return static function () use ($generator) {
return $generator->firstName();
};
case 'lastname':
return static function () use ($generator) {
return $generator->lastName();
};
case 'username':
case 'login':
return static function () use ($generator) {
return $generator->userName();
};
case 'email':
case 'emailaddress':
return static function () use ($generator) {
return $generator->email();
};
case 'phonenumber':
case 'phone':
case 'telephone':
case 'telnumber':
return static function () use ($generator) {
return $generator->phoneNumber();
};
case 'address':
return static function () use ($generator) {
return $generator->address();
};
case 'city':
case 'town':
return static function () use ($generator) {
return $generator->city();
};
case 'streetaddress':
return static function () use ($generator) {
return $generator->streetAddress();
};
case 'postcode':
case 'zipcode':
return static function () use ($generator) {
return $generator->postcode();
};
case 'state':
return static function () use ($generator) {
return $generator->state();
};
case 'county':
if ($this->generator->locale == 'en_US') {
return static function () use ($generator) {
return sprintf('%s County', $generator->city());
};
}
return static function () use ($generator) {
return $generator->state();
};
case 'country':
switch ($size) {
case 2:
return static function () use ($generator) {
return $generator->countryCode();
};
case 3:
return static function () use ($generator) {
return $generator->countryISOAlpha3();
};
case 5:
case 6:
return static function () use ($generator) {
return $generator->locale();
};
default:
return static function () use ($generator) {
return $generator->country();
};
}
break;
case 'locale':
return static function () use ($generator) {
return $generator->locale();
};
case 'currency':
case 'currencycode':
return static function () use ($generator) {
return $generator->currencyCode();
};
case 'url':
case 'website':
return static function () use ($generator) {
return $generator->url();
};
case 'company':
case 'companyname':
case 'employer':
return static function () use ($generator) {
return $generator->company();
};
case 'title':
if ($size !== null && $size <= 10) {
return static function () use ($generator) {
return $generator->title();
};
}
return static function () use ($generator) {
return $generator->sentence();
};
case 'body':
case 'summary':
case 'article':
case 'description':
return static function () use ($generator) {
return $generator->text();
};
}
return null;
}
}
@@ -1,79 +0,0 @@
<?php
namespace Faker\ORM\CakePHP;
class ColumnTypeGuesser
{
protected $generator;
public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}
/**
* @return \Closure|null
*/
public function guessFormat($column, $table)
{
$generator = $this->generator;
$schema = $table->schema();
switch ($schema->columnType($column)) {
case 'boolean':
return static function () use ($generator) {
return $generator->boolean;
};
case 'integer':
return static function () use ($generator) {
return $generator->numberBetween(0, 2147483647);
};
case 'biginteger':
return static function () use ($generator) {
return $generator->numberBetween(0, PHP_INT_MAX);
};
case 'decimal':
case 'float':
return static function () use ($generator) {
return $generator->randomFloat();
};
case 'uuid':
return static function () use ($generator) {
return $generator->uuid();
};
case 'string':
if (method_exists($schema, 'getColumn')) {
$columnData = $schema->getColumn($column);
} else {
$columnData = $schema->column($column);
}
$length = $columnData['length'];
return static function () use ($generator, $length) {
return $generator->text($length);
};
case 'text':
return static function () use ($generator) {
return $generator->text();
};
case 'date':
case 'datetime':
case 'timestamp':
case 'time':
return static function () use ($generator) {
return $generator->datetime();
};
case 'binary':
default:
return null;
}
}
}
@@ -1,173 +0,0 @@
<?php
namespace Faker\ORM\CakePHP;
use Cake\ORM\TableRegistry;
class EntityPopulator
{
protected $class;
protected $connectionName;
protected $columnFormatters = [];
protected $modifiers = [];
public function __construct($class)
{
$this->class = $class;
}
/**
* @param string $name
*/
public function __get($name)
{
return $this->{$name};
}
/**
* @param string $name
*/
public function __set($name, $value)
{
$this->{$name} = $value;
}
public function mergeColumnFormattersWith($columnFormatters)
{
$this->columnFormatters = array_merge($this->columnFormatters, $columnFormatters);
}
public function mergeModifiersWith($modifiers)
{
$this->modifiers = array_merge($this->modifiers, $modifiers);
}
/**
* @return array
*/
public function guessColumnFormatters($populator)
{
$formatters = [];
$class = $this->class;
$table = $this->getTable($class);
$schema = $table->schema();
$pk = $schema->primaryKey();
$guessers = $populator->getGuessers() + ['ColumnTypeGuesser' => new ColumnTypeGuesser($populator->getGenerator())];
$isForeignKey = static function ($column) use ($table) {
foreach ($table->associations()->type('BelongsTo') as $assoc) {
if ($column == $assoc->foreignKey()) {
return true;
}
}
return false;
};
foreach ($schema->columns() as $column) {
if ($column == $pk[0] || $isForeignKey($column)) {
continue;
}
foreach ($guessers as $guesser) {
if ($formatter = $guesser->guessFormat($column, $table)) {
$formatters[$column] = $formatter;
break;
}
}
}
return $formatters;
}
/**
* @return array
*/
public function guessModifiers()
{
$modifiers = [];
$table = $this->getTable($this->class);
$belongsTo = $table->associations()->type('BelongsTo');
foreach ($belongsTo as $assoc) {
$modifiers['belongsTo' . $assoc->name()] = function ($data, $insertedEntities) use ($assoc) {
$table = $assoc->target();
$foreignModel = $table->alias();
$foreignKeys = [];
if (!empty($insertedEntities[$foreignModel])) {
$foreignKeys = $insertedEntities[$foreignModel];
} else {
$foreignKeys = $table->find('all')
->select(['id'])
->map(static function ($row) {
return $row->id;
})
->toArray();
}
if (empty($foreignKeys)) {
throw new \Exception(sprintf('%s belongsTo %s, which seems empty at this point.', $this->getTable($this->class)->table(), $assoc->table()));
}
$foreignKey = $foreignKeys[array_rand($foreignKeys)];
$data[$assoc->foreignKey()] = $foreignKey;
return $data;
};
}
// TODO check if TreeBehavior attached to modify lft/rgt cols
return $modifiers;
}
/**
* @param array $options
*/
public function execute($class, $insertedEntities, $options = [])
{
$table = $this->getTable($class);
$entity = $table->newEntity();
foreach ($this->columnFormatters as $column => $format) {
if (null !== $format) {
$entity->{$column} = is_callable($format) ? $format($insertedEntities, $table) : $format;
}
}
foreach ($this->modifiers as $modifier) {
$entity = $modifier($entity, $insertedEntities);
}
if (!$entity = $table->save($entity, $options)) {
throw new \RuntimeException("Failed saving $class record");
}
$pk = $table->primaryKey();
if (is_string($pk)) {
return $entity->{$pk};
}
return $entity->{$pk[0]};
}
public function setConnection($name)
{
$this->connectionName = $name;
}
protected function getTable($class)
{
$options = [];
if (!empty($this->connectionName)) {
$options['connection'] = $this->connectionName;
}
return TableRegistry::get($class, $options);
}
}
@@ -1,113 +0,0 @@
<?php
namespace Faker\ORM\CakePHP;
class Populator
{
protected $generator;
protected $entities = [];
protected $quantities = [];
protected $guessers = [];
public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}
/**
* @return \Faker\Generator
*/
public function getGenerator()
{
return $this->generator;
}
/**
* @return array
*/
public function getGuessers()
{
return $this->guessers;
}
/**
* @return $this
*/
public function removeGuesser($name)
{
if ($this->guessers[$name]) {
unset($this->guessers[$name]);
}
return $this;
}
/**
* @throws \Exception
*
* @return $this
*/
public function addGuesser($class)
{
if (!is_object($class)) {
$class = new $class($this->generator);
}
if (!method_exists($class, 'guessFormat')) {
throw new \Exception('Missing required custom guesser method: ' . get_class($class) . '::guessFormat()');
}
$this->guessers[get_class($class)] = $class;
return $this;
}
/**
* @param array $customColumnFormatters
* @param array $customModifiers
*
* @return $this
*/
public function addEntity($entity, $number, $customColumnFormatters = [], $customModifiers = [])
{
if (!$entity instanceof EntityPopulator) {
$entity = new EntityPopulator($entity);
}
$entity->columnFormatters = $entity->guessColumnFormatters($this);
if ($customColumnFormatters) {
$entity->mergeColumnFormattersWith($customColumnFormatters);
}
$entity->modifiers = $entity->guessModifiers($this);
if ($customModifiers) {
$entity->mergeModifiersWith($customModifiers);
}
$class = $entity->class;
$this->entities[$class] = $entity;
$this->quantities[$class] = $number;
return $this;
}
/**
* @param array $options
*
* @return array
*/
public function execute($options = [])
{
$insertedEntities = [];
foreach ($this->quantities as $class => $number) {
for ($i = 0; $i < $number; ++$i) {
$insertedEntities[$class][] = $this->entities[$class]->execute($class, $insertedEntities, $options);
}
}
return $insertedEntities;
}
}
@@ -1,91 +0,0 @@
<?php
namespace Faker\ORM\Doctrine;
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
use Faker\Generator;
require_once 'backward-compatibility.php';
class ColumnTypeGuesser
{
protected $generator;
public function __construct(Generator $generator)
{
$this->generator = $generator;
}
/**
* @return \Closure|null
*/
public function guessFormat($fieldName, ClassMetadata $class)
{
$generator = $this->generator;
$type = $class->getTypeOfField($fieldName);
switch ($type) {
case 'boolean':
return static function () use ($generator) {
return $generator->boolean();
};
case 'decimal':
$size = $class->fieldMappings[$fieldName]['precision'] ?? 2;
return static function () use ($generator, $size) {
return $generator->randomNumber($size + 2) / 100;
};
case 'smallint':
return static function () use ($generator) {
return $generator->numberBetween(0, 65535);
};
case 'integer':
return static function () use ($generator) {
return $generator->numberBetween(0, 2147483647);
};
case 'bigint':
return static function () use ($generator) {
return $generator->numberBetween(0, PHP_INT_MAX);
};
case 'float':
return static function () use ($generator) {
return $generator->randomFloat();
};
case 'string':
$size = $class->fieldMappings[$fieldName]['length'] ?? 255;
return static function () use ($generator, $size) {
return $generator->text($size);
};
case 'text':
return static function () use ($generator) {
return $generator->text();
};
case 'datetime':
case 'date':
case 'time':
return static function () use ($generator) {
return $generator->datetime();
};
case 'datetime_immutable':
case 'date_immutable':
case 'time_immutable':
return static function () use ($generator) {
return \DateTimeImmutable::createFromMutable($generator->datetime);
};
default:
// no smart way to guess what the user expects here
return null;
}
}
}
@@ -1,248 +0,0 @@
<?php
namespace Faker\ORM\Doctrine;
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
use Doctrine\Common\Persistence\ObjectManager;
require_once 'backward-compatibility.php';
/**
* Service class for populating a table through a Doctrine Entity class.
*/
class EntityPopulator
{
/**
* @var ClassMetadata
*/
protected $class;
/**
* @var array
*/
protected $columnFormatters = [];
/**
* @var array
*/
protected $modifiers = [];
public function __construct(ClassMetadata $class)
{
$this->class = $class;
}
/**
* @return string
*/
public function getClass()
{
return $this->class->getName();
}
public function setColumnFormatters($columnFormatters)
{
$this->columnFormatters = $columnFormatters;
}
/**
* @return array
*/
public function getColumnFormatters()
{
return $this->columnFormatters;
}
public function mergeColumnFormattersWith($columnFormatters)
{
$this->columnFormatters = array_merge($this->columnFormatters, $columnFormatters);
}
public function setModifiers(array $modifiers)
{
$this->modifiers = $modifiers;
}
/**
* @return array
*/
public function getModifiers()
{
return $this->modifiers;
}
public function mergeModifiersWith(array $modifiers)
{
$this->modifiers = array_merge($this->modifiers, $modifiers);
}
/**
* @return array
*/
public function guessColumnFormatters(\Faker\Generator $generator)
{
$formatters = [];
$nameGuesser = new \Faker\Guesser\Name($generator);
$columnTypeGuesser = new ColumnTypeGuesser($generator);
foreach ($this->class->getFieldNames() as $fieldName) {
if ($this->class->isIdentifier($fieldName) || !$this->class->hasField($fieldName)) {
continue;
}
$size = $this->class->fieldMappings[$fieldName]['length'] ?? null;
if ($formatter = $nameGuesser->guessFormat($fieldName, $size)) {
$formatters[$fieldName] = $formatter;
continue;
}
if ($formatter = $columnTypeGuesser->guessFormat($fieldName, $this->class)) {
$formatters[$fieldName] = $formatter;
continue;
}
}
foreach ($this->class->getAssociationNames() as $assocName) {
if ($this->class->isCollectionValuedAssociation($assocName)) {
continue;
}
$relatedClass = $this->class->getAssociationTargetClass($assocName);
$unique = $optional = false;
if ($this->class instanceof \Doctrine\ORM\Mapping\ClassMetadata) {
$mappings = $this->class->getAssociationMappings();
foreach ($mappings as $mapping) {
if ($mapping['targetEntity'] == $relatedClass) {
if ($mapping['type'] == \Doctrine\ORM\Mapping\ClassMetadata::ONE_TO_ONE) {
$unique = true;
$optional = $mapping['joinColumns'][0]['nullable'] ?? false;
break;
}
}
}
} elseif ($this->class instanceof \Doctrine\ODM\MongoDB\Mapping\ClassMetadata) {
$mappings = $this->class->associationMappings;
foreach ($mappings as $mapping) {
if ($mapping['targetDocument'] == $relatedClass) {
if ($mapping['type'] == \Doctrine\ODM\MongoDB\Mapping\ClassMetadata::ONE && $mapping['association'] == \Doctrine\ODM\MongoDB\Mapping\ClassMetadata::REFERENCE_ONE) {
$unique = true;
$optional = $mapping['nullable'] ?? false;
break;
}
}
}
}
$index = 0;
$formatters[$assocName] = static function ($inserted) use ($relatedClass, &$index, $unique, $optional, $generator) {
if (isset($inserted[$relatedClass])) {
if ($unique) {
$related = null;
if (isset($inserted[$relatedClass][$index]) || !$optional) {
$related = $inserted[$relatedClass][$index];
}
++$index;
return $related;
}
return $generator->randomElement($inserted[$relatedClass]);
}
return null;
};
}
return $formatters;
}
/**
* Insert one new record using the Entity class.
*
* @param bool $generateId
*
* @return EntityPopulator
*/
public function execute(ObjectManager $manager, $insertedEntities, $generateId = false)
{
$obj = $this->class->newInstance();
$this->fillColumns($obj, $insertedEntities);
$this->callMethods($obj, $insertedEntities);
if ($generateId) {
$idsName = $this->class->getIdentifier();
foreach ($idsName as $idName) {
$id = $this->generateId($obj, $idName, $manager);
$this->class->reflFields[$idName]->setValue($obj, $id);
}
}
$manager->persist($obj);
return $obj;
}
private function fillColumns($obj, $insertedEntities): void
{
foreach ($this->columnFormatters as $field => $format) {
if (null !== $format) {
// Add some extended debugging information to any errors thrown by the formatter
try {
$value = is_callable($format) ? $format($insertedEntities, $obj) : $format;
} catch (\InvalidArgumentException $ex) {
throw new \InvalidArgumentException(sprintf(
'Failed to generate a value for %s::%s: %s',
get_class($obj),
$field,
$ex->getMessage(),
));
}
// Try a standard setter if it's available, otherwise fall back on reflection
$setter = sprintf('set%s', ucfirst($field));
if (is_callable([$obj, $setter])) {
$obj->$setter($value);
} else {
$this->class->reflFields[$field]->setValue($obj, $value);
}
}
}
}
private function callMethods($obj, $insertedEntities): void
{
foreach ($this->getModifiers() as $modifier) {
$modifier($obj, $insertedEntities);
}
}
/**
* @return int
*/
private function generateId($obj, $column, ObjectManager $manager)
{
$repository = $manager->getRepository(get_class($obj));
$result = $repository->createQueryBuilder('e')
->select(sprintf('e.%s', $column))
->getQuery()
->execute();
$ids = array_map('current', $result->toArray());
do {
$id = mt_rand();
} while (in_array($id, $ids, false));
return $id;
}
}
@@ -1,126 +0,0 @@
<?php
namespace Faker\ORM\Doctrine;
use Doctrine\Common\Persistence\ObjectManager;
use Faker\Generator;
require_once 'backward-compatibility.php';
/**
* Service class for populating a database using the Doctrine ORM or ODM.
* A Populator can populate several tables using ActiveRecord classes.
*/
class Populator
{
/**
* @var int
*/
protected $batchSize;
/**
* @var Generator
*/
protected $generator;
/**
* @var ObjectManager|null
*/
protected $manager;
/**
* @var array
*/
protected $entities = [];
/**
* @var array
*/
protected $quantities = [];
/**
* @var array
*/
protected $generateId = [];
/**
* Populator constructor.
*
* @param int $batchSize
*/
public function __construct(Generator $generator, ?ObjectManager $manager = null, $batchSize = 1000)
{
$this->generator = $generator;
$this->manager = $manager;
$this->batchSize = $batchSize;
}
/**
* Add an order for the generation of $number records for $entity.
*
* @param mixed $entity A Doctrine classname, or a \Faker\ORM\Doctrine\EntityPopulator instance
* @param int $number The number of entities to populate
*/
public function addEntity($entity, $number, $customColumnFormatters = [], $customModifiers = [], $generateId = false)
{
if (!$entity instanceof \Faker\ORM\Doctrine\EntityPopulator) {
if (null === $this->manager) {
throw new \InvalidArgumentException('No entity manager passed to Doctrine Populator.');
}
$entity = new \Faker\ORM\Doctrine\EntityPopulator($this->manager->getClassMetadata($entity));
}
$entity->setColumnFormatters($entity->guessColumnFormatters($this->generator));
if ($customColumnFormatters) {
$entity->mergeColumnFormattersWith($customColumnFormatters);
}
$entity->mergeModifiersWith($customModifiers);
$this->generateId[$entity->getClass()] = $generateId;
$class = $entity->getClass();
$this->entities[$class] = $entity;
$this->quantities[$class] = $number;
}
/**
* Populate the database using all the Entity classes previously added.
*
* Please note that large amounts of data will result in more memory usage since the the Populator will return
* all newly created primary keys after executing.
*
* @param ObjectManager|null $entityManager A Doctrine connection object
*
* @return array A list of the inserted PKs
*/
public function execute($entityManager = null)
{
if (null === $entityManager) {
$entityManager = $this->manager;
}
if (null === $entityManager) {
throw new \InvalidArgumentException('No entity manager passed to Doctrine Populator.');
}
$insertedEntities = [];
foreach ($this->quantities as $class => $number) {
$generateId = $this->generateId[$class];
for ($i = 0; $i < $number; ++$i) {
$insertedEntities[$class][] = $this->entities[$class]->execute(
$entityManager,
$insertedEntities,
$generateId,
);
if (count($insertedEntities) % $this->batchSize === 0) {
$entityManager->flush();
}
}
$entityManager->flush();
}
return $insertedEntities;
}
}
@@ -1,11 +0,0 @@
<?php
declare(strict_types=1);
if (!class_exists('Doctrine\Common\Persistence\Mapping\ClassMetadata')) {
class_alias(\Doctrine\Persistence\Mapping\ClassMetadata::class, 'Doctrine\Common\Persistence\Mapping\ClassMetadata');
}
if (!class_exists('Doctrine\Common\Persistence\ObjectManager')) {
class_alias(\Doctrine\Persistence\ObjectManager::class, 'Doctrine\Common\Persistence\ObjectManager');
}
@@ -1,57 +0,0 @@
<?php
namespace Faker\ORM\Mandango;
use Faker\Generator;
class ColumnTypeGuesser
{
/**
* @var Generator
*/
protected $generator;
public function __construct(Generator $generator)
{
$this->generator = $generator;
}
/**
* @return \Closure|null
*/
public function guessFormat($field)
{
$generator = $this->generator;
switch ($field['type']) {
case 'boolean':
return static function () use ($generator) {
return $generator->boolean;
};
case 'integer':
return static function () use ($generator) {
return $generator->numberBetween(0, 4294967295);
};
case 'float':
return static function () use ($generator) {
return $generator->randomFloat();
};
case 'string':
return static function () use ($generator) {
return $generator->text(255);
};
case 'date':
return static function () use ($generator) {
return $generator->dateTime;
};
default:
// no smart way to guess what the user expects here
return null;
}
}
}
@@ -1,123 +0,0 @@
<?php
namespace Faker\ORM\Mandango;
use Faker\Provider\Base;
use Mandango\Mandango;
/**
* Service class for populating a table through a Mandango ActiveRecord class.
*/
class EntityPopulator
{
protected $class;
protected $columnFormatters = [];
/**
* @param string $class A Mandango ActiveRecord classname
*/
public function __construct($class)
{
$this->class = $class;
}
/**
* @return string
*/
public function getClass()
{
return $this->class;
}
public function setColumnFormatters($columnFormatters)
{
$this->columnFormatters = $columnFormatters;
}
/**
* @return array
*/
public function getColumnFormatters()
{
return $this->columnFormatters;
}
public function mergeColumnFormattersWith($columnFormatters)
{
$this->columnFormatters = array_merge($this->columnFormatters, $columnFormatters);
}
/**
* @return array
*/
public function guessColumnFormatters(\Faker\Generator $generator, Mandango $mandango)
{
$formatters = [];
$nameGuesser = new \Faker\Guesser\Name($generator);
$columnTypeGuesser = new \Faker\ORM\Mandango\ColumnTypeGuesser($generator);
$metadata = $mandango->getMetadata($this->class);
// fields
foreach ($metadata['fields'] as $fieldName => $field) {
if ($formatter = $nameGuesser->guessFormat($fieldName)) {
$formatters[$fieldName] = $formatter;
continue;
}
if ($formatter = $columnTypeGuesser->guessFormat($field)) {
$formatters[$fieldName] = $formatter;
continue;
}
}
// references
foreach (array_merge($metadata['referencesOne'], $metadata['referencesMany']) as $referenceName => $reference) {
if (!isset($reference['class'])) {
continue;
}
$referenceClass = $reference['class'];
$formatters[$referenceName] = static function ($insertedEntities) use ($referenceClass) {
if (isset($insertedEntities[$referenceClass])) {
return Base::randomElement($insertedEntities[$referenceClass]);
}
return null;
};
}
return $formatters;
}
/**
* Insert one new record using the Entity class.
*/
public function execute(Mandango $mandango, $insertedEntities)
{
$metadata = $mandango->getMetadata($this->class);
$obj = $mandango->create($this->class);
foreach ($this->columnFormatters as $column => $format) {
if (null !== $format) {
$value = is_callable($format) ? $format($insertedEntities, $obj) : $format;
if (isset($metadata['fields'][$column])
|| isset($metadata['referencesOne'][$column])) {
$obj->set($column, $value);
}
if (isset($metadata['referencesMany'][$column])) {
$adder = 'add' . ucfirst($column);
$obj->$adder($value);
}
}
}
$mandango->persist($obj);
return $obj;
}
}
@@ -1,63 +0,0 @@
<?php
namespace Faker\ORM\Mandango;
use Mandango\Mandango;
/**
* Service class for populating a database using Mandango.
* A Populator can populate several tables using ActiveRecord classes.
*/
class Populator
{
protected $generator;
protected $mandango;
protected $entities = [];
protected $quantities = [];
public function __construct(\Faker\Generator $generator, Mandango $mandango)
{
$this->generator = $generator;
$this->mandango = $mandango;
}
/**
* Add an order for the generation of $number records for $entity.
*
* @param mixed $entity A Propel ActiveRecord classname, or a \Faker\ORM\Propel\EntityPopulator instance
* @param int $number The number of entities to populate
*/
public function addEntity($entity, $number, $customColumnFormatters = [])
{
if (!$entity instanceof \Faker\ORM\Mandango\EntityPopulator) {
$entity = new \Faker\ORM\Mandango\EntityPopulator($entity);
}
$entity->setColumnFormatters($entity->guessColumnFormatters($this->generator, $this->mandango));
if ($customColumnFormatters) {
$entity->mergeColumnFormattersWith($customColumnFormatters);
}
$class = $entity->getClass();
$this->entities[$class] = $entity;
$this->quantities[$class] = $number;
}
/**
* Populate the database using all the Entity classes previously added.
*
* @return array A list of the inserted entities.
*/
public function execute()
{
$insertedEntities = [];
foreach ($this->quantities as $class => $number) {
for ($i = 0; $i < $number; ++$i) {
$insertedEntities[$class][] = $this->entities[$class]->execute($this->mandango, $insertedEntities);
}
}
$this->mandango->flush();
return $insertedEntities;
}
}
@@ -1,109 +0,0 @@
<?php
namespace Faker\ORM\Propel;
class ColumnTypeGuesser
{
protected $generator;
public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}
/**
* @return \Closure|null
*/
public function guessFormat(\ColumnMap $column)
{
$generator = $this->generator;
if ($column->isTemporal()) {
if ($column->isEpochTemporal()) {
return static function () use ($generator) {
return $generator->dateTime;
};
}
return static function () use ($generator) {
return $generator->dateTimeAD;
};
}
$type = $column->getType();
switch ($type) {
case \PropelColumnTypes::BOOLEAN:
case \PropelColumnTypes::BOOLEAN_EMU:
return static function () use ($generator) {
return $generator->boolean;
};
case \PropelColumnTypes::NUMERIC:
case \PropelColumnTypes::DECIMAL:
$size = $column->getSize();
return static function () use ($generator, $size) {
return $generator->randomNumber($size + 2) / 100;
};
case \PropelColumnTypes::TINYINT:
return static function () use ($generator) {
return $generator->numberBetween(0, 127);
};
case \PropelColumnTypes::SMALLINT:
return static function () use ($generator) {
return $generator->numberBetween(0, 32767);
};
case \PropelColumnTypes::INTEGER:
return static function () use ($generator) {
return $generator->numberBetween(0, 2147483647);
};
case \PropelColumnTypes::BIGINT:
return static function () use ($generator) {
return $generator->numberBetween(0, PHP_INT_MAX);
};
case \PropelColumnTypes::FLOAT:
case \PropelColumnTypes::DOUBLE:
case \PropelColumnTypes::REAL:
return static function () use ($generator) {
return $generator->randomFloat();
};
case \PropelColumnTypes::CHAR:
case \PropelColumnTypes::VARCHAR:
case \PropelColumnTypes::BINARY:
case \PropelColumnTypes::VARBINARY:
$size = $column->getSize();
return static function () use ($generator, $size) {
return $generator->text($size);
};
case \PropelColumnTypes::LONGVARCHAR:
case \PropelColumnTypes::LONGVARBINARY:
case \PropelColumnTypes::CLOB:
case \PropelColumnTypes::CLOB_EMU:
case \PropelColumnTypes::BLOB:
return static function () use ($generator) {
return $generator->text;
};
case \PropelColumnTypes::ENUM:
$valueSet = $column->getValueSet();
return static function () use ($generator, $valueSet) {
return $generator->randomElement($valueSet);
};
case \PropelColumnTypes::OBJECT:
case \PropelColumnTypes::PHP_ARRAY:
default:
// no smart way to guess what the user expects here
return null;
}
}
}
@@ -1,204 +0,0 @@
<?php
namespace Faker\ORM\Propel;
use Faker\Provider\Base;
/**
* Service class for populating a table through a Propel ActiveRecord class.
*/
class EntityPopulator
{
protected $class;
protected $columnFormatters = [];
protected $modifiers = [];
/**
* @param string $class A Propel ActiveRecord classname
*/
public function __construct($class)
{
$this->class = $class;
}
/**
* @return string
*/
public function getClass()
{
return $this->class;
}
public function setColumnFormatters($columnFormatters)
{
$this->columnFormatters = $columnFormatters;
}
/**
* @return array
*/
public function getColumnFormatters()
{
return $this->columnFormatters;
}
public function mergeColumnFormattersWith($columnFormatters)
{
$this->columnFormatters = array_merge($this->columnFormatters, $columnFormatters);
}
/**
* @return array
*/
public function guessColumnFormatters(\Faker\Generator $generator)
{
$formatters = [];
$class = $this->class;
$peerClass = $class::PEER;
$tableMap = $peerClass::getTableMap();
$nameGuesser = new \Faker\Guesser\Name($generator);
$columnTypeGuesser = new \Faker\ORM\Propel\ColumnTypeGuesser($generator);
foreach ($tableMap->getColumns() as $columnMap) {
// skip behavior columns, handled by modifiers
if ($this->isColumnBehavior($columnMap)) {
continue;
}
if ($columnMap->isForeignKey()) {
$relatedClass = $columnMap->getRelation()->getForeignTable()->getClassname();
$formatters[$columnMap->getPhpName()] = static function ($inserted) use ($relatedClass, $generator) {
return isset($inserted[$relatedClass]) ? $generator->randomElement($inserted[$relatedClass]) : null;
};
continue;
}
if ($columnMap->isPrimaryKey()) {
continue;
}
if ($formatter = $nameGuesser->guessFormat($columnMap->getPhpName(), $columnMap->getSize())) {
$formatters[$columnMap->getPhpName()] = $formatter;
continue;
}
if ($formatter = $columnTypeGuesser->guessFormat($columnMap)) {
$formatters[$columnMap->getPhpName()] = $formatter;
continue;
}
}
return $formatters;
}
/**
* @return bool
*/
protected function isColumnBehavior(\ColumnMap $columnMap)
{
foreach ($columnMap->getTable()->getBehaviors() as $name => $params) {
$columnName = Base::toLower($columnMap->getName());
switch ($name) {
case 'nested_set':
$columnNames = [$params['left_column'], $params['right_column'], $params['level_column']];
if (in_array($columnName, $columnNames, false)) {
return true;
}
break;
case 'timestampable':
$columnNames = [$params['create_column'], $params['update_column']];
if (in_array($columnName, $columnNames, false)) {
return true;
}
break;
}
}
return false;
}
public function setModifiers($modifiers)
{
$this->modifiers = $modifiers;
}
/**
* @return array
*/
public function getModifiers()
{
return $this->modifiers;
}
public function mergeModifiersWith($modifiers)
{
$this->modifiers = array_merge($this->modifiers, $modifiers);
}
/**
* @return array
*/
public function guessModifiers(\Faker\Generator $generator)
{
$modifiers = [];
$class = $this->class;
$peerClass = $class::PEER;
$tableMap = $peerClass::getTableMap();
foreach ($tableMap->getBehaviors() as $name => $params) {
switch ($name) {
case 'nested_set':
$modifiers['nested_set'] = static function ($obj, $inserted) use ($class, $generator): void {
if (isset($inserted[$class])) {
$queryClass = $class . 'Query';
$parent = $queryClass::create()->findPk($generator->randomElement($inserted[$class]));
$obj->insertAsLastChildOf($parent);
} else {
$obj->makeRoot();
}
};
break;
case 'sortable':
$modifiers['sortable'] = static function ($obj, $inserted) use ($class, $generator): void {
$obj->insertAtRank($generator->numberBetween(1, count($inserted[$class] ?? []) + 1));
};
break;
}
}
return $modifiers;
}
/**
* Insert one new record using the Entity class.
*/
public function execute($con, $insertedEntities)
{
$obj = new $this->class();
foreach ($this->getColumnFormatters() as $column => $format) {
if (null !== $format) {
$obj->setByName($column, is_callable($format) ? $format($insertedEntities, $obj) : $format);
}
}
foreach ($this->getModifiers() as $modifier) {
$modifier($obj, $insertedEntities);
}
$obj->save($con);
return $obj->getPrimaryKey();
}
}
@@ -1,90 +0,0 @@
<?php
namespace Faker\ORM\Propel;
/**
* Service class for populating a database using the Propel ORM.
* A Populator can populate several tables using ActiveRecord classes.
*/
class Populator
{
protected $generator;
protected $entities = [];
protected $quantities = [];
public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}
/**
* Add an order for the generation of $number records for $entity.
*
* @param mixed $entity A Propel ActiveRecord classname, or a \Faker\ORM\Propel\EntityPopulator instance
* @param int $number The number of entities to populate
*/
public function addEntity($entity, $number, $customColumnFormatters = [], $customModifiers = [])
{
if (!$entity instanceof \Faker\ORM\Propel\EntityPopulator) {
$entity = new \Faker\ORM\Propel\EntityPopulator($entity);
}
$entity->setColumnFormatters($entity->guessColumnFormatters($this->generator));
if ($customColumnFormatters) {
$entity->mergeColumnFormattersWith($customColumnFormatters);
}
$entity->setModifiers($entity->guessModifiers($this->generator));
if ($customModifiers) {
$entity->mergeModifiersWith($customModifiers);
}
$class = $entity->getClass();
$this->entities[$class] = $entity;
$this->quantities[$class] = $number;
}
/**
* Populate the database using all the Entity classes previously added.
*
* @param PropelPDO $con A Propel connection object
*
* @return array A list of the inserted PKs
*/
public function execute($con = null)
{
if (null === $con) {
$con = $this->getConnection();
}
$isInstancePoolingEnabled = \Propel::isInstancePoolingEnabled();
\Propel::disableInstancePooling();
$insertedEntities = [];
$con->beginTransaction();
foreach ($this->quantities as $class => $number) {
for ($i = 0; $i < $number; ++$i) {
$insertedEntities[$class][] = $this->entities[$class]->execute($con, $insertedEntities);
}
}
$con->commit();
if ($isInstancePoolingEnabled) {
\Propel::enableInstancePooling();
}
return $insertedEntities;
}
protected function getConnection()
{
// use the first connection available
$class = key($this->entities);
if (!$class) {
throw new \RuntimeException('No class found from entities. Did you add entities to the Populator ?');
}
$peer = $class::PEER;
return \Propel::getConnection($peer::DATABASE_NAME, \Propel::CONNECTION_WRITE);
}
}
@@ -1,112 +0,0 @@
<?php
namespace Faker\ORM\Propel2;
use Propel\Generator\Model\PropelTypes;
use Propel\Runtime\Map\ColumnMap;
class ColumnTypeGuesser
{
protected $generator;
public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}
/**
* @return \Closure|null
*/
public function guessFormat(ColumnMap $column)
{
$generator = $this->generator;
if ($column->isTemporal()) {
if ($column->getType() == PropelTypes::BU_DATE || $column->getType() == PropelTypes::BU_TIMESTAMP) {
return static function () use ($generator) {
return $generator->dateTime;
};
}
return static function () use ($generator) {
return $generator->dateTimeAD;
};
}
$type = $column->getType();
switch ($type) {
case PropelTypes::BOOLEAN:
case PropelTypes::BOOLEAN_EMU:
return static function () use ($generator) {
return $generator->boolean;
};
case PropelTypes::NUMERIC:
case PropelTypes::DECIMAL:
$size = $column->getSize();
return static function () use ($generator, $size) {
return $generator->randomNumber($size + 2) / 100;
};
case PropelTypes::TINYINT:
return static function () use ($generator) {
return $generator->numberBetween(0, 127);
};
case PropelTypes::SMALLINT:
return static function () use ($generator) {
return $generator->numberBetween(0, 32767);
};
case PropelTypes::INTEGER:
return static function () use ($generator) {
return $generator->numberBetween(0, 2147483647);
};
case PropelTypes::BIGINT:
return static function () use ($generator) {
return $generator->numberBetween(0, PHP_INT_MAX);
};
case PropelTypes::FLOAT:
case PropelTypes::DOUBLE:
case PropelTypes::REAL:
return static function () use ($generator) {
return $generator->randomFloat();
};
case PropelTypes::CHAR:
case PropelTypes::VARCHAR:
case PropelTypes::BINARY:
case PropelTypes::VARBINARY:
$size = $column->getSize();
return static function () use ($generator, $size) {
return $generator->text($size);
};
case PropelTypes::LONGVARCHAR:
case PropelTypes::LONGVARBINARY:
case PropelTypes::CLOB:
case PropelTypes::CLOB_EMU:
case PropelTypes::BLOB:
return static function () use ($generator) {
return $generator->text;
};
case PropelTypes::ENUM:
$valueSet = $column->getValueSet();
return static function () use ($generator, $valueSet) {
return $generator->randomElement($valueSet);
};
case PropelTypes::OBJECT:
case PropelTypes::PHP_ARRAY:
default:
// no smart way to guess what the user expects here
return null;
}
}
}
@@ -1,207 +0,0 @@
<?php
namespace Faker\ORM\Propel2;
use Faker\Provider\Base;
use Propel\Runtime\Map\ColumnMap;
/**
* Service class for populating a table through a Propel ActiveRecord class.
*/
class EntityPopulator
{
protected $class;
protected $columnFormatters = [];
protected $modifiers = [];
/**
* @param string $class A Propel ActiveRecord classname
*/
public function __construct($class)
{
$this->class = $class;
}
/**
* @return string
*/
public function getClass()
{
return $this->class;
}
public function setColumnFormatters($columnFormatters)
{
$this->columnFormatters = $columnFormatters;
}
/**
* @return array
*/
public function getColumnFormatters()
{
return $this->columnFormatters;
}
public function mergeColumnFormattersWith($columnFormatters)
{
$this->columnFormatters = array_merge($this->columnFormatters, $columnFormatters);
}
/**
* @return array
*/
public function guessColumnFormatters(\Faker\Generator $generator)
{
$formatters = [];
$class = $this->class;
$peerClass = $class::TABLE_MAP;
$tableMap = $peerClass::getTableMap();
$nameGuesser = new \Faker\Guesser\Name($generator);
$columnTypeGuesser = new \Faker\ORM\Propel2\ColumnTypeGuesser($generator);
foreach ($tableMap->getColumns() as $columnMap) {
// skip behavior columns, handled by modifiers
if ($this->isColumnBehavior($columnMap)) {
continue;
}
if ($columnMap->isForeignKey()) {
$relatedClass = $columnMap->getRelation()->getForeignTable()->getClassname();
$formatters[$columnMap->getPhpName()] = static function ($inserted) use ($relatedClass, $generator) {
$relatedClass = trim($relatedClass, '\\');
return isset($inserted[$relatedClass]) ? $generator->randomElement($inserted[$relatedClass]) : null;
};
continue;
}
if ($columnMap->isPrimaryKey()) {
continue;
}
if ($formatter = $nameGuesser->guessFormat($columnMap->getPhpName(), $columnMap->getSize())) {
$formatters[$columnMap->getPhpName()] = $formatter;
continue;
}
if ($formatter = $columnTypeGuesser->guessFormat($columnMap)) {
$formatters[$columnMap->getPhpName()] = $formatter;
continue;
}
}
return $formatters;
}
/**
* @return bool
*/
protected function isColumnBehavior(ColumnMap $columnMap)
{
foreach ($columnMap->getTable()->getBehaviors() as $name => $params) {
$columnName = Base::toLower($columnMap->getName());
switch ($name) {
case 'nested_set':
$columnNames = [$params['left_column'], $params['right_column'], $params['level_column']];
if (in_array($columnName, $columnNames, false)) {
return true;
}
break;
case 'timestampable':
$columnNames = [$params['create_column'], $params['update_column']];
if (in_array($columnName, $columnNames, false)) {
return true;
}
break;
}
}
return false;
}
public function setModifiers($modifiers)
{
$this->modifiers = $modifiers;
}
/**
* @return array
*/
public function getModifiers()
{
return $this->modifiers;
}
public function mergeModifiersWith($modifiers)
{
$this->modifiers = array_merge($this->modifiers, $modifiers);
}
/**
* @return array
*/
public function guessModifiers(\Faker\Generator $generator)
{
$modifiers = [];
$class = $this->class;
$peerClass = $class::TABLE_MAP;
$tableMap = $peerClass::getTableMap();
foreach ($tableMap->getBehaviors() as $name => $params) {
switch ($name) {
case 'nested_set':
$modifiers['nested_set'] = static function ($obj, $inserted) use ($class, $generator): void {
if (isset($inserted[$class])) {
$queryClass = $class . 'Query';
$parent = $queryClass::create()->findPk($generator->randomElement($inserted[$class]));
$obj->insertAsLastChildOf($parent);
} else {
$obj->makeRoot();
}
};
break;
case 'sortable':
$modifiers['sortable'] = static function ($obj, $inserted) use ($class, $generator): void {
$obj->insertAtRank($generator->numberBetween(1, count($inserted[$class] ?? []) + 1));
};
break;
}
}
return $modifiers;
}
/**
* Insert one new record using the Entity class.
*/
public function execute($con, $insertedEntities)
{
$obj = new $this->class();
foreach ($this->getColumnFormatters() as $column => $format) {
if (null !== $format) {
$obj->setByName($column, is_callable($format) ? $format($insertedEntities, $obj) : $format);
}
}
foreach ($this->getModifiers() as $modifier) {
$modifier($obj, $insertedEntities);
}
$obj->save($con);
return $obj->getPrimaryKey();
}
}
@@ -1,93 +0,0 @@
<?php
namespace Faker\ORM\Propel2;
use Propel\Runtime\Propel;
use Propel\Runtime\ServiceContainer\ServiceContainerInterface;
/**
* Service class for populating a database using the Propel ORM.
* A Populator can populate several tables using ActiveRecord classes.
*/
class Populator
{
protected $generator;
protected $entities = [];
protected $quantities = [];
public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}
/**
* Add an order for the generation of $number records for $entity.
*
* @param mixed $entity A Propel ActiveRecord classname, or a \Faker\ORM\Propel2\EntityPopulator instance
* @param int $number The number of entities to populate
*/
public function addEntity($entity, $number, $customColumnFormatters = [], $customModifiers = [])
{
if (!$entity instanceof \Faker\ORM\Propel2\EntityPopulator) {
$entity = new \Faker\ORM\Propel2\EntityPopulator($entity);
}
$entity->setColumnFormatters($entity->guessColumnFormatters($this->generator));
if ($customColumnFormatters) {
$entity->mergeColumnFormattersWith($customColumnFormatters);
}
$entity->setModifiers($entity->guessModifiers($this->generator));
if ($customModifiers) {
$entity->mergeModifiersWith($customModifiers);
}
$class = $entity->getClass();
$this->entities[$class] = $entity;
$this->quantities[$class] = $number;
}
/**
* Populate the database using all the Entity classes previously added.
*
* @param PropelPDO $con A Propel connection object
*
* @return array A list of the inserted PKs
*/
public function execute($con = null)
{
if (null === $con) {
$con = $this->getConnection();
}
$isInstancePoolingEnabled = Propel::isInstancePoolingEnabled();
Propel::disableInstancePooling();
$insertedEntities = [];
$con->beginTransaction();
foreach ($this->quantities as $class => $number) {
for ($i = 0; $i < $number; ++$i) {
$insertedEntities[$class][] = $this->entities[$class]->execute($con, $insertedEntities);
}
}
$con->commit();
if ($isInstancePoolingEnabled) {
Propel::enableInstancePooling();
}
return $insertedEntities;
}
protected function getConnection()
{
// use the first connection available
$class = key($this->entities);
if (!$class) {
throw new \RuntimeException('No class found from entities. Did you add entities to the Populator ?');
}
$peer = $class::TABLE_MAP;
return Propel::getConnection($peer::DATABASE_NAME, ServiceContainerInterface::CONNECTION_WRITE);
}
}
@@ -1,84 +0,0 @@
<?php
namespace Faker\ORM\Spot;
use Faker\Generator;
class ColumnTypeGuesser
{
protected $generator;
/**
* ColumnTypeGuesser constructor.
*/
public function __construct(Generator $generator)
{
$this->generator = $generator;
}
/**
* @return \Closure|null
*/
public function guessFormat(array $field)
{
$generator = $this->generator;
$type = $field['type'];
switch ($type) {
case 'boolean':
return static function () use ($generator) {
return $generator->boolean;
};
case 'decimal':
$size = $field['precision'] ?? 2;
return static function () use ($generator, $size) {
return $generator->randomNumber($size + 2) / 100;
};
case 'smallint':
return static function () use ($generator) {
return $generator->numberBetween(0, 65535);
};
case 'integer':
return static function () use ($generator) {
return $generator->numberBetween(0, 2147483647);
};
case 'bigint':
return static function () use ($generator) {
return $generator->numberBetween(0, PHP_INT_MAX);
};
case 'float':
return static function () use ($generator) {
return $generator->randomFloat(null, 0, 4294967295);
};
case 'string':
$size = $field['length'] ?? 255;
return static function () use ($generator, $size) {
return $generator->text($size);
};
case 'text':
return static function () use ($generator) {
return $generator->text;
};
case 'datetime':
case 'date':
case 'time':
return static function () use ($generator) {
return $generator->datetime;
};
default:
// no smart way to guess what the user expects here
return null;
}
}
}
@@ -1,199 +0,0 @@
<?php
namespace Faker\ORM\Spot;
use Faker\Generator;
use Faker\Guesser\Name;
use Spot\Locator;
use Spot\Mapper;
use Spot\Relation\BelongsTo;
/**
* Service class for populating a table through a Spot Entity class.
*/
class EntityPopulator
{
/**
* When fetching existing data - fetch only few first rows.
*/
public const RELATED_FETCH_COUNT = 10;
/**
* @var Mapper
*/
protected $mapper;
/**
* @var Locator
*/
protected $locator;
/**
* @var array
*/
protected $columnFormatters = [];
/**
* @var array
*/
protected $modifiers = [];
/**
* @var bool
*/
protected $useExistingData = false;
/**
* @param bool $useExistingData
*/
public function __construct(Mapper $mapper, Locator $locator, $useExistingData = false)
{
$this->mapper = $mapper;
$this->locator = $locator;
$this->useExistingData = $useExistingData;
}
/**
* @return string
*/
public function getMapper()
{
return $this->mapper;
}
public function setColumnFormatters($columnFormatters)
{
$this->columnFormatters = $columnFormatters;
}
/**
* @return array
*/
public function getColumnFormatters()
{
return $this->columnFormatters;
}
public function mergeColumnFormattersWith($columnFormatters)
{
$this->columnFormatters = array_merge($this->columnFormatters, $columnFormatters);
}
public function setModifiers(array $modifiers)
{
$this->modifiers = $modifiers;
}
/**
* @return array
*/
public function getModifiers()
{
return $this->modifiers;
}
public function mergeModifiersWith(array $modifiers)
{
$this->modifiers = array_merge($this->modifiers, $modifiers);
}
/**
* @return array
*/
public function guessColumnFormatters(Generator $generator)
{
$formatters = [];
$nameGuesser = new Name($generator);
$columnTypeGuesser = new ColumnTypeGuesser($generator);
$fields = $this->mapper->fields();
foreach ($fields as $fieldName => $field) {
if ($field['primary'] === true) {
continue;
}
if ($formatter = $nameGuesser->guessFormat($fieldName)) {
$formatters[$fieldName] = $formatter;
continue;
}
if ($formatter = $columnTypeGuesser->guessFormat($field)) {
$formatters[$fieldName] = $formatter;
continue;
}
}
$entityName = $this->mapper->entity();
$entity = $this->mapper->build([]);
$relations = $entityName::relations($this->mapper, $entity);
foreach ($relations as $relation) {
// We don't need any other relation here.
if ($relation instanceof BelongsTo) {
$fieldName = $relation->localKey();
$entityName = $relation->entityName();
$field = $fields[$fieldName];
$required = $field['required'];
$locator = $this->locator;
$formatters[$fieldName] = function ($inserted) use ($required, $entityName, $locator, $generator) {
if (!empty($inserted[$entityName])) {
return $generator->randomElement($inserted[$entityName])->get('id');
}
if ($required && $this->useExistingData) {
// We did not add anything like this, but it's required,
// So let's find something existing in DB.
$mapper = $locator->mapper($entityName);
$records = $mapper->all()->limit(self::RELATED_FETCH_COUNT)->toArray();
if (empty($records)) {
return null;
}
return $generator->randomElement($records)['id'];
}
return null;
};
}
}
return $formatters;
}
/**
* Insert one new record using the Entity class.
*
* @return string
*/
public function execute($insertedEntities)
{
$obj = $this->mapper->build([]);
$this->fillColumns($obj, $insertedEntities);
$this->callMethods($obj, $insertedEntities);
$this->mapper->insert($obj);
return $obj;
}
private function fillColumns($obj, $insertedEntities): void
{
foreach ($this->columnFormatters as $field => $format) {
if (null !== $format) {
$value = is_callable($format) ? $format($insertedEntities, $obj) : $format;
$obj->set($field, $value);
}
}
}
private function callMethods($obj, $insertedEntities): void
{
foreach ($this->getModifiers() as $modifier) {
$modifier($obj, $insertedEntities);
}
}
}
-89
View File
@@ -1,89 +0,0 @@
<?php
namespace Faker\ORM\Spot;
use Spot\Locator;
/**
* Service class for populating a database using the Spot ORM.
*/
class Populator
{
protected $generator;
protected $locator;
protected $entities = [];
protected $quantities = [];
/**
* Populator constructor.
*/
public function __construct(\Faker\Generator $generator, ?Locator $locator = null)
{
$this->generator = $generator;
$this->locator = $locator;
}
/**
* Add an order for the generation of $number records for $entity.
*
* @param string $entityName Name of Entity object to generate
* @param int $number The number of entities to populate
* @param array $customColumnFormatters
* @param array $customModifiers
* @param bool $useExistingData Should we use existing rows (e.g. roles) to populate relations?
*/
public function addEntity(
$entityName,
$number,
$customColumnFormatters = [],
$customModifiers = [],
$useExistingData = false
) {
$mapper = $this->locator->mapper($entityName);
if (null === $mapper) {
throw new \InvalidArgumentException('No mapper can be found for entity ' . $entityName);
}
$entity = new EntityPopulator($mapper, $this->locator, $useExistingData);
$entity->setColumnFormatters($entity->guessColumnFormatters($this->generator));
if ($customColumnFormatters) {
$entity->mergeColumnFormattersWith($customColumnFormatters);
}
$entity->mergeModifiersWith($customModifiers);
$this->entities[$entityName] = $entity;
$this->quantities[$entityName] = $number;
}
/**
* Populate the database using all the Entity classes previously added.
*
* @param Locator $locator A Spot locator
*
* @return array A list of the inserted PKs
*/
public function execute($locator = null)
{
if (null === $locator) {
$locator = $this->locator;
}
if (null === $locator) {
throw new \InvalidArgumentException('No entity manager passed to Spot Populator.');
}
$insertedEntities = [];
foreach ($this->quantities as $entityName => $number) {
for ($i = 0; $i < $number; ++$i) {
$insertedEntities[$entityName][] = $this->entities[$entityName]->execute(
$insertedEntities,
);
}
}
return $insertedEntities;
}
}
-166
View File
@@ -1,166 +0,0 @@
<?php
namespace Faker\Provider;
class Address extends Base
{
protected static $citySuffix = ['Ville'];
protected static $streetSuffix = ['Street'];
protected static $cityFormats = [
'{{firstName}}{{citySuffix}}',
];
protected static $streetNameFormats = [
'{{lastName}} {{streetSuffix}}',
];
protected static $streetAddressFormats = [
'{{buildingNumber}} {{streetName}}',
];
protected static $addressFormats = [
'{{streetAddress}} {{postcode}} {{city}}',
];
protected static $buildingNumber = ['%#'];
protected static $postcode = ['#####'];
protected static $country = [];
/**
* @example 'town'
*
* @return string
*/
public static function citySuffix()
{
return static::randomElement(static::$citySuffix);
}
/**
* @example 'Avenue'
*
* @return string
*/
public static function streetSuffix()
{
return static::randomElement(static::$streetSuffix);
}
/**
* @example '791'
*
* @return string
*/
public static function buildingNumber()
{
return static::numerify(static::randomElement(static::$buildingNumber));
}
/**
* @example 'Sashabury'
*
* @return string
*/
public function city()
{
$format = static::randomElement(static::$cityFormats);
return $this->generator->parse($format);
}
/**
* @example 'Crist Parks'
*
* @return string
*/
public function streetName()
{
$format = static::randomElement(static::$streetNameFormats);
return $this->generator->parse($format);
}
/**
* @example '791 Crist Parks'
*
* @return string
*/
public function streetAddress()
{
$format = static::randomElement(static::$streetAddressFormats);
return $this->generator->parse($format);
}
/**
* @example 86039-9874
*
* @return string
*/
public static function postcode()
{
return static::toUpper(static::bothify(static::randomElement(static::$postcode)));
}
/**
* @example '791 Crist Parks, Sashabury, IL 86039-9874'
*
* @return string
*/
public function address()
{
$format = static::randomElement(static::$addressFormats);
return $this->generator->parse($format);
}
/**
* @example 'Japan'
*
* @return string
*/
public static function country()
{
return static::randomElement(static::$country);
}
/**
* Uses signed degrees format (returns a float number between -90 and 90)
*
* @example '77.147489'
*
* @param float|int $min
* @param float|int $max
*
* @return float
*/
public static function latitude($min = -90, $max = 90)
{
return static::randomFloat(6, $min, $max);
}
/**
* Uses signed degrees format (returns a float number between -180 and 180)
*
* @example '86.211205'
*
* @param float|int $min
* @param float|int $max
*
* @return float
*/
public static function longitude($min = -180, $max = 180)
{
return static::randomFloat(6, $min, $max);
}
/**
* @example array('77.147489', '86.211205')
*
* @return float[]
*/
public static function localCoordinates()
{
return [
'latitude' => static::latitude(),
'longitude' => static::longitude(),
];
}
}
-107
View File
@@ -1,107 +0,0 @@
<?php
namespace Faker\Provider;
use Faker\Calculator\Ean;
use Faker\Calculator\Isbn;
/**
* @see http://en.wikipedia.org/wiki/EAN-13
* @see http://en.wikipedia.org/wiki/ISBN
*/
class Barcode extends Base
{
private function ean($length = 13)
{
$code = static::numerify(str_repeat('#', $length - 1));
return $code . Ean::checksum($code);
}
/**
* Utility function for computing EAN checksums
*
* @deprecated Use \Faker\Calculator\Ean::checksum() instead
*
* @param string $input
*
* @return int
*/
protected static function eanChecksum($input)
{
return Ean::checksum($input);
}
/**
* ISBN-10 check digit
*
* @see http://en.wikipedia.org/wiki/International_Standard_Book_Number#ISBN-10_check_digits
* @deprecated Use \Faker\Calculator\Isbn::checksum() instead
*
* @param string $input ISBN without check-digit
*
* @throws \LengthException When wrong input length passed
*
* @return string
*/
protected static function isbnChecksum($input)
{
return Isbn::checksum($input);
}
/**
* Get a random EAN13 barcode.
*
* @return string
*
* @example '4006381333931'
*/
public function ean13()
{
return $this->ean(13);
}
/**
* Get a random EAN8 barcode.
*
* @return string
*
* @example '73513537'
*/
public function ean8()
{
return $this->ean(8);
}
/**
* Get a random ISBN-10 code
*
* @see http://en.wikipedia.org/wiki/International_Standard_Book_Number
*
* @return string
*
* @example '4881416324'
*/
public function isbn10()
{
$code = static::numerify(str_repeat('#', 9));
return $code . Isbn::checksum($code);
}
/**
* Get a random ISBN-13 code
*
* @see http://en.wikipedia.org/wiki/International_Standard_Book_Number
*
* @return string
*
* @example '9790404436093'
*/
public function isbn13()
{
$code = '97' . self::numberBetween(8, 9) . static::numerify(str_repeat('#', 9));
return $code . Ean::checksum($code);
}
}
-710
View File
@@ -1,710 +0,0 @@
<?php
namespace Faker\Provider;
use Faker\DefaultGenerator;
use Faker\Generator;
use Faker\UniqueGenerator;
use Faker\ValidGenerator;
class Base
{
/**
* @var \Faker\Generator
*/
protected $generator;
/**
* @var \Faker\UniqueGenerator
*/
protected $unique;
public function __construct(Generator $generator)
{
$this->generator = $generator;
}
/**
* Returns a random number between 0 and 9
*
* @return int
*/
public static function randomDigit()
{
return mt_rand(0, 9);
}
/**
* Returns a random number between 1 and 9
*
* @return int
*/
public static function randomDigitNotNull()
{
return mt_rand(1, 9);
}
/**
* Generates a random digit, which cannot be $except
*
* @param int $except
*
* @return int
*/
public static function randomDigitNot($except)
{
$result = self::numberBetween(0, 8);
if ($result >= $except) {
++$result;
}
return $result;
}
/**
* Returns a random integer with 0 to $nbDigits digits.
*
* The maximum value returned is mt_getrandmax()
*
* @param int $nbDigits Defaults to a random number between 1 and 9
* @param bool $strict Whether the returned number should have exactly $nbDigits
*
* @example 79907610
*
* @return int
*/
public static function randomNumber($nbDigits = null, $strict = false)
{
if (!is_bool($strict)) {
throw new \InvalidArgumentException('randomNumber() generates numbers of fixed width. To generate numbers between two boundaries, use numberBetween() instead.');
}
if (null === $nbDigits) {
$nbDigits = static::randomDigitNotNull();
}
$max = 10 ** $nbDigits - 1;
if ($max > mt_getrandmax()) {
throw new \InvalidArgumentException('randomNumber() can only generate numbers up to mt_getrandmax()');
}
if ($strict) {
return mt_rand(10 ** ($nbDigits - 1), $max);
}
return mt_rand(0, $max);
}
/**
* Return a random float number
*
* @param int $nbMaxDecimals
* @param float|int $min
* @param float|int $max
*
* @example 48.8932
*
* @return float
*/
public static function randomFloat($nbMaxDecimals = null, $min = 0, $max = null)
{
if (null === $nbMaxDecimals) {
$nbMaxDecimals = static::randomDigit();
}
if (null === $max) {
$max = static::randomNumber();
if ($min > $max) {
$max = $min;
}
}
if ($min > $max) {
$tmp = $min;
$min = $max;
$max = $tmp;
}
return round($min + mt_rand() / mt_getrandmax() * ($max - $min), $nbMaxDecimals);
}
/**
* Returns a random number between $int1 and $int2 (any order)
*
* @param int $int1 default to 0
* @param int $int2 defaults to 32 bit max integer, ie 2147483647
*
* @example 79907610
*
* @return int
*/
public static function numberBetween($int1 = 0, $int2 = 2147483647)
{
$min = $int1 < $int2 ? $int1 : $int2;
$max = $int1 < $int2 ? $int2 : $int1;
return mt_rand($min, $max);
}
/**
* Returns the passed value
*/
public static function passthrough($value)
{
return $value;
}
/**
* Returns a random letter from a to z
*
* @return string
*/
public static function randomLetter()
{
return chr(mt_rand(97, 122));
}
/**
* Returns a random ASCII character (excluding accents and special chars)
*
* @return string
*/
public static function randomAscii()
{
return chr(mt_rand(33, 126));
}
/**
* Returns randomly ordered subsequence of $count elements from a provided array
*
* @todo update default $count to `null` (BC) for next major version
*
* @param array|class-string|\Traversable $array Array to take elements from. Defaults to a-c
* @param int|null $count Number of elements to take. If `null` then returns random number of elements
* @param bool $allowDuplicates Allow elements to be picked several times. Defaults to false
*
* @throws \InvalidArgumentException
* @throws \LengthException When requesting more elements than provided
*
* @return array New array with $count elements from $array
*/
public static function randomElements($array = ['a', 'b', 'c'], $count = 1, $allowDuplicates = false)
{
$elements = $array;
if (is_string($array) && function_exists('enum_exists') && enum_exists($array)) {
$elements = $array::cases();
}
if ($array instanceof \Traversable) {
$elements = \iterator_to_array($array, false);
}
if (!is_array($elements)) {
throw new \InvalidArgumentException(sprintf(
'Argument for parameter $array needs to be array, an instance of %s, or an instance of %s, got %s instead.',
\UnitEnum::class,
\Traversable::class,
is_object($array) ? get_class($array) : gettype($array),
));
}
$numberOfElements = count($elements);
if (!$allowDuplicates && null !== $count && $numberOfElements < $count) {
throw new \LengthException(sprintf(
'Cannot get %d elements, only %d in array',
$count,
$numberOfElements,
));
}
if (null === $count) {
$count = mt_rand(1, $numberOfElements);
}
$randomElements = [];
$keys = array_keys($elements);
$maxIndex = $numberOfElements - 1;
$elementHasBeenSelectedAlready = [];
$numberOfRandomElements = 0;
while ($numberOfRandomElements < $count) {
$index = mt_rand(0, $maxIndex);
if (!$allowDuplicates) {
if (isset($elementHasBeenSelectedAlready[$index])) {
continue;
}
$elementHasBeenSelectedAlready[$index] = true;
}
$key = $keys[$index];
$randomElements[] = $elements[$key];
++$numberOfRandomElements;
}
return $randomElements;
}
/**
* Returns a random element from a passed array
*
* @param array|class-string|\Traversable $array
*
* @throws \InvalidArgumentException
*/
public static function randomElement($array = ['a', 'b', 'c'])
{
$elements = $array;
if (is_string($array) && function_exists('enum_exists') && enum_exists($array)) {
$elements = $array::cases();
}
if ($array instanceof \Traversable) {
$elements = iterator_to_array($array, false);
}
if ($elements === []) {
return null;
}
if (!is_array($elements)) {
throw new \InvalidArgumentException(sprintf(
'Argument for parameter $array needs to be array, an instance of %s, or an instance of %s, got %s instead.',
\UnitEnum::class,
\Traversable::class,
is_object($array) ? get_class($array) : gettype($array),
));
}
$randomElements = static::randomElements($elements, 1);
return $randomElements[0];
}
/**
* Returns a random key from a passed associative array
*
* @param array $array
*
* @return int|string|null
*/
public static function randomKey($array = [])
{
if (!$array) {
return null;
}
$keys = array_keys($array);
return $keys[mt_rand(0, count($keys) - 1)];
}
/**
* Returns a shuffled version of the argument.
*
* This function accepts either an array, or a string.
*
* @example $faker->shuffle([1, 2, 3]); // [2, 1, 3]
* @example $faker->shuffle('hello, world'); // 'rlo,h eold!lw'
*
* @see shuffleArray()
* @see shuffleString()
*
* @param array|string $arg The set to shuffle
*
* @return array|string The shuffled set
*/
public static function shuffle($arg = '')
{
if (is_array($arg)) {
return static::shuffleArray($arg);
}
if (is_string($arg)) {
return static::shuffleString($arg);
}
throw new \InvalidArgumentException('shuffle() only supports strings or arrays');
}
/**
* Returns a shuffled version of the array.
*
* This function does not mutate the original array. It uses the
* FisherYates algorithm, which is unbiased, together with a Mersenne
* twister random generator. This function is therefore more random than
* PHP's shuffle() function, and it is seedable.
*
* @see http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
*
* @example $faker->shuffleArray([1, 2, 3]); // [2, 1, 3]
*
* @param array $array The set to shuffle
*
* @return array The shuffled set
*/
public static function shuffleArray($array = [])
{
$shuffledArray = [];
$i = 0;
reset($array);
foreach ($array as $key => $value) {
if ($i == 0) {
$j = 0;
} else {
$j = mt_rand(0, $i);
}
if ($j == $i) {
$shuffledArray[] = $value;
} else {
$shuffledArray[] = $shuffledArray[$j];
$shuffledArray[$j] = $value;
}
++$i;
}
return $shuffledArray;
}
/**
* Returns a shuffled version of the string.
*
* This function does not mutate the original string. It uses the
* FisherYates algorithm, which is unbiased, together with a Mersenne
* twister random generator. This function is therefore more random than
* PHP's shuffle() function, and it is seedable. Additionally, it is
* UTF8 safe if the mb extension is available.
*
* @see http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
*
* @example $faker->shuffleString('hello, world'); // 'rlo,h eold!lw'
*
* @param string $string The set to shuffle
* @param string $encoding The string encoding (defaults to UTF-8)
*
* @return string The shuffled set
*/
public static function shuffleString($string = '', $encoding = 'UTF-8')
{
if (function_exists('mb_strlen')) {
// UTF8-safe str_split()
$array = [];
$strlen = mb_strlen($string, $encoding);
for ($i = 0; $i < $strlen; ++$i) {
$array[] = mb_substr($string, $i, 1, $encoding);
}
} else {
$array = str_split($string, 1);
}
return implode('', static::shuffleArray($array));
}
private static function replaceWildcard($string, $wildcard, $callback)
{
if (($pos = strpos($string, $wildcard)) === false) {
return $string;
}
for ($i = $pos, $last = strrpos($string, $wildcard, $pos) + 1; $i < $last; ++$i) {
if ($string[$i] === $wildcard) {
$string[$i] = call_user_func($callback);
}
}
return $string;
}
/**
* Replaces all hash sign ('#') occurrences with a random number
* Replaces all percentage sign ('%') occurrences with a not null number
*
* @param string $string String that needs to bet parsed
*
* @return string
*/
public static function numerify($string = '###')
{
// instead of using randomDigit() several times, which is slow,
// count the number of hashes and generate once a large number
$toReplace = [];
if (($pos = strpos($string, '#')) !== false) {
for ($i = $pos, $last = strrpos($string, '#', $pos) + 1; $i < $last; ++$i) {
if ($string[$i] === '#') {
$toReplace[] = $i;
}
}
}
if ($nbReplacements = count($toReplace)) {
$maxAtOnce = strlen((string) mt_getrandmax()) - 1;
$numbers = '';
$i = 0;
while ($i < $nbReplacements) {
$size = min($nbReplacements - $i, $maxAtOnce);
$numbers .= str_pad(static::randomNumber($size), $size, '0', STR_PAD_LEFT);
$i += $size;
}
for ($i = 0; $i < $nbReplacements; ++$i) {
$string[$toReplace[$i]] = $numbers[$i];
}
}
$string = self::replaceWildcard($string, '%', [static::class, 'randomDigitNotNull']);
return $string;
}
/**
* Replaces all question mark ('?') occurrences with a random letter
*
* @param string $string String that needs to bet parsed
*
* @return string
*/
public static function lexify($string = '????')
{
return self::replaceWildcard($string, '?', [static::class, 'randomLetter']);
}
/**
* Replaces hash signs ('#') and question marks ('?') with random numbers and letters
* An asterisk ('*') is replaced with either a random number or a random letter
*
* @param string $string String that needs to be parsed
*
* @return string
*/
public static function bothify($string = '## ??')
{
$string = self::replaceWildcard($string, '*', static function () {
return mt_rand(0, 1) === 1 ? '#' : '?';
});
return static::lexify(static::numerify($string));
}
/**
* Replaces * signs with random numbers and letters and special characters
*
* @example $faker->asciify(''********'); // "s5'G!uC3"
*
* @param string $string String that needs to bet parsed
*
* @return string
*/
public static function asciify($string = '****')
{
return preg_replace_callback('/\*/u', [static::class, 'randomAscii'], $string);
}
/**
* Transforms a basic regular expression into a random string satisfying the expression.
*
* @example $faker->regexify('[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}'); // sm0@y8k96a.ej
*
* Regex delimiters '/.../' and begin/end markers '^...$' are ignored.
*
* Only supports a small subset of the regex syntax. For instance,
* unicode, negated classes, unbounded ranges, subpatterns, back references,
* assertions, recursive patterns, and comments are not supported. Escaping
* support is extremely fragile.
*
* This method is also VERY slow. Use it only when no other formatter
* can generate the fake data you want. For instance, prefer calling
* `$faker->email` rather than `regexify` with the previous regular
* expression.
*
* Also note than `bothify` can probably do most of what this method does,
* but much faster. For instance, for a dummy email generation, try
* `$faker->bothify('?????????@???.???')`.
*
* @see https://github.com/icomefromthenet/ReverseRegex for a more robust implementation
*
* @param string $regex A regular expression (delimiters are optional)
*
* @return string
*/
public static function regexify($regex = '')
{
// ditch the anchors
$regex = preg_replace('/^\/?\^?/', '', $regex);
$regex = preg_replace('/\$?\/?$/', '', $regex);
// All {2} become {2,2}
$regex = preg_replace('/\{(\d+)\}/', '{\1,\1}', $regex);
// Single-letter quantifiers (?, *, +) become bracket quantifiers ({0,1}, {0,rand}, {1, rand})
$regex = preg_replace('/(?<!\\\)\?/', '{0,1}', $regex);
$regex = preg_replace('/(?<!\\\)\*/', '{0,' . static::randomDigitNotNull() . '}', $regex);
$regex = preg_replace('/(?<!\\\)\+/', '{1,' . static::randomDigitNotNull() . '}', $regex);
// [12]{1,2} becomes [12] or [12][12]
$regex = preg_replace_callback('/(\[[^\]]+\])\{(\d+),(\d+)\}/', static function ($matches) {
return str_repeat($matches[1], Base::randomElement(range($matches[2], $matches[3])));
}, $regex);
// (12|34){1,2} becomes (12|34) or (12|34)(12|34)
$regex = preg_replace_callback('/(\([^\)]+\))\{(\d+),(\d+)\}/', static function ($matches) {
return str_repeat($matches[1], Base::randomElement(range($matches[2], $matches[3])));
}, $regex);
// A{1,2} becomes A or AA or \d{3} becomes \d\d\d
$regex = preg_replace_callback('/(\\\?.)\{(\d+),(\d+)\}/', static function ($matches) {
return str_repeat($matches[1], Base::randomElement(range($matches[2], $matches[3])));
}, $regex);
// (this|that) becomes 'this' or 'that'
$regex = preg_replace_callback('/\((.*?)\)/', static function ($matches) {
return Base::randomElement(explode('|', str_replace(['(', ')'], '', $matches[1])));
}, $regex);
// All A-F inside of [] become ABCDEF
$regex = preg_replace_callback('/\[([^\]]+)\]/', static function ($matches) {
return '[' . preg_replace_callback('/(\w|\d)\-(\w|\d)/', static function ($range) {
return implode('', range($range[1], $range[2]));
}, $matches[1]) . ']';
}, $regex);
// All [ABC] become B (or A or C)
$regex = preg_replace_callback('/\[([^\]]+)\]/', static function ($matches) {
// remove backslashes (that are not followed by another backslash) because they are escape characters
$match = preg_replace('/\\\(?!\\\)/', '', $matches[1]);
$randomElement = Base::randomElement(str_split($match));
//[.] should not be a random character, but a literal .
return str_replace('.', '\.', $randomElement);
}, $regex);
// replace \d with number and \w with letter and . with ascii
$regex = preg_replace_callback('/\\\w/', [static::class, 'randomLetter'], $regex);
$regex = preg_replace_callback('/\\\d/', [static::class, 'randomDigit'], $regex);
//replace . with ascii except backslash
$regex = preg_replace_callback('/(?<!\\\)\./', static function () {
$chr = static::asciify('*');
if ($chr === '\\') {
$chr .= '\\';
}
return $chr;
}, $regex);
// remove remaining single backslashes
$regex = str_replace('\\\\', '[:escaped_backslash:]', $regex);
$regex = str_replace('\\', '', $regex);
$regex = str_replace('[:escaped_backslash:]', '\\', $regex);
// phew
return $regex;
}
/**
* Converts string to lowercase.
* Uses mb_string extension if available.
*
* @param string $string String that should be converted to lowercase
*
* @return string
*/
public static function toLower($string = '')
{
return extension_loaded('mbstring') ? mb_strtolower($string, 'UTF-8') : strtolower($string);
}
/**
* Converts string to uppercase.
* Uses mb_string extension if available.
*
* @param string $string String that should be converted to uppercase
*
* @return string
*/
public static function toUpper($string = '')
{
return extension_loaded('mbstring') ? mb_strtoupper($string, 'UTF-8') : strtoupper($string);
}
/**
* Chainable method for making any formatter optional.
*
* @param float|int $weight Set the probability of receiving a null value.
* "0" will always return null, "1" will always return the generator.
* If $weight is an integer value, then the same system works
* between 0 (always get false) and 100 (always get true).
*
* @return mixed|null
*/
public function optional($weight = 0.5, $default = null)
{
// old system based on 0.1 <= $weight <= 0.9
// TODO: remove in v2
if ($weight > 0 && $weight < 1 && mt_rand() / mt_getrandmax() <= $weight) {
return $this->generator;
}
// new system with percentage
if (is_int($weight) && mt_rand(1, 100) <= $weight) {
return $this->generator;
}
return new DefaultGenerator($default);
}
/**
* Chainable method for making any formatter unique.
*
* <code>
* // will never return twice the same value
* $faker->unique()->randomElement(array(1, 2, 3));
* </code>
*
* @param bool $reset If set to true, resets the list of existing values
* @param int $maxRetries Maximum number of retries to find a unique value,
* After which an OverflowException is thrown.
*
* @throws \OverflowException When no unique value can be found by iterating $maxRetries times
*
* @return UniqueGenerator A proxy class returning only non-existing values
*/
public function unique($reset = false, $maxRetries = 10000)
{
if ($reset || !$this->unique) {
$this->unique = new UniqueGenerator($this->generator, $maxRetries);
}
return $this->unique;
}
/**
* Chainable method for forcing any formatter to return only valid values.
*
* The value validity is determined by a function passed as first argument.
*
* <code>
* $values = array();
* $evenValidator = function ($digit) {
* return $digit % 2 === 0;
* };
* for ($i=0; $i < 10; $i++) {
* $values []= $faker->valid($evenValidator)->randomDigit;
* }
* print_r($values); // [0, 4, 8, 4, 2, 6, 0, 8, 8, 6]
* </code>
*
* @param Closure $validator A function returning true for valid values
* @param int $maxRetries Maximum number of retries to find a unique value,
* After which an OverflowException is thrown.
*
* @throws \OverflowException When no valid value can be found by iterating $maxRetries times
*
* @return ValidGenerator A proxy class returning only valid values
*/
public function valid($validator = null, $maxRetries = 10000)
{
return new ValidGenerator($this->generator, $validator, $maxRetries);
}
}
-65
View File
@@ -1,65 +0,0 @@
<?php
namespace Faker\Provider;
class Biased extends Base
{
/**
* Returns a biased integer between $min and $max (both inclusive).
* The distribution depends on $function.
*
* The algorithm creates two doubles, x ∈ [0, 1], y ∈ [0, 1) and checks whether the
* return value of $function for x is greater than or equal to y. If this is
* the case the number is accepted and x is mapped to the appropriate integer
* between $min and $max. Otherwise two new doubles are created until the pair
* is accepted.
*
* @param int $min Minimum value of the generated integers.
* @param int $max Maximum value of the generated integers.
* @param callable $function A function mapping x ∈ [0, 1] onto a double ∈ [0, 1]
*
* @return int An integer between $min and $max.
*/
public function biasedNumberBetween($min = 0, $max = 100, $function = 'sqrt')
{
do {
$x = mt_rand() / mt_getrandmax();
$y = mt_rand() / (mt_getrandmax() + 1);
} while (call_user_func($function, $x) < $y);
return (int) floor($x * ($max - $min + 1) + $min);
}
/**
* 'unbiased' creates an unbiased distribution by giving
* each value the same value of one.
*
* @return int
*/
protected static function unbiased()
{
return 1;
}
/**
* 'linearLow' favors lower numbers. The probability decreases
* in a linear fashion.
*
* @return int
*/
protected static function linearLow($x)
{
return 1 - $x;
}
/**
* 'linearHigh' favors higher numbers. The probability increases
* in a linear fashion.
*
* @return int
*/
protected static function linearHigh($x)
{
return $x;
}
}
-158
View File
@@ -1,158 +0,0 @@
<?php
namespace Faker\Provider;
class Color extends Base
{
protected static $safeColorNames = [
'black', 'maroon', 'green', 'navy', 'olive',
'purple', 'teal', 'lime', 'blue', 'silver',
'gray', 'yellow', 'fuchsia', 'aqua', 'white',
];
protected static $allColorNames = [
'AliceBlue', 'AntiqueWhite', 'Aqua', 'Aquamarine',
'Azure', 'Beige', 'Bisque', 'Black', 'BlanchedAlmond',
'Blue', 'BlueViolet', 'Brown', 'BurlyWood', 'CadetBlue',
'Chartreuse', 'Chocolate', 'Coral', 'CornflowerBlue',
'Cornsilk', 'Crimson', 'Cyan', 'DarkBlue', 'DarkCyan',
'DarkGoldenRod', 'DarkGray', 'DarkGreen', 'DarkKhaki',
'DarkMagenta', 'DarkOliveGreen', 'Darkorange', 'DarkOrchid',
'DarkRed', 'DarkSalmon', 'DarkSeaGreen', 'DarkSlateBlue',
'DarkSlateGray', 'DarkTurquoise', 'DarkViolet', 'DeepPink',
'DeepSkyBlue', 'DimGray', 'DimGrey', 'DodgerBlue', 'FireBrick',
'FloralWhite', 'ForestGreen', 'Fuchsia', 'Gainsboro', 'GhostWhite',
'Gold', 'GoldenRod', 'Gray', 'Green', 'GreenYellow', 'HoneyDew',
'HotPink', 'IndianRed', 'Indigo', 'Ivory', 'Khaki', 'Lavender',
'LavenderBlush', 'LawnGreen', 'LemonChiffon', 'LightBlue', 'LightCoral',
'LightCyan', 'LightGoldenRodYellow', 'LightGray', 'LightGreen', 'LightPink',
'LightSalmon', 'LightSeaGreen', 'LightSkyBlue', 'LightSlateGray', 'LightSteelBlue',
'LightYellow', 'Lime', 'LimeGreen', 'Linen', 'Magenta', 'Maroon', 'MediumAquaMarine',
'MediumBlue', 'MediumOrchid', 'MediumPurple', 'MediumSeaGreen', 'MediumSlateBlue',
'MediumSpringGreen', 'MediumTurquoise', 'MediumVioletRed', 'MidnightBlue',
'MintCream', 'MistyRose', 'Moccasin', 'NavajoWhite', 'Navy', 'OldLace', 'Olive',
'OliveDrab', 'Orange', 'OrangeRed', 'Orchid', 'PaleGoldenRod', 'PaleGreen',
'PaleTurquoise', 'PaleVioletRed', 'PapayaWhip', 'PeachPuff', 'Peru', 'Pink', 'Plum',
'PowderBlue', 'Purple', 'Red', 'RosyBrown', 'RoyalBlue', 'SaddleBrown', 'Salmon',
'SandyBrown', 'SeaGreen', 'SeaShell', 'Sienna', 'Silver', 'SkyBlue', 'SlateBlue',
'SlateGray', 'Snow', 'SpringGreen', 'SteelBlue', 'Tan', 'Teal', 'Thistle', 'Tomato',
'Turquoise', 'Violet', 'Wheat', 'White', 'WhiteSmoke', 'Yellow', 'YellowGreen',
];
/**
* @example '#fa3cc2'
*
* @return string
*/
public static function hexColor()
{
return '#' . str_pad(dechex(self::numberBetween(1, 16777215)), 6, '0', STR_PAD_LEFT);
}
/**
* @example '#ff0044'
*
* @return string
*/
public static function safeHexColor()
{
$color = str_pad(dechex(self::numberBetween(0, 255)), 3, '0', STR_PAD_LEFT);
return '#' . $color[0] . $color[0] . $color[1] . $color[1] . $color[2] . $color[2];
}
/**
* @example 'array(0,255,122)'
*
* @return array
*/
public static function rgbColorAsArray()
{
$color = static::hexColor();
return [
hexdec(substr($color, 1, 2)),
hexdec(substr($color, 3, 2)),
hexdec(substr($color, 5, 2)),
];
}
/**
* @example '0,255,122'
*
* @return string
*/
public static function rgbColor()
{
return implode(',', static::rgbColorAsArray());
}
/**
* @example 'rgb(0,255,122)'
*
* @return string
*/
public static function rgbCssColor()
{
return 'rgb(' . static::rgbColor() . ')';
}
/**
* @example 'rgba(0,255,122,0.8)'
*
* @return string
*/
public static function rgbaCssColor()
{
return 'rgba(' . static::rgbColor() . ',' . static::randomFloat(1, 0, 1) . ')';
}
/**
* @example 'blue'
*
* @return string
*/
public static function safeColorName()
{
return static::randomElement(static::$safeColorNames);
}
/**
* @example 'NavajoWhite'
*
* @return string
*/
public static function colorName()
{
return static::randomElement(static::$allColorNames);
}
/**
* @example '340,50,20'
*
* @return string
*/
public static function hslColor()
{
return sprintf(
'%s,%s,%s',
self::numberBetween(0, 360),
self::numberBetween(0, 100),
self::numberBetween(0, 100),
);
}
/**
* @example array(340, 50, 20)
*
* @return array
*/
public static function hslColorAsArray()
{
return [
self::numberBetween(0, 360),
self::numberBetween(0, 100),
self::numberBetween(0, 100),
];
}
}
-50
View File
@@ -1,50 +0,0 @@
<?php
namespace Faker\Provider;
class Company extends Base
{
protected static $formats = [
'{{lastName}} {{companySuffix}}',
];
protected static $companySuffix = ['Ltd'];
protected static $jobTitleFormat = [
'{{word}}',
];
/**
* @example 'Acme Ltd'
*
* @return string
*/
public function company()
{
$format = static::randomElement(static::$formats);
return $this->generator->parse($format);
}
/**
* @example 'Ltd'
*
* @return string
*/
public static function companySuffix()
{
return static::randomElement(static::$companySuffix);
}
/**
* @example 'Job'
*
* @return string
*/
public function jobTitle()
{
$format = static::randomElement(static::$jobTitleFormat);
return $this->generator->parse($format);
}
}
-389
View File
@@ -1,389 +0,0 @@
<?php
namespace Faker\Provider;
class DateTime extends Base
{
protected static $century = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII', 'XIII', 'XIV', 'XV', 'XVI', 'XVII', 'XVIII', 'XIX', 'XX', 'XXI'];
protected static $defaultTimezone = null;
/**
* @param \DateTime|float|int|string $max
*
* @return false|int
*/
protected static function getMaxTimestamp($max = 'now')
{
if (is_numeric($max)) {
return (int) $max;
}
if ($max instanceof \DateTime) {
return $max->getTimestamp();
}
return strtotime(empty($max) ? 'now' : $max);
}
/**
* Get a timestamp between January 1, 1970, and now
*
* @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now"
*
* @return int
*
* @example 1061306726
*/
public static function unixTime($max = 'now')
{
return self::numberBetween(0, static::getMaxTimestamp($max));
}
/**
* Get a datetime object for a date between January 1, 1970 and now
*
* @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now"
* @param string $timezone time zone in which the date time should be set, default to DateTime::$defaultTimezone, if set, otherwise the result of `date_default_timezone_get`
*
* @return \DateTime
*
* @see http://php.net/manual/en/timezones.php
* @see http://php.net/manual/en/function.date-default-timezone-get.php
*
* @example DateTime('2005-08-16 20:39:21')
*/
public static function dateTime($max = 'now', $timezone = null)
{
return static::setTimezone(
new \DateTime('@' . static::unixTime($max)),
$timezone,
);
}
/**
* Get a datetime object for a date between January 1, 001 and now
*
* @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now"
* @param string|null $timezone time zone in which the date time should be set, default to DateTime::$defaultTimezone, if set, otherwise the result of `date_default_timezone_get`
*
* @return \DateTime
*
* @see http://php.net/manual/en/timezones.php
* @see http://php.net/manual/en/function.date-default-timezone-get.php
*
* @example DateTime('1265-03-22 21:15:52')
*/
public static function dateTimeAD($max = 'now', $timezone = null)
{
$min = (PHP_INT_SIZE > 4 ? -62135597361 : -PHP_INT_MAX);
return static::setTimezone(
new \DateTime('@' . self::numberBetween($min, static::getMaxTimestamp($max))),
$timezone,
);
}
/**
* get a date string formatted with ISO8601
*
* @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now"
*
* @return string
*
* @example '2003-10-21T16:05:52+0000'
*/
public static function iso8601($max = 'now')
{
return static::date(\DateTime::ISO8601, $max);
}
/**
* Get a date string between January 1, 1970 and now
*
* @param string $format
* @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now"
*
* @return string
*
* @example '2008-11-27'
*/
public static function date($format = 'Y-m-d', $max = 'now')
{
return static::dateTime($max)->format($format);
}
/**
* Get a time string (24h format by default)
*
* @param string $format
* @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now"
*
* @return string
*
* @example '15:02:34'
*/
public static function time($format = 'H:i:s', $max = 'now')
{
return static::dateTime($max)->format($format);
}
/**
* Get a DateTime object based on a random date between two given dates.
* Accepts date strings that can be recognized by strtotime().
*
* @param \DateTime|string $startDate Defaults to 30 years ago
* @param \DateTime|string $endDate Defaults to "now"
* @param string|null $timezone time zone in which the date time should be set, default to DateTime::$defaultTimezone, if set, otherwise the result of `date_default_timezone_get`
*
* @return \DateTime
*
* @see http://php.net/manual/en/timezones.php
* @see http://php.net/manual/en/function.date-default-timezone-get.php
*
* @example DateTime('1999-02-02 11:42:52')
*/
public static function dateTimeBetween($startDate = '-30 years', $endDate = 'now', $timezone = null)
{
$startTimestamp = $startDate instanceof \DateTime ? $startDate->getTimestamp() : strtotime($startDate);
$endTimestamp = static::getMaxTimestamp($endDate);
if ($startTimestamp > $endTimestamp) {
throw new \InvalidArgumentException('Start date must be anterior to end date.');
}
$timestamp = self::numberBetween($startTimestamp, $endTimestamp);
return static::setTimezone(
new \DateTime('@' . $timestamp),
$timezone,
);
}
/**
* Get a DateTime object based on a random date between one given date and
* an interval
* Accepts date string that can be recognized by strtotime().
*
* @param \DateTime|string $date Defaults to 30 years ago
* @param string $interval Defaults to 5 days after
* @param string|null $timezone time zone in which the date time should be set, default to DateTime::$defaultTimezone, if set, otherwise the result of `date_default_timezone_get`
*
* @return \DateTime
*
* @example dateTimeInInterval('1999-02-02 11:42:52', '+ 5 days')
*
* @see http://php.net/manual/en/timezones.php
* @see http://php.net/manual/en/function.date-default-timezone-get.php
*/
public static function dateTimeInInterval($date = '-30 years', $interval = '+5 days', $timezone = null)
{
$intervalObject = \DateInterval::createFromDateString($interval);
$datetime = $date instanceof \DateTime ? $date : new \DateTime($date);
$otherDatetime = clone $datetime;
$otherDatetime->add($intervalObject);
$begin = min($datetime, $otherDatetime);
$end = $datetime === $begin ? $otherDatetime : $datetime;
return static::dateTimeBetween(
$begin,
$end,
$timezone,
);
}
/**
* Get a date time object somewhere within a century.
*
* @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now"
* @param string|null $timezone time zone in which the date time should be set, default to DateTime::$defaultTimezone, if set, otherwise the result of `date_default_timezone_get`
*
* @return \DateTime
*/
public static function dateTimeThisCentury($max = 'now', $timezone = null)
{
return static::dateTimeBetween('-100 year', $max, $timezone);
}
/**
* Get a date time object somewhere within a decade.
*
* @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now"
* @param string|null $timezone time zone in which the date time should be set, default to DateTime::$defaultTimezone, if set, otherwise the result of `date_default_timezone_get`
*
* @return \DateTime
*/
public static function dateTimeThisDecade($max = 'now', $timezone = null)
{
return static::dateTimeBetween('-10 year', $max, $timezone);
}
/**
* Get a date time object somewhere inside the current year.
*
* @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now"
* @param string|null $timezone time zone in which the date time should be set, default to DateTime::$defaultTimezone, if set, otherwise the result of `date_default_timezone_get`
*
* @return \DateTime
*/
public static function dateTimeThisYear($max = 'now', $timezone = null)
{
return static::dateTimeBetween('first day of january this year', $max, $timezone);
}
/**
* Get a date time object somewhere within a month.
*
* @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now"
* @param string|null $timezone time zone in which the date time should be set, default to DateTime::$defaultTimezone, if set, otherwise the result of `date_default_timezone_get`
*
* @return \DateTime
*/
public static function dateTimeThisMonth($max = 'now', $timezone = null)
{
return static::dateTimeBetween('-1 month', $max, $timezone);
}
/**
* Get a string containing either "am" or "pm".
*
* @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now"
*
* @return string
*
* @example 'am'
*/
public static function amPm($max = 'now')
{
return static::dateTime($max)->format('a');
}
/**
* @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now"
*
* @return string
*
* @example '22'
*/
public static function dayOfMonth($max = 'now')
{
return static::dateTime($max)->format('d');
}
/**
* @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now"
*
* @return string
*
* @example 'Tuesday'
*/
public static function dayOfWeek($max = 'now')
{
return static::dateTime($max)->format('l');
}
/**
* @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now"
*
* @return string
*
* @example '7'
*/
public static function month($max = 'now')
{
return static::dateTime($max)->format('m');
}
/**
* @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now"
*
* @return string
*
* @example 'September'
*/
public static function monthName($max = 'now')
{
return static::dateTime($max)->format('F');
}
/**
* @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now"
*
* @return string
*
* @example '1987'
*/
public static function year($max = 'now')
{
return static::dateTime($max)->format('Y');
}
/**
* @return string
*
* @example 'XVII'
*/
public static function century()
{
return static::randomElement(static::$century);
}
/**
* @return string
*
* @example 'Europe/Paris'
*/
public static function timezone(?string $countryCode = null)
{
if ($countryCode) {
$timezones = \DateTimeZone::listIdentifiers(\DateTimeZone::PER_COUNTRY, $countryCode);
} else {
$timezones = \DateTimeZone::listIdentifiers();
}
return static::randomElement($timezones);
}
/**
* Internal method to set the time zone on a DateTime.
*
* @param string|null $timezone
*
* @return \DateTime
*/
private static function setTimezone(\DateTime $dt, $timezone)
{
return $dt->setTimezone(new \DateTimeZone(static::resolveTimezone($timezone)));
}
/**
* Sets default time zone.
*
* @param string $timezone
*/
public static function setDefaultTimezone($timezone = null)
{
static::$defaultTimezone = $timezone;
}
/**
* Gets default time zone.
*
* @return string|null
*/
public static function getDefaultTimezone()
{
return static::$defaultTimezone;
}
/**
* @param string|null $timezone
*
* @return string|null
*/
private static function resolveTimezone($timezone)
{
return (null === $timezone) ? ((null === static::$defaultTimezone) ? date_default_timezone_get() : static::$defaultTimezone) : $timezone;
}
}
-610
View File
@@ -1,610 +0,0 @@
<?php
namespace Faker\Provider;
class File extends Base
{
/**
* MIME types from the apache.org file. Some types are truncated.
*
* @var array Map of MIME types => file extension(s)
*
* @see http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
*/
protected static $mimeTypes = [
'application/atom+xml' => 'atom',
'application/ecmascript' => 'ecma',
'application/emma+xml' => 'emma',
'application/epub+zip' => 'epub',
'application/java-archive' => 'jar',
'application/java-vm' => 'class',
'application/javascript' => 'js',
'application/json' => 'json',
'application/jsonml+json' => 'jsonml',
'application/lost+xml' => 'lostxml',
'application/mathml+xml' => 'mathml',
'application/mets+xml' => 'mets',
'application/mods+xml' => 'mods',
'application/mp4' => 'mp4s',
'application/msword' => ['doc', 'dot'],
'application/octet-stream' => [
'bin',
'dms',
'lrf',
'mar',
'so',
'dist',
'distz',
'pkg',
'bpk',
'dump',
'elc',
'deploy',
],
'application/ogg' => 'ogx',
'application/omdoc+xml' => 'omdoc',
'application/pdf' => 'pdf',
'application/pgp-encrypted' => 'pgp',
'application/pgp-signature' => ['asc', 'sig'],
'application/pkix-pkipath' => 'pkipath',
'application/pkixcmp' => 'pki',
'application/pls+xml' => 'pls',
'application/postscript' => ['ai', 'eps', 'ps'],
'application/pskc+xml' => 'pskcxml',
'application/rdf+xml' => 'rdf',
'application/reginfo+xml' => 'rif',
'application/rss+xml' => 'rss',
'application/rtf' => 'rtf',
'application/sbml+xml' => 'sbml',
'application/vnd.adobe.air-application-installer-package+zip' => 'air',
'application/vnd.adobe.xdp+xml' => 'xdp',
'application/vnd.adobe.xfdf' => 'xfdf',
'application/vnd.ahead.space' => 'ahead',
'application/vnd.dart' => 'dart',
'application/vnd.data-vision.rdz' => 'rdz',
'application/vnd.dece.data' => ['uvf', 'uvvf', 'uvd', 'uvvd'],
'application/vnd.dece.ttml+xml' => ['uvt', 'uvvt'],
'application/vnd.dece.unspecified' => ['uvx', 'uvvx'],
'application/vnd.dece.zip' => ['uvz', 'uvvz'],
'application/vnd.denovo.fcselayout-link' => 'fe_launch',
'application/vnd.dna' => 'dna',
'application/vnd.dolby.mlp' => 'mlp',
'application/vnd.dpgraph' => 'dpg',
'application/vnd.dreamfactory' => 'dfac',
'application/vnd.ds-keypoint' => 'kpxx',
'application/vnd.dvb.ait' => 'ait',
'application/vnd.dvb.service' => 'svc',
'application/vnd.dynageo' => 'geo',
'application/vnd.ecowin.chart' => 'mag',
'application/vnd.enliven' => 'nml',
'application/vnd.epson.esf' => 'esf',
'application/vnd.epson.msf' => 'msf',
'application/vnd.epson.quickanime' => 'qam',
'application/vnd.epson.salt' => 'slt',
'application/vnd.epson.ssf' => 'ssf',
'application/vnd.ezpix-album' => 'ez2',
'application/vnd.ezpix-package' => 'ez3',
'application/vnd.fdf' => 'fdf',
'application/vnd.fdsn.mseed' => 'mseed',
'application/vnd.fdsn.seed' => ['seed', 'dataless'],
'application/vnd.flographit' => 'gph',
'application/vnd.fluxtime.clip' => 'ftc',
'application/vnd.hal+xml' => 'hal',
'application/vnd.hydrostatix.sof-data' => 'sfd-hdstx',
'application/vnd.ibm.minipay' => 'mpy',
'application/vnd.ibm.secure-container' => 'sc',
'application/vnd.iccprofile' => ['icc', 'icm'],
'application/vnd.igloader' => 'igl',
'application/vnd.immervision-ivp' => 'ivp',
'application/vnd.kde.karbon' => 'karbon',
'application/vnd.kde.kchart' => 'chrt',
'application/vnd.kde.kformula' => 'kfo',
'application/vnd.kde.kivio' => 'flw',
'application/vnd.kde.kontour' => 'kon',
'application/vnd.kde.kpresenter' => ['kpr', 'kpt'],
'application/vnd.kde.kspread' => 'ksp',
'application/vnd.kde.kword' => ['kwd', 'kwt'],
'application/vnd.kenameaapp' => 'htke',
'application/vnd.kidspiration' => 'kia',
'application/vnd.kinar' => ['kne', 'knp'],
'application/vnd.koan' => ['skp', 'skd', 'skt', 'skm'],
'application/vnd.kodak-descriptor' => 'sse',
'application/vnd.las.las+xml' => 'lasxml',
'application/vnd.llamagraphics.life-balance.desktop' => 'lbd',
'application/vnd.llamagraphics.life-balance.exchange+xml' => 'lbe',
'application/vnd.lotus-1-2-3' => '123',
'application/vnd.lotus-approach' => 'apr',
'application/vnd.lotus-freelance' => 'pre',
'application/vnd.lotus-notes' => 'nsf',
'application/vnd.lotus-organizer' => 'org',
'application/vnd.lotus-screencam' => 'scm',
'application/vnd.mozilla.xul+xml' => 'xul',
'application/vnd.ms-artgalry' => 'cil',
'application/vnd.ms-cab-compressed' => 'cab',
'application/vnd.ms-excel' => [
'xls',
'xlm',
'xla',
'xlc',
'xlt',
'xlw',
],
'application/vnd.ms-excel.addin.macroenabled.12' => 'xlam',
'application/vnd.ms-excel.sheet.binary.macroenabled.12' => 'xlsb',
'application/vnd.ms-excel.sheet.macroenabled.12' => 'xlsm',
'application/vnd.ms-excel.template.macroenabled.12' => 'xltm',
'application/vnd.ms-fontobject' => 'eot',
'application/vnd.ms-htmlhelp' => 'chm',
'application/vnd.ms-ims' => 'ims',
'application/vnd.ms-lrm' => 'lrm',
'application/vnd.ms-officetheme' => 'thmx',
'application/vnd.ms-pki.seccat' => 'cat',
'application/vnd.ms-pki.stl' => 'stl',
'application/vnd.ms-powerpoint' => ['ppt', 'pps', 'pot'],
'application/vnd.ms-powerpoint.addin.macroenabled.12' => 'ppam',
'application/vnd.ms-powerpoint.presentation.macroenabled.12' => 'pptm',
'application/vnd.ms-powerpoint.slide.macroenabled.12' => 'sldm',
'application/vnd.ms-powerpoint.slideshow.macroenabled.12' => 'ppsm',
'application/vnd.ms-powerpoint.template.macroenabled.12' => 'potm',
'application/vnd.ms-project' => ['mpp', 'mpt'],
'application/vnd.ms-word.document.macroenabled.12' => 'docm',
'application/vnd.ms-word.template.macroenabled.12' => 'dotm',
'application/vnd.ms-works' => ['wps', 'wks', 'wcm', 'wdb'],
'application/vnd.ms-wpl' => 'wpl',
'application/vnd.ms-xpsdocument' => 'xps',
'application/vnd.mseq' => 'mseq',
'application/vnd.musician' => 'mus',
'application/vnd.oasis.opendocument.chart' => 'odc',
'application/vnd.oasis.opendocument.chart-template' => 'otc',
'application/vnd.oasis.opendocument.database' => 'odb',
'application/vnd.oasis.opendocument.formula' => 'odf',
'application/vnd.oasis.opendocument.formula-template' => 'odft',
'application/vnd.oasis.opendocument.graphics' => 'odg',
'application/vnd.oasis.opendocument.graphics-template' => 'otg',
'application/vnd.oasis.opendocument.image' => 'odi',
'application/vnd.oasis.opendocument.image-template' => 'oti',
'application/vnd.oasis.opendocument.presentation' => 'odp',
'application/vnd.oasis.opendocument.presentation-template' => 'otp',
'application/vnd.oasis.opendocument.spreadsheet' => 'ods',
'application/vnd.oasis.opendocument.spreadsheet-template' => 'ots',
'application/vnd.oasis.opendocument.text' => 'odt',
'application/vnd.oasis.opendocument.text-master' => 'odm',
'application/vnd.oasis.opendocument.text-template' => 'ott',
'application/vnd.oasis.opendocument.text-web' => 'oth',
'application/vnd.olpc-sugar' => 'xo',
'application/vnd.oma.dd2+xml' => 'dd2',
'application/vnd.openofficeorg.extension' => 'oxt',
'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'pptx',
'application/vnd.openxmlformats-officedocument.presentationml.slide' => 'sldx',
'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => 'ppsx',
'application/vnd.openxmlformats-officedocument.presentationml.template' => 'potx',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'xlsx',
'application/vnd.openxmlformats-officedocument.spreadsheetml.template' => 'xltx',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx',
'application/vnd.openxmlformats-officedocument.wordprocessingml.template' => 'dotx',
'application/vnd.pvi.ptid1' => 'ptid',
'application/vnd.quark.quarkxpress' => [
'qxd',
'qxt',
'qwd',
'qwt',
'qxl',
'qxb',
],
'application/vnd.realvnc.bed' => 'bed',
'application/vnd.recordare.musicxml' => 'mxl',
'application/vnd.recordare.musicxml+xml' => 'musicxml',
'application/vnd.rig.cryptonote' => 'cryptonote',
'application/vnd.rim.cod' => 'cod',
'application/vnd.rn-realmedia' => 'rm',
'application/vnd.rn-realmedia-vbr' => 'rmvb',
'application/vnd.route66.link66+xml' => 'link66',
'application/vnd.sailingtracker.track' => 'st',
'application/vnd.seemail' => 'see',
'application/vnd.sema' => 'sema',
'application/vnd.semd' => 'semd',
'application/vnd.semf' => 'semf',
'application/vnd.shana.informed.formdata' => 'ifm',
'application/vnd.shana.informed.formtemplate' => 'itp',
'application/vnd.shana.informed.interchange' => 'iif',
'application/vnd.shana.informed.package' => 'ipk',
'application/vnd.simtech-mindmapper' => ['twd', 'twds'],
'application/vnd.smaf' => 'mmf',
'application/vnd.stepmania.stepchart' => 'sm',
'application/vnd.sun.xml.calc' => 'sxc',
'application/vnd.sun.xml.calc.template' => 'stc',
'application/vnd.sun.xml.draw' => 'sxd',
'application/vnd.sun.xml.draw.template' => 'std',
'application/vnd.sun.xml.impress' => 'sxi',
'application/vnd.sun.xml.impress.template' => 'sti',
'application/vnd.sun.xml.math' => 'sxm',
'application/vnd.sun.xml.writer' => 'sxw',
'application/vnd.sun.xml.writer.global' => 'sxg',
'application/vnd.sun.xml.writer.template' => 'stw',
'application/vnd.sus-calendar' => ['sus', 'susp'],
'application/vnd.svd' => 'svd',
'application/vnd.symbian.install' => ['sis', 'sisx'],
'application/vnd.syncml+xml' => 'xsm',
'application/vnd.syncml.dm+wbxml' => 'bdm',
'application/vnd.syncml.dm+xml' => 'xdm',
'application/vnd.tao.intent-module-archive' => 'tao',
'application/vnd.tcpdump.pcap' => ['pcap', 'cap', 'dmp'],
'application/vnd.tmobile-livetv' => 'tmo',
'application/vnd.trid.tpt' => 'tpt',
'application/vnd.triscape.mxs' => 'mxs',
'application/vnd.trueapp' => 'tra',
'application/vnd.ufdl' => ['ufd', 'ufdl'],
'application/vnd.uiq.theme' => 'utz',
'application/vnd.umajin' => 'umj',
'application/vnd.unity' => 'unityweb',
'application/vnd.uoml+xml' => 'uoml',
'application/vnd.vcx' => 'vcx',
'application/vnd.visio' => ['vsd', 'vst', 'vss', 'vsw'],
'application/vnd.visionary' => 'vis',
'application/vnd.vsf' => 'vsf',
'application/vnd.wap.wbxml' => 'wbxml',
'application/vnd.wap.wmlc' => 'wmlc',
'application/vnd.wap.wmlscriptc' => 'wmlsc',
'application/vnd.webturbo' => 'wtb',
'application/vnd.wolfram.player' => 'nbp',
'application/vnd.wordperfect' => 'wpd',
'application/vnd.wqd' => 'wqd',
'application/vnd.wt.stf' => 'stf',
'application/vnd.xara' => 'xar',
'application/vnd.xfdl' => 'xfdl',
'application/voicexml+xml' => 'vxml',
'application/widget' => 'wgt',
'application/winhlp' => 'hlp',
'application/wsdl+xml' => 'wsdl',
'application/wspolicy+xml' => 'wspolicy',
'application/x-7z-compressed' => '7z',
'application/x-bittorrent' => 'torrent',
'application/x-blorb' => ['blb', 'blorb'],
'application/x-bzip' => 'bz',
'application/x-cdlink' => 'vcd',
'application/x-cfs-compressed' => 'cfs',
'application/x-chat' => 'chat',
'application/x-chess-pgn' => 'pgn',
'application/x-conference' => 'nsc',
'application/x-cpio' => 'cpio',
'application/x-csh' => 'csh',
'application/x-debian-package' => ['deb', 'udeb'],
'application/x-dgc-compressed' => 'dgc',
'application/x-director' => [
'dir',
'dcr',
'dxr',
'cst',
'cct',
'cxt',
'w3d',
'fgd',
'swa',
],
'application/x-font-ttf' => ['ttf', 'ttc'],
'application/x-font-type1' => ['pfa', 'pfb', 'pfm', 'afm'],
'application/x-font-woff' => 'woff',
'application/x-freearc' => 'arc',
'application/x-futuresplash' => 'spl',
'application/x-gca-compressed' => 'gca',
'application/x-glulx' => 'ulx',
'application/x-gnumeric' => 'gnumeric',
'application/x-gramps-xml' => 'gramps',
'application/x-gtar' => 'gtar',
'application/x-hdf' => 'hdf',
'application/x-install-instructions' => 'install',
'application/x-iso9660-image' => 'iso',
'application/x-java-jnlp-file' => 'jnlp',
'application/x-latex' => 'latex',
'application/x-lzh-compressed' => ['lzh', 'lha'],
'application/x-mie' => 'mie',
'application/x-mobipocket-ebook' => ['prc', 'mobi'],
'application/x-ms-application' => 'application',
'application/x-ms-shortcut' => 'lnk',
'application/x-ms-wmd' => 'wmd',
'application/x-ms-wmz' => 'wmz',
'application/x-ms-xbap' => 'xbap',
'application/x-msaccess' => 'mdb',
'application/x-msbinder' => 'obd',
'application/x-mscardfile' => 'crd',
'application/x-msclip' => 'clp',
'application/x-msdownload' => ['exe', 'dll', 'com', 'bat', 'msi'],
'application/x-msmediaview' => [
'mvb',
'm13',
'm14',
],
'application/x-msmetafile' => ['wmf', 'wmz', 'emf', 'emz'],
'application/x-rar-compressed' => 'rar',
'application/x-research-info-systems' => 'ris',
'application/x-sh' => 'sh',
'application/x-shar' => 'shar',
'application/x-shockwave-flash' => 'swf',
'application/x-silverlight-app' => 'xap',
'application/x-sql' => 'sql',
'application/x-stuffit' => 'sit',
'application/x-stuffitx' => 'sitx',
'application/x-subrip' => 'srt',
'application/x-sv4cpio' => 'sv4cpio',
'application/x-sv4crc' => 'sv4crc',
'application/x-t3vm-image' => 't3',
'application/x-tads' => 'gam',
'application/x-tar' => 'tar',
'application/x-tcl' => 'tcl',
'application/x-tex' => 'tex',
'application/x-tex-tfm' => 'tfm',
'application/x-texinfo' => ['texinfo', 'texi'],
'application/x-tgif' => 'obj',
'application/x-ustar' => 'ustar',
'application/x-wais-source' => 'src',
'application/x-x509-ca-cert' => ['der', 'crt'],
'application/x-xfig' => 'fig',
'application/x-xliff+xml' => 'xlf',
'application/x-xpinstall' => 'xpi',
'application/x-xz' => 'xz',
'application/x-zmachine' => 'z1',
'application/xaml+xml' => 'xaml',
'application/xcap-diff+xml' => 'xdf',
'application/xenc+xml' => 'xenc',
'application/xhtml+xml' => ['xhtml', 'xht'],
'application/xml' => ['xml', 'xsl'],
'application/xml-dtd' => 'dtd',
'application/xop+xml' => 'xop',
'application/xproc+xml' => 'xpl',
'application/xslt+xml' => 'xslt',
'application/xspf+xml' => 'xspf',
'application/xv+xml' => ['mxml', 'xhvml', 'xvml', 'xvm'],
'application/yang' => 'yang',
'application/yin+xml' => 'yin',
'application/zip' => 'zip',
'audio/adpcm' => 'adp',
'audio/basic' => ['au', 'snd'],
'audio/midi' => ['mid', 'midi', 'kar', 'rmi'],
'audio/mp4' => 'mp4a',
'audio/mpeg' => [
'mpga',
'mp2',
'mp2a',
'mp3',
'm2a',
'm3a',
],
'audio/ogg' => ['oga', 'ogg', 'spx'],
'audio/vnd.dece.audio' => ['uva', 'uvva'],
'audio/vnd.rip' => 'rip',
'audio/webm' => 'weba',
'audio/x-aac' => 'aac',
'audio/x-aiff' => ['aif', 'aiff', 'aifc'],
'audio/x-caf' => 'caf',
'audio/x-flac' => 'flac',
'audio/x-matroska' => 'mka',
'audio/x-mpegurl' => 'm3u',
'audio/x-ms-wax' => 'wax',
'audio/x-ms-wma' => 'wma',
'audio/x-pn-realaudio' => ['ram', 'ra'],
'audio/x-pn-realaudio-plugin' => 'rmp',
'audio/x-wav' => 'wav',
'audio/xm' => 'xm',
'image/bmp' => 'bmp',
'image/cgm' => 'cgm',
'image/g3fax' => 'g3',
'image/gif' => 'gif',
'image/ief' => 'ief',
'image/jpeg' => ['jpeg', 'jpg', 'jpe'],
'image/ktx' => 'ktx',
'image/png' => 'png',
'image/prs.btif' => 'btif',
'image/sgi' => 'sgi',
'image/svg+xml' => ['svg', 'svgz'],
'image/tiff' => ['tiff', 'tif'],
'image/vnd.adobe.photoshop' => 'psd',
'image/vnd.dece.graphic' => ['uvi', 'uvvi', 'uvg', 'uvvg'],
'image/vnd.dvb.subtitle' => 'sub',
'image/vnd.djvu' => ['djvu', 'djv'],
'image/vnd.dwg' => 'dwg',
'image/vnd.dxf' => 'dxf',
'image/vnd.fastbidsheet' => 'fbs',
'image/vnd.fpx' => 'fpx',
'image/vnd.fst' => 'fst',
'image/vnd.fujixerox.edmics-mmr' => 'mmr',
'image/vnd.fujixerox.edmics-rlc' => 'rlc',
'image/vnd.ms-modi' => 'mdi',
'image/vnd.ms-photo' => 'wdp',
'image/vnd.net-fpx' => 'npx',
'image/vnd.wap.wbmp' => 'wbmp',
'image/vnd.xiff' => 'xif',
'image/webp' => 'webp',
'image/x-3ds' => '3ds',
'image/x-cmu-raster' => 'ras',
'image/x-cmx' => 'cmx',
'image/x-freehand' => ['fh', 'fhc', 'fh4', 'fh5', 'fh7'],
'image/x-icon' => 'ico',
'image/x-mrsid-image' => 'sid',
'image/x-pcx' => 'pcx',
'image/x-pict' => ['pic', 'pct'],
'image/x-portable-anymap' => 'pnm',
'image/x-portable-bitmap' => 'pbm',
'image/x-portable-graymap' => 'pgm',
'image/x-portable-pixmap' => 'ppm',
'image/x-rgb' => 'rgb',
'image/x-tga' => 'tga',
'image/x-xbitmap' => 'xbm',
'image/x-xpixmap' => 'xpm',
'image/x-xwindowdump' => 'xwd',
'message/rfc822' => ['eml', 'mime'],
'model/iges' => ['igs', 'iges'],
'model/mesh' => ['msh', 'mesh', 'silo'],
'model/vnd.collada+xml' => 'dae',
'model/vnd.dwf' => 'dwf',
'model/vnd.gdl' => 'gdl',
'model/vnd.gtw' => 'gtw',
'model/vnd.mts' => 'mts',
'model/vnd.vtu' => 'vtu',
'model/vrml' => ['wrl', 'vrml'],
'model/x3d+binary' => 'x3db',
'model/x3d+vrml' => 'x3dv',
'model/x3d+xml' => 'x3d',
'text/cache-manifest' => 'appcache',
'text/calendar' => ['ics', 'ifb'],
'text/css' => 'css',
'text/csv' => 'csv',
'text/html' => ['html', 'htm'],
'text/n3' => 'n3',
'text/plain' => [
'txt',
'text',
'conf',
'def',
'list',
'log',
'in',
],
'text/prs.lines.tag' => 'dsc',
'text/richtext' => 'rtx',
'text/sgml' => ['sgml', 'sgm'],
'text/tab-separated-values' => 'tsv',
'text/troff' => [
't',
'tr',
'roff',
'man',
'me',
'ms',
],
'text/turtle' => 'ttl',
'text/uri-list' => ['uri', 'uris', 'urls'],
'text/vcard' => 'vcard',
'text/vnd.curl' => 'curl',
'text/vnd.curl.dcurl' => 'dcurl',
'text/vnd.curl.scurl' => 'scurl',
'text/vnd.curl.mcurl' => 'mcurl',
'text/vnd.dvb.subtitle' => 'sub',
'text/vnd.fly' => 'fly',
'text/vnd.fmi.flexstor' => 'flx',
'text/vnd.graphviz' => 'gv',
'text/vnd.in3d.3dml' => '3dml',
'text/vnd.in3d.spot' => 'spot',
'text/vnd.sun.j2me.app-descriptor' => 'jad',
'text/vnd.wap.wml' => 'wml',
'text/vnd.wap.wmlscript' => 'wmls',
'text/x-asm' => ['s', 'asm'],
'text/x-fortran' => ['f', 'for', 'f77', 'f90'],
'text/x-java-source' => 'java',
'text/x-opml' => 'opml',
'text/x-pascal' => ['p', 'pas'],
'text/x-nfo' => 'nfo',
'text/x-setext' => 'etx',
'text/x-sfv' => 'sfv',
'text/x-uuencode' => 'uu',
'text/x-vcalendar' => 'vcs',
'text/x-vcard' => 'vcf',
'video/3gpp' => '3gp',
'video/3gpp2' => '3g2',
'video/h261' => 'h261',
'video/h263' => 'h263',
'video/h264' => 'h264',
'video/jpeg' => 'jpgv',
'video/jpm' => ['jpm', 'jpgm'],
'video/mj2' => 'mj2',
'video/mp4' => 'mp4',
'video/mpeg' => ['mpeg', 'mpg', 'mpe', 'm1v', 'm2v'],
'video/ogg' => 'ogv',
'video/quicktime' => ['qt', 'mov'],
'video/vnd.dece.hd' => ['uvh', 'uvvh'],
'video/vnd.dece.mobile' => ['uvm', 'uvvm'],
'video/vnd.dece.pd' => ['uvp', 'uvvp'],
'video/vnd.dece.sd' => ['uvs', 'uvvs'],
'video/vnd.dece.video' => ['uvv', 'uvvv'],
'video/vnd.dvb.file' => 'dvb',
'video/vnd.fvt' => 'fvt',
'video/vnd.mpegurl' => ['mxu', 'm4u'],
'video/vnd.ms-playready.media.pyv' => 'pyv',
'video/vnd.uvvu.mp4' => ['uvu', 'uvvu'],
'video/vnd.vivo' => 'viv',
'video/webm' => 'webm',
'video/x-f4v' => 'f4v',
'video/x-fli' => 'fli',
'video/x-flv' => 'flv',
'video/x-m4v' => 'm4v',
'video/x-matroska' => ['mkv', 'mk3d', 'mks'],
'video/x-mng' => 'mng',
'video/x-ms-asf' => ['asf', 'asx'],
'video/x-ms-vob' => 'vob',
'video/x-ms-wm' => 'wm',
'video/x-ms-wmv' => 'wmv',
'video/x-ms-wmx' => 'wmx',
'video/x-ms-wvx' => 'wvx',
'video/x-msvideo' => 'avi',
'video/x-sgi-movie' => 'movie',
];
/**
* Get a random MIME type
*
* @return string
*
* @example 'video/avi'
*/
public static function mimeType()
{
return static::randomElement(array_keys(static::$mimeTypes));
}
/**
* Get a random file extension (without a dot)
*
* @example avi
*
* @return string
*/
public static function fileExtension()
{
$random_extension = static::randomElement(array_values(static::$mimeTypes));
return is_array($random_extension) ? static::randomElement($random_extension) : $random_extension;
}
/**
* Copy a random file from the source directory to the target directory and returns the filename/fullpath
*
* @param string $sourceDirectory The directory to look for random file taking
* @param string $targetDirectory
* @param bool $fullPath Whether to have the full path or just the filename
*
* @return string
*/
public static function file($sourceDirectory = '/tmp', $targetDirectory = '/tmp', $fullPath = true)
{
if (!is_dir($sourceDirectory)) {
throw new \InvalidArgumentException(sprintf('Source directory %s does not exist or is not a directory.', $sourceDirectory));
}
if (!is_dir($targetDirectory)) {
throw new \InvalidArgumentException(sprintf('Target directory %s does not exist or is not a directory.', $targetDirectory));
}
if ($sourceDirectory == $targetDirectory) {
throw new \InvalidArgumentException('Source and target directories must differ.');
}
// Drop . and .. and reset array keys
$files = array_filter(array_values(array_diff(scandir($sourceDirectory), ['.', '..'])), static function ($file) use ($sourceDirectory) {
return is_file($sourceDirectory . DIRECTORY_SEPARATOR . $file) && is_readable($sourceDirectory . DIRECTORY_SEPARATOR . $file);
});
if (empty($files)) {
throw new \InvalidArgumentException(sprintf('Source directory %s is empty.', $sourceDirectory));
}
$sourceFullPath = $sourceDirectory . DIRECTORY_SEPARATOR . static::randomElement($files);
$destinationFile = Uuid::uuid() . '.' . pathinfo($sourceFullPath, PATHINFO_EXTENSION);
$destinationFullPath = $targetDirectory . DIRECTORY_SEPARATOR . $destinationFile;
if (false === copy($sourceFullPath, $destinationFullPath)) {
return false;
}
return $fullPath ? $destinationFullPath : $destinationFile;
}
}
-307
View File
@@ -1,307 +0,0 @@
<?php
namespace Faker\Provider;
use Faker\Generator;
use Faker\UniqueGenerator;
class HtmlLorem extends Base
{
public const HTML_TAG = 'html';
public const HEAD_TAG = 'head';
public const BODY_TAG = 'body';
public const DIV_TAG = 'div';
public const P_TAG = 'p';
public const A_TAG = 'a';
public const SPAN_TAG = 'span';
public const TABLE_TAG = 'table';
public const THEAD_TAG = 'thead';
public const TBODY_TAG = 'tbody';
public const TR_TAG = 'tr';
public const TD_TAG = 'td';
public const TH_TAG = 'th';
public const UL_TAG = 'ul';
public const LI_TAG = 'li';
public const H_TAG = 'h';
public const B_TAG = 'b';
public const I_TAG = 'i';
public const TITLE_TAG = 'title';
public const FORM_TAG = 'form';
public const INPUT_TAG = 'input';
public const LABEL_TAG = 'label';
private $idGenerator;
public function __construct(Generator $generator)
{
parent::__construct($generator);
$generator->addProvider(new Lorem($generator));
$generator->addProvider(new Internet($generator));
}
/**
* @param int $maxDepth
* @param int $maxWidth
*
* @return string
*/
public function randomHtml($maxDepth = 4, $maxWidth = 4)
{
if (!class_exists(\DOMDocument::class, false)) {
throw new \RuntimeException('ext-dom is required to use randomHtml.');
}
$document = new \DOMDocument();
$this->idGenerator = new UniqueGenerator($this->generator);
$head = $document->createElement('head');
$this->addRandomTitle($head);
$body = $document->createElement('body');
$this->addLoginForm($body);
$this->addRandomSubTree($body, $maxDepth, $maxWidth);
$html = $document->createElement('html');
$html->appendChild($head);
$html->appendChild($body);
$document->appendChild($html);
return $document->saveHTML();
}
private function addRandomSubTree(\DOMElement $root, $maxDepth, $maxWidth)
{
--$maxDepth;
if ($maxDepth <= 0) {
return $root;
}
$siblings = self::numberBetween(1, $maxWidth);
for ($i = 0; $i < $siblings; ++$i) {
if ($maxDepth == 1) {
$this->addRandomLeaf($root);
} else {
$sibling = $root->ownerDocument->createElement('div');
$root->appendChild($sibling);
$this->addRandomAttribute($sibling);
$this->addRandomSubTree($sibling, self::numberBetween(0, $maxDepth), $maxWidth);
}
}
return $root;
}
private function addRandomLeaf(\DOMElement $node): void
{
$rand = self::numberBetween(1, 10);
switch ($rand) {
case 1:
$this->addRandomP($node);
break;
case 2:
$this->addRandomA($node);
break;
case 3:
$this->addRandomSpan($node);
break;
case 4:
$this->addRandomUL($node);
break;
case 5:
$this->addRandomH($node);
break;
case 6:
$this->addRandomB($node);
break;
case 7:
$this->addRandomI($node);
break;
case 8:
$this->addRandomTable($node);
break;
default:
$this->addRandomText($node);
break;
}
}
private function addRandomAttribute(\DOMElement $node): void
{
$rand = self::numberBetween(1, 2);
switch ($rand) {
case 1:
$node->setAttribute('class', $this->generator->word());
break;
case 2:
$node->setAttribute('id', (string) $this->idGenerator->randomNumber(5));
break;
}
}
private function addRandomP(\DOMElement $element, $maxLength = 10): void
{
$node = $element->ownerDocument->createElement(static::P_TAG);
$node->textContent = $this->generator->sentence(self::numberBetween(1, $maxLength));
$element->appendChild($node);
}
private function addRandomText(\DOMElement $element, $maxLength = 10): void
{
$text = $element->ownerDocument->createTextNode($this->generator->sentence(self::numberBetween(1, $maxLength)));
$element->appendChild($text);
}
private function addRandomA(\DOMElement $element, $maxLength = 10): void
{
$text = $element->ownerDocument->createTextNode($this->generator->sentence(self::numberBetween(1, $maxLength)));
$node = $element->ownerDocument->createElement(static::A_TAG);
$node->setAttribute('href', $this->generator->safeEmailDomain());
$node->appendChild($text);
$element->appendChild($node);
}
private function addRandomTitle(\DOMElement $element, $maxLength = 10): void
{
$text = $element->ownerDocument->createTextNode($this->generator->sentence(self::numberBetween(1, $maxLength)));
$node = $element->ownerDocument->createElement(static::TITLE_TAG);
$node->appendChild($text);
$element->appendChild($node);
}
private function addRandomH(\DOMElement $element, $maxLength = 10): void
{
$h = static::H_TAG . (string) self::numberBetween(1, 3);
$text = $element->ownerDocument->createTextNode($this->generator->sentence(self::numberBetween(1, $maxLength)));
$node = $element->ownerDocument->createElement($h);
$node->appendChild($text);
$element->appendChild($node);
}
private function addRandomB(\DOMElement $element, $maxLength = 10): void
{
$text = $element->ownerDocument->createTextNode($this->generator->sentence(self::numberBetween(1, $maxLength)));
$node = $element->ownerDocument->createElement(static::B_TAG);
$node->appendChild($text);
$element->appendChild($node);
}
private function addRandomI(\DOMElement $element, $maxLength = 10): void
{
$text = $element->ownerDocument->createTextNode($this->generator->sentence(self::numberBetween(1, $maxLength)));
$node = $element->ownerDocument->createElement(static::I_TAG);
$node->appendChild($text);
$element->appendChild($node);
}
private function addRandomSpan(\DOMElement $element, $maxLength = 10): void
{
$text = $element->ownerDocument->createTextNode($this->generator->sentence(self::numberBetween(1, $maxLength)));
$node = $element->ownerDocument->createElement(static::SPAN_TAG);
$node->appendChild($text);
$element->appendChild($node);
}
private function addLoginForm(\DOMElement $element): void
{
$textInput = $element->ownerDocument->createElement(static::INPUT_TAG);
$textInput->setAttribute('type', 'text');
$textInput->setAttribute('id', 'username');
$textLabel = $element->ownerDocument->createElement(static::LABEL_TAG);
$textLabel->setAttribute('for', 'username');
$textLabel->textContent = $this->generator->word();
$passwordInput = $element->ownerDocument->createElement(static::INPUT_TAG);
$passwordInput->setAttribute('type', 'password');
$passwordInput->setAttribute('id', 'password');
$passwordLabel = $element->ownerDocument->createElement(static::LABEL_TAG);
$passwordLabel->setAttribute('for', 'password');
$passwordLabel->textContent = $this->generator->word();
$submit = $element->ownerDocument->createElement(static::INPUT_TAG);
$submit->setAttribute('type', 'submit');
$submit->setAttribute('value', $this->generator->word());
$submit = $element->ownerDocument->createElement(static::FORM_TAG);
$submit->setAttribute('action', $this->generator->safeEmailDomain());
$submit->setAttribute('method', 'POST');
$submit->appendChild($textLabel);
$submit->appendChild($textInput);
$submit->appendChild($passwordLabel);
$submit->appendChild($passwordInput);
$element->appendChild($submit);
}
private function addRandomTable(\DOMElement $element, $maxRows = 10, $maxCols = 6, $maxTitle = 4, $maxLength = 10): void
{
$rows = self::numberBetween(1, $maxRows);
$cols = self::numberBetween(1, $maxCols);
$table = $element->ownerDocument->createElement(static::TABLE_TAG);
$thead = $element->ownerDocument->createElement(static::THEAD_TAG);
$tbody = $element->ownerDocument->createElement(static::TBODY_TAG);
$table->appendChild($thead);
$table->appendChild($tbody);
$tr = $element->ownerDocument->createElement(static::TR_TAG);
$thead->appendChild($tr);
for ($i = 0; $i < $cols; ++$i) {
$th = $element->ownerDocument->createElement(static::TH_TAG);
$th->textContent = $this->generator->sentence(self::numberBetween(1, $maxTitle));
$tr->appendChild($th);
}
for ($i = 0; $i < $rows; ++$i) {
$tr = $element->ownerDocument->createElement(static::TR_TAG);
$tbody->appendChild($tr);
for ($j = 0; $j < $cols; ++$j) {
$th = $element->ownerDocument->createElement(static::TD_TAG);
$th->textContent = $this->generator->sentence(self::numberBetween(1, $maxLength));
$tr->appendChild($th);
}
}
$element->appendChild($table);
}
private function addRandomUL(\DOMElement $element, $maxItems = 11, $maxLength = 4): void
{
$num = self::numberBetween(1, $maxItems);
$ul = $element->ownerDocument->createElement(static::UL_TAG);
for ($i = 0; $i < $num; ++$i) {
$li = $element->ownerDocument->createElement(static::LI_TAG);
$li->textContent = $this->generator->sentence(self::numberBetween(1, $maxLength));
$ul->appendChild($li);
}
$element->appendChild($ul);
}
}
-196
View File
@@ -1,196 +0,0 @@
<?php
namespace Faker\Provider;
/**
* Depends on image generation from http://lorempixel.com/
*/
class Image extends Base
{
/**
* @var string
*/
public const BASE_URL = 'https://via.placeholder.com';
public const FORMAT_JPG = 'jpg';
public const FORMAT_JPEG = 'jpeg';
public const FORMAT_PNG = 'png';
/**
* @var array
*
* @deprecated Categories are no longer used as a list in the placeholder API but referenced as string instead
*/
protected static $categories = [
'abstract', 'animals', 'business', 'cats', 'city', 'food', 'nightlife',
'fashion', 'people', 'nature', 'sports', 'technics', 'transport',
];
/**
* Generate the URL that will return a random image
*
* Set randomize to false to remove the random GET parameter at the end of the url.
*
* @example 'http://via.placeholder.com/640x480.png/CCCCCC?text=well+hi+there'
*
* @param int $width
* @param int $height
* @param string|null $category
* @param bool $randomize
* @param string|null $word
* @param bool $gray
* @param string $format
*
* @return string
*/
public static function imageUrl(
$width = 640,
$height = 480,
$category = null,
$randomize = true,
$word = null,
$gray = false,
$format = 'png'
) {
trigger_deprecation(
'fakerphp/faker',
'1.20',
'Provider is deprecated and will no longer be available in Faker 2. Please use a custom provider instead',
);
// Validate image format
$imageFormats = static::getFormats();
if (!in_array(strtolower($format), $imageFormats, true)) {
throw new \InvalidArgumentException(sprintf(
'Invalid image format "%s". Allowable formats are: %s',
$format,
implode(', ', $imageFormats),
));
}
$size = sprintf('%dx%d.%s', $width, $height, $format);
$imageParts = [];
if ($category !== null) {
$imageParts[] = $category;
}
if ($word !== null) {
$imageParts[] = $word;
}
if ($randomize === true) {
$imageParts[] = Lorem::word();
}
$backgroundColor = $gray === true ? 'CCCCCC' : str_replace('#', '', Color::safeHexColor());
return sprintf(
'%s/%s/%s%s',
self::BASE_URL,
$size,
$backgroundColor,
count($imageParts) > 0 ? '?text=' . urlencode(implode(' ', $imageParts)) : '',
);
}
/**
* Download a remote random image to disk and return its location
*
* Requires curl, or allow_url_fopen to be on in php.ini.
*
* @example '/path/to/dir/13b73edae8443990be1aa8f1a483bc27.png'
*
* @return bool|string
*/
public static function image(
$dir = null,
$width = 640,
$height = 480,
$category = null,
$fullPath = true,
$randomize = true,
$word = null,
$gray = false,
$format = 'png'
) {
trigger_deprecation(
'fakerphp/faker',
'1.20',
'Provider is deprecated and will no longer be available in Faker 2. Please use a custom provider instead',
);
$dir = null === $dir ? sys_get_temp_dir() : $dir; // GNU/Linux / OS X / Windows compatible
// Validate directory path
if (!is_dir($dir) || !is_writable($dir)) {
throw new \InvalidArgumentException(sprintf('Cannot write to directory "%s"', $dir));
}
// Generate a random filename. Use the server address so that a file
// generated at the same time on a different server won't have a collision.
$name = md5(uniqid(empty($_SERVER['SERVER_ADDR']) ? '' : $_SERVER['SERVER_ADDR'], true));
$filename = sprintf('%s.%s', $name, $format);
$filepath = $dir . DIRECTORY_SEPARATOR . $filename;
$url = static::imageUrl($width, $height, $category, $randomize, $word, $gray, $format);
// save file
if (function_exists('curl_exec')) {
// use cURL
$fp = fopen($filepath, 'w');
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FILE, $fp);
$success = curl_exec($ch) && curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200;
fclose($fp);
curl_close($ch);
if (!$success) {
unlink($filepath);
// could not contact the distant URL or HTTP error - fail silently.
return false;
}
} elseif (ini_get('allow_url_fopen')) {
// use remote fopen() via copy()
$success = copy($url, $filepath);
if (!$success) {
// could not contact the distant URL or HTTP error - fail silently.
return false;
}
} else {
return new \RuntimeException('The image formatter downloads an image from a remote HTTP server. Therefore, it requires that PHP can request remote hosts, either via cURL or fopen()');
}
return $fullPath ? $filepath : $filename;
}
public static function getFormats(): array
{
trigger_deprecation(
'fakerphp/faker',
'1.20',
'Provider is deprecated and will no longer be available in Faker 2. Please use a custom provider instead',
);
return array_keys(static::getFormatConstants());
}
public static function getFormatConstants(): array
{
trigger_deprecation(
'fakerphp/faker',
'1.20',
'Provider is deprecated and will no longer be available in Faker 2. Please use a custom provider instead',
);
return [
static::FORMAT_JPG => constant('IMAGETYPE_JPEG'),
static::FORMAT_JPEG => constant('IMAGETYPE_JPEG'),
static::FORMAT_PNG => constant('IMAGETYPE_PNG'),
];
}
}
-407
View File
@@ -1,407 +0,0 @@
<?php
namespace Faker\Provider;
class Internet extends Base
{
protected static $freeEmailDomain = ['gmail.com', 'yahoo.com', 'hotmail.com'];
protected static $tld = ['com', 'com', 'com', 'com', 'com', 'com', 'biz', 'info', 'net', 'org'];
protected static $userNameFormats = [
'{{lastName}}.{{firstName}}',
'{{firstName}}.{{lastName}}',
'{{firstName}}##',
'?{{lastName}}',
];
protected static $emailFormats = [
'{{userName}}@{{domainName}}',
'{{userName}}@{{freeEmailDomain}}',
];
protected static $urlFormats = [
'http://www.{{domainName}}/',
'http://{{domainName}}/',
'http://www.{{domainName}}/{{slug}}',
'http://www.{{domainName}}/{{slug}}',
'https://www.{{domainName}}/{{slug}}',
'http://www.{{domainName}}/{{slug}}.html',
'http://{{domainName}}/{{slug}}',
'http://{{domainName}}/{{slug}}',
'http://{{domainName}}/{{slug}}.html',
'https://{{domainName}}/{{slug}}.html',
];
/**
* @see https://tools.ietf.org/html/rfc1918#section-3
*/
protected static $localIpBlocks = [
['10.0.0.0', '10.255.255.255'],
['172.16.0.0', '172.31.255.255'],
['192.168.0.0', '192.168.255.255'],
];
/**
* @example 'jdoe@acme.biz'
*
* @return string
*/
public function email()
{
$format = static::randomElement(static::$emailFormats);
return $this->generator->parse($format);
}
/**
* @example 'jdoe@example.com'
*
* @return string
*/
final public function safeEmail()
{
return preg_replace('/\s/u', '', $this->userName() . '@' . static::safeEmailDomain());
}
/**
* @example 'jdoe@gmail.com'
*
* @return string
*/
public function freeEmail()
{
return preg_replace('/\s/u', '', $this->userName() . '@' . static::freeEmailDomain());
}
/**
* @example 'jdoe@dawson.com'
*
* @return string
*/
public function companyEmail()
{
return preg_replace('/\s/u', '', $this->userName() . '@' . $this->domainName());
}
/**
* @example 'gmail.com'
*
* @return string
*/
public static function freeEmailDomain()
{
return static::randomElement(static::$freeEmailDomain);
}
/**
* @example 'example.org'
*
* @return string
*/
final public static function safeEmailDomain()
{
$domains = [
'example.com',
'example.org',
'example.net',
];
return static::randomElement($domains);
}
/**
* @example 'jdoe'
*
* @return string
*/
public function userName()
{
$format = static::randomElement(static::$userNameFormats);
$username = static::bothify($this->generator->parse($format));
$username = strtolower(static::transliterate($username));
// check if transliterate() didn't support the language and removed all letters
if (trim($username, '._') === '') {
throw new \Exception('userName failed with the selected locale. Try a different locale or activate the "intl" PHP extension.');
}
// clean possible trailing dots from first/last names
$username = str_replace('..', '.', $username);
$username = rtrim($username, '.');
return $username;
}
/**
* @example 'fY4èHdZv68'
*
* @return string
*/
public function password($minLength = 6, $maxLength = 20)
{
$pattern = str_repeat('*', $this->numberBetween($minLength, $maxLength));
return $this->asciify($pattern);
}
/**
* @example 'tiramisu.com'
*
* @return string
*/
public function domainName()
{
return $this->domainWord() . '.' . $this->tld();
}
/**
* @example 'faber'
*
* @return string
*/
public function domainWord()
{
$lastName = $this->generator->format('lastName');
$lastName = strtolower(static::transliterate($lastName));
// check if transliterate() didn't support the language and removed all letters
if (trim($lastName, '._') === '') {
throw new \Exception('domainWord failed with the selected locale. Try a different locale or activate the "intl" PHP extension.');
}
// clean possible trailing dot from last name
$lastName = rtrim($lastName, '.');
return $lastName;
}
/**
* @example 'com'
*
* @return string
*/
public function tld()
{
return static::randomElement(static::$tld);
}
/**
* @example 'http://www.runolfsdottir.com/'
*
* @return string
*/
public function url()
{
$format = static::randomElement(static::$urlFormats);
return $this->generator->parse($format);
}
/**
* @example 'aut-repellat-commodi-vel-itaque-nihil-id-saepe-nostrum'
*
* @return string
*/
public function slug($nbWords = 6, $variableNbWords = true)
{
if ($nbWords <= 0) {
return '';
}
if ($variableNbWords) {
$nbWords = (int) ($nbWords * self::numberBetween(60, 140) / 100) + 1;
}
$words = $this->generator->words($nbWords);
return implode('-', $words);
}
/**
* @example '237.149.115.38'
*
* @return string
*/
public function ipv4()
{
return long2ip(Miscellaneous::boolean() ? self::numberBetween(-2147483648, -2) : self::numberBetween(16777216, 2147483647));
}
/**
* @example '35cd:186d:3e23:2986:ef9f:5b41:42a4:e6f1'
*
* @return string
*/
public function ipv6()
{
$res = [];
for ($i = 0; $i < 8; ++$i) {
$res[] = dechex(self::numberBetween(0, 65535));
}
return implode(':', $res);
}
/**
* @example '10.1.1.17'
*
* @return string
*/
public static function localIpv4()
{
$ipBlock = self::randomElement(static::$localIpBlocks);
return long2ip(static::numberBetween(ip2long($ipBlock[0]), ip2long($ipBlock[1])));
}
/**
* @example '32:F1:39:2F:D6:18'
*
* @return string
*/
public static function macAddress()
{
$mac = [];
for ($i = 0; $i < 6; ++$i) {
$mac[] = sprintf('%02X', self::numberBetween(0, 0xff));
}
return implode(':', $mac);
}
protected static function transliterate($string)
{
if (0 === preg_match('/[^A-Za-z0-9_.]/', $string)) {
return $string;
}
$transId = 'Any-Latin; Latin-ASCII; NFD; [:Nonspacing Mark:] Remove; NFC;';
if (class_exists(\Transliterator::class, false) && $transliterator = \Transliterator::create($transId)) {
$transString = $transliterator->transliterate($string);
} else {
$transString = static::toAscii($string);
}
return preg_replace('/[^A-Za-z0-9_.]/u', '', $transString);
}
protected static function toAscii($string)
{
static $arrayFrom, $arrayTo;
if (empty($arrayFrom)) {
$transliterationTable = [
'IJ' => 'I', 'Ö' => 'O', 'Œ' => 'O', 'Ü' => 'U', 'ä' => 'a', 'æ' => 'a',
'ij' => 'i', 'ö' => 'o', 'œ' => 'o', 'ü' => 'u', 'ß' => 's', 'ſ' => 's',
'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'A', 'Å' => 'A',
'Æ' => 'A', 'Ā' => 'A', 'Ą' => 'A', 'Ă' => 'A', 'Ç' => 'C', 'Ć' => 'C',
'Č' => 'C', 'Ĉ' => 'C', 'Ċ' => 'C', 'Ď' => 'D', 'Đ' => 'D', 'È' => 'E',
'É' => 'E', 'Ê' => 'E', 'Ë' => 'E', 'Ē' => 'E', 'Ę' => 'E', 'Ě' => 'E',
'Ĕ' => 'E', 'Ė' => 'E', 'Ĝ' => 'G', 'Ğ' => 'G', 'Ġ' => 'G', 'Ģ' => 'G',
'Ĥ' => 'H', 'Ħ' => 'H', 'Ì' => 'I', 'Í' => 'I', 'Î' => 'I', 'Ï' => 'I',
'Ī' => 'I', 'Ĩ' => 'I', 'Ĭ' => 'I', 'Į' => 'I', 'İ' => 'I', 'Ĵ' => 'J',
'Ķ' => 'K', 'Ľ' => 'K', 'Ĺ' => 'K', 'Ļ' => 'K', 'Ŀ' => 'K', 'Ł' => 'L',
'Ñ' => 'N', 'Ń' => 'N', 'Ň' => 'N', 'Ņ' => 'N', 'Ŋ' => 'N', 'Ò' => 'O',
'Ó' => 'O', 'Ô' => 'O', 'Õ' => 'O', 'Ø' => 'O', 'Ō' => 'O', 'Ő' => 'O',
'Ŏ' => 'O', 'Ŕ' => 'R', 'Ř' => 'R', 'Ŗ' => 'R', 'Ś' => 'S', 'Ş' => 'S',
'Ŝ' => 'S', 'Ș' => 'S', 'Š' => 'S', 'Ť' => 'T', 'Ţ' => 'T', 'Ŧ' => 'T',
'Ț' => 'T', 'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ū' => 'U', 'Ů' => 'U',
'Ű' => 'U', 'Ŭ' => 'U', 'Ũ' => 'U', 'Ų' => 'U', 'Ŵ' => 'W', 'Ŷ' => 'Y',
'Ÿ' => 'Y', 'Ý' => 'Y', 'Ź' => 'Z', 'Ż' => 'Z', 'Ž' => 'Z', 'à' => 'a',
'á' => 'a', 'â' => 'a', 'ã' => 'a', 'ā' => 'a', 'ą' => 'a', 'ă' => 'a',
'å' => 'a', 'ç' => 'c', 'ć' => 'c', 'č' => 'c', 'ĉ' => 'c', 'ċ' => 'c',
'ď' => 'd', 'đ' => 'd', 'è' => 'e', 'é' => 'e', 'ê' => 'e', 'ë' => 'e',
'ē' => 'e', 'ę' => 'e', 'ě' => 'e', 'ĕ' => 'e', 'ė' => 'e', 'ƒ' => 'f',
'ĝ' => 'g', 'ğ' => 'g', 'ġ' => 'g', 'ģ' => 'g', 'ĥ' => 'h', 'ħ' => 'h',
'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i', 'ī' => 'i', 'ĩ' => 'i',
'ĭ' => 'i', 'į' => 'i', 'ı' => 'i', 'ĵ' => 'j', 'ķ' => 'k', 'ĸ' => 'k',
'ł' => 'l', 'ľ' => 'l', 'ĺ' => 'l', 'ļ' => 'l', 'ŀ' => 'l', 'ñ' => 'n',
'ń' => 'n', 'ň' => 'n', 'ņ' => 'n', 'ʼn' => 'n', 'ŋ' => 'n', 'ò' => 'o',
'ó' => 'o', 'ô' => 'o', 'õ' => 'o', 'ø' => 'o', 'ō' => 'o', 'ő' => 'o',
'ŏ' => 'o', 'ŕ' => 'r', 'ř' => 'r', 'ŗ' => 'r', 'ś' => 's', 'š' => 's',
'ť' => 't', 'ù' => 'u', 'ú' => 'u', 'û' => 'u', 'ū' => 'u', 'ů' => 'u',
'ű' => 'u', 'ŭ' => 'u', 'ũ' => 'u', 'ų' => 'u', 'ŵ' => 'w', 'ÿ' => 'y',
'ý' => 'y', 'ŷ' => 'y', 'ż' => 'z', 'ź' => 'z', 'ž' => 'z', 'Α' => 'A',
'Ά' => 'A', 'Ἀ' => 'A', 'Ἁ' => 'A', 'Ἂ' => 'A', 'Ἃ' => 'A', 'Ἄ' => 'A',
'Ἅ' => 'A', 'Ἆ' => 'A', 'Ἇ' => 'A', 'ᾈ' => 'A', 'ᾉ' => 'A', 'ᾊ' => 'A',
'ᾋ' => 'A', 'ᾌ' => 'A', 'ᾍ' => 'A', 'ᾎ' => 'A', 'ᾏ' => 'A', 'Ᾰ' => 'A',
'Ᾱ' => 'A', 'Ὰ' => 'A', 'ᾼ' => 'A', 'Β' => 'B', 'Γ' => 'G', 'Δ' => 'D',
'Ε' => 'E', 'Έ' => 'E', 'Ἐ' => 'E', 'Ἑ' => 'E', 'Ἒ' => 'E', 'Ἓ' => 'E',
'Ἔ' => 'E', 'Ἕ' => 'E', 'Ὲ' => 'E', 'Ζ' => 'Z', 'Η' => 'I', 'Ή' => 'I',
'Ἠ' => 'I', 'Ἡ' => 'I', 'Ἢ' => 'I', 'Ἣ' => 'I', 'Ἤ' => 'I', 'Ἥ' => 'I',
'Ἦ' => 'I', 'Ἧ' => 'I', 'ᾘ' => 'I', 'ᾙ' => 'I', 'ᾚ' => 'I', 'ᾛ' => 'I',
'ᾜ' => 'I', 'ᾝ' => 'I', 'ᾞ' => 'I', 'ᾟ' => 'I', 'Ὴ' => 'I', 'ῌ' => 'I',
'Θ' => 'T', 'Ι' => 'I', 'Ί' => 'I', 'Ϊ' => 'I', 'Ἰ' => 'I', 'Ἱ' => 'I',
'Ἲ' => 'I', 'Ἳ' => 'I', 'Ἴ' => 'I', 'Ἵ' => 'I', 'Ἶ' => 'I', 'Ἷ' => 'I',
'Ῐ' => 'I', 'Ῑ' => 'I', 'Ὶ' => 'I', 'Κ' => 'K', 'Λ' => 'L', 'Μ' => 'M',
'Ν' => 'N', 'Ξ' => 'K', 'Ο' => 'O', 'Ό' => 'O', 'Ὀ' => 'O', 'Ὁ' => 'O',
'Ὂ' => 'O', 'Ὃ' => 'O', 'Ὄ' => 'O', 'Ὅ' => 'O', 'Ὸ' => 'O', 'Π' => 'P',
'Ρ' => 'R', 'Ῥ' => 'R', 'Σ' => 'S', 'Τ' => 'T', 'Υ' => 'Y', 'Ύ' => 'Y',
'Ϋ' => 'Y', 'Ὑ' => 'Y', 'Ὓ' => 'Y', 'Ὕ' => 'Y', 'Ὗ' => 'Y', 'Ῠ' => 'Y',
'Ῡ' => 'Y', 'Ὺ' => 'Y', 'Φ' => 'F', 'Χ' => 'X', 'Ψ' => 'P', 'Ω' => 'O',
'Ώ' => 'O', 'Ὠ' => 'O', 'Ὡ' => 'O', 'Ὢ' => 'O', 'Ὣ' => 'O', 'Ὤ' => 'O',
'Ὥ' => 'O', 'Ὦ' => 'O', 'Ὧ' => 'O', 'ᾨ' => 'O', 'ᾩ' => 'O', 'ᾪ' => 'O',
'ᾫ' => 'O', 'ᾬ' => 'O', 'ᾭ' => 'O', 'ᾮ' => 'O', 'ᾯ' => 'O', 'Ὼ' => 'O',
'ῼ' => 'O', 'α' => 'a', 'ά' => 'a', 'ἀ' => 'a', 'ἁ' => 'a', 'ἂ' => 'a',
'ἃ' => 'a', 'ἄ' => 'a', 'ἅ' => 'a', 'ἆ' => 'a', 'ἇ' => 'a', 'ᾀ' => 'a',
'ᾁ' => 'a', 'ᾂ' => 'a', 'ᾃ' => 'a', 'ᾄ' => 'a', 'ᾅ' => 'a', 'ᾆ' => 'a',
'ᾇ' => 'a', 'ὰ' => 'a', 'ᾰ' => 'a', 'ᾱ' => 'a', 'ᾲ' => 'a', 'ᾳ' => 'a',
'ᾴ' => 'a', 'ᾶ' => 'a', 'ᾷ' => 'a', 'β' => 'b', 'γ' => 'g', 'δ' => 'd',
'ε' => 'e', 'έ' => 'e', 'ἐ' => 'e', 'ἑ' => 'e', 'ἒ' => 'e', 'ἓ' => 'e',
'ἔ' => 'e', 'ἕ' => 'e', 'ὲ' => 'e', 'ζ' => 'z', 'η' => 'i', 'ή' => 'i',
'ἠ' => 'i', 'ἡ' => 'i', 'ἢ' => 'i', 'ἣ' => 'i', 'ἤ' => 'i', 'ἥ' => 'i',
'ἦ' => 'i', 'ἧ' => 'i', 'ᾐ' => 'i', 'ᾑ' => 'i', 'ᾒ' => 'i', 'ᾓ' => 'i',
'ᾔ' => 'i', 'ᾕ' => 'i', 'ᾖ' => 'i', 'ᾗ' => 'i', 'ὴ' => 'i', 'ῂ' => 'i',
'ῃ' => 'i', 'ῄ' => 'i', 'ῆ' => 'i', 'ῇ' => 'i', 'θ' => 't', 'ι' => 'i',
'ί' => 'i', 'ϊ' => 'i', 'ΐ' => 'i', 'ἰ' => 'i', 'ἱ' => 'i', 'ἲ' => 'i',
'ἳ' => 'i', 'ἴ' => 'i', 'ἵ' => 'i', 'ἶ' => 'i', 'ἷ' => 'i', 'ὶ' => 'i',
'ῐ' => 'i', 'ῑ' => 'i', 'ῒ' => 'i', 'ῖ' => 'i', 'ῗ' => 'i', 'κ' => 'k',
'λ' => 'l', 'μ' => 'm', 'ν' => 'n', 'ξ' => 'k', 'ο' => 'o', 'ό' => 'o',
'ὀ' => 'o', 'ὁ' => 'o', 'ὂ' => 'o', 'ὃ' => 'o', 'ὄ' => 'o', 'ὅ' => 'o',
'ὸ' => 'o', 'π' => 'p', 'ρ' => 'r', 'ῤ' => 'r', 'ῥ' => 'r', 'σ' => 's',
'ς' => 's', 'τ' => 't', 'υ' => 'y', 'ύ' => 'y', 'ϋ' => 'y', 'ΰ' => 'y',
'ὐ' => 'y', 'ὑ' => 'y', 'ὒ' => 'y', 'ὓ' => 'y', 'ὔ' => 'y', 'ὕ' => 'y',
'ὖ' => 'y', 'ὗ' => 'y', 'ὺ' => 'y', 'ῠ' => 'y', 'ῡ' => 'y', 'ῢ' => 'y',
'ῦ' => 'y', 'ῧ' => 'y', 'φ' => 'f', 'χ' => 'x', 'ψ' => 'p', 'ω' => 'o',
'ώ' => 'o', 'ὠ' => 'o', 'ὡ' => 'o', 'ὢ' => 'o', 'ὣ' => 'o', 'ὤ' => 'o',
'ὥ' => 'o', 'ὦ' => 'o', 'ὧ' => 'o', 'ᾠ' => 'o', 'ᾡ' => 'o', 'ᾢ' => 'o',
'ᾣ' => 'o', 'ᾤ' => 'o', 'ᾥ' => 'o', 'ᾦ' => 'o', 'ᾧ' => 'o', 'ὼ' => 'o',
'ῲ' => 'o', 'ῳ' => 'o', 'ῴ' => 'o', 'ῶ' => 'o', 'ῷ' => 'o', 'А' => 'A',
'Б' => 'B', 'В' => 'V', 'Г' => 'G', 'Д' => 'D', 'Е' => 'E', 'Ё' => 'E',
'Ж' => 'Z', 'З' => 'Z', 'И' => 'I', 'Й' => 'I', 'К' => 'K', 'Л' => 'L',
'М' => 'M', 'Н' => 'N', 'О' => 'O', 'П' => 'P', 'Р' => 'R', 'С' => 'S',
'Т' => 'T', 'У' => 'U', 'Ф' => 'F', 'Х' => 'K', 'Ц' => 'T', 'Ч' => 'C',
'Ш' => 'S', 'Щ' => 'S', 'Ы' => 'Y', 'Э' => 'E', 'Ю' => 'Y', 'Я' => 'Y',
'а' => 'A', 'б' => 'B', 'в' => 'V', 'г' => 'G', 'д' => 'D', 'е' => 'E',
'ё' => 'E', 'ж' => 'Z', 'з' => 'Z', 'и' => 'I', 'й' => 'I', 'к' => 'K',
'л' => 'L', 'м' => 'M', 'н' => 'N', 'о' => 'O', 'п' => 'P', 'р' => 'R',
'с' => 'S', 'т' => 'T', 'у' => 'U', 'ф' => 'F', 'х' => 'K', 'ц' => 'T',
'ч' => 'C', 'ш' => 'S', 'щ' => 'S', 'ы' => 'Y', 'э' => 'E', 'ю' => 'Y',
'я' => 'Y', 'ð' => 'd', 'Ð' => 'D', 'þ' => 't', 'Þ' => 'T', 'ა' => 'a',
'ბ' => 'b', 'გ' => 'g', 'დ' => 'd', 'ე' => 'e', 'ვ' => 'v', 'ზ' => 'z',
'თ' => 't', 'ი' => 'i', 'კ' => 'k', 'ლ' => 'l', 'მ' => 'm', 'ნ' => 'n',
'ო' => 'o', 'პ' => 'p', 'ჟ' => 'z', 'რ' => 'r', 'ს' => 's', 'ტ' => 't',
'უ' => 'u', 'ფ' => 'p', 'ქ' => 'k', 'ღ' => 'g', '' => 'q', 'შ' => 's',
'ჩ' => 'c', 'ც' => 't', 'ძ' => 'd', 'წ' => 't', 'ჭ' => 'c', 'ხ' => 'k',
'ჯ' => 'j', 'ჰ' => 'h', 'ţ' => 't', 'ʼ' => "'", '̧' => '', 'ḩ' => 'h',
'' => "'", '' => "'", 'ừ' => 'u', '/' => '', 'ế' => 'e', 'ả' => 'a',
'ị' => 'i', 'ậ' => 'a', 'ệ' => 'e', 'ỉ' => 'i', 'ồ' => 'o', 'ề' => 'e',
'ơ' => 'o', 'ạ' => 'a', 'ẵ' => 'a', 'ư' => 'u', 'ằ' => 'a', 'ầ' => 'a',
'ḑ' => 'd', 'Ḩ' => 'H', 'Ḑ' => 'D', 'ș' => 's', 'ț' => 't', 'ộ' => 'o',
'ắ' => 'a', 'ş' => 's', "'" => '', 'ու' => 'u', 'ա' => 'a', 'բ' => 'b',
'գ' => 'g', 'դ' => 'd', 'ե' => 'e', 'զ' => 'z', 'է' => 'e', 'ը' => 'y',
'թ' => 't', 'ժ' => 'zh', 'ի' => 'i', 'լ' => 'l', 'խ' => 'kh', 'ծ' => 'ts',
'կ' => 'k', 'հ' => 'h', 'ձ' => 'dz', 'ղ' => 'gh', 'ճ' => 'ch', 'մ' => 'm',
'յ' => 'y', 'ն' => 'n', 'շ' => 'sh', 'ո' => 'o', 'չ' => 'ch', 'պ' => 'p',
'ջ' => 'j', 'ռ' => 'r', 'ս' => 's', 'վ' => 'v', 'տ' => 't', 'ր' => 'r',
'ց' => 'ts', 'փ' => 'p', 'ք' => 'q', 'և' => 'ev', 'օ' => 'o', 'ֆ' => 'f',
];
$arrayFrom = array_keys($transliterationTable);
$arrayTo = array_values($transliterationTable);
}
return str_replace($arrayFrom, $arrayTo, $string);
}
}

Some files were not shown because too many files have changed in this diff Show More