asUrl()   A
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 11
nc 1
nop 2
dl 0
loc 18
rs 9.9
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Composable strings functions.
5
 *
6
 * This file is part of PinkCrab Function Constructors.
7
 *
8
 * PinkCrab Function Constructors is free software: you can redistribute it and/or modify it under the terms of the
9
 * GNU General Public License as published by the Free Software Foundation, either version 2
10
 * of the License, or (at your option) any later version.
11
 *
12
 * PinkCrab Function Constructors is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
13
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
 * See the GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with PinkCrab Function Constructors.
17
 * If not, see <https://www.gnu.org/licenses/>.
18
 *
19
 * @author Glynn Quelch <[email protected]>
20
 * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
21
 * @package PinkCrab\FunctionConstructors
22
 * @since 0.0.1
23
 *
24
 * @template Number of int|float
25
 * @phpstan-template Number of int|float
26
 * @psalm-template Number of int|float
27
 */
28
29
declare(strict_types=1);
30
31
namespace PinkCrab\FunctionConstructors\Strings;
32
33
use Closure;
34
use PinkCrab\FunctionConstructors\Comparisons as C;
0 ignored issues
show
Bug introduced by
The type PinkCrab\FunctionConstructors\Comparisons was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
35
use PinkCrab\FunctionConstructors\GeneralFunctions as F;
0 ignored issues
show
Bug introduced by
The type PinkCrab\FunctionConstructors\GeneralFunctions was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
36
37
/**
38
 * Creates a callable for wrapping a string.
39
 * By defaults uses opening as closing, if no closing defined.
40
 *
41
 * @param string $opening
42
 * @param string|null $closing
43
 * @return Closure(string):string
44
 */
45
function wrap(string $opening, ?string $closing = null): Closure
46
{
47
    /**
48
     * @param string $string
49
     * @return string
50
     */
51
    return function (string $string) use ($opening, $closing): string {
52
        return \sprintf('%s%s%s', $opening, $string, $closing ?? $opening);
53
    };
54
}
55
56
/**
57
 * Creates a callable for wrapping a string with html/xml style tags.
58
 * By defaults uses opening as closing, if no closing defined.
59
 *
60
 * @param string $openingTag
61
 * @param string|null $closingTag
62
 * @return Closure(string):string
63
 */
64
function tagWrap(string $openingTag, ?string $closingTag = null): Closure
65
{
66
    /**
67
     * @param string $string
68
     * @return string
69
     */
70
    return function (string $string) use ($openingTag, $closingTag): string {
71
        return \sprintf('<%s>%s</%s>', $openingTag, $string, $closingTag ?? $openingTag);
72
    };
73
}
74
75
/**
76
 * Creates a callable for turning a string into a url.
77
 *
78
 * @param string $url
79
 * @param string|null $target
80
 * @return Closure(string):string
81
 */
82
function asUrl(string $url, ?string $target = null): Closure
83
{
84
    /**
85
     * @param string $string
86
     * @return string
87
     */
88
    return function (string $string) use ($url, $target): string {
89
        return $target ?
90
            \sprintf(
91
                "<a href='%s' target='%s'>%s</a>",
92
                $url,
93
                $target,
94
                $string
95
            ) :
96
            \sprintf(
97
                "<a href='%s'>%s</a>",
98
                $url,
99
                $string
100
            );
101
    };
102
}
103
104
105
/**
106
 * Creates a callable for slicing a string
107
 *
108
 * Uses substr()
109
 *
110
 * @param int $start start position
111
 * @param int|null $finish end position
112
 * @return Closure(string):string
113
 */
114
function slice(int $start, ?int $finish = null): Closure
115
{
116
    /**
117
     * @param string $string
118
     * @return string
119
     */
120
    return function (string $string) use ($start, $finish): string {
121
        return ! $finish
122
            ? substr($string, $start)
123
            : substr($string, $start, $finish);
124
    };
125
}
126
127
/**
128
 * Creates a callable for prepending to a string.
129
 *
130
 * @param string $prepend
131
 * @return Closure(string):string
132
 */
