Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 1 addition & 14 deletions src/Http/Controllers/FilesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,7 @@ public function index(Request $request)
$sortingMethod = config('log-viewer.defaults.file_sorting_method', SortingMethod::ModifiedTime);
$direction = $this->validateDirection($request->query('direction'));

if ($sortingMethod === SortingMethod::ModifiedTime) {
if ($direction === SortingOrder::Ascending) {
$files = $files->sortByEarliestFirst();
} else {
$files = $files->sortByLatestFirst();
}

} else {
if ($direction === SortingOrder::Ascending) {
$files = $files->sortAlphabeticallyAsc();
} else {
$files = $files->sortAlphabeticallyDesc();
}
}
$files->sortUsing($sortingMethod, $direction);

return LogFileResource::collection($files);
}
Expand Down
32 changes: 2 additions & 30 deletions src/Http/Controllers/FoldersController.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,37 +23,9 @@ public function index(Request $request)
$fileSortingMethod = config('log-viewer.defaults.file_sorting_method', SortingMethod::ModifiedTime);
$fileSortingOrder = $this->validateDirection($request->query('direction'));

if ($sortingMethod === SortingMethod::Alphabetical) {
if ($sortingOrder === SortingOrder::Ascending) {
$folders = $folders->sortAlphabeticallyAsc();
} else {
$folders = $folders->sortAlphabeticallyDesc();
}
} else { // ModifiedTime
if ($fileSortingOrder === SortingOrder::Ascending) {
$folders = $folders->sortByEarliestFirst();
} else {
$folders = $folders->sortByLatestFirst();
}
}
$folders->sortUsing($sortingMethod, $sortingOrder);

// Sort files within folders after sorting folders
$folders->each(function ($folder) use ($fileSortingMethod, $fileSortingOrder) {
if ($fileSortingMethod === SortingMethod::ModifiedTime) {
if ($fileSortingOrder === SortingOrder::Ascending) {
$folder->files()->sortByEarliestFirst();
} else {
$folder->files()->sortByLatestFirst();
}

} else {
if ($fileSortingOrder === SortingOrder::Ascending) {
$folder->files()->sortAlphabeticallyAsc();
} else {
$folder->files()->sortAlphabeticallyDesc();
}
}
});
$folders->each(fn ($folder) => $folder->files()->sortUsing($fileSortingMethod, $fileSortingOrder));

return LogFolderResource::collection($folders->values());
}
Expand Down
43 changes: 28 additions & 15 deletions src/LogFileCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,56 @@
namespace Opcodes\LogViewer;

use Illuminate\Support\Collection;
use Opcodes\LogViewer\Enums\SortingMethod;
use Opcodes\LogViewer\Enums\SortingOrder;
use Opcodes\LogViewer\Readers\MultipleLogReader;

