Skip to content

Commit 4e9b11e

Browse files
committed
Added file read/write
1 parent 87c7399 commit 4e9b11e

File tree

11 files changed

+240
-74
lines changed

11 files changed

+240
-74
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ php:
44
- 7.2
55
- 7.3
66
- 7.4
7-
- 8.0
7+
- nightly
88

99
install:
1010
- composer self-update

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
## [Unreleased]
99

1010
### Added
11+
- Added the option to write conversions to files.
12+
- Added the option to load conversions from files.
1113
- Added case-sensitive option for encoding validation.
1214
- Added support for php 8.0.
1315

docs/encoding.md

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,35 @@ echo $newstr; // "Calendrier de l'avent façon Necta!" in US-ASCII encoding.
5151

5252
### Read sources
5353

54-
Currently, we only support loading from strings, as the examples above show. We will add additional ways to read sources in future versions. If you have any suggestions please let us know by opening an issue.
54+
The `ConvertReadInterface` gives access to the the methods available to read strings into the converter. You can both read from a string variable or you can read from a file.
55+
56+
#### Read from file
57+
58+
```php
59+
<?php
60+
61+
use StringEncoder\Encoder;
62+
63+
$encoder = new Encoder();
64+
$newString = $encoder->convert()->fromFile('./path/to/file.txt')->toString();
65+
echo $newString; // the contents of the file in UTF-8 encoding (default).
66+
```
5567

5668
### Write sources
5769

58-
The `ConvertWriteInterface` allows you to both convert the string to another string or a DTO. This allows you the flexibility to decide how you want to receive the data from the convert action.
70+
The `ConvertWriteInterface` allows you to both convert the string to another string, file, or a DTO. This allows you the flexibility to decide how you want to receive the data from the convert action.
71+
72+
#### Write to file
73+
74+
```php
75+
<?php
76+
77+
use StringEncoder\Encoder;
78+
79+
$str = "Calendrier de l'avent façon Necta!";
80+
$encoder = new Encoder();
81+
$encoder->convert()->fromString($str)->toFile('./path/to/file.txt'); // file.txt will be created and the contents will be put in it.
82+
```
5983

6084
#### Write to DTO
6185

src/StringEncoder/Contracts/ConvertReadInterface.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,19 @@
44

55
namespace StringEncoder\Contracts;
66

7+
use StringEncoder\Exceptions\ContentsFailedException;
8+
use StringEncoder\Exceptions\InvalidEncodingException;
9+
710
interface ConvertReadInterface
811
{
12+
/**
13+
* @throws InvalidEncodingException
14+
*/
915
public function fromString(string $value): ConvertWriteInterface;
16+
17+
/**
18+
* @throws ContentsFailedException
19+
* @throws InvalidEncodingException
20+
*/
21+
public function fromFile(string $filePath): ConvertWriteInterface;
1022
}

src/StringEncoder/Contracts/ConvertWriteInterface.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,24 @@
55
namespace StringEncoder\Contracts;
66

77
use StringEncoder\Contracts\DTO\MBStringDTOInterface;
8+
use StringEncoder\Exceptions\ContentsFailedException;
9+
use StringEncoder\Exceptions\ConvertNoValueException;
810