133
function prepend(string $prepend): Closure
134
{
135
    /**
136
     * @param string $string
137
     * @return string
138
     */
139
    return function (string $string) use ($prepend): string {
140
        return \sprintf('%s%s', $prepend, $string);
141
    };
142
}
143
144
/**
145
 * Creates a callable for appending to a string.
146
 *
147
 * @param string $append
148
 * @return Closure(string):string
149
 */
150
function append(string $append): Closure
151
{
152
    /**
153
     * @param string $string
154
     * @return string
155
     */
156
    return function (string $string) use ($append): string {
157
        return \sprintf('%s%s', $string, $append);
158
    };
159
}
160
161
/**
162
 * Returns a callable for formatting a string with a defined set of rules
163
 *
164
 * @param array<string, mixed> $args
165
 * @return Closure(string):string
166
 */
167
function vSprintf(array $args = array()): Closure
168
{
169
    /**
170
     * @param string $string
171
     * @return string Will return original string if false.
172
     */
173
    return function (string $string) use ($args): string {
174
        $result = \vsprintf($string, $args);
175
        return ! C\isFalse($result) ? $result : $string;
0 ignored issues
show
Unused Code introduced by
The call to isFalse() has too many arguments starting with $result. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

175
        return ! /** @scrutinizer ignore-call */ C\isFalse($result) ? $result : $string;

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
176
    };
177
}
178
179
/**
180
 * Creates a double curried find to replace.
181
 *
182
 * @param string $find Value to look for
183
 * @return Closure(string):Closure(string):string
184
 */
185
function findToReplace(string $find): Closure
186
{
187
    /**
188
     * @param string $replace value to replace with
189
     * @return Closure(string):string
190
     */
191
    return function (string $replace) use ($find): Closure {
192
        /**
193
         * @param string $subject String to carry out find and replace.
194
         * @return string
195
         */
196
        return function ($subject) use ($find, $replace): string {
197
            return \str_replace($find, $replace, $subject);
198
        };
199
    };
200
}
201
202
/**
203
 * Creates a Closure to find and replace within a string.
204
 *
205
 * @param string  $find
206
 * @param string  $replace
207
 * @return Closure(string):string
208
 */
209
function replaceWith(string $find, string $replace): Closure
210
{
211
    /**
212
     * @param string $source
213
     * @return string
214
     */
215
    return function ($source) use ($find, $replace): string {
216
        return \str_replace($find, $replace, $source);
217
    };
218
}
219
220
/**
221
 * Returns a callable that can replace a sub string with a pre defined value.
222
 *
223
 * @param string $replace The value to replace in passed string
224
 * @param int $offset The offset to start, negative numbers count back from end.
225
 * @param int|null $length Number of chars to stop replacing at end of replacement.
226
 * @return Closure(string):string
227
 */
228
function replaceSubString(string $replace, int $offset = 0, ?int $length = null): Closure
229
{
230
    /**
231
     * @param string $string
232
     * @return string
233
     */
234
    return function (string $string) use ($replace, $offset, $length): string {
235
        return $length
0 ignored issues
show
Bug Best Practice introduced by
The expression return $length ? substr_...ing, $replace, $offset) could return the type array which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
236
            ? \substr_replace($string, $replace, $offset, $length)
237
            : \substr_replace($string, $replace, $offset);
238
    };
239
}
240
241
/**
242
 * Creates a callable for checking if a string starts with
243
 *
244
 * @param string $find The value to look for.
245
 * @return Closure(string):bool
246
 */
247
function startsWith(string $find): Closure
248
{
249
    /**
250
     * @param string $source
251
     * @return bool
252
     */
253
    return function (string $source) use ($find): bool {
254
        return (\substr($source, 0, \strlen($find)) === $find);
255
    };
256
}
257
258
/**
259
 * Creates a callable for checkin if a string ends with
260
 *
261
 * @param string $find The value to look for.
262
 * @return Closure(string):bool
263
 */
