Skip to content

Commit

Permalink
Add OriginUrlNormalizer and FilteredUrlNormalizer ✨ 🎨
Browse files Browse the repository at this point in the history
  • Loading branch information
Bukashk0zzz committed Mar 1, 2017
1 parent 298beea commit 635a0b1
Show file tree
Hide file tree
Showing 13 changed files with 242 additions and 29 deletions.
5 changes: 3 additions & 2 deletions .travis.yml
Expand Up @@ -9,7 +9,7 @@ php:

env:
- SYMFONY_VERSION=2.7.*
- SYMFONY_VERSION=3.0.*
- SYMFONY_VERSION=3.2.*

allow_failures:
- php: hhvm
Expand All @@ -20,7 +20,8 @@ before_script:
- composer install --dev --prefer-dist --no-interaction

script:
- ./vendor/bin/phpcs ./ -p --encoding=utf-8 --extensions=php --ignore=vendor --standard=./vendor/escapestudios/symfony2-coding-standard/Symfony2
- rm -rf vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/PHPCompatibility; cp -rp vendor/wimg/php-compatibility vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/PHPCompatibility
- ./vendor/bin/phpcs ./ -p --standard=./ruleset.xml
- ./vendor/bin/phpunit -c phpunit.xml.dist --coverage-clover=coverage.xml

after_success:
Expand Down
4 changes: 3 additions & 1 deletion DependencyInjection/Configuration.php
Expand Up @@ -24,7 +24,7 @@ class Configuration implements ConfigurationInterface
/**
* Generates the configuration tree.
*
* @return \Symfony\Component\Config\Definition\NodeInterface
* @return \Symfony\Component\Config\Definition\Builder\NodeParentInterface
* @throws \Exception
*/
public function getConfigTreeBuilder()
Expand All @@ -38,6 +38,8 @@ public function getConfigTreeBuilder()
->scalarNode('vichUploaderSerialize')->defaultValue(true)->end()
->scalarNode('includeOriginal')->defaultValue(false)->end()
->scalarNode('includeHostForOriginal')->defaultValue(false)->end()
->scalarNode('originUrlNormalizer')->defaultValue(null)->end()
->scalarNode('filteredUrlNormalizer')->defaultValue(null)->end()
;

return $treeBuilder;
Expand Down
1 change: 1 addition & 0 deletions EventListener/JmsPostSerializeListener.php
Expand Up @@ -27,6 +27,7 @@ class JmsPostSerializeListener extends JmsSerializeListenerAbstract
* On post serialize
*
* @param ObjectEvent $event Event
* @throws \InvalidArgumentException
*/
public function onPostSerialize(ObjectEvent $event)
{
Expand Down
3 changes: 2 additions & 1 deletion EventListener/JmsPreSerializeListener.php
Expand Up @@ -26,6 +26,7 @@ class JmsPreSerializeListener extends JmsSerializeListenerAbstract
* On pre serialize
*
* @param ObjectEvent $event Event
* @throws \InvalidArgumentException
*/
public function onPreSerialize(ObjectEvent $event)
{
Expand Down Expand Up @@ -54,7 +55,7 @@ public function onPreSerialize(ObjectEvent $event)
if (array_key_exists('includeHost', $this->config) && $this->config['includeHost']) {
$originalImageUri = $this->getHostUrl().$originalImageUri;
}
$property->setValue($object, $originalImageUri);
$property->setValue($object, $this->normalizeUrl($originalImageUri, 'originUrlNormalizer'));
}
}
}
Expand Down
50 changes: 36 additions & 14 deletions EventListener/JmsSerializeListenerAbstract.php
Expand Up @@ -11,6 +11,7 @@
namespace Bukashk0zzz\LiipImagineSerializationBundle\EventListener;

use Bukashk0zzz\LiipImagineSerializationBundle\Annotation\LiipImagineSerializableField;
use Bukashk0zzz\LiipImagineSerializationBundle\Normalizer\UrlNormalizerInterface;
use Doctrine\Common\Annotations\CachedReader;
use JMS\Serializer\EventDispatcher\ObjectEvent;
use Symfony\Component\Routing\RequestContext;
Expand Down Expand Up @@ -50,8 +51,7 @@ class JmsSerializeListenerAbstract
*/
protected $config;

