Skip to content

Commit

Permalink
Add Gravatar extension
Browse files Browse the repository at this point in the history
Add GravatarExtension.
Update the documentation.
  • Loading branch information
cristianoc72 committed May 14, 2022
1 parent df65fd0 commit 291faa5
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 32 deletions.
19 changes: 6 additions & 13 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
File renamed without changes.
42 changes: 38 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand Down Expand Up @@ -68,14 +77,22 @@ 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
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
Expand All @@ -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
<img src="{{ [email protected] | gravatar }}" alt="My avatar" />
```

You can also pass some options to the filter, i.e.:
```twig
<img src="{{ [email protected] | gravatar({ size: 200, default: mp }) }}" alt="My avatar" />
```

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).
Expand All @@ -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
Expand Down
15 changes: 8 additions & 7 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,33 +22,34 @@
},
"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": {
"analytics": "vendor/bin/psalm.phar",
"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": {
"analytics": "Run static analysis tool",
"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"
}
}
71 changes: 71 additions & 0 deletions src/GravatarExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php declare(strict_types=1);

namespace Susina\TwigExtensions;

use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;

/**
* Class GravatarExtension
*/
class GravatarExtension extends AbstractExtension
{
public const AVATAR_URL = "https://secure.gravatar.com/avatar";

/**
* @inheritdoc
*/
public function getFilters(): array
{
return [
new TwigFilter('gravatar', [$this ,'gravatarFilter']),
];
}

/**
* @param string $email
* @param array $params
*
* @return string
*/
public function gravatarFilter(string $email, array $params = []): string
{
$resolver = new OptionsResolver();
$this->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'
);
}
}
7 changes: 5 additions & 2 deletions src/VariablesExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -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),
];
}

Expand All @@ -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
)
];
}
}
10 changes: 7 additions & 3 deletions tests/Fixtures/filters/bool_to_string.test
Original file line number Diff line number Diff line change
@@ -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
false
no
light
20 changes: 20 additions & 0 deletions tests/Fixtures/filters/gravatar.test
Original file line number Diff line number Diff line change
@@ -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 protected]"]
--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&amp;forcedefault=y&amp;default=mp&amp;rating=pg
8 changes: 5 additions & 3 deletions tests/IntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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';
}
}

0 comments on commit 291faa5

Please sign in to comment.