264
function endsWith(string $find): Closure
265
{
266
    /**
267
     * @param string $source
268
     * @return bool
269
     */
270
    return function (string $source) use ($find): bool {
271
        if (\strlen($find) === 0) {
272
            return true;
273
        }
274
        return (\substr($source, -\strlen($find)) === $find);
275
    };
276
}
277
278
/**
279
 * Creates a callable for checking if a string contains. using stringContains
280
 *
281
 * @param string $needle The value to look for.
282
 * @return Closure(string):bool
283
 */
284
function contains(string $needle): Closure
285
{
286
    /**
287
     * @param string $haystack String to look in.
288
     * @return bool
289
     */
290
    return function (string $haystack) use ($needle): bool {
291
        return \stringContains($haystack, $needle);
292
    };
293
}
294
295
/**
296
 * Creates a callable for checking if a string contains using preg_match.
297
 *
298
 * @param string $pattern
299
 * @return Closure(string):bool
300
 */
301
function containsPattern(string $pattern): Closure
302
{
303
    /**
304
     * @param string $source String to look in.
305
     * @return bool
306
     */
307
    return function (string $source) use ($pattern): bool {
308
        return (bool) \preg_match($pattern, $source);
309
    };
310
}
311
312
/**
313
 * Splits a string with a pattern
314
 *
315
 * @param string $pattern
316
 * @return Closure(string):?string[]
317
 */
318
function splitPattern(string $pattern): Closure
319
{
320
    /**
321
     * @param string $name
322
     * @return string[]
323
     */
324
    return function (string $string) use ($pattern): ?array {
325
        return \preg_split($pattern, $string) ?: null;
326
    };
327
}
328
329
/**
330
 * Converts a number (loose type) to a string representation of a float.
331
 *
332
 * @param string|int|float $precision Number of decimal places
333
 * @param string $point The decimal separator
334
 * @param string $thousands The thousand separator.
335
 * @return Closure(string|int|float):string
336
 */
337
function decimalNumber($precision = 2, $point = '.', $thousands = ''): Closure
338
{
339
    /**
340
     * @param string|int|float $number
341
     * @return string
342
     */
343
    return function ($number) use ($precision, $point, $thousands): string {
344
        return \is_numeric($number)
345
            ? \number_format((float) $number, (int) $precision, $point, $thousands)
346
            : '';
347
    };
348
}
349
350
351
352
/**
353
 * Returns a callable for adding C slashes to a string based on a defined char list.
354
 *
355
 * @param string $charList The Char list to add slashes too.
356
 * @return Closure(string):string
357
 */
358
function addSlashes(string $charList): Closure
359
{
360
    /**
361
     * @param string $string The string to have char, slash escaped.
362
     * @return string
363
     */
364
    return function (string $string) use ($charList): string {
365
        return \addcslashes($string, $charList);
366
    };
367
}
368
369
/**
370
 * Returns a callable for splitting a string by a set amount.
371
 *
372
 * @param int $length The length to split the string up with.
373
 * @return Closure(string):array<string> The parts.
374
 */
375
function split(int $length): Closure
376
{
377
    /**
378
     * @param string $string The string to be split
379
     * @return array<int, string>
380
     */
381
    return function (string $string) use ($length): array {
382
        return \str_split($string, max(1, $length)) ?: array(); // @phpstan-ignore-line, inconsistent errors with differing php versions.
0 ignored issues
show
Bug Best Practice introduced by
The expression return str_split($string...1, $length)) ?: array() could return the type true which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
383
    };
384
}
385
386
/**
387
 * Returns a callback for splitting a string into chunks.
388
 *
389
 * @param int $length The length of each chunk.
390
 * @param string $end The string to use at the end.
391
 * @return Closure(string):string
392
 */
393
function chunk(int $length, string $end = "\r\n"): Closure
394
{
395
    /**
396
     * @param string $string The string to be chunked
397
     * @return string
398
     */
399
    return function (string $string) use ($length, $end): string {
400
        return \chunk_split($string, max(1, $length), $end);
401
    };
402
}
403
404
/**
405
 * Creates a callable for wrapping a string to a defined value.
406
 *
407
 * @param int $width Max width for each "line"
408
 * @param string $break The string to use to denote the end of line.
409
 * @param bool $cut If set to true, words are cut at $width, else overflow.
410
 * @return Closure(string):string
411
 */
