added support for legacy tickets, fixed switching of modes and also style updates
This commit is contained in:
@@ -5,31 +5,19 @@ declare(strict_types=1);
|
||||
namespace Modules\Documentation\Console;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
use Modules\Documentation\Models\DocumentationCategory;
|
||||
|
||||
use Modules\Documentation\Models\DocumentationDocument;
|
||||
|
||||
use SplFileInfo;
|
||||
|
||||
use Symfony\Component\Finder\Finder;
|
||||
|
||||
use Throwable;
|
||||
|
||||
final class ImportDocumentationCommand extends Command
|
||||
|
||||
{
|
||||
|
||||
/**
|
||||
|
||||
* The console command signature.
|
||||
|
||||
*/
|
||||
|
||||
protected $signature = 'helpdesk:import-documentation
|
||||
|
||||
{path? : Directory containing Markdown files; defaults to the bundled Sentinel documentation}
|
||||
@@ -39,21 +27,14 @@ final class ImportDocumentationCommand extends Command
|
||||
{--fresh : Remove previously imported documents in this category before importing}';
|
||||
|
||||
/**
|
||||
|
||||
* The console command description.
|
||||
|
||||
*/
|
||||
|
||||
protected $description = 'Import Markdown documentation into the Helpdesk Documentation module.';
|
||||
|
||||
/**
|
||||
|
||||
* Execute the console command.
|
||||
|
||||
*/
|
||||
|
||||
public function handle(): int
|
||||
|
||||
{
|
||||
|
||||
$path = $this->resolvePath();
|
||||
@@ -164,7 +145,7 @@ final class ImportDocumentationCommand extends Command
|
||||
|
||||
$this->importFile($category, $file, $path);
|
||||
|
||||
++$imported;
|
||||
$imported++;
|
||||
|
||||
$progress->advance();
|
||||
|
||||
@@ -198,7 +179,7 @@ final class ImportDocumentationCommand extends Command
|
||||
|
||||
$this->components->error(
|
||||
|
||||
'Documentation import failed: ' . $exception->getMessage(),
|
||||
'Documentation import failed: '.$exception->getMessage(),
|
||||
|
||||
);
|
||||
|
||||
@@ -217,13 +198,9 @@ final class ImportDocumentationCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
* Resolve the requested documentation source directory.
|
||||
|
||||
*/
|
||||
|
||||
private function resolvePath(): string
|
||||
|
||||
{
|
||||
|
||||
$argument = $this->argument('path');
|
||||
@@ -247,17 +224,13 @@ final class ImportDocumentationCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
* Find Markdown files recursively.
|
||||
|
||||
*
|
||||
|
||||
* @return list<SplFileInfo>
|
||||
|
||||
*/
|
||||
|
||||
private function markdownFiles(string $path): array
|
||||
|
||||
{
|
||||
|
||||
$finder = Finder::create()
|
||||
@@ -273,7 +246,6 @@ final class ImportDocumentationCommand extends Command
|
||||
->sortByName();
|
||||
|
||||
/** @var list<SplFileInfo> $files */
|
||||
|
||||
$files = iterator_to_array($finder, false);
|
||||
|
||||
return $files;
|
||||
@@ -281,11 +253,8 @@ final class ImportDocumentationCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
* Import one Markdown document.
|
||||
|
||||
*/
|
||||
|
||||
private function importFile(
|
||||
|
||||
DocumentationCategory $category,
|
||||
@@ -301,7 +270,6 @@ final class ImportDocumentationCommand extends Command
|
||||
if ($realPath === false || ! is_readable($realPath)) {
|
||||
|
||||
throw new \RuntimeException(
|
||||
|
||||
sprintf('Unable to read documentation file: %s', $file->getPathname()),
|
||||
|
||||
);
|
||||
@@ -313,7 +281,6 @@ final class ImportDocumentationCommand extends Command
|
||||
if ($body === false) {
|
||||
|
||||
throw new \RuntimeException(
|
||||
|
||||
sprintf('Unable to read documentation file: %s', $realPath),
|
||||
|
||||
);
|
||||
@@ -360,7 +327,7 @@ final class ImportDocumentationCommand extends Command
|
||||
|
||||
'status' => DocumentationDocument::STATUS_PUBLISHED,
|
||||
|
||||
'is_featured' => strtolower($file->getBasename('.' . $file->getExtension())) === 'index',
|
||||
'is_featured' => strtolower($file->getBasename('.'.$file->getExtension())) === 'index',
|
||||
|
||||
'version' => '1.0.0',
|
||||
|
||||
@@ -377,13 +344,9 @@ final class ImportDocumentationCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
* Extract the first Markdown H1 heading.
|
||||
|
||||
*/
|
||||
|
||||
private function extractTitle(string $body, SplFileInfo $file): string
|
||||
|
||||
{
|
||||
|
||||
if (preg_match('/^\s*#\s+(.+?)\s*$/m', $body, $matches) === 1) {
|
||||
@@ -417,13 +380,9 @@ final class ImportDocumentationCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
* Extract a useful summary from the first normal Markdown paragraph.
|
||||
|
||||
*/
|
||||
|
||||
private function extractSummary(string $body): ?string
|
||||
|
||||
{
|
||||
|
||||
$lines = preg_split('/\R/', $body);
|
||||
@@ -507,13 +466,9 @@ final class ImportDocumentationCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
* Generate a stable globally unique slug from the source path.
|
||||
|
||||
*/
|
||||
|
||||
private function makeSlug(string $relativePath, string $title): string
|
||||
|
||||
{
|
||||
|
||||
$withoutExtension = preg_replace(
|
||||
@@ -536,7 +491,7 @@ final class ImportDocumentationCommand extends Command
|
||||
|
||||
if ($slug === '') {
|
||||
|
||||
$slug = 'document-' . substr(sha1($relativePath), 0, 12);
|
||||
$slug = 'document-'.substr(sha1($relativePath), 0, 12);
|
||||
|
||||
}
|
||||
|
||||
@@ -545,13 +500,9 @@ final class ImportDocumentationCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
* Remove a UTF-8 byte-order mark.
|
||||
|
||||
*/
|
||||
|
||||
private function stripBom(string $contents): string
|
||||
|
||||
{
|
||||
|
||||
if (str_starts_with($contents, "\xEF\xBB\xBF")) {
|
||||
@@ -563,6 +514,4 @@ final class ImportDocumentationCommand extends Command
|
||||
return $contents;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ class DocumentationController extends Controller
|
||||
}
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$search = '%' . $request->string('search')->trim()->toString() . '%';
|
||||
$search = '%'.$request->string('search')->trim()->toString().'%';
|
||||
$query->where(function ($builder) use ($search): void {
|
||||
$builder->where('title', 'like', $search)
|
||||
->orWhere('summary', 'like', $search)
|
||||
|
||||
@@ -33,9 +33,9 @@ class StoreDocumentationDocumentRequest extends FormRequest
|
||||
'is_featured' => ['nullable', 'boolean'],
|
||||
'version' => ['required', 'string', 'max:50'],
|
||||
'reference' => ['nullable', 'string', 'max:100'],
|
||||
'attachment' => ['nullable', 'file', 'max:' . config('documentation.max_upload_kb', 20480), 'mimes:' . implode(',', config('documentation.allowed_upload_mimes', []))],
|
||||
'attachment' => ['nullable', 'file', 'max:'.config('documentation.max_upload_kb', 20480), 'mimes:'.implode(',', config('documentation.allowed_upload_mimes', []))],
|
||||
'attachments' => ['nullable', 'array'],
|
||||
'attachments.*' => ['file', 'max:' . config('documentation.max_upload_kb', 20480), 'mimes:' . implode(',', config('documentation.allowed_upload_mimes', []))],
|
||||
'attachments.*' => ['file', 'max:'.config('documentation.max_upload_kb', 20480), 'mimes:'.implode(',', config('documentation.allowed_upload_mimes', []))],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,9 +36,9 @@ class UpdateDocumentationDocumentRequest extends FormRequest
|
||||
'is_featured' => ['nullable', 'boolean'],
|
||||
'version' => ['required', 'string', 'max:50'],
|
||||
'reference' => ['nullable', 'string', 'max:100'],
|
||||
'attachment' => ['nullable', 'file', 'max:' . config('documentation.max_upload_kb', 20480), 'mimes:' . implode(',', config('documentation.allowed_upload_mimes', []))],
|
||||
'attachment' => ['nullable', 'file', 'max:'.config('documentation.max_upload_kb', 20480), 'mimes:'.implode(',', config('documentation.allowed_upload_mimes', []))],
|
||||
'attachments' => ['nullable', 'array'],
|
||||
'attachments.*' => ['file', 'max:' . config('documentation.max_upload_kb', 20480), 'mimes:' . implode(',', config('documentation.allowed_upload_mimes', []))],
|
||||
'attachments.*' => ['file', 'max:'.config('documentation.max_upload_kb', 20480), 'mimes:'.implode(',', config('documentation.allowed_upload_mimes', []))],
|
||||
'remove_attachment' => ['nullable', 'boolean'],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -7,13 +7,13 @@ use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
* @property int $documentation_document_id
|
||||
* @property string $disk
|
||||
* @property string $path
|
||||
* @property string $original_name
|
||||
* @property int $id
|
||||
* @property int $documentation_document_id
|
||||
* @property string $disk
|
||||
* @property string $path
|
||||
* @property string $original_name
|
||||
* @property string|null $mime_type
|
||||
* @property int|null $size
|
||||
* @property int|null $size
|
||||
*/
|
||||
class DocumentationAttachment extends Model
|
||||
{
|
||||
@@ -57,13 +57,13 @@ class DocumentationAttachment extends Model
|
||||
}
|
||||
|
||||
if ($bytes < 1024) {
|
||||
return $bytes . ' B';
|
||||
return $bytes.' B';
|
||||
}
|
||||
|
||||
if ($bytes < 1048576) {
|
||||
return number_format($bytes / 1024, 1) . ' KB';
|
||||
return number_format($bytes / 1024, 1).' KB';
|
||||
}
|
||||
|
||||
return number_format($bytes / 1048576, 1) . ' MB';
|
||||
return number_format($bytes / 1048576, 1).' MB';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,14 +9,14 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
* @property string $name
|
||||
* @property string $slug
|
||||
* @property int $id
|
||||
* @property string $name
|
||||
* @property string $slug
|
||||
* @property string|null $icon
|
||||
* @property string $colour
|
||||
* @property string $colour
|
||||
* @property string|null $description
|
||||
* @property int $sort_order
|
||||
* @property bool $is_active
|
||||
* @property int $sort_order
|
||||
* @property bool $is_active
|
||||
*/
|
||||
class DocumentationCategory extends Model
|
||||
{
|
||||
@@ -66,8 +66,7 @@ class DocumentationCategory extends Model
|
||||
/**
|
||||
* Active category scope.
|
||||
*
|
||||
* @param Builder<DocumentationCategory> $query
|
||||
*
|
||||
* @param Builder<DocumentationCategory> $query
|
||||
* @return Builder<DocumentationCategory>
|
||||
*/
|
||||
public function scopeActive(Builder $query): Builder
|
||||
@@ -78,8 +77,7 @@ class DocumentationCategory extends Model
|
||||
/**
|
||||
* Ordered category scope.
|
||||
*
|
||||
* @param Builder<DocumentationCategory> $query
|
||||
*
|
||||
* @param Builder<DocumentationCategory> $query
|
||||
* @return Builder<DocumentationCategory>
|
||||
*/
|
||||
public function scopeOrdered(Builder $query): Builder
|
||||
|
||||
@@ -11,15 +11,15 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
* @property int|null $documentation_category_id
|
||||
* @property string $title
|
||||
* @property string $slug
|
||||
* @property int $id
|
||||
* @property int|null $documentation_category_id
|
||||
* @property string $title
|
||||
* @property string $slug
|
||||
* @property string|null $summary
|
||||
* @property string|null $body
|
||||
* @property string $status
|
||||
* @property bool $is_featured
|
||||
* @property string $version
|
||||
* @property string $status
|
||||
* @property bool $is_featured
|
||||
* @property string $version
|
||||
* @property string|null $reference
|
||||
* @property-read string $rendered_body
|
||||
*/
|
||||
@@ -101,8 +101,7 @@ class DocumentationDocument extends Model
|
||||
/**
|
||||
* Published document scope.
|
||||
*
|
||||
* @param Builder<DocumentationDocument> $query
|
||||
*
|
||||
* @param Builder<DocumentationDocument> $query
|
||||
* @return Builder<DocumentationDocument>
|
||||
*/
|
||||
public function scopePublished(Builder $query): Builder
|
||||
@@ -113,8 +112,7 @@ class DocumentationDocument extends Model
|
||||
/**
|
||||
* Featured document scope.
|
||||
*
|
||||
* @param Builder<DocumentationDocument> $query
|
||||
*
|
||||
* @param Builder<DocumentationDocument> $query
|
||||
* @return Builder<DocumentationDocument>
|
||||
*/
|
||||
public function scopeFeatured(Builder $query): Builder
|
||||
@@ -140,7 +138,7 @@ class DocumentationDocument extends Model
|
||||
]);
|
||||
}
|
||||
|
||||
return '<p>' . nl2br(e($body), false) . '</p>';
|
||||
return '<p>'.nl2br(e($body), false).'</p>';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace Modules\Documentation\Providers;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Modules\Documentation\Console\ImportDocumentationCommand;
|
||||
|
||||
final class DocumentationServiceProvider extends ServiceProvider
|
||||
{
|
||||
@@ -43,7 +44,7 @@ final class DocumentationServiceProvider extends ServiceProvider
|
||||
}
|
||||
|
||||
$this->commands([
|
||||
\Modules\Documentation\Console\ImportDocumentationCommand::class,
|
||||
ImportDocumentationCommand::class,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -62,12 +63,12 @@ final class DocumentationServiceProvider extends ServiceProvider
|
||||
$paths = [$sourcePath];
|
||||
|
||||
foreach (Config::get('view.paths', []) as $path) {
|
||||
if (is_dir($path . '/modules/documentation')) {
|
||||
array_unshift($paths, $path . '/modules/documentation');
|
||||
if (is_dir($path.'/modules/documentation')) {
|
||||
array_unshift($paths, $path.'/modules/documentation');
|
||||
}
|
||||
}
|
||||
|
||||
$this->loadViewsFrom($paths, 'documentation');
|
||||
Blade::anonymousComponentPath($sourcePath . '/components', 'documentation');
|
||||
Blade::anonymousComponentPath($sourcePath.'/components', 'documentation');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ namespace Modules\Documentation\Tests\Feature;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Modules\Documentation\Models\DocumentationAttachment;
|
||||
use Modules\Documentation\Models\DocumentationDocument;
|
||||
use Tests\TestCase;
|
||||
|
||||
|
||||
@@ -17,8 +17,7 @@ class DocumentationModuleTest extends TestCase
|
||||
/**
|
||||
* Add a CSRF token for projects that keep web middleware enabled during tests.
|
||||
*
|
||||
* @param array<string, mixed> $payload
|
||||
*
|
||||
* @param array<string, mixed> $payload
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function csrfPayload(array $payload): array
|
||||
|
||||
Reference in New Issue
Block a user