dev-master
9999999-devCollection of useful functions
MIT
The Requires
- php >=5.3.0
- symfony/property-access ^2.8||^3.1
1.0.0
1.0.0.0Collection of useful functions
MIT
The Requires
- php >=5.3.0
- symfony/property-access ^2.8||^3.1
Collection of useful functions
Collection of useful PHP functions/classes/utils., (*1)
composer require cosmologist/gears
ArrayType::get(['fruit' => 'apple', 'color' => 'red'], 'fruit'); // 'apple' ArrayType::get(['fruit' => 'apple', 'color' => 'red'], 'weight'); // null ArrayType::get(['fruit' => 'apple', 'color' => 'red'], 'weight', 15); // 15 ArrayType::get(['apple', 'red'], -1); // 'red'
It's more intuitive variant to <code>$array += [$key => $value];
, (*2)
$array = ['fruit' => 'apple']; ArrayType::touch($array, 'color', 'red']); // ['fruit' => 'apple', 'color' => 'red']; ArrayType::touch($array, 'fruit', 'banana']); // ['fruit' => 'apple'];
$a = [1,2]; ArrayType::push($a, 3); // [1,2,3]
$a = [2,3]; ArrayType::unshift($a, 1); // [1,2,3]
ArrayType::average([1, 2, 3]); // 3
ArrayType::checkAssoc([1, 2, 3]); // false ArrayType::checkAssoc(['foo' => 'bar']); // true
ArrayType::contains(array $list, mixed $item);
ArrayType::insertAfter(['a' => 1, 'c' => 3], 'a', ['b' => 2]); // ['a' => 1, 'b' => 2, 'c' => 3] // If the key doesn't exist ArrayType::insertAfter(['a' => 1, 'b' => 2], 'c', ['foo' => 'bar']); // ['a' => 1, 'b' => 2, 'foo' => 'bar']
ArrayType::insertBefore(['a' => 1, 'c' => 3], 'c', ['b' => 2]); // ['a' => 1, 'b' => 2, 'c' => 3] // If the key doesn't exist ArrayType::insertBefore(['a' => 1, 'b' => 2], 'c', ['foo' => 'bar']); // ['foo' => 'bar', 'a' => 1, 'b' => 2]
ArrayType::ranges([1, 3, 7, 9]); // [[1, 3], [3, 7], [7, 9]]
ArrayType::unsetValue(['a', 'b', 'c'], 'b'); // ['a', 'c']
ArrayType::deviation([1, 2, 1]); // float(0.4714045207910317)
Behavior for different types:
- array - returns as is
- iterable - converts to a native array (iterator_to_array()
)
- another - creates an array with argument ([value]), (*3)
ArrayType::toArray($value);
If encoded value is false, true or null then returns empty array.
JSON_THROW_ON_ERROR always enabled., (*4)
ArrayType::fromJson($json): array;
ObjectType::get($person, 'address.street');
Uses Symfony PropertyAccessor, (*5)
ObjectType::set($person, 'address.street', 'Abbey Road');
Uses Symfony PropertyAccessor, (*6)
Read ocramius, (*7)
ObjectType::getInternal($object, $property);
Read ocramius, (*8)
ObjectType::setInternal($object, $property, $value);
Read ocramius, (*9)
ObjectType::callInternal($object, $method, $arg1, $arg2, $arg3, ...);
PHP default behavior: if the method is not defined, an error (Object of class X could not be converted to string
) is triggered., (*10)
namespace Foo; class Bar { } class BarMagicMethod { public function __toString(): string { return 'Bar'; } } enum BazUnitEnum { case APPLE; } enum BazStringBackedEnum: string { case APPLE = 'apple'; } enum BazIntBackedEnum: int { case APPLE = 1; } ObjectType::toString(new Foo); // 'Foo/Bar@1069' ObjectType::toString(new FooMagicMethod); // 'Foo' ObjectType::toString(BazUnitEnum::APPLE); // 'APPLE' ObjectType::toString(BazStringBackedEnum::APPLE); // '1'
Returns the result of __toString
or null if the method is not defined.
PHP default behavior: if the method is not defined, an error (Object of class X could not be converted to string
) is triggered., (*11)
ObjectType::toClassName($objectOrClass): string;
StringType::contains('Foo', 'Bar'); // false StringType::contains('FooBar', 'Bar'); // true
StringType::decrypt(StringType::encrypt('The sensitive string', 'qwerty123456'), 'qwerty123456'); // 'The sensitive string'
StringType::encrypt('The sensitive string', 'qwerty123456');
Default behaviour like preg_match_all(..., ..., PREG_SET_ORDER), (*12)
StringType::regexp('a1b2', '\S(\d)'); // [0 => [0 => 'a1', 1 => '1'], 1 => [0 => 'b2', 1 => '2']]
Exclude full matches from regular expression matches, (*13)
StringType::regexp('a1b2', '\S(\d)', true); // [0 => [0 => '1'], 1 => [0 => '2']]
Get only first set from regular expression matches (exclude full matches), (*14)
StringType::regexp('a1b2', '(\S)(\d)', true, true); // [0 => 'a', 1 => '1']
Get only first match of each set from regular expression matches (exclude full matches), (*15)
StringType::regexp('a1b2', '(\S)(\d)', true, false, true); // [0 => 'a', 1 => 'b']
Get only first match of the first set from regular expression matches as single scalar value, (*16)
StringType::regexp('a1b2', '(\S)(\d)', true, true, true); // 'a'
StringType::replaceFirst('name name name', 'name', 'title'); // 'title name name'
StringType::wrap('target', '/'); // '/target/'
StringType::guessMime('foo bar'); // "text/plain" StringType::guessMime(file_get_content("foo.jpg")); // "image/jpeg"
StringType::guessExtension('foo bar'); // "txt" StringType::guessExtension(file_get_content("foo.jpg")); // "jpeg"
StringType::isBinary('Foo bar baz'); // false
StringType::toCamelCase('string like this'); // 'StringLikeThis' StringType::toCamelCase('string_like_this'); // 'StringLikeThis'
StringType::toSnakeCase('StringLikeThis'); // 'string_like_this' StringType::toSnakeCase('string Like this'); // 'string_like_this'
Use these only if you are supplying the charlist optional arg and it contains UTF-8 characters. Otherwise trim will work normally on a UTF-8 string., (*17)
trim('«foo»', '»'); // "�foo" StringType::trim('«foo»', '»'); // "«foo"
StringType::sentences('Fry me a Beaver. Fry me a Beaver! Fry me a Beaver? Fry me Beaver no. 4?! Fry me many Beavers... End);
returns, (*18)
[ [0] => 'Fry me a Beaver.', [1] => 'Fry me a Beaver!', [2] => 'Fry me a Beaver?', [3] => 'Fry me Beaver no. 4?!', [4] => 'Fry me many Beavers...', [5] => 'End' ]
StringType::words('Fry me many Beavers... End'); // ['Fry', 'me', 'many', 'Beavers', 'End']
StringType::unword('Remove word from text', 'word'); // 'Remove from text'
Remove all characters except digits, +-.,eE from the argument and returns result as the float value or NULL if the parser fails., (*19)
NumberType::parse(" 123 "); // int(123) NumberType::parse(" 123.45 "); // float(123.45) NumberType::parse(" 123.00 "); // int(123)
Remove all characters except digits, +-.,eE from the argument and returns result as the float value or NULL if the parser fails., (*20)
NumberType::parseFloat(" 123 "); // float(123) NumberType::parseFloat(" 123.45 "); // float(123.45)
Remove all characters except digits, plus and minus sign and returns result as the integer value or NULL if the parser fails., (*21)
NumberType::parseInteger(" 123 "); // int(123) NumberType::parseFloat(" 123.45 "); // int(12345)
NumberType::fractions(123.45); // float(0.45) NumberType::parseFloat(123); // float(0)
NumberType::odd(2); // false NumberType::odd(3); // true
NumberType::even(2); // true NumberType::even(3); // false
NumberType::roundStep(50, 5); // 50 NumberType::roundStep(52, 5); // 50 NumberType::roundStep(53, 5); // 55
NumberType::floorStep(50, 5); // 50 NumberType::floorStep(52, 5); // 50 NumberType::floorStep(53, 5); // 50
NumberType::ceilStep(50, 5); // 50 NumberType::ceilStep(52, 5); // 55 NumberType::ceilStep(53, 5); // 55
// Current locale used NumberType::spellout(123.45); // one hundred twenty-three point four five // Specific locale used NumberType::spellout(123.45, 'ru'); // сто двадцать три целых сорок пять сотых
NumberType::divideSafely(1, 0); // null NumberType::divideSafely(1, null); // null NumberType::divideSafely(1, 0, 'zero'); // 'zero'
The first argument is a value for calculating the percentage. The second argument is a base value corresponding to 100%., (*22)
NumberType::percentage(10, 100); // 10 NumberType::percentage(100, 100); // 100 NumberType::percentage(200, 100); // 200
A negative value will be converted to zero, positive or zero value will be returned unchanged., (*23)
NumberType::unsign(-1); // 0 NumberType::unsign(-0.99); // 0 NumberType::unsign(0); // 0 NumberType::unsign(0.99); // 0.99 NumberType::unsign(1); // 1
NumberType::toStringWithSign(-1); // "-1" NumberType::toStringWithSign(1); // "+1" NumberType::toStringWithSign(0); // "0"
CallableType::reflection('is_null'); // Returns a ReflectionFunction instance CallableType::reflection([$foo, 'bar']); // Returns a ReflectionMethod instance
ClassType::short('Foo\Bar'); // "Bar" ClassType::short(Foo\Bar::class); // "Bar" ClassType::short(new Foo\Bar()); // "Bar"
namespace Foo; class Bar {}; class Baz extends Foo {}; ... ClassType::selfAndParents('Foo\Bar'); // ["Foo\Bar"] ClassType::selfAndParents(Foo\Bar::class); // ["Foo\Bar"] ClassType::selfAndParents(new Foo\Bar()); // ["Foo\Bar"] ClassType::selfAndParents('Foo\Baz'); // ["Foo\Baz", "Foo\Bar"] ClassType::selfAndParents(Foo\Baz::class); // ["Foo\Baz", "Foo\Bar"] ClassType::selfAndParents(new Foo\Baz()); // ["Foo\Baz", "Foo\Bar"]
namespace Foo; class Bar {}; class Baz extends Foo {}; ... ClassType::selfAndParents('Foo\Bar'); // ["Foo\Bar"] ClassType::selfAndParents(Foo\Bar::class); // ["Foo\Bar"] ClassType::selfAndParents(new Foo\Bar()); // ["Foo\Bar"] ClassType::selfAndParents('Foo\Baz'); // ["Foo\Baz", "Foo\Bar"] ClassType::selfAndParents(Foo\Baz::class); // ["Foo\Baz", "Foo\Bar"] ClassType::selfAndParents(new Foo\Baz()); // ["Foo\Baz", "Foo\Bar"]
Basic enumerations does not implement from() or tryFrom() methods, but it is possible to return the corresponding enum case using the constant() function., (*24)
ClassType::enumCase(FooEnum::class, 'bar');
It's maybe useful when you validate your model from form on the domain layer and want to map violations to the form., (*25)
use Cosmologist\Gears\Symfony\Form\FormUtils; use Symfony\Component\Form\Extension\Validator\ViolationMapper\ViolationMapper; use Symfony\Component\Validator\Exception\ValidationFailedException; if ($form->isSubmitted()) { try { return $this->handler->create($form->getData()); } catch (ValidationFailedException $exception) { $violationMapper = new ViolationMapper(); foreach ($exception->getViolations() as $domainViolation) { $violationMapper->mapViolation(FormUtils::convertDomainViolationToFormViolation($domainViolation), $form); } } } return $form->createView();
This is convenient for mapping of form data to a model via DataMapperInterface::mapFormsToData(), for example, to create a model via a constructor, in this case, the mapping of model data to a form via DataMapperInterface::mapDataToForms() will remain unchanged, and you cannot not define it, since it is required by the DataMapperInterface., (*26)
use Cosmologist\Gears\Symfony\Form\DataFormsMapperDefaultTrait; class TransactionFormType extends AbstractType implements DataMapperInterface { use DataFormsMapperDefaultTrait; #[Override] public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('name', TextType::class) ->setDataMapper($this); } #[Override] public function mapFormsToData(Traversable $forms, mixed &$viewData): void { $forms = iterator_to_array($forms); $viewData = new Contact($forms['name']->getData()); }
use Cosmologist\Gears\Symfony\Validator\ValidationFailedException; ValidationFailedException::violate($foo, "Foo with invalid bar"); ValidationFailedException::violate($foo, "Foo with invalid {{ bar }}", compact('bar')); ValidationFailedException::violate($foo, "Foo with invalid bar", propertyPath: 'bar');
Collection of useful functions
MIT
Collection of useful functions
MIT