Skip to content

Commit

Permalink
Merge branch 'feature/config-providers' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
qzminski committed Nov 30, 2017
2 parents e7098f5 + 0dd4fe3 commit c6fa1c7
Show file tree
Hide file tree
Showing 31 changed files with 1,643 additions and 290 deletions.
57 changes: 54 additions & 3 deletions README.md
Expand Up @@ -4,9 +4,13 @@
[![](https://img.shields.io/travis/terminal42/contao-url-rewrite/master.svg?style=flat-square)](https://travis-ci.org/terminal42/contao-url-rewrite/)
[![](https://img.shields.io/coveralls/terminal42/contao-url-rewrite/master.svg?style=flat-square)](https://coveralls.io/github/terminal42/contao-url-rewrite)

The extension provides a new backend module for Contao that allows to set various URL rewrites. Behind the scenes
the rules are added as routes to the internal application router which allows to use all the features provided
by the Symfony Routing component.
The extension provides a new way for Contao to set various URL rewrites. The available config providers are:

- Bundle config provider – the entries are taken from `config.yml` file
- Database provider – the entries are taken from backend module

Behind the scenes the rules are added as routes to the internal application router which allows to use all the features
provided by the Symfony Routing component.

## Installation

Expand All @@ -18,6 +22,38 @@ composer require terminal42/contao-url-rewrite

## Configuration

### Bundle configuration

The bundle configuration is optional. Here you can define the entries and disable the backend management module.

```yaml
# config/config.yml
terminal42_url_rewrite:
backend_management: false # Disable backend management of entries (true by default)
entries: # Optional entries
-
request: { path: 'find/{address}' }
response: { code: 303, uri: 'https://www.google.com/maps?q={address}' }

-
request:
path: 'news/{news}'
requirements: {news: '\d+'}
response:
code: 301
uri: '{{news_url::{news}|absolute}}'

-
request:
path: 'home.php'
hosts: ['localhost']
condition: "context.getMethod() == 'GET' and request.query.has('page')"
response:
uri: '{{link_url::{page}|absolute}}'
```

### Running under non Contao managed edition

If you are running the Contao Managed Edition then the extension should work out of the box. For all the other systems
you have to additionally register the routing configuration in the config files:

Expand Down Expand Up @@ -65,6 +101,21 @@ Response URI: {{link_url::{page}|absolute}}
Result: domain.tld/home.php?page=123 → domain.tld/foobar-123.html
```

## Create a custom config provider

In addition to the existing providers you can create your own class that provides the rewrite configurations.
The new service must extend the [Terminal42\UrlRewriteBundle\ConfigProvider\ConfigProviderInterface](src/ConfigProvider/ConfigProviderInterface.php)
interface and be registered with the appropriate tag:

```yaml
services:
app.my_rewrite_provider:
class: AppBundle\RewriteProvider\MyRewriteProvider
public: false
tags:
- { name: terminal42_url_rewrite.provider, priority: 128 }
```

## Resources

1. [Symfony Routing](https://symfony.com/doc/current/routing.html)
Expand Down
103 changes: 103 additions & 0 deletions src/ConfigProvider/BundleConfigProvider.php
@@ -0,0 +1,103 @@
<?php

/*
* UrlRewrite Bundle for Contao Open Source CMS.
*
* @copyright Copyright (c) 2017, terminal42 gmbh
* @author terminal42 <https://terminal42.ch>
* @license MIT
*/

namespace Terminal42\UrlRewriteBundle\ConfigProvider;

use Terminal42\UrlRewriteBundle\RewriteConfig;
use Terminal42\UrlRewriteBundle\RewriteConfigInterface;

class BundleConfigProvider implements ConfigProviderInterface
{
/**
* @var array
*/
private $entries = [];

/**
* BundleConfigProvider constructor.
*
* @param array $entries
*/
public function __construct(array $entries = [])
{
$this->entries = $entries;
}

/**
* {@inheritdoc}
*/
public function find(string $id): ?RewriteConfigInterface
{
if (!array_key_exists($id, $this->entries)) {
return null;
}

return $this->createConfig($id, $this->entries[$id]);
}

/**
* {@inheritdoc}
*/
public function findAll(): array
{
if (count($this->entries) === 0) {
return [];
}

$configs = [];

foreach ($this->entries as $id => $entry) {
if (($config = $this->createConfig((string) $id, $entry)) !== null) {
$configs[] = $config;
}
}

return $configs;
}

/**
* Create the config.
*
* @param string $id
* @param array $data
*
* @return null|RewriteConfig
*/
private function createConfig(string $id, array $data): ?RewriteConfig
{
if (!isset($data['request']['path'], $data['response']['code'])) {
return null;
}

$config = new RewriteConfig($id, $data['request']['path'], (int) $data['response']['code']);

// Request hosts
if (isset($data['request']['hosts'])) {
$config->setRequestHosts($data['request']['hosts']);
}

// Request condition
if (isset($data['request']['condition'])) {
$config->setRequestCondition($data['request']['condition']);
}

// Request requirements
if (isset($data['request']['requirements'])) {
$config->setRequestRequirements($data['request']['requirements']);
}

// Response URI
if (isset($data['response']['uri'])) {
$config->setResponseUri($data['response']['uri']);
}

return $config;
}
}
82 changes: 82 additions & 0 deletions src/ConfigProvider/ChainConfigProvider.php
@@ -0,0 +1,82 @@
<?php

/*
* UrlRewrite Bundle for Contao Open Source CMS.
*
* @copyright Copyright (c) 2017, terminal42 gmbh
* @author terminal42 <https://terminal42.ch>
* @license MIT
*/

namespace Terminal42\UrlRewriteBundle\ConfigProvider;

use Terminal42\UrlRewriteBundle\RewriteConfigInterface;

class ChainConfigProvider implements ConfigProviderInterface
{
/**
* @var array
*/
private $providers = [];

/**
* Add the config provider.
*
* @param ConfigProviderInterface $provider
*/
public function addProvider(ConfigProviderInterface $provider): void
{
$this->providers[] = $provider;
}

/**
* {@inheritdoc}
*/
public function find(string $id): ?RewriteConfigInterface
{
list($class, $id) = explode(':', $id);

/** @var ConfigProviderInterface $provider */
foreach ($this->providers as $provider) {
if ($class === $this->getProviderIdentifier($provider) && ($config = $provider->find($id)) !== null) {
return $config;
}
}

return null;
}

/**
* {@inheritdoc}
*/
public function findAll(): array
{
$configs = [];

/** @var ConfigProviderInterface $provider */
foreach ($this->providers as $provider) {
$providerConfigs = $provider->findAll();

/** @var RewriteConfigInterface $config */
foreach ($providerConfigs as $config) {
$config->setIdentifier($this->getProviderIdentifier($provider) . ':' . $config->getIdentifier());
}

$configs = array_merge($configs, $providerConfigs);
}

return $configs;
}

/**
* Get the provider identifier
*
* @param ConfigProviderInterface $provider
*
* @return string
*/
private function getProviderIdentifier(ConfigProviderInterface $provider): string
{
return get_class($provider);
}
}
32 changes: 32 additions & 0 deletions src/ConfigProvider/ConfigProviderInterface.php
@@ -0,0 +1,32 @@
<?php

/*
* UrlRewrite Bundle for Contao Open Source CMS.
*
* @copyright Copyright (c) 2017, terminal42 gmbh
* @author terminal42 <https://terminal42.ch>
* @license MIT
*/

namespace Terminal42\UrlRewriteBundle\ConfigProvider;

use Terminal42\UrlRewriteBundle\RewriteConfigInterface;

interface ConfigProviderInterface
{
/**
* Find the config.
*
* @param string $id
*
* @return RewriteConfigInterface|null
*/
public function find(string $id): ?RewriteConfigInterface;

/**
* Find all configs.
*
* @return array
*/
public function findAll(): array;
}

0 comments on commit c6fa1c7

Please sign in to comment.