Skip to content

Commit 57ef8dc

Browse files
authored
Merge pull request #2353 from Blair2004/v5.0.x
V5.0.x
2 parents 106b6c6 + fdcfce6 commit 57ef8dc

39 files changed

+397
-82
lines changed

app/Classes/Cache.php

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
<?php
2+
3+
namespace App\Classes;
4+
5+
use Illuminate\Support\Facades\Cache as CoreCache;
6+
7+
class Cache extends CoreCache
8+
{
9+
protected static function applyPrefix( $key )
10+
{
11+
return Hook::filter( 'ns-cache-prefix', $key );
12+
}
13+
14+
/**
15+
* Check if a key exists in the cache.
16+
*
17+
* @param string $key
18+
* @return bool
19+
*/
20+
public static function has( $key )
21+
{
22+
$key = self::applyPrefix( $key );
23+
24+
return parent::has( $key );
25+
}
26+
27+
/**
28+
* Check if a key is missing from the cache.
29+
*
30+
* @param string $key
31+
* @return bool
32+
*/
33+
public static function missing( $key )
34+
{
35+
$key = self::applyPrefix( $key );
36+
37+
return parent::missing( $key );
38+
}
39+
40+
/**
41+
* Retrieve a value from the cache.
42+
*
43+
* @param string $key
44+
* @param mixed $default
45+
* @return mixed
46+
*/
47+
public static function get( $key, $default = null )
48+
{
49+
$key = self::applyPrefix( $key );
50+
51+
return parent::get( $key, $default );
52+
}
53+
54+
/**
55+
* Retrieve multiple values from the cache.
56+
*
57+
* @param array $keys
58+
* @param mixed $default
59+
* @return array
60+
*/
61+
public static function getMultiple( $keys, $default = null )
62+
{
63+
$keys = array_map( [self::class, 'applyPrefix'], $keys );
64+
65+
return parent::getMultiple( $keys, $default );
66+
}
67+
68+
/**
69+
* Retrieve and delete a value from the cache.
70+
*
71+
* @param string $key
72+
* @param mixed $default
73+
* @return mixed
74+
*/
75+
public static function pull( $key, $default = null )
76+
{
77+
$key = self::applyPrefix( $key );
78+
79+
return parent::pull( $key, $default );
80+
}
81+
82+
/**
83+
* Store a value in the cache for a given time-to-live (TTL).
84+
*
85+
* @param string $key
86+
* @param mixed $value
87+
* @param int|null $ttl
88+
* @return bool
89+
*/
90+
public static function put( $key, $value, $ttl = null )
91+
{
92+
$key = self::applyPrefix( $key );
93+
94+
return parent::put ( $key, $value, $ttl );
95+
}
96+
97+
public static function set( $key, $value, $ttl = null )
98+
{
99+
$key = self::applyPrefix( $key );
100+
101+
return parent::set( $key, $value, $ttl );
102+
}
103+
104+
/**
105+
* Store multiple key-value pairs in the cache for a given time-to-live (TTL).
106+
*
107+
* @param array $values
108+
* @param int|null $ttl
109+
* @return bool
110+
*/
111+
public static function putMany( array $values, $ttl = null )
112+
{
113+
$prefixedValues = [];
114+
foreach ( $values as $key => $value ) {
115+
$prefixedValues[self::applyPrefix( $key )] = $value;
116+
}
117+
118+
return parent::putMany( $prefixedValues, $ttl );
119+
}
120+
121+
/**
122+
* Store multiple key-value pairs in the cache indefinitely.
123+
*
124+
* @param array $values
125+
* @param int|null $ttl
126+
* @return bool
127+
*/
128+
public static function setMultiple( $values, $ttl = null )
129+
{
130+
$prefixedValues = [];
131+
foreach ( $values as $key => $value ) {
132+
$prefixedValues[self::applyPrefix( $key )] = $value;
133+
}
134+
135+
return parent::setMultiple( $prefixedValues, $ttl );
136+
}
137+
138+
/**
139+
* Add a value to the cache if it does not already exist.
140+
*
141+
* @param string $key
142+
* @param mixed $value
143+
* @param int|null $ttl
144+
* @return bool
145+
*/
146+
public static function add( $key, $value, $ttl = null )
147+
{
148+
$key = self::applyPrefix( $key );
149+
150+
return parent::add( $key, $value, $ttl );
151+
}
152+
153+
/**
154+
* Increment a value in the cache.
155+
*
156+
* @param string $key
157+
* @param int $value
158+
* @return int|bool
159+
*/
160+
public static function increment( $key, $value = 1 )
161+
{
162+
$key = self::applyPrefix( $key );
163+
164+
return parent::increment( $key, $value );
165+
}
166+
167+
/**
168+
* Decrement a value in the cache.
169+
*
170+
* @param string $key
171+
* @param int $value
172+
* @return int|bool
173+
*/
174+
public static function decrement( $key, $value = 1 )
175+
{
176+
$key = self::applyPrefix( $key );
177+
178+
return parent::decrement( $key, $value );
179+
}
180+
181+
/**
182+
* Store a value in the cache indefinitely.
183+
*
184+
* @param string $key
185+
* @param mixed $value
186+
* @return bool
187+
*/
188+
public static function forever( $key, $value )
189+
{
190+
$key = self::applyPrefix( $key );
191+
192+
return parent::forever( $key, $value );
193+
}
194+
195+
/**
196+
* Remember a value in the cache for a given time-to-live (TTL).
197+
*
198+
* @param string $key
199+
* @param int $ttl
200+
* @param callable $callback
201+
* @return mixed
202+
*/
203+
public static function remember( $key, $ttl, $callback )
204+
{
205+
$key = self::applyPrefix( $key );
206+
207+
return parent::remember( $key, $ttl, $callback );
208+
}
209+
210+
/**
211+
* Remember a value in the cache indefinitely.
212+
*
213+
* @param string $key
214+
* @param callable $callback
215+
* @return mixed
216+
*/
217+
public static function rememberForever( $key, $callback )
218+
{
219+
$key = self::applyPrefix( $key );
220+
221+
return parent::rememberForever( $key, $callback );
222+
}
223+
224+
/**
225+
* Forget a value in the cache.
226+
*
227+
* @param string $key
228+
* @return bool
229+
*/
230+
public static function forget( $key )
231+
{
232+
$key = self::applyPrefix( $key );
233+
234+
return parent::forget( $key );
235+
}
236+
237+
/**
238+
* Delete a value from the cache.
239+
*
240+
* @param string $key
241+
* @return bool
242+
*/
243+
public static function delete( $key )
244+
{
245+
$key = self::applyPrefix( $key );
246+
247+
return parent::delete( $key );
248+
}
249+
250+
/**
251+
* Delete multiple values from the cache.
252+
*
253+
* @param array $keys
254+
* @return bool
255+
*/
256+
public static function deleteMultiple( $keys )
257+
{
258+
$keys = array_map( [self::class, 'applyPrefix'], $keys );
259+
260+
return parent::deleteMultiple( $keys );
261+
}
262+
}