412
function wordWrap(int $width, string $break = "\n", bool $cut = false): Closure
413
{
414
    /**
415
     * @param string $string The string to be wrapped
416
     * @return string
417
     */
418
    return function (string $string) use ($width, $break, $cut): string {
419
        return \wordwrap($string, $width, $break, $cut);
420
    };
421
}
422
423
/**
424
 * Returns a callback for counting the number of occurrences of each char in a string.
425
 *
426
 * @link https://www.php.net/manual/en/function.count-chars.php
427
 * @param int $mode See the PHP docs for details.
428
 * @return Closure(string):(int[]|string)
429
 */
430
function countChars(int $mode = 1): Closure
431
{
432
    // Throw an exception if the mode is not supported.
433
    if (! in_array($mode, array( 0, 1, 2, 3, 4 ), true)) {
434
        throw new \InvalidArgumentException('Invalid mode');
435
    }
436
437
    /**
438
     * @param string $string The string to have its char counted.
439
     * @return int[]|string
440
     */
441
    return function (string $string) use ($mode) {
442
        return \count_chars($string, $mode);
443
    };
444
}
445
446
/**
447
 * Returns a callable that counts the occurrences of a given substring in a string
448
 *
449
 * @param string $needle The substring to find
450
 * @param int $offset Place to start, defaults to 0 (start)
451
 * @param int|null $length Max length after offset to search.
452
 * @return Closure(string):int
453
 */
454
function countSubString(string $needle, int $offset = 0, ?int $length = null): Closure
455
{
456
    /**
457
     * @param string $haystack
458
     * @return int
459
     */
460
    return function (string $haystack) use ($needle, $offset, $length): int {
461
        return $length
462
            ? \substr_count($haystack, $needle, $offset, $length)
463
            : \substr_count($haystack, $needle, $offset);
464
    };
465
}
466
467
/**
468
 * Returns a callable for doing repeated trim.
469
 *
470
 * @param string $mask
471
 * @return Closure(string):string
472
 */
473
function trim(string $mask = "\t\n\r\0\x0B"): Closure
474
{
475
    /**
476
     * @param string $string The string to be trimmed
477
     * @return string
478
     */
479
    return function (string $string) use ($mask): string {
480
        return \trim($string, $mask);
481
    };
482
}
483
484
/**
485
 * Returns a callable for doing repeated ltrim.
486
 *
487
 * @param string $mask
488
 * @return Closure(string):string
489
 */
490
function lTrim(string $mask = "\t\n\r\0\x0B"): Closure
491
{
492
    /**
493
     * @param string $string The string to be trimmed
494
     * @return string
495
     */
496
    return function (string $string) use ($mask): string {
497
        return \ltrim($string, $mask);
498
    };
499
}
500
501
/**
502
 * Returns a callable for doing repeated rtrim.
503
 *
504
 * @param string $mask
505
 * @return Closure(string):string
506
 */
507
function rTrim(string $mask = "\t\n\r\0\x0B"): Closure
508
{
509
    /**
510
     * @param string $string The string to be trimmed
511
     * @return string
512
     */
513
    return function (string $string) use ($mask): string {
514
        return \rtrim($string, $mask);
515
    };
516
}
517
518
/**
519
 * Returns a callable for finding the similarities between 2 string.
520
 * This sets the defined value as the base (similar_text as first)
521
 *
522
 * @param string $base The string to act as the base.
523
 * @param bool $asPc If set to true will return the percentage match, rather than char count.
524
 * @return Closure(string):Number
525
 */
526
function similarAsBase(string $base, bool $asPc = false): Closure
527
{
528
    /**
529
     * @param string $comparisonString The string to compare against base.
530
     * @return Number
531
     */
532
    return function (string $comparisonString) use ($base, $asPc) {
533
        $pc       = 0.00;
534
        $matching = similar_text($base, $comparisonString, $pc);
535
        return $asPc ? $pc : $matching;
536
    };
537
}
538
539
/**
540
 * Returns a callable for finding the similarities between 2 string.
541
 * This sets the defined value as the comparisonString (similar_text as second)
542
 *
543
 * @param string $comparisonString The string to compare against base.
544
 * @param bool $asPc If set to true will return the percentage match, rather than char count.
545
 * @return Closure(string):Number
546
 */