/**
* @var LogFile[] $items
*/
class LogFileCollection extends Collection
{
public function sortByEarliestFirst(): self
public function sortUsing(string $method, string $order): self
{
$this->items = $this->sortBy(function (LogFile $file) {
return $file->earliestTimestamp().($file->name ?? '');
}, SORT_NATURAL)->values()->all();
if ($method === SortingMethod::ModifiedTime) {
if ($order === SortingOrder::Ascending) {
$this->items = $this->sortBy(function (LogFile $file) {
return $file->earliestTimestamp().($file->name ?? '');
}, SORT_NATURAL)->values()->all();
} else {
$this->items = $this->sortByDesc(function (LogFile $file) {
return $file->latestTimestamp().($file->name ?? '');
}, SORT_NATURAL)->values()->all();
}
} else {
if ($order === SortingOrder::Ascending) {
$this->items = $this->sortBy('name')->values()->all();
} else {
$this->items = $this->sortByDesc('name')->values()->all();
}
}

return $this;
}

public function sortByLatestFirst(): self
public function sortByEarliestFirst(): self
{
$this->items = $this->sortByDesc(function (LogFile $file) {
return $file->latestTimestamp().($file->name ?? '');
}, SORT_NATURAL)->values()->all();
return $this->sortUsing(SortingMethod::ModifiedTime, SortingOrder::Ascending);
}

return $this;
public function sortByLatestFirst(): self
{
return $this->sortUsing(SortingMethod::ModifiedTime, SortingOrder::Descending);
}

public function sortAlphabeticallyAsc(): self
{
$this->items = $this->sortBy('name')->values()->all();

return $this;
return $this->sortUsing(SortingMethod::Alphabetical, SortingOrder::Ascending);
}

public function sortAlphabeticallyDesc(): self
{
$this->items = $this->sortByDesc('name')->values()->all();

return $this;
return $this->sortUsing(SortingMethod::Alphabetical, SortingOrder::Descending);
}

public function latest(): ?LogFile
Expand Down
71 changes: 35 additions & 36 deletions src/LogFolderCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,40 @@
namespace Opcodes\LogViewer;

use Illuminate\Support\Collection;
use Opcodes\LogViewer\Enums\SortingMethod;
use Opcodes\LogViewer\Enums\SortingOrder;

class LogFolderCollection extends Collection
{
public function sortUsing(string $method, string $order): self
{
if ($method === SortingMethod::ModifiedTime) {
if ($order === SortingOrder::Ascending) {
$this->items = $this->sortBy->earliestTimestamp()->values()->all();
} else {
$this->items = $this->sortByDesc->latestTimestamp()->values()->all();
}
} else {
$this->items = collect($this->items)
->sort(function (LogFolder $a, LogFolder $b) use ($order) {
if ($a->isRoot() && ! $b->isRoot()) {
return -1;
}
if (! $a->isRoot() && $b->isRoot()) {
return 1;
}

return $order === SortingOrder::Ascending
? strcmp($a->cleanPath(), $b->cleanPath())
: strcmp($b->cleanPath(), $a->cleanPath());
})
->values()
->all();
}

return $this;
}

public static function fromFiles($files = []): LogFolderCollection
{
return new LogFolderCollection(
Expand All @@ -18,16 +49,12 @@ public static function fromFiles($files = []): LogFolderCollection

public function sortByEarliestFirst(): self
{
$this->items = $this->sortBy->earliestTimestamp()->values()->all();

return $this;
return $this->sortUsing(SortingMethod::ModifiedTime, SortingOrder::Ascending);
}

public function sortByLatestFirst(): self
{
$this->items = $this->sortByDesc->latestTimestamp()->values()->all();

return $this;
return $this->sortUsing(SortingMethod::ModifiedTime, SortingOrder::Descending);
}

public function sortByEarliestFirstIncludingFiles(): self
Expand All @@ -48,39 +75,11 @@ public function sortByLatestFirstIncludingFiles(): self

public function sortAlphabeticallyAsc(): self
{
$this->items = collect($this->items)
->sort(function (LogFolder $a, LogFolder $b) {
if ($a->isRoot() && ! $b->isRoot()) {
return -1;
}
if (! $a->isRoot() && $b->isRoot()) {
return 1;
}

return strcmp($a->cleanPath(), $b->cleanPath());
})
->values()
->all();

return $this;
return $this->sortUsing(SortingMethod::Alphabetical, SortingOrder::Ascending);
}

public function sortAlphabeticallyDesc(): self
{
$this->items = collect($this->items)
->sort(function (LogFolder $a, LogFolder $b) {
if ($a->isRoot() && ! $b->isRoot()) {
return -1;
}
if (! $a->isRoot() && $b->isRoot()) {
return 1;
}

return strcmp($b->cleanPath(), $a->cleanPath());
})
->values()
->all();

return $this;
return $this->sortUsing(SortingMethod::Alphabetical, SortingOrder::Descending);
}
}
54 changes: 54 additions & 0 deletions tests/Unit/LogFileCollectionTest.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

use Opcodes\LogViewer\Enums\SortingMethod;
use Opcodes\LogViewer\Enums\SortingOrder;
use Opcodes\LogViewer\Facades\LogViewer;
use Opcodes\LogViewer\LogFile;
use Opcodes\LogViewer\LogFileCollection;
Expand Down Expand Up @@ -64,3 +66,55 @@

expect($logFile)->toBe($secondFile);
});

test('LogFileCollection can sort by ModifiedTime ascending using sortUsing method', function () {
$firstFile = Mockery::mock(new LogFile('test.log'))
->allows(['earliestTimestamp' => now()->subDay()->timestamp, 'name' => 'test.log']);
$secondFile = Mockery::mock(new LogFile('test2.log'))
->allows(['earliestTimestamp' => now()->subDays(2)->timestamp, 'name' => 'test2.log']);
$collection = new LogFileCollection([$firstFile, $secondFile]);

$collection->sortUsing(SortingMethod::ModifiedTime, SortingOrder::Ascending);

expect($collection[0])->toBe($secondFile)
->and($collection[1])->toBe($firstFile);
});

test('LogFileCollection can sort by ModifiedTime descending using sortUsing method', function () {
$firstFile = Mockery::mock(new LogFile('test.log'))
->allows(['latestTimestamp' => now()->subDays(2)->timestamp, 'name' => 'test.log']);
$secondFile = Mockery::mock(new LogFile('test2.log'))
->allows(['latestTimestamp' => now()->subDay()->timestamp, 'name' => 'test2.log']);
$collection = new LogFileCollection([$firstFile, $secondFile]);

$collection->sortUsing(SortingMethod::ModifiedTime, SortingOrder::Descending);

expect($collection[0])->toBe($secondFile)
->and($collection[1])->toBe($firstFile);
});

test('LogFileCollection can sort alphabetically ascending using sortUsing method', function () {
$fileA = new LogFile('a.log');
$fileB = new LogFile('b.log');
$fileC = new LogFile('c.log');
$collection = new LogFileCollection([$fileC, $fileA, $fileB]);

$collection->sortUsing(SortingMethod::Alphabetical, SortingOrder::Ascending);

expect($collection[0])->toBe($fileA)
->and($collection[1])->toBe($fileB)
->and($collection[2])->toBe($fileC);
});

test('LogFileCollection can sort alphabetically descending using sortUsing method', function () {
$fileA = new LogFile('a.log');
$fileB = new LogFile('b.log');
$fileC = new LogFile('c.log');
$collection = new LogFileCollection([$fileA, $fileC, $fileB]);

$collection->sortUsing(SortingMethod::Alphabetical, SortingOrder::Descending);

expect($collection[0])->toBe($fileC)
->and($collection[1])->toBe($fileB)
->and($collection[2])->toBe($fileA);
});
58 changes: 58 additions & 0 deletions tests/Unit/LogFolderCollectionTest.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

use Opcodes\LogViewer\Enums\SortingMethod;
use Opcodes\LogViewer\Enums\SortingOrder;
use Opcodes\LogViewer\Facades\LogViewer;
use Opcodes\LogViewer\LogFile;
use Opcodes\LogViewer\LogFileCollection;
Expand Down Expand Up @@ -151,3 +153,59 @@
->and($collection[2])->toBe($bFolder)
->and($collection[3])->toBe($aFolder);
});