911
interface ConvertWriteInterface
1012
{
13+
/**
14+
* @throws ConvertNoValueException
15+
*/
1116
public function toString(): string;
1217

18+
/**
19+
* @throws ContentsFailedException
20+
* @throws ConvertNoValueException
21+
*/
22+
public function toFile(string $path): void;
23+
24+
/**
25+
* @throws ConvertNoValueException
26+
*/
1327
public function toDTO(): MBStringDTOInterface;
1428
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace StringEncoder\Exceptions;
6+
7+
class ContentsFailedException extends \Exception
8+
{
9+
}

src/StringEncoder/MB/Convert.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use StringEncoder\Contracts\DTO\MBStringDTOInterface;
1111
use StringEncoder\Contracts\OptionsInterface;
1212
use StringEncoder\DTO\MBStringDTO;
13+
use StringEncoder\Exceptions\ContentsFailedException;
1314
use StringEncoder\Exceptions\ConvertNoValueException;
1415
use StringEncoder\Exceptions\InvalidEncodingException;
1516
use StringEncoder\MB\UTF8\Bom;
@@ -59,6 +60,9 @@ public function __construct(
5960
$this->targetEncoding = $targetEncoding;
6061
}
6162

63+
/**
64+
* @throws InvalidEncodingException
65+
*/
6266
public function fromString(string $value): ConvertWriteInterface
6367
{
6468
$this->convert($value);
@@ -78,6 +82,42 @@ public function toString(): string
7882
return $this->mbStringDTO->getString();
7983
}
8084

85+
/**
86+
* @throws ContentsFailedException
87+
* @throws InvalidEncodingException
88+
*/
89+
public function fromFile(string $filePath): ConvertWriteInterface
90+
{
91+
$content = @\file_get_contents($filePath);
92+
if ($content === false) {
93+
throw new ContentsFailedException('file_get_contents failed and returned false when trying to read "' . $filePath . '".');
94+
}
95+
96+
$this->convert($content);
97+
98+
return $this;
99+
}
100+
101+
/**
102+
* @throws ContentsFailedException
103+
* @throws ConvertNoValueException
104+
*/
105+
public function toFile(string $filePath): void
106+
{
107+
if ($this->mbStringDTO === null) {
108+
throw new ConvertNoValueException('No value set for call to convert to string.');
109+
}
110+
111+
$string = $this->mbStringDTO->getString();
112+
$status = @\file_put_contents($filePath, $string);
113+
if ($status === false) {
114+
throw new ContentsFailedException('file_put_contents failed and returned false when trying to write "' . $filePath . '".');
115+
}
116+
}
117+
118+
/**
119+
* @throws ConvertNoValueException
120+
*/
81121
public function toDTO(): MBStringDTOInterface
82122
{
83123
if ($this->mbStringDTO === null) {
@@ -87,6 +127,9 @@ public function toDTO(): MBStringDTOInterface
87127
return $this->mbStringDTO;
88128
}
89129

130+
/**
131+
* @throws InvalidEncodingException
132+
*/
90133
private function convert(string $value): void
91134
{
92135
if ($this->sourceEncoding === null) {

src/StringEncoder/MB/Validator.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public function determineEncoding(string $encoding, bool $caseSensitive): ?strin
2626
foreach ($encodingList as $validEncoding) {
2727
if ($validEncoding === $encoding || (
2828
$caseSensitive === false &&
29-
mb_convert_case($validEncoding, MB_CASE_LOWER) === mb_convert_case($encoding, MB_CASE_LOWER))
29+
\mb_convert_case($validEncoding, MB_CASE_LOWER) === \mb_convert_case($encoding, MB_CASE_LOWER))
3030
) {
3131
return $validEncoding;
3232
}
@@ -54,7 +54,7 @@ private function validateEncodingAlias(string $encoding, string $validEncoding,
5454
if ($caseSensitive) {
5555
$aliasEncoding = \mb_encoding_aliases($validEncoding);
5656
} else {
57-
$encoding = mb_convert_case($encoding, MB_CASE_LOWER);
57+
$encoding = \mb_convert_case($encoding, MB_CASE_LOWER);
5858
$aliasEncoding = $this->lowerCaseArray(\mb_encoding_aliases($validEncoding));
5959
}
6060

@@ -63,14 +63,16 @@ private function validateEncodingAlias(string $encoding, string $validEncoding,
6363

6464
/**
6565
* @internal
66+
*
6667
* @param string[] $encodings
68+
*
6769
* @return string[]
6870
*/
6971
private function lowerCaseArray(array $encodings): array
7072
{
7173
$newEncodings = [];
7274
foreach ($encodings as $key => $encoding) {
73-
$newEncodings[$key] = mb_convert_case($encoding, MB_CASE_LOWER);
75+
$newEncodings[$key] = \mb_convert_case($encoding, MB_CASE_LOWER);
7476
}
7577

7678
return $newEncodings;

tests/data/data.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
this is a random string, so random it is the most random string.

tests/tests/MB/ConvertFileTest.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace tests\MB;
6+
7+
use PHPUnit\Framework\TestCase;
8+
use StringEncoder\DTO\EncodingDTO;
9+
use StringEncoder\Exceptions\ContentsFailedException;
10+
use StringEncoder\Exceptions\ConvertNoValueException;
11+
use StringEncoder\MB\Convert;
12+
13+
class ConvertFileTest extends TestCase
14+
{
15+
/**
16+
* @var Convert
17+
*/
18+
private $convert;
19+
20+
public function setUp()
21+
{
22+
$this->convert = new Convert(
23+
EncodingDTO::makeFromString('ISO-8859-1'),
24+
EncodingDTO::makeFromString('UTF-8')
25+
);
26+
}
27+
28+
public function testFromFile()
29+
{
30+
$string = $this->convert->fromFile('./tests/data/data.txt')->toString();
31+
$this->assertEquals('this is a random string, so random it is the most random string.', $string);
32+
}
33+
34+
public function testFromFileNotFound()
35+
{
36+
$this->expectException(ContentsFailedException::class);
37+
$this->convert->fromFile('./path/not/fount.txt');
38+
}
39+
40+
public function testToFile()
41+
{
42+
$this->convert->fromFile('./tests/data/data.txt')->toFile('./tests/data/test.data.txt');
43+
$string = $this->convert->fromFile('./tests/data/test.data.txt')->toString();
44+
unlink('./tests/data/test.data.txt');
45+
$this->assertEquals('this is a random string, so random it is the most random string.', $string);
46+
}
47+
48+
public function testToFileNoFrom()
49+
{
50+
$this->expectException(ConvertNoValueException::class);
51+
$this->convert->toFile('./tests/data/test.data.txt');
52+
}
53+
54+
public function testToFileDirectory()
55+
{
56+
$this->expectException(ContentsFailedException::class);
57+
$this->convert->fromFile('./tests/data/data.txt')->toFile('./tests');
58+
59+
}
60+
}

0 commit comments

Comments
 (0)