/** @noinspection MoreThanThreeArgumentsInspection
*
/**
* JmsSerializeListenerAbstract constructor.
*
* @param RequestContext $requestContext
Expand Down Expand Up @@ -91,11 +91,14 @@ protected function getObject(ObjectEvent $event)
return $object;
}

/** @noinspection GenericObjectTypeUsageInspection
/**
* @param LiipImagineSerializableField $liipAnnotation
* @param object $object Serialized object
* @param string $value Value of field
*
* @return array|string
*
* @throws \InvalidArgumentException
*/
protected function serializeValue(LiipImagineSerializableField $liipAnnotation, $object, $value)
{
Expand All @@ -104,6 +107,7 @@ protected function serializeValue(LiipImagineSerializableField $liipAnnotation,
}

$result = [];
$value = $this->normalizeUrl($value, 'originUrlNormalizer');
if (array_key_exists('includeOriginal', $this->config) && $this->config['includeOriginal']) {
$result['original'] = (array_key_exists('includeHostForOriginal', $this->config) && $this->config['includeHostForOriginal'] && $liipAnnotation->getVichUploaderField())
? $this->getHostUrl().$value
Expand All @@ -114,16 +118,15 @@ protected function serializeValue(LiipImagineSerializableField $liipAnnotation,
if (is_array($filters)) {
/** @var array $filters */
foreach ($filters as $filter) {
$result[$filter] = $this->cacheManager->getBrowserPath($value, $filter);
$result[$filter] = $this->checkIncludeHostForUrl($result[$filter]);
$result[$filter] = $this->prepareFilteredUrl($this->cacheManager->getBrowserPath($value, $filter));
}

return $result;
}

$filtered = $this->cacheManager->getBrowserPath($value, $filters);
if (count($result) !== 0) {
$result[$filters] = $this->checkIncludeHostForUrl($filtered);
$result[$filters] = $this->prepareFilteredUrl($filtered);

return $result;
}
Expand All @@ -149,36 +152,55 @@ protected function getHostUrl()
return $url;
}

/**
* Normalize url if needed
*
* @param string $url
* @param string $normalizer
* @return string
*/
protected function normalizeUrl($url, $normalizer)
{
if (array_key_exists($normalizer, $this->config) && $this->config[$normalizer]) {
$normalizer = new $this->config[$normalizer]();
if ($normalizer instanceof UrlNormalizerInterface) {
$url = $normalizer->normalize($url);
}
}

return $url;
}

/**
* If config demands, it will remove host and scheme (protocol) from passed url
*
* @param $url
* @return string
* @throws \InvalidArgumentException
*/
private function checkIncludeHostForUrl($url)
private function prepareFilteredUrl($url)
{
if (array_key_exists('includeHost', $this->config) && !$this->config['includeHost']) {
$url = $this->stripHostFromUrl($url);
}

return $url;
return $this->normalizeUrl($url, 'filteredUrlNormalizer');
}

/**
* Removes host and scheme (protocol) from passed url
*
* @param $url
* @return string
* @throws \InvalidArgumentException
*/
private function stripHostFromUrl($url)
{
$parts = parse_url($url);
if (isset($parts['path'])) {
if (array_key_exists('query', $parts)) {
return $parts['path'].'?'.$parts['query'];
} else {
return $parts['path'];
}
if ($parts !== false && array_key_exists('path', $parts)) {
return array_key_exists('query', $parts) ? $parts['path'].'?'.$parts['query'] : $parts['path'];
}

throw new \InvalidArgumentException('Can\'t strip host from url, because can\'t parse url.');
}
}
17 changes: 17 additions & 0 deletions Normalizer/UrlNormalizerInterface.php
@@ -0,0 +1,17 @@
<?php

namespace Bukashk0zzz\LiipImagineSerializationBundle\Normalizer;

/**
* UrlNormalizerInterface
*
* @author Denis Golubovskiy <bukashk0zzz@gmail.com>
*/
interface UrlNormalizerInterface
{
/**
* @param string $url
* @return string
*/
public function normalize($url);
}
48 changes: 44 additions & 4 deletions README.md
Expand Up @@ -26,7 +26,7 @@ Add this to your `composer.json` file:

```json
"require": {
"bukashk0zzz/liip-imagine-serialization-bundle": "dev-master",
"bukashk0zzz/liip-imagine-serialization-bundle": "^1.1"
}
```

Expand Down Expand Up @@ -55,6 +55,10 @@ bukashk0zzz_liip_imagine_serialization:
includeOriginal: false
# Set true for adding host url to original value for vichUploader fields
includeHostForOriginal: false
# You can pass there your UrlNormalizer class that implements UrlNormalizerInterface
originUrlNormalizer: null
# You can pass there your UrlNormalizer class that implements UrlNormalizerInterface
filteredUrlNormalizer: null
```


Expand All @@ -81,8 +85,8 @@ For example if you add annotation `@Bukashk0zzz\LiipImagineSerializableField(fil
```json
{
"image": {
"big": {}"/uploads/users/big/5659828fa80a7.jpg",
"small": {}"/uploads/users/small/5659828fa80a7.jpg"
"big": "/uploads/users/big/5659828fa80a7.jpg",
"small": "/uploads/users/small/5659828fa80a7.jpg"
}
}
```
Expand All @@ -91,7 +95,7 @@ Also there is another two options:
- `vichUploaderField` - If you use VichUploaderBundle for your uploads you must specify link to the field with `@Vich\UploadableField` annotation
- `virtualField` - By default serializer will override field value with link to filtered image. If you add `virtualField` option serializer will add to serialized object new field with name that you provided in this option and url to filtered image, original field in this case will be unattached. This option are required if you're using an array of filters.

And also don't forget that to serialize image fields they also should be marked with `@JMS` annotations to be serialized.
Don't forget that to serialize image fields they also should be marked with `@JMS` annotations to be serialized.

The generated URI by default:

Expand All @@ -111,6 +115,41 @@ The generated URI with `includeHost` set to `false`:
}
```

If you need to change url before passing it to LiipImagine, for example you need to swap origin name, you can use originUrlNormalizer option in bundle config.
```yaml
bukashk0zzz_liip_imagine_serialization:
originUrlNormalizer: AppBundle\Normalizer\UrlNormalizer
```

If you need to change url after LiipImagine processing, for example you need to swap origin domain, you can use filteredUrlNormalizer option in bundle config.
```yaml
bukashk0zzz_liip_imagine_serialization:
filteredUrlNormalizer: AppBundle\Normalizer\UrlNormalizer
```

UrlNormalizer class must implement [UrlNormalizerInterface](https://github.com/Bukashk0zzz/LiipImagineSerializationBundle/blob/master/Normalizer/UrlNormalizerInterface.php)

```php
<?php

namespace AppBundle\Normalizer;

use Bukashk0zzz\LiipImagineSerializationBundle\Normalizer\UrlNormalizerInterface;

/**
* Url normalizer
*/
class UrlNormalizer implements UrlNormalizerInterface
{
/**
* {@inheritdoc}
*/
public function normalize($url){
return str_replace('photo.jpg', 'my_photo.jpg', $url);
}
}
```

Example
-------

Expand All @@ -123,6 +162,7 @@ use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as JMS;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Bukashk0zzz\LiipImagineSerializationBundle\Annotation as Bukashk0zzz;
use Symfony\Component\HttpFoundation\File\File;

/**
* User Entity
Expand Down
55 changes: 55 additions & 0 deletions Tests/EventListener/JmsSerializeListenerTest.php
Expand Up @@ -13,6 +13,8 @@

use Bukashk0zzz\LiipImagineSerializationBundle\Tests\Fixtures\UserPhotos;
use Bukashk0zzz\LiipImagineSerializationBundle\Tests\Fixtures\UserPictures;
use Bukashk0zzz\LiipImagineSerializationBundle\Tests\Normalizer\FilteredUrlNormalizer;
use Bukashk0zzz\LiipImagineSerializationBundle\Tests\Normalizer\OriginUrlNormalizer;
use Doctrine\Common\Annotations\AnnotationRegistry;
use JMS\Serializer\DeserializationContext;
use JMS\Serializer\SerializerBuilder;
Expand Down Expand Up @@ -134,6 +136,59 @@ public function testProxySerialization()
static::assertEquals('http://example.com:8800/a/path/to/an/image3.png', $data['photoThumb']);
}

/**
* Test serialization with origin normalizer
*/
public function testSerializationWithOriginNormalizer()
{
$userPictures = new UserPictures();
$this->generateCacheManager();
$this->generateRequestContext();
$data = $this->serializeObject($userPictures, [
'includeHost' => false,
'vichUploaderSerialize' => true,
'includeOriginal' => true,
'originUrlNormalizer' => OriginUrlNormalizer::class,
]);

static::assertEquals('/uploads/newPhoto.jpg', $data['photoThumb']['original']);
static::assertEquals('/uploads/newPhoto.jpg', $data['photo']);
}

/**
* Test serialization with filtered normalizer
*/
public function testSerializationWithFilteredNormalizer()
{
$userPictures = new UserPictures();
$this->generateCacheManager();
$this->generateRequestContext();
$data = $this->serializeObject($userPictures, [
'includeHost' => true,
'vichUploaderSerialize' => true,
'includeOriginal' => true,
'filteredUrlNormalizer' => FilteredUrlNormalizer::class,
]);

static::assertEquals('http://img.example.com:8800/a/path/to/an/image3.png', $data['photoThumb']['thumb_filter']);
static::assertEquals('http://img.example.com:8800/a/path/to/an/image1.png', $data['cover']['big']);
}

/**
* Test serialization with url parse exception
*
* @expectedException \InvalidArgumentException
*/
public function testSerializationWithUrlParseException()
{
$userPictures = new UserPictures();
$this->generateCacheManager('http://blah.com:abcdef');
$this->generateRequestContext();
$this->serializeObject($userPictures, [
'includeHost' => false,
]);
}

/**
* Test serialization with included http host and port in the URI and include original option "true"
*/
Expand Down
2 changes: 2 additions & 0 deletions Tests/Fixtures/UserPictures.php
Expand Up @@ -92,6 +92,7 @@ class UserPictures implements Proxy
*/
private $status = false;

// @codingStandardsIgnoreStart
/**
* @inheritdoc
*/
Expand All @@ -110,6 +111,7 @@ public function __isInitialized()
{
return $this->status;
}
// @codingStandardsIgnoreEnd

/**
* To string
Expand Down

0 comments on commit 635a0b1

Please sign in to comment.