Skip to content
This repository has been archived by the owner on May 25, 2019. It is now read-only.

Commit

Permalink
- Refactored images providers
Browse files Browse the repository at this point in the history
- Updated documentation
  • Loading branch information
akadlec committed Sep 6, 2016
1 parent 5c21394 commit 44f6c42
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 73 deletions.
21 changes: 16 additions & 5 deletions docs/en/generation.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@
Image url can be generated automatically by Latte macros in templates. But in some cases you want to generate image url in presenters or components.

```php
namespace MyApp\Frontend;

use IPub\Images\TImages;

class YourPresenter extends BasePresenter
{
use TImages;

public function handleUpload(Nette\Http\FileUpload $file)
{
// Get images provider
Expand All @@ -18,7 +24,7 @@ class YourPresenter extends BasePresenter
}
```

In this step image is not generated yet, only link is generated. Image will be generated on first request by client.
In this step, if you are using Presenter provider, image is not generated yet, only link is generated. Image will be generated on first request by client.

## Generating responsive images

Expand All @@ -27,12 +33,17 @@ For this you need use some external JS library, eg. [jQuery Picture](http://jque
```html
<a n:src="'presenter:imageStorage://namespace/image.jpg'">
<picture data-settings="[]">
<source n:src="'presenter:imageStorage://namespace/image.jpg', '768x'" >
<source n:src="'presenter:imageStorage://namespace/image.jpg', '1200x'" media="(min-width: 768px)">
<source n:src="'presenter:imageStorage://namespace/image.jpg'" media="(min-width: 768px)">
<source n:src="presenter:imageStorage://namespace/image.jpg, 768x" >
<source n:src="presenter:imageStorage://namespace/image.jpg, 1200x" media="(min-width: 768px)">
<source n:src="presenter:imageStorage://namespace/image.jpg" media="(min-width: 768px)">
<noscript>
<img n:src="'presenter:imageStorage://namespace/image.jpg'">
<img n:src="presenter:imageStorage://namespace/image.jpg">
</noscript>
</picture>
</a>
```

## More

- [Read more images providers](https://github.com/iPublikuj/images/blob/master/docs/en/providers.md)
- [Read abou basic implementation](https://github.com/iPublikuj/images/blob/master/docs/en/index.md)
31 changes: 8 additions & 23 deletions docs/en/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This extension brings you ability to store images in your application and serve

## Concept

Basic concept of this extensions is to use several data storage based on [Flysystem extension](https://github.com/iPublikuj/flysystem). For example for each module or part of your application. Sou you can have e-shop images storage for
Basic concept of this extensions is to use independent data storage based on [Flysystem extension](https://github.com/iPublikuj/flysystem). For example for each module or part of your application. Sou you can have e-shop images storage for
e-shop module, or users avatars storage to store users avatars.

Second important think is, all storage services can store files outside of document root folder even on some cloud servers like AWS or own cloud.
Expand Down Expand Up @@ -32,13 +32,14 @@ At first you have to register your storage services in [Flysystem extension](htt

### Providers

This extension come with default presenter provider which is registered automatically. If you want to use this provider, you have to specify route and web directory:
This extension come with default presenter provider which is registered automatically. If you want to use this provider, you have to specify at least one route and public web directory:

```neon
images:
routes:
- "/images[/<namespace .+>]/<size>[-<algorithm>]/<filename>.<extension>"
wwwDir: path/to/document/root
presenterProvider: true # Default value is true, if you want to disable set it to false
```

Required parameters for each route are:
Expand All @@ -58,33 +59,16 @@ images:
otherParam : otherValue
```

Or if you want to enable secure route you can configure route like this:

```neon
images:
routes:
someRouteName:
route: "/images[/<namespace .+>]/<size>[-<algorithm>]/<filename>.<extension>"
metadata:
defaultParam : defaultValue
otherParam : otherValue
secured: TRUE
```

Second mandatory parameter is **wwwDir**. With this parameter you have to specify absolute path to your document root folder where will be saved generated images.

> By default all these routes will be prepended before your other routes - assuming you use `Nette\Application\Routers\RouteList` as your root router. You can disable this by setting `prependRoutesToRouter: false`. Then it's your responsibility to plug extension router (service `images.router`) to your routing implementation.
### Namespaces

Namespaces can be understand as folders, so you can split your images into folders. Eg. if you want to use this extension for e-shop products images and as namespace can be used product name or category.

### Using in Latte

This extension gives you new latte macro **n:src**. Now you're ready to use it.

```html
<a n:src="'providerName:storageName://products/filename.jpg'"><img n:src="'providerName:storageName://products/filename.jpg', '200x200', 'fill'" /></a>
<a n:src="providerName:storageName://products/filename.jpg"><img n:src="providerName:storageName://products/filename.jpg, 200x200, fill" /></a>
```

output:
Expand All @@ -95,14 +79,15 @@ output:

Parameters of this macro are:

* **path** - full path to the image with storage name eg.: *presenter:eshopStorage://some/namespace/product-image.jpg*
* **path** - full path to the image with storage name and images provider eg.: *presenter:eshopStorage://some/namespace/product-image.jpg*
* **size** - image size. It could be only width or width and height eg.: *150* or *50x50*
* **algorithm** - (optional) resize algorithm which is used to convert image

### Resizing algorithm

For resizing (third argument) you can use these keywords - `fit`, `fill`, `exact`, `stretch`, `shrink_only`. For details see comments above [these constants](http://api.nette.org/2.0/source-common.Image.php.html#105)

## Want more?
## More

In case you need information how to handle images paths in your presenters, components, etc., checkout page about [generator](https://github.com/iPublikuj/images/blob/master/docs/en/generation.md)
- [Read more images providers](https://github.com/iPublikuj/images/blob/master/docs/en/providers.md)
- [Read more about images generation](https://github.com/iPublikuj/images/blob/master/docs/en/generation.md)
48 changes: 48 additions & 0 deletions docs/en/providers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Images providers

If you want to create your own custom images providers, you have to create service which will implement `\IPub\Images\Providers\IProvider`.
Images extension will search for services implementing this interface and register them into the loader.

Your custom provider must implement two methods `getName` and `request`

```php
namespace MyApplication\Services;

use IPub\Images\Providers\IProvider;

class MyOwnImagesProvider implements IProvider
{
/**
* @var string
*/
private $webPath;

/**
* @var SomeModel
*/
private $someModel;

public function __construct(SomeModel $someModel, $webPath)
{
$this->someModel = $someModel;
$this->webPath = $webPath;
}

public function getName()
{
return 'myName';
}

public function request(string $storage, string $namespace = NULL, string $filename, string $size = NULL, string $algorithm = NULL) : string
{
return $this->webPath . '/' . $this->someModel->findImage($filename, $namespace);
}
}
```

Method `getName` should return string without whitespaces, special chars etc. because this name is used in template helpers and other request for images path generation.

## More

- [Read more about images generation](https://github.com/iPublikuj/images/blob/master/docs/en/generation.md)
- [Read abou basic implementation](https://github.com/iPublikuj/images/blob/master/docs/en/index.md)
54 changes: 23 additions & 31 deletions src/IPub/Images/DI/ImagesExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
use IPub\Images\Validators;

use IPub\IPubModule;
use Tracy\Debugger;

/**
* Images extension container
Expand All @@ -51,19 +52,12 @@ class ImagesExtension extends DI\CompilerExtension
*/
private $defaults = [
'routes' => [],
'providers' => [
'presenter' => Images\Providers\PresenterProvider::CLASS_NAME
],
'presenterProvider' => TRUE,
'prependRoutesToRouter' => TRUE,
'rules' => [],
'wwwDir' => NULL,
];

/**
* @var bool
*/
private $isPresenterRegistered = FALSE;

public function loadConfiguration()
{
// Get container builder
Expand All @@ -72,11 +66,11 @@ public function loadConfiguration()
$configuration = $this->getExtensionConfig();

// Check for valid values
Utils\Validators::assert($configuration['providers'], 'array', 'Images providers');
Utils\Validators::assert($configuration['routes'], 'array', 'Images routes');
Utils\Validators::assert($configuration['rules'], 'array', 'Images rules');

// Extension loader
$loader = $builder->addDefinition($this->prefix('loader'))
$builder->addDefinition($this->prefix('loader'))
->setClass(Images\ImagesLoader::CLASS_NAME);

// Create default storage validator
Expand All @@ -85,25 +79,12 @@ public function loadConfiguration()

$this->registerRules($configuration['rules'], $validator);

if ($configuration['routes']) {
$this->registerRoutes($configuration['routes']);
if ($configuration['presenterProvider'] === TRUE) {
$this->registerPresenter();
}

foreach ($configuration['providers'] as $name => $provider) {
if (method_exists($this->compiler, 'loadDefinitions')) {
$this->compiler->loadDefinitions($builder, [$this->prefix('providers.' . $name) => $provider]);

} else {
$this->compiler->parseServices($builder, [
'services' => [$this->prefix('providers.' . $name) => $provider],
]);
}

$loader->addSetup('registerProvider', [$name, $this->prefix('@providers.' . $name)]);

if ($provider === Images\Providers\PresenterProvider::CLASS_NAME && !$this->isPresenterRegistered) {
$this->registerPresenter();
}
if ($configuration['routes']) {
$this->registerRoutes($configuration['routes']);
}

// Register template helpers
Expand Down Expand Up @@ -138,10 +119,19 @@ public function beforeCompile()
}

foreach (array_keys($builder->findByTag(self::TAG_IMAGES_ROUTES)) as $service) {
$router->addSetup('IPub\Images\Application\Route::prependTo($service, ?)', ['@'. $service]);
$router->addSetup('IPub\Images\Application\Route::prependTo($service, ?)', ['@' . $service]);
}
}

// Get images loader service
$loader = $builder->getDefinition($builder->getByType(Images\ImagesLoader::CLASS_NAME));

// Get all registered providers
foreach ($builder->findByType(Images\Providers\IProvider::INTERFACE_NAME) as $service) {
// Register all images providers which are now allowed
$loader->addSetup('$service->registerProvider(?->getName(), ?)', [$service, $service]);
}

// Install extension latte macros
$latteFactory = $builder->getDefinition($builder->getByType('\Nette\Bridges\ApplicationLatte\ILatteFactory') ?: 'nette.latteFactory');

Expand Down Expand Up @@ -175,8 +165,13 @@ private function registerPresenter()
$configuration = $this->getExtensionConfig();

// For this provider wwwDir have to be defined
Utils\Validators::assert($configuration['routes'], 'array:1..', 'Images routes');
Utils\Validators::assert($configuration['wwwDir'], 'string', 'Web public dir');

// Presenter provider
$builder->addDefinition($this->prefix('providers.presenter'))
->setClass(Images\Providers\PresenterProvider::CLASS_NAME);

// Images presenter
$builder->addDefinition($this->prefix('presenter'))
->setClass(IPubModule\ImagesPresenter::CLASS_NAME, [
Expand All @@ -189,9 +184,6 @@ private function registerPresenter()
. 'elseif (property_exists($service, ?)) { $service->mapping[?] = ?; }',
['setMapping', 'IPub', 'IPub\IPubModule\*\*Presenter', 'mapping', 'IPub', 'IPub\IPubModule\*\*Presenter']
);

// Presenter could be registered only once
$this->isPresenterRegistered = TRUE;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/IPub/Images/ImagesLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public function getProvider(string $name) : Providers\IProvider
return $this->providers[$name];
}

throw new Exceptions\InvalidArgumentException(sprintf('Image provider "%s" is not registered.', $name));
throw new Exceptions\InvalidArgumentException(sprintf('Images provider "%s" is not registered.', $name));
}

/**
Expand Down
10 changes: 10 additions & 0 deletions src/IPub/Images/Providers/IProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@
*/
interface IProvider
{
/**
* Define interface name
*/
const INTERFACE_NAME = __CLASS__;

/**
* @return string
*/
public function getName() : string;

/**
* @param string $storage
* @param string|NULL $namespace
Expand Down
8 changes: 8 additions & 0 deletions src/IPub/Images/Providers/PresenterProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ public function __construct(
$this->linkGenerator = $linkGenerator;
}

/**
* {@inheritdoc}
*/
public function getName() : string
{
return 'presenter';
}

/**
* {@inheritdoc}
*/
Expand Down
13 changes: 0 additions & 13 deletions src/IPub/Images/Templating/Helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,6 @@ public function __construct(
$this->imagesLoader = $imagesLoader;
}

/**
* Register template filters
*
* @param Engine $engine
*/
public function register(Engine $engine)
{
$engine->addFilter('isSquare', [$this, 'isSquare']);
$engine->addFilter('isHigher', [$this, 'isHigher']);
$engine->addFilter('isWider', [$this, 'isWider']);
$engine->addFilter('getImagesLoader', [$this, 'getImagesLoader']);
}

/**
* @param string $file
*
Expand Down
5 changes: 5 additions & 0 deletions src/IPub/Images/Validators/IValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@
*/
interface IValidator
{
/**
* Define interface name
*/
const INTERFACE_NAME = __CLASS__;

/**
* @param int $width
* @param int $height
Expand Down

0 comments on commit 44f6c42

Please sign in to comment.