547
function similarAsComparison(string $comparisonString, bool $asPc = false): Closure
548
{
549
    /**
550
     * @param string $comparisonString The string to act as the base.
551
     * @return Number
552
     */
553
    return function (string $base) use ($comparisonString, $asPc) {
554
        $pc       = 0.00;
555
        $matching = similar_text($base, $comparisonString, $pc);
556
        return $asPc ? $pc : $matching;
557
    };
558
}
559
560
/**
561
 * Returns a callable for padding out a string.
562
 *
563
 * @param int $length Max length to make string.
564
 * @param string $padContent The value to padd the string with (defaults to ' ')
565
 * @param int $type How to pad, please use these constants. STR_PAD_RIGHT|STR_PAD_LEFT|STR_PAD_BOTH
566
 * @return Closure(string):string
567
 */
568
function pad(int $length, string $padContent = ' ', int $type = STR_PAD_RIGHT): Closure
569
{
570
    /**
571
     * @param string $string The string to pad out.
572
     * @return string
573
     */
574
    return function (string $string) use ($length, $padContent, $type): string {
575
        return \str_pad($string, $length, $padContent, $type);
576
    };
577
}
578
579
/**
580
 * Returns a callable for repeating a string by a defined number of times.
581
 *
582
 * @param int $count Number of times to repeat string.
583
 * @return Closure(string):string
584
 */
585
function repeat(int $count): Closure
586
{
587
    /**
588
     * @param string $string The string to repeat
589
     * @return string
590
     */
591
    return function (string $string) use ($count): string {
592
        return \str_repeat($string, $count);
593
    };
594
}
595
596
/**
597
 * Returns a callback for creating a word counter, with set format and char list.
598
 *
599
 * @param int $format can use WORD_COUNT_NUMBER_OF_WORDS | WORD_COUNT_ARRAY | WORD_COUNT_ASSOCIATIVE_ARRAY
600
 * @param string|null $charList The char list of option values considered words.
601
 * @return Closure(string):(int|string[])
602
 */
603
function wordCount(int $format = WORD_COUNT_NUMBER_OF_WORDS, ?string $charList = null): Closure
604
{
605
    /**
606
     * @param string $string The string to pad out.
607
     * @return int|string[]
608
     */
609
    return function (string $string) use ($format, $charList) {
610
        return $charList
611
            ? (\str_word_count($string, $format, $charList) ?: 0)
612
            : (\str_word_count($string, $format) ?: 0);
613
    };
614
}
615
616
/**
617
 * Creates a function for stripping tags with a defined set of allowed tags.
618
 *
619
 * @param string|null $allowedTags The allowed tags, pass null or leave blank for none.
620
 * @return Closure(string):string
621
 */
622
function stripTags(?string $allowedTags = null): Closure
623
{
624
    /**
625
     * @param string $string The string to strip tags from.
626
     * @return string
627
     */
628
    return function (string $string) use ($allowedTags): string {
629
        return $allowedTags
630
            ? \strip_tags($string, $allowedTags)
631
            : \strip_tags($string);
632
    };
633
}
634
635
/**
636
 * Returns a callable for finding the first postition of a defined value in any string.
637
 *
638
 * @param string $needle The value to look for.
639
 * @param int  $offset The offset to start
640
 * @param int $flags STRINGS_CASE_SENSITIVE | STRINGS_CASE_INSENSITIVE
641
 * @return Closure(string):?int
642
 */