test('LogFolderCollection can sort by ModifiedTime ascending using sortUsing method', function () {
$firstFolder = Mockery::mock(new LogFolder('folder', []))
->allows(['earliestTimestamp' => now()->subDay()->timestamp]);
$secondFolder = Mockery::mock(new LogFolder('folder2', []))
->allows(['earliestTimestamp' => now()->subDays(2)->timestamp]);
$collection = new LogFolderCollection([$firstFolder, $secondFolder]);

$collection->sortUsing(SortingMethod::ModifiedTime, SortingOrder::Ascending);

expect($collection[0])->toBe($secondFolder)
->and($collection[1])->toBe($firstFolder);
});

test('LogFolderCollection can sort by ModifiedTime descending using sortUsing method', function () {
$firstFolder = Mockery::mock(new LogFolder('folder', []))
->allows(['latestTimestamp' => now()->subDays(2)->timestamp]);
$secondFolder = Mockery::mock(new LogFolder('folder2', []))
->allows(['latestTimestamp' => now()->subDay()->timestamp]);
$collection = new LogFolderCollection([$firstFolder, $secondFolder]);

$collection->sortUsing(SortingMethod::ModifiedTime, SortingOrder::Descending);

expect($collection[0])->toBe($secondFolder)
->and($collection[1])->toBe($firstFolder);
});

test('LogFolderCollection can sort alphabetically ascending using sortUsing method, with root always on top', function () {
$rootFolder = Mockery::mock(new LogFolder('', []))->allows(['isRoot' => true, 'cleanPath' => LogFolder::rootPrefix()]);
$bFolder = Mockery::mock(new LogFolder('b', []))->allows(['isRoot' => false, 'cleanPath' => 'b']);
$aFolder = Mockery::mock(new LogFolder('a', []))->allows(['isRoot' => false, 'cleanPath' => 'a']);
$zFolder = Mockery::mock(new LogFolder('z', []))->allows(['isRoot' => false, 'cleanPath' => 'z']);
$collection = new LogFolderCollection([$zFolder, $rootFolder, $bFolder, $aFolder]);

$collection->sortUsing(SortingMethod::Alphabetical, SortingOrder::Ascending);

expect($collection[0])->toBe($rootFolder)
->and($collection[1])->toBe($aFolder)
->and($collection[2])->toBe($bFolder)
->and($collection[3])->toBe($zFolder);
});

test('LogFolderCollection can sort alphabetically descending using sortUsing method, with root always on top', function () {
$rootFolder = Mockery::mock(new LogFolder('', []))->allows(['isRoot' => true, 'cleanPath' => LogFolder::rootPrefix()]);
$bFolder = Mockery::mock(new LogFolder('b', []))->allows(['isRoot' => false, 'cleanPath' => 'b']);
$aFolder = Mockery::mock(new LogFolder('a', []))->allows(['isRoot' => false, 'cleanPath' => 'a']);
$zFolder = Mockery::mock(new LogFolder('z', []))->allows(['isRoot' => false, 'cleanPath' => 'z']);
$collection = new LogFolderCollection([$aFolder, $zFolder, $rootFolder, $bFolder]);

$collection->sortUsing(SortingMethod::Alphabetical, SortingOrder::Descending);

expect($collection[0])->toBe($rootFolder)
->and($collection[1])->toBe($zFolder)
->and($collection[2])->toBe($bFolder)
->and($collection[3])->toBe($aFolder);
});
Loading