app/Console/Commands/ExtractTranslation.php

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ private function extractForModuleLanguage( $lang, $module, $files )
8585
$finalArray = $this->extractLocalization( $files->flatten() );
8686
$finalArray = $this->flushTranslation( $finalArray, $filePath );
8787

88-
Storage::disk( 'ns' )->put( $filePath, json_encode( $finalArray ) );
88+
Storage::disk( 'ns' )->put( $filePath, json_encode( $finalArray, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
8989

9090
$this->newLine();
9191
$this->info( sprintf( __( 'Localization for %s extracted to %s' ), config( 'nexopos.languages' )[ $lang ], $filePath ) );
@@ -156,7 +156,7 @@ private function extractLanguageForSystem( $lang, $files )
156156
$finalArray = $this->extractLocalization( $files );
157157
$finalArray = $this->flushTranslation( $finalArray, $filePath );
158158

159-
Storage::disk( 'ns' )->put( 'lang/' . $lang . '.json', json_encode( $finalArray ) );
159+
Storage::disk( 'ns' )->put( 'lang/' . $lang . '.json', json_encode( $finalArray, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
160160

161161
$this->newLine();
162162
$this->info( 'Extraction complete for language : ' . config( 'nexopos.languages' )[ $lang ] );
@@ -203,25 +203,36 @@ private function flushTranslation( $newTranslation, $filePath )
203203
private function extractLocalization( $files )
204204
{
205205
$supportedExtensions = [ 'vue', 'php', 'ts', 'js' ];
206+
$excludedDirectories = [ 'resources/views/generate' ];
206207

207-
$filtered = collect( $files )->filter( function ( $file ) use ( $supportedExtensions ) {
208+
$filtered = collect( $files )->filter( function ( $file ) use ( $supportedExtensions, $excludedDirectories ) {
208209
$info = pathinfo( $file );
210+
foreach ( $excludedDirectories as $excludedDir ) {
211+
if ( str_starts_with( $info['dirname'], $excludedDir ) ) {
212+
return false;
213+
}
214+
}
209215

210216
return in_array( $info[ 'extension' ], $supportedExtensions );
211217
} );
212218

213219
$exportable = [];
214220

215221
/**
216-
* we'll extract all the string that can be translated
222+
* we'll extract all the strings that can be translated
217223
* and save them within an array.
218224
*/
219225
$this->withProgressBar( $filtered, function ( $file ) use ( &$exportable ) {
220226
$fileContent = Storage::disk( 'ns' )->get( $file );
221-
preg_match_all( '/__[m]?\(\s*(?(?=[\'"`](?:[\s\S]*?)[\'"`](?:,\s*(?:[^)]*))?)[\'"`]([\s\S]*?)[\'"`](?:,\s*(?:[^)]*))?|)\s*\)/', $fileContent, $output_array );
222-
223-
if ( isset( $output_array[1] ) ) {
224-
foreach ( $output_array[1] as $string ) {
227+
$contentWithoutCommentBlocks = preg_replace( '/(\/\*.*?\*\/)/is', ' ', $fileContent );
228+
preg_match_all( '/__[m]?\(\s*([\'"`])(?<text>(?:\\\\\1|(?!\1)[\S\s])*)(\1)\s*(?:,\s*[\'"`]?(?<arg>\w*)[\'"`]?\s*)?\)/', $contentWithoutCommentBlocks, $output_array );
229+
230+
if ( isset( $output_array['text'] ) ) {
231+
foreach ( $output_array['text'] as $i => $rawString ) {
232+
$delimiter = $output_array[1][$i];
233+
$fileExtension = pathinfo( $file, PATHINFO_EXTENSION );
234+
$rawString = str_replace( "\r", '', $rawString ); // remove \r if not explicitly encoded in string as escape sequence
235+
$string = $this->unescapeString( $rawString, $delimiter, $fileExtension );
225236
$exportable[ $string ] = compact( 'file', 'string' );
226237
}
227238
}
@@ -231,4 +242,37 @@ private function extractLocalization( $files )
231242
return [ $exportable[ 'string' ] => $exportable[ 'string' ] ];
232243
} )->toArray();
233244
}
245+
246+
private function unescapeString( string $string, string $delimiter, string $fileExt ): string
247+
{
248+
if ( $fileExt === 'php' ) {
249+
if ( $delimiter === "'" ) {
250+
// PHP single-quoted strings only handle \' and \\, for others the backslash is kept!
251+
return str_replace( ['\\\\', "\'"], ['\\', "'"], $string );
252+
} elseif ( $delimiter === '"' ) {
253+
// PHP double-quoted string handle several escape sequences, for others the backslash is kept!
254+
$string = str_replace( ['\\\\', "\'", '\n', '\r', '\t', '\v', '\e', '\f', '\$', '\"'], ['\\', "'", "\n", "\r", "\t", "\v", "\e", "\f", '$', '"'], $string );
255+
256+
// handle octal \777 and hex \xFF escapes; unicode escapes \u{....} are currently not implemented!
257+
return $this->replaceHexEscapes( $this->replaceOctalEscapes( $string ) );
258+
}
259+
}
260+
261+
// JS removes the backslash for invalid/unknown escape sequences
262+
return stripslashes( $string );
263+
}
264+
265+
private function replaceOctalEscapes( $string ): string
266+
{
267+
return preg_replace_callback( '/\\\([0-7]{1,3})/', function ( $matches ) {
268+
return chr( octdec( $matches[1] ) );
269+
}, $string );
270+
}
271+
272+
private function replaceHexEscapes( $string ): string
273+
{
274+
return preg_replace_callback( '/\x([0-9a-fA-F]{1,2})/', function ( $matches ) {
275+
return chr( hexdec( $matches[1] ) );
276+
}, $string );
277+
}
234278
}

app/Console/Commands/MakeFieldsCommand.php

Whitespace-only changes.

app/Crud/PaymentTypeCrud.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace App\Crud;
44

5+
use App\Classes\Cache;
56
use App\Classes\CrudForm;
67
use App\Classes\FormInput;
78
use App\Exceptions\NotAllowedException;
@@ -11,7 +12,6 @@
1112
use App\Services\CrudService;
1213
use App\Services\Helper;
1314
use Illuminate\Http\Request;
14-
use Illuminate\Support\Facades\Cache;
1515
use Illuminate\Support\Str;
1616
use TorMorten\Eventy\Facades\Events as Hook;
1717

0 commit comments

Comments
 (0)