643
function firstPosition(string $needle, int $offset = 0, int $flags = STRINGS_CASE_SENSITIVE): Closure
644
{
645
    $caseSensitive = ! (bool) ($flags & STRINGS_CASE_INSENSITIVE); // Assumes true unless INSESNITVE passed
646
647
    /**
648
     * @param string $haystack The haystack to look through.
649
     * @return int|null
650
     */
651
    return function (string $haystack) use ($needle, $offset, $caseSensitive): ?int {
652
        $pos = $caseSensitive
653
            ? strpos($haystack, $needle, $offset)
654
            : stripos($haystack, $needle, $offset);
655
        return is_int($pos) ? (int) $pos : null;
0 ignored issues
show
introduced by
The condition is_int($pos) is always true.
Loading history...
656
    };
657
}
658
659
/**
660
 * Returns a callable for finding the first position of a defined value in any string.
661
 *
662
 * @param string $needle The value to look for.
663
 * @param int  $offset The offset to start
664
 * @param int $flags STRINGS_CASE_SENSITIVE | STRINGS_CASE_INSENSITIVE
665
 * @return Closure(string):?int
666
 */
667
function lastPosition(string $needle, int $offset = 0, int $flags = STRINGS_CASE_SENSITIVE): Closure
668
{
669
    $caseSensitive = ! (bool) ($flags & STRINGS_CASE_INSENSITIVE); // Assumes true unless INSESNITVE passed
670
671
    /**
672
     * @param string $haystack The haystack to look through.
673
     * @return int|null
674
     */
675
    return function (string $haystack) use ($needle, $offset, $caseSensitive): ?int {
676
        $pos = $caseSensitive
677
            ? strrpos($haystack, $needle, $offset)
678
            : strripos($haystack, $needle, $offset);
679
        return is_int($pos) ? (int) $pos : null;
0 ignored issues
show
introduced by
The condition is_int($pos) is always true.
Loading history...
680
    };
681
}
682
683
/**
684
 * Returns a callable for looking for the first occurrence of a substring.
685
 * When found can return all after or before the needle (sub string)
686
 * Can be done as case sensitive (strstr()) or insensitive (stristr())
687
 *
688
 * @param string $needle The substring to look for.
689
 * @param int $flags Possible STRINGS_CASE_INSENSITIVE | STRINGS_CASE_SENSITIVE | STRINGS_AFTER_NEEDLE | STRINGS_BEFORE_NEEDLE
690
 * @return Closure(string):string
691
 */
692
function firstSubString(string $needle, int $flags = STRINGS_CASE_SENSITIVE | STRINGS_AFTER_NEEDLE): Closure
693
{
694
695
    // Decode flags, only look for none defaults.
696
    $beforeNeedle  = (bool) ($flags & STRINGS_BEFORE_NEEDLE);
697
    $caseSensitive = ! (bool) ($flags & STRINGS_CASE_INSENSITIVE); // Assumes true unless INSESNITVE passed
698
699
    /**
700
     * @param string $haystack The haystack to look through.
701
     * @return string
702
     */
703
    return function (string $haystack) use ($needle, $beforeNeedle, $caseSensitive): string {
704
        $result = $caseSensitive
705
            ? strstr($haystack, $needle, $beforeNeedle)
706
            : stristr($haystack, $needle, $beforeNeedle);
707
        return is_string($result) ? $result : '';
0 ignored issues
show
introduced by
The condition is_string($result) is always true.
Loading history...
708
    };
709
}
710
711
/**
712
 * Returns a callable for creating a function which finds the first occurrence of
713
 * any character (from a list) in a defined string.
714
 *
715
 * @param string $chars All chars to check with.
716
 * @return Closure(string):string
717
 */
718
function firstChar(string $chars): Closure
719
{
720
    /**
721
     * @param string $haystack
722
     * @return string
723
     */
724
    return function (string $haystack) use ($chars): string {
725
        $result = strpbrk($haystack, $chars);
726
        return is_string($result) ? $result : '';
0 ignored issues
show
introduced by
The condition is_string($result) is always true.
Loading history...
727
    };
728
}
729
730
/**
731
 * Returns a function that finds the last char in a string and returns the following text.
732
 * Matches the first char passed, if more than 1 char passed, the rest are ignored.
733
 *
734
 * @param string $char
735
 * @return Closure(string):string
736
 */
737
function lastChar(string $char): Closure
738
{
739
    /**
740
     * @param string $haystack
741
     * @return string
742
     */
743
    return function (string $haystack) use ($char): string {
744
        $result = strrchr($haystack, $char);
745
        return is_string($result) ? $result : '';
0 ignored issues
show
introduced by
The condition is_string($result) is always true.
Loading history...
746
    };
747
}
748
749
/**
750
 * Returns a callable which translates substrings from a defined dictionary.
751
 * Dictionary should be ['from' => 'to' ]
752
 *
753
 * @param array<string, mixed> $dictionary
754
 * @return Closure(string):string
755
 */
756
function translateWith(array $dictionary): Closure
757
{
758
    /**
759
     * @param string $haystack
760
     * @return string
761
     */
762
    return function (string $haystack) use ($dictionary): string {
763
        $result = strtr($haystack, $dictionary);
764
        return $result;
765
    };
766
}
767
768
/**
769
 * Creates a callable for a string safe function compose.
770
 *
771
 * @uses F\composeTypeSafe
772
 * @param callable(mixed):string ...$callable
773
 * @return Closure(mixed):string
774
 */
775
function composeSafeStringFunc(callable ...$callable): Closure
776
{
777
    return F\composeTypeSafe('is_string', ...$callable);
0 ignored issues
show
Bug introduced by
The function composeTypeSafe was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

777
    return /** @scrutinizer ignore-call */ F\composeTypeSafe('is_string', ...$callable);
Loading history...
778
}
779
780
/**
781
 * Creates a callable for compiling a string.
782
 *
783
 * @param string $initial
784
 * @return Closure(string|null):(Closure|string)
785
 */
786
function stringCompiler(string $initial = ''): Closure
787
{
788
    /**
789
     * @param string|null $value
790
     * @return Closure|string
791
     */
792
    return function (?string $value = null) use ($initial) {
793
        if ($value) {
794
            $initial .= $value;
795
        }
796
        return $value ? stringCompiler($initial) : $initial;
797
    };
798
}
799
800
/**
801
 * Checks if the passe value is a string and if its length is 0.
802
 *
803
 * @param mixed $value
804
 * @return bool
805
 */
806
function isBlank($value): bool
807
{
808
    return is_string($value) && \mb_strlen($value) === 0;
809
}
810
811
812
/************************************************************************/
813
/************************************************************************/
814
/**                        Deprecated Functions                        **/
815
/************************************************************************/
816
/************************************************************************/
817
818
819
/**
820
 * See decimalNumber()
821
 *
822
 * @deprecated Use decimalNumber() instead.
823
 * @param int $precision
824
 * @param string $point
825
 * @param string $thousands
826
 * @return Closure
827
 */
828
function decimialNumber($precision = 2, $point = '.', $thousands = ''): Closure
829
{
830
    return decimalNumber($precision, $point, $thousands);
831
}
832
833
/**
834
 * See similarAsComparison()
835
 *
836
 * @deprecated Use similarAsComparison() instead.
837
 * @param string $comparisonString
838
 * @param bool $asPc
839
 * @return Closure
840
 */
841
function similarAsComparisson(string $comparisonString, bool $asPc = false): Closure
842
{
843
    return similarAsComparison($comparisonString, $asPc);
844
}
845
846
/**
847
 * See firstPosition()
848
 *
849
 * @deprecated
850
 * @param string $needle
851
 * @param int $offset
852
 * @param int $flags
853
 * @return Closure
854
 */
855
function firstPosistion(string $needle, int $offset = 0, int $flags = STRINGS_CASE_SENSITIVE): Closure
856
{
857
    return firstPosition($needle, $offset, $flags);
858
}
859
860
/**
861
 * See lastPosition()
862
 *
863
 * @deprecated Use lastPosition() instead.
864
 * @param string $needle The value to look for.
865
 * @param int  $offset The offset to start
866
 * @param int $flags STRINGS_CASE_SENSITIVE | STRINGS_CASE_INSENSITIVE
867
 * @return Closure
868
 */
869
function lastPosistion(string $needle, int $offset = 0, int $flags = STRINGS_CASE_SENSITIVE): Closure
870
{
871
    return lastPosition($needle, $offset, $flags);
872
}
873