diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index fdd0d5a..97fd6c2 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -8,7 +8,7 @@ jobs:
fail-fast: false
matrix:
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
- php-versions: ['7.4', '8.0']
+ php-versions: ['7.4', '8.0', '8.1']
runs-on: ${{ matrix.operating-system }}
steps:
- name: Set autocrlf on windows
@@ -20,18 +20,11 @@ jobs:
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-versions }}
- - name: Get composer cache directory
- id: composer-cache
- run: echo "::set-output name=dir::$(composer config cache-files-dir)"
- - name: Cache composer dependencies
- uses: actions/cache@v1
+ - name: Install composer dependencies
+ uses: ramsey/composer-install@v2
with:
- path: ${{ steps.composer-cache.outputs.dir }}
- key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
- restore-keys: ${{ runner.os }}-composer-
- - name: Install dependencies
- run: composer install --no-progress --no-suggest --prefer-dist --optimize-autoloader
- - name: Check coding standanrd
- run: composer cs
+ composer-options: "--prefer-dist --optimize-autoloader"
+ - name: Check coding standard
+ run: composer cs:check
- name: Test with phpunit
run: composer test
diff --git a/.php_cs.dist b/.php-cs-fixer.php
similarity index 100%
rename from .php_cs.dist
rename to .php-cs-fixer.php
diff --git a/README.md b/README.md
index 9016774..6ba7650 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@ It contains some useful functions, tests and filters missing in the original lib
## Installation
-Firstly, install via Composer:
+Firstly, install the package via Composer:
```
composer require susina/twig-extensions
@@ -25,6 +25,15 @@ $twig = new \Twig\Environment($loader);
$twig->addExtension(new \Susina\TwigExtensions\VariablesExtension());
```
+Or, if you are working with Symfony, register the extensions you want as services and tag them as `twig.extension`:
+
+```yaml
+// In your `services.yml` file
+services:
+ Susina\TwigExtensions\GravatarExtension:
+ tags: [twig.extension]
+```
+
## VariablesExtension
VariablesExtension contains some tests and functions useful for manipulating variables.
@@ -68,7 +77,7 @@ behaves in the same way. It can be useful if you want to generate some valid php
### Filters
-`bool_to_string` filter return the string 'true' if the variable filtered can be evaluated as _true_, otherwise
+`bool_to_string` filter returns the string 'true' if the variable filtered can be evaluated as _true_, otherwise
it returns the string _false_:
```twig
@@ -76,6 +85,14 @@ The "boolVariable" is {{ boolVariable|bool_to_string }}.
```
it returns `The "boolVariable" is true`.
+You can customize the _true/false_ strings by passing two variables to the filter: the first one represents the
+_true_ value, the second one the _false_ value, i.e.:
+
+```twig
+The "boolVariable" is {{ boolVariable|bool_to_string('yes', 'no' }}.
+```
+it returns `The "boolVariable" is yes`.
+
## StringExtension
### Filters
@@ -97,6 +114,23 @@ By default, the filter applies single quotes `'` but you can pass any character
```
then it returns `"Donald Duck"`.
+
+## Gravatar Extension
+
+Gravatar extension contain a filter to retrieve the [Gravatar](https://www.gravatar.com) image from a given email.
+`gravatar` filter returns the uri for the avatar and you can easily use it in your html:
+
+```twig
+
+```
+
+You can also pass some options to the filter, i.e.:
+```twig
+
+```
+
+For a full options description, please see [https://en.gravatar.com/site/implement/images/](https://en.gravatar.com/site/implement/images/).
+
## Issues
We manage issues and feature requests via [Github repository issues](https://github.com/susina/twig-extensions/issues).
@@ -109,8 +143,8 @@ This library includes some useful composer scripts for developers:
- `composer test` to run the test suite
- `composer analytics` to run [Psalm](https://psalm.dev/) static analysis tool
-- `composer cs-fix` to fix coding standard
-- `composer cs` to check the coding standard (see https://github.com/susina/coding-standard for details)
+- `composer cs:fix` to fix coding standard
+- `composer cs:check` to check the coding standard (see https://github.com/susina/coding-standard for details)
- `composer coverage:html` to generate code coverage report in html format (into `/coverage` directory)
- `composer coverage:clover` to generate code coverage report in xml format
- `composer check` runs the first three commands
diff --git a/composer.json b/composer.json
index f6c9973..c0ec98d 100644
--- a/composer.json
+++ b/composer.json
@@ -22,11 +22,12 @@
},
"require": {
"php" : ">=7.4",
- "twig/twig": "^3.0"
+ "twig/twig": "^3.0",
+ "symfony/options-resolver": "^5.4"
},
"require-dev" : {
"phpunit/phpunit": "^9.3",
- "susina/coding-standard": "^1.2",
+ "susina/coding-standard": "^2.3",
"psalm/phar": "^4.6"
},
"scripts": {
@@ -34,12 +35,12 @@
"check": [
"@test",
"@analytics",
- "@cs-fix"
+ "@cs:fix"
],
"coverage:html": "@test --coverage-html coverage/",
"coverage:clover": "@test --coverage-clover clover.xml",
- "cs": "php-cs-fixer fix -v --diff --dry-run",
- "cs-fix": "php-cs-fixer fix -v --diff",
+ "cs:check": "php-cs-fixer fix -v --diff --dry-run",
+ "cs:fix": "php-cs-fixer fix -v --diff",
"test": "phpunit --colors=always --exclude-group=legacy"
},
"scripts-descriptions": {
@@ -47,8 +48,8 @@
"check": "Perform all tests and analysis, required before submitting a pull request",
"coverage:html": "Create a code coverage report in html format, into the `coverage/` directory",
"coverage:clover": "Create a code coverage report in xml format, into the `clover.xml` file",
- "cs": "Run code style analysis, without fixing errors",
- "cs-fix": "Run code style analysis and fix errors",
+ "cs:check": "Run code style analysis, without fixing errors",
+ "cs:fix": "Run code style analysis and fix errors",
"test": "Run all tests"
}
}
diff --git a/src/GravatarExtension.php b/src/GravatarExtension.php
new file mode 100644
index 0000000..ff1140c
--- /dev/null
+++ b/src/GravatarExtension.php
@@ -0,0 +1,71 @@
+configureOptions($resolver);
+
+ $params = $resolver->resolve($params);
+ $hash = md5(strtolower(trim($email)));
+
+ return self::AVATAR_URL . "/$hash" . ($params !== [] ? "?" . http_build_query($params) : '');
+ }
+
+ /**
+ * @psalm-suppress UnusedClosureParam $options param is mandatory even if unused.
+ */
+ private function configureOptions(OptionsResolver $resolver): void
+ {
+ $resolver->setDefined(['size', 'forcedefault', 'default', 'rating']);
+
+ $resolver->setAllowedTypes('size', 'int');
+ $resolver->setAllowedTypes('forcedefault', 'bool');
+ $resolver->setAllowedTypes('default', 'string');
+ $resolver->setAllowedTypes('rating', 'string');
+
+ $resolver->setAllowedValues('size', fn (int $value): bool => $value >= 1 && $value <= 2048);
+ $resolver->setAllowedValues('default', function (string $image): bool {
+ return str_contains($image, '://') ?
+ (bool) filter_var($image, FILTER_VALIDATE_URL) :
+ in_array($image, ['404', 'mp', 'identicon', 'monsterid', 'wavatar', 'retro', 'robohash', 'blank'])
+ ;
+ });
+ $resolver->addAllowedValues('rating', ['g', 'pg', 'r', 'x']);
+
+ $resolver->setNormalizer('default', fn (Options $options, string $image): string => urlencode($image));
+ $resolver->setNormalizer(
+ 'forcedefault',
+ fn (Options $options, bool $value): string => $value === true ? 'y' : 'n'
+ );
+ }
+}
diff --git a/src/VariablesExtension.php b/src/VariablesExtension.php
index 11b22c9..7971738 100644
--- a/src/VariablesExtension.php
+++ b/src/VariablesExtension.php
@@ -29,7 +29,7 @@ public function getTests(): array
new TwigTest('object', 'is_object'),
new TwigTest('scalar', 'is_scalar'),
new TwigTest('string', 'is_string'),
- new TwigTest('instanceOf', fn (?object $object, string $class): bool => is_a($object, $class)),
+ new TwigTest('instanceOf', fn (?object $object, string $class): bool => $object instanceof $class),
];
}
@@ -48,7 +48,10 @@ public function getFunctions(): array
public function getFilters(): array
{
return [
- new TwigFilter('bool_to_string', fn (bool $value): string => $value ? 'true' : 'false'),
+ new TwigFilter(
+ 'bool_to_string',
+ fn (bool $value, string $true = 'true', string $false = 'false'): string => $value ? $true : $false
+ )
];
}
}
diff --git a/tests/Fixtures/filters/bool_to_string.test b/tests/Fixtures/filters/bool_to_string.test
index 8508cd1..c40f272 100644
--- a/tests/Fixtures/filters/bool_to_string.test
+++ b/tests/Fixtures/filters/bool_to_string.test
@@ -1,10 +1,14 @@
--TEST--
"bool_to_string" filter test
--TEMPLATE--
-{{ bool1|bool_to_string }}
-{{ bool2|bool_to_string }}
+{{ bool1 | bool_to_string }}
+{{ bool2 | bool_to_string }}
+{{ bool2 | bool_to_string('yes', 'no') }}
+{{ bool1 | bool_to_string('light', 'darkness') }}
--DATA--
return ['bool1' => true, 'bool2' => false]
--EXPECT--
true
-false
\ No newline at end of file
+false
+no
+light
\ No newline at end of file
diff --git a/tests/Fixtures/filters/gravatar.test b/tests/Fixtures/filters/gravatar.test
new file mode 100644
index 0000000..dee0d61
--- /dev/null
+++ b/tests/Fixtures/filters/gravatar.test
@@ -0,0 +1,20 @@
+--TEST--
+"gravatar" filter test
+--TEMPLATE--
+{{ email | gravatar }}
+{{ email | gravatar({"size": 500}) }}
+{{ email | gravatar({"forcedefault": true}) }}
+{{ email | gravatar({"default": "mp"}) }}
+{{ email | gravatar({"default": "https://domain.org/image.jpg"}) }}
+{{ email | gravatar({"rating": "pg"}) }}
+{{ email | gravatar({"size": 500, "forcedefault": true, "default": "mp", "rating": "pg"}) }}
+--DATA--
+return ['email' => "email@example.org"]
+--EXPECT--
+https://secure.gravatar.com/avatar/8fbf4bd0581c9ccc67c560dea9931a1b
+https://secure.gravatar.com/avatar/8fbf4bd0581c9ccc67c560dea9931a1b?size=500
+https://secure.gravatar.com/avatar/8fbf4bd0581c9ccc67c560dea9931a1b?forcedefault=y
+https://secure.gravatar.com/avatar/8fbf4bd0581c9ccc67c560dea9931a1b?default=mp
+https://secure.gravatar.com/avatar/8fbf4bd0581c9ccc67c560dea9931a1b?default=https%253A%252F%252Fdomain.org%252Fimage.jpg
+https://secure.gravatar.com/avatar/8fbf4bd0581c9ccc67c560dea9931a1b?rating=pg
+https://secure.gravatar.com/avatar/8fbf4bd0581c9ccc67c560dea9931a1b?size=500&forcedefault=y&default=mp&rating=pg
\ No newline at end of file
diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php
index 20b74e9..db0ac30 100644
--- a/tests/IntegrationTest.php
+++ b/tests/IntegrationTest.php
@@ -11,25 +11,27 @@
namespace Susina\TwigExtensions\Tests;
+use Susina\TwigExtensions\GravatarExtension;
use Susina\TwigExtensions\StringExtension;
use Susina\TwigExtensions\VariablesExtension;
use Twig\Test\IntegrationTestCase;
class IntegrationTest extends IntegrationTestCase
{
- public function getExtensions()
+ public function getExtensions(): array
{
return [
new VariablesExtension(),
new StringExtension(),
+ new GravatarExtension()
];
}
/**
* {@inheritdoc}
*/
- protected function getFixturesDir()
+ protected function getFixturesDir(): string
{
- return __DIR__.'/Fixtures';
+ return __DIR__ . '/Fixtures';
}
}