Skip to content

Commit ed40a83

Browse files
authored
Merge pull request #41 from UseDataKit/feature/translator
Add translation possibilities
2 parents 4f1355f + 6b6b0df commit ed40a83

14 files changed

+259
-14
lines changed

src/Data/CachedDataSource.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ private function get_cache_key( ...$arguments ): string {
7676
return md5( json_encode( $arguments, JSON_THROW_ON_ERROR ) );
7777
} catch ( JsonException $e ) {
7878
throw new InvalidArgumentException(
79-
'The cache key could not be generated based on the provide arguments',
79+
'The cache key could not be generated based on the provided arguments.',
8080
$e->getCode(),
8181
$e,
8282
);

src/Data/CsvDataSource.php

+4-3
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
use Closure;
88
use DataKit\DataViews\Data\DataMatcher\ArrayDataMatcher;
99
use DataKit\DataViews\Data\Exception\DataNotFoundException;
10+
use DataKit\DataViews\Data\Exception\DataSourceNotFoundException;
1011
use DataKit\DataViews\DataView\Sort;
11-
use InvalidArgumentException;
1212
use Iterator;
1313
use LimitIterator;
1414
use SplFileObject;
@@ -34,6 +34,8 @@ final class CsvDataSource extends BaseDataSource {
3434
* @since $ver$
3535
*
3636
* @param string $file_path The file path to the CSV file.
37+
*
38+
* @throws DataSourceNotFoundException When file is not readable.
3739
*/
3840
public function __construct(
3941
string $file_path,
@@ -44,7 +46,7 @@ public function __construct(
4446
if (
4547
! file_exists( $file_path )
4648
|| ! is_readable( $file_path ) ) {
47-
throw new InvalidArgumentException( 'The CSV data source file is not found or readable.' );
49+
throw new DataSourceNotFoundException();
4850
}
4951

5052
$this->file = new SplFileObject( $file_path, 'rb' );
@@ -101,7 +103,6 @@ public function get_data_by_id( string $id ): array {
101103
throw DataNotFoundException::with_id( $this, $id );
102104
}
103105

104-
105106
/**
106107
* Cleans CSV data.
107108
*

src/Data/Exception/ActionForbiddenException.php

+28-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace DataKit\DataViews\Data\Exception;
44

55
use DataKit\DataViews\Data\DataSource;
6+
use DataKit\DataViews\Translation\Translator;
67
use Throwable;
78

89
/**
@@ -20,14 +21,23 @@ final class ActionForbiddenException extends DataSourceException {
2021
*/
2122
private DataSource $data_source;
2223

24+
/**
25+
* The ID of the DataSet.
26+
*
27+
* @since $ve$
28+
*
29+
* @var string
30+
*/
31+
private string $id;
32+
2333
/**
2434
* @inheritDoc
2535
*
2636
* @since $ver$
2737
*/
2838
public function __construct(
2939
DataSource $data_source,
30-
$message = 'Action is forbidden.',
40+
$message = 'datakit.action.forbidden',
3141
$code = 403,
3242
Throwable $previous = null
3343
) {
@@ -47,7 +57,10 @@ public function __construct(
4757
* @return self The exception.
4858
*/
4959
public static function with_id( DataSource $data_source, string $id ): self {
50-
return new self( $data_source, sprintf( 'This action is forbidden for data set with id "%s".', $id ) );
60+
$exception = new self( $data_source );
61+
$exception->id = $id;
62+
63+
return $exception;
5164
}
5265

5366
/**
@@ -60,4 +73,17 @@ public static function with_id( DataSource $data_source, string $id ): self {
6073
public function data_source(): DataSource {
6174
return $this->data_source;
6275
}
76+
77+
/**
78+
* {@inheritDoc}
79+
*
80+
* @since $ver$
81+
*/
82+
public function translate( Translator $translator ): string {
83+
if ( ! isset( $this->id ) ) {
84+
return parent::translate( $translator );
85+
}
86+
87+
return $translator->translate( 'datakit.action.forbidden.with_id', [ 'id' => $this->id ] );
88+
}
6389
}

src/Data/Exception/DataNotFoundException.php

+28-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace DataKit\DataViews\Data\Exception;
44

55
use DataKit\DataViews\Data\DataSource;
6+
use DataKit\DataViews\Translation\Translator;
67
use Throwable;
78

89
/**
@@ -20,14 +21,23 @@ final class DataNotFoundException extends DataSourceException {
2021
*/
2122
private DataSource $data_source;
2223

24+
/**
25+
* The ID of the DataSet.
26+
*
27+
* @since $ve$
28+
*
29+
* @var string
30+
*/
31+
private string $id;
32+
2333
/**
2434
* @inheritDoc
2535
*
2636
* @since $ver$
2737
*/
2838
public function __construct(
2939
DataSource $data_source,
30-
$message = 'Dataset for id not found.',
40+
$message = 'datakit.data.not_found',
3141
$code = 404,
3242
Throwable $previous = null
3343
) {
@@ -47,7 +57,10 @@ public function __construct(
4757
* @return self The exception.
4858
*/
4959
public static function with_id( DataSource $data_source, string $id ): self {
50-
return new self( $data_source, sprintf( 'Data set with id "%s" not found.', $id ) );
60+
$exception = new self( $data_source );
61+
$exception->id = $id;
62+
63+
return $exception;
5164
}
5265

5366
/**
@@ -60,4 +73,17 @@ public static function with_id( DataSource $data_source, string $id ): self {
6073
public function data_source(): DataSource {
6174
return $this->data_source;
6275
}
76+
77+
/**
78+
* {@inheritDoc}
79+
*
80+
* @since $ver
81+
*/
82+
public function translate( Translator $translator ): string {
83+
if ( ! isset( $this->id ) ) {
84+
return parent::translate( $translator );
85+
}
86+
87+
return $translator->translate( 'datakit.data.not_found.with_id', [ 'id' => $this->id ] );
88+
}
6389
}

src/Data/Exception/DataSourceNotFoundException.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ final class DataSourceNotFoundException extends DataSourceException {
1717
*
1818
* @phpcs:disable Generic.CodeAnalysis.UselessOverridingMethod.Found
1919
*/
20-
public function __construct( $message = 'Data source not found.', $code = 404, Throwable $previous = null ) {
20+
public function __construct( $message = 'datakit.data_source.not_found', $code = 404, Throwable $previous = null ) {
2121
parent::__construct( $message, $code, $previous );
2222
}
2323
}

src/DataView/DataViewNotFoundException.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ final class DataViewNotFoundException extends DataViewException {
1919
* @param string $message The message.
2020
* @param Exception|null $previous The previous exception.
2121
*/
22-
public function __construct( $message = 'The DataView was not found.', Exception $previous = null ) {
22+
public function __construct( $message = 'datakit.dataview.not_found', Exception $previous = null ) {
2323
parent::__construct( $message, 404, $previous );
2424
}
2525
}

src/DataViewException.php

+11-1
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,22 @@
22

33
namespace DataKit\DataViews;
44

5+
use DataKit\DataViews\Translation\Translatable;
6+
use DataKit\DataViews\Translation\Translator;
57
use Exception;
68

79
/**
810
* Exception from the DataView namespace.
911
*
1012
* @since $ver$
1113
*/
12-
class DataViewException extends Exception {
14+
class DataViewException extends Exception implements Translatable {
15+
/**
16+
* {@inheritDoc}
17+
*
18+
* @since $ver$
19+
*/
20+
public function translate( Translator $translator ): string {
21+
return $translator->translate( $this->getMessage() );
22+
}
1323
}

src/Translation/ReplaceParameters.php

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace DataKit\DataViews\Translation;
4+
5+
/**
6+
* Helper trait to replace parameters on a string.
7+
*
8+
* @since $ver$
9+
*/
10+
trait ReplaceParameters {
11+
/**
12+
* Replaces any parameters found in square brackets with the value.
13+
*
14+
* @since $ver$
15+
*
16+
* @param string $message The message.
17+
* @param array $parameters The parameters to replace.
18+
*
19+
* @return string The message with replaced parameters.
20+
*/
21+
protected function replace_parameters( string $message, array $parameters = [] ): string {
22+
$values = array_values( $parameters );
23+
$keys = array_map( static fn( string $key ): string => '[' . $key . ']', array_keys( $parameters ) );
24+
25+
return strtr( $message, array_combine( $keys, $values ) );
26+
}
27+
}

src/Translation/Translatable.php

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace DataKit\DataViews\Translation;
4+
5+
/**
6+
* Marks a class to be translatable.
7+
*
8+
* @since $ver$
9+
*/
10+
interface Translatable {
11+
/**
12+
* Returns a messages through the provided translator.
13+
*
14+
* @since $ver$
15+
*
16+
* @param Translator $translator The translator.
17+
*
18+
* @return string The translation.
19+
*/
20+
public function translate( Translator $translator ): string;
21+
}

src/Translation/Translator.php

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace DataKit\DataViews\Translation;
4+
5+
/**
6+
* Represents a translator that can translate a message and replace placeholders.
7+
*
8+
* @since $ver$
9+
*/
10+
interface Translator {
11+
/**
12+
* Translates the message.
13+
*
14+
* @since $ver$
15+
*
16+
* @param string $message The message to translate.
17+
* @param array $parameters An array of parameters for the message.
18+
*
19+
* @return string The translated message with the
20+
*/
21+
public function translate( string $message, array $parameters = [] ): string;
22+
}

tests/Data/CsvDataSourceTest.php

+2-3
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44

55
use DataKit\DataViews\Data\CsvDataSource;
66
use DataKit\DataViews\Data\Exception\DataNotFoundException;
7+
use DataKit\DataViews\Data\Exception\DataSourceNotFoundException;
78
use DataKit\DataViews\DataView\Filter;
89
use DataKit\DataViews\DataView\Filters;
910
use DataKit\DataViews\DataView\Search;
1011
use DataKit\DataViews\DataView\Sort;
11-
use InvalidArgumentException;
1212
use PHPUnit\Framework\TestCase;
1313

1414
/**
@@ -34,14 +34,13 @@ protected function setUp(): void {
3434
$this->data_source = new CsvDataSource( __DIR__ . '/../assets/oscar-example-data.csv' );
3535
}
3636

37-
3837
/**
3938
* Test case for missing or unreadable path.
4039
*
4140
* @since $ver$
4241
*/
4342
public function test_invalid_path(): void {
44-
$this->expectException( InvalidArgumentException::class );
43+
$this->expectException( DataSourceNotFoundException::class );
4544
new CsvDataSource( 'invalid-path' );
4645
}
4746

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
namespace DataKit\DataViews\Tests\Data\Exception;
4+
5+
use DataKit\DataViews\Data\ArrayDataSource;
6+
use DataKit\DataViews\Data\Exception\ActionForbiddenException;
7+
use DataKit\DataViews\Translation\ReplaceParameters;
8+
use DataKit\DataViews\Translation\Translator;
9+
use PHPUnit\Framework\TestCase;
10+
11+
/**
12+
* Unit tests for {@see ActionForbiddenException}
13+
*
14+
* @since $ver$
15+
*/
16+
final class ActionForbiddenExceptionTest extends TestCase {
17+
/**
18+
* Test case for {@see ActionForbiddenException}.
19+
*
20+
* @since $ver$
21+
*/
22+
public function test_exception(): void {
23+
$translator = new class implements Translator {
24+
use ReplaceParameters;
25+
26+
public function translate( string $message, array $parameters = [] ): string {
27+
return $this->replace_parameters( $message, $parameters );
28+
}
29+
};
30+
31+
$data_source = new ArrayDataSource( 'test', [] );
32+
$custom_message = new ActionForbiddenException( $data_source, 'some message' );
33+
$with_id = ActionForbiddenException::with_id( $data_source, 'test-id' );
34+
35+
self::assertSame( $data_source, $custom_message->data_source() );
36+
self::assertSame( $data_source, $with_id->data_source() );
37+
38+
self::assertSame( 'some message', $custom_message->translate( $translator ) );
39+
self::assertSame( 'datakit.action.forbidden.with_id', $with_id->translate( $translator ) );
40+
}
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
namespace DataKit\DataViews\Tests\Data\Exception;
4+
5+
use DataKit\DataViews\Data\ArrayDataSource;
6+
use DataKit\DataViews\Data\Exception\DataNotFoundException;
7+
use DataKit\DataViews\Translation\ReplaceParameters;
8+
use DataKit\DataViews\Translation\Translator;
9+
use PHPUnit\Framework\TestCase;
10+
11+
/**
12+
* Unit tests for {@see DataNotFoundException}
13+
*
14+
* @since $ver$
15+
*/
16+
final class DataNotFoundExceptionTest extends TestCase {
17+
/**
18+
* Test case for {@see DataNotFoundException}.
19+
*
20+
* @since $ver$
21+
*/
22+
public function test_exception(): void {
23+
$translator = new class implements Translator {
24+
use ReplaceParameters;
25+
26+
public function translate( string $message, array $parameters = [] ): string {
27+
return $this->replace_parameters( $message, $parameters );
28+
}
29+
};
30+
31+
$data_source = new ArrayDataSource( 'test', [] );
32+
$custom_message = new DataNotFoundException( $data_source, 'some message' );
33+
$with_id = DataNotFoundException::with_id( $data_source, 'test-id' );
34+
35+
self::assertSame( $data_source, $custom_message->data_source() );
36+
self::assertSame( $data_source, $with_id->data_source() );
37+
38+
self::assertSame( 'some message', $custom_message->translate( $translator ) );
39+
self::assertSame( 'datakit.data.not_found.with_id', $with_id->translate( $translator ) );
40+
}
41+
}

0 commit comments

Comments
 (0)