Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ability to redirect user from subdomain to some predefined url. #3

Merged
merged 6 commits into from
Apr 18, 2014
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,21 @@ php:
- 5.3
- 5.4
- 5.5
- 5.6
- hhvm

matrix:
fast_finish: true
allow_failures:
- php: 5.6
- php: hhvm

env:
- SYMFONY_VERSION="2.1.*"
- SYMFONY_VERSION="2.2.*"
- SYMFONY_VERSION="2.3.*"
- SYMFONY_VERSION="2.4.*"

before_script:
- composer self-update
- composer require symfony/framework-bundle:${SYMFONY_VERSION}
- composer install --dev
7 changes: 7 additions & 0 deletions AstinaRedirectManagerBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@

use Symfony\Component\HttpKernel\Bundle\Bundle;

/**
* Class AstinaRedirectManagerBundle
*
* @package Astina\Bundle\RedirectManagerBundle
* @author Matej Velikonja <mvelikonja@astina.ch>
* @copyright 2014 Astina AG (http://astina.ch)
*/
class AstinaRedirectManagerBundle extends Bundle
{
}
26 changes: 24 additions & 2 deletions DependencyInjection/AstinaRedirectManagerExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,31 @@ class AstinaRedirectManagerExtension extends Extension
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$this->processConfiguration($configuration, $configs);
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));

$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');

// if redirect_subdomain is present, than we set up listener
if (isset($config['redirect_subdomains'])) {
$routerDefinition = $container->getDefinition('armb.router');
$routerDefinitionTag = $routerDefinition->getTag('kernel.event_listener');
$routerDefinitionTag = reset($routerDefinitionTag);

$subDomainDefinition = $container->getDefinition('armb.subdomain');
$subDomainDefinition->addTag(
'kernel.event_listener',
array(
'event' => 'kernel.request',
'method' => 'onKernelRequest',
'priority' => $routerDefinitionTag['priority'] - 1 //has to be lower than armb_router listener
)
);

// let's add customizable arguments
$subDomainDefinition->addArgument($config['redirect_subdomains']['route_name']);
$subDomainDefinition->addArgument($config['redirect_subdomains']['route_params']);
$subDomainDefinition->addArgument($config['redirect_subdomains']['redirect_code']);
}
}
}
24 changes: 20 additions & 4 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,27 @@ class Configuration implements ConfigurationInterface
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$treeBuilder->root('astina_redirect_manager');
$rootNode = $treeBuilder->root('astina_redirect_manager');

$rootNode
->children()
->arrayNode('redirect_subdomains')
->children()
->scalarNode('route_name')
->isRequired()
->end()
->arrayNode('route_params')
->useAttributeAsKey('name')
->prototype('scalar')->end()
->end()
->integerNode('redirect_code')
->defaultValue(301)
->min(300)
->max(308)
->end()
->end()
->end();

// Here you should define the parameters that are allowed to
// configure your bundle. See the documentation linked above for
// more information on that topic.

return $treeBuilder;
}
Expand Down
13 changes: 8 additions & 5 deletions Entity/MapRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@
use Doctrine\ORM\EntityRepository;

/**
* MapRepository
* Class MapRepository
*
* @package Astina\Bundle\RedirectManagerBundle\Entity
* @author Philipp Kräutli <pkraeutli@astina.ch>
* @copyright 2014 Astina AG (http://astina.ch)
*/
class MapRepository extends EntityRepository
{
/**
* @param $url
* @param $path
* @param string $url
* @param string $path
*
* @return Map
*/
public function findOneForUrlOrPath($url, $path)
Expand All @@ -25,8 +29,7 @@ public function findOneForUrlOrPath($url, $path)
->orderBy('m.urlFrom', 'desc') // urls starting with "http" will be sorted before urls starting with "/"
->setMaxResults(1)
->getQuery()
->getResult()
;
->getResult();

if (empty($maps)) {
return null;
Expand Down
5 changes: 4 additions & 1 deletion EventListener/RedirectListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ class RedirectListener
*/
private $redirectFinder;

function __construct(RedirectFinderInterface $redirectFinder)
/**
* @param RedirectFinderInterface $redirectFinder
*/
public function __construct(RedirectFinderInterface $redirectFinder)
{
$this->redirectFinder = $redirectFinder;
}
Expand Down
91 changes: 91 additions & 0 deletions EventListener/SubDomainListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php

namespace Astina\Bundle\RedirectManagerBundle\EventListener;

use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use JMS\DiExtraBundle\Annotation as DI;
use Symfony\Component\HttpKernel\KernelEvents;

/**
* Class SubDomainListener
*
* @package Astina\Bundle\RedirectManagerBundle\EventListener
* @author Matej Velikonja <mvelikonja@astina.ch>
* @copyright 2014 Astina AG (http://astina.ch)
*/
class SubDomainListener
{
/**
* @var \Symfony\Bundle\FrameworkBundle\Routing\Router
*/
private $router;

/**
* @var string
*/
private $pathName;

/**
* @var array
*/
private $pathParams;

/**
* @var int
*/
private $redirectCode;

/**
* @param Router $router
* @param string $pathName
* @param array $pathParams
* @param int $redirectCode
*/
public function __construct(Router $router, $pathName, array $pathParams, $redirectCode = 301)
{
$this->router = $router;
$this->pathName = $pathName;
$this->pathParams = $pathParams;
$this->redirectCode = $redirectCode;
}

/**
* Executes on kernel event request. Must be executed after RedirectListener.
*
* @param GetResponseEvent $event
*/
public function onKernelRequest(GetResponseEvent $event)
{
if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
return;
}

$request = $event->getRequest();
$host = $request->getHttpHost();
$parts = explode('.', $host);
$subDomains = array_slice($parts, 0, count($parts) - 2);

if ($request->getMethod() != 'GET') {
return;
}

if (! count($subDomains)) {
return;
}

$redirectResponse = new RedirectResponse($this->getRedirectUrl(), $this->redirectCode);

$event->setResponse($redirectResponse);
}

/**
* @return string
*/
private function getRedirectUrl()
{
return $this->router->generate($this->pathName, $this->pathParams, true);
}
}
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,32 @@ CSV has to contain two columns, where the first one contain urlFrom and second u
```bash
$ php app/console armb:import /path/to/csv/file.csv [--redirect-code=302] [--count-redirects]
```

### Using subDomain listener to redirect to somewhere else

If listener detects that subDomain is used it redirects visitor to url with name `route_name` with `route_params` and redirect code `redirect_code`.

```yaml
# app/config/config.yml

astina_redirect_manager:
redirect_subdomains:
route_name: ~ # Required
route_params:
param1: some-value
param2: some-different-value
redirect_code: 301

```

*Warning*

You have to set parameter `router.request_context.host` in parameters.yml file. Otherwise value `localhost` will be used as domain name.

```yaml
# app/config/parameters.yml

# ...
router.request_context.host: example.com
# ...
```
4 changes: 4 additions & 0 deletions Resources/config/services.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
parameters:
armb.redirect.class: Astina\Bundle\RedirectManagerBundle\EventListener\RedirectListener
armb.subdomain.class: Astina\Bundle\RedirectManagerBundle\EventListener\SubDomainListener
armb.service.csv_importer: Astina\Bundle\RedirectManagerBundle\Service\CsvImporter
armb.redirect_finder.class: Astina\Bundle\RedirectManagerBundle\Service\RedirectFinder

Expand All @@ -9,6 +10,9 @@ services:
arguments: [@armb.redirect_finder]
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: 512 }
armb.subdomain:
class: %armb.subdomain.class%
arguments: [@router]
armb.csv_importer:
class: %armb.service.csv_importer%
arguments: [@doctrine]
Expand Down
17 changes: 17 additions & 0 deletions Service/RedirectFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;

/**
* Class RedirectFinder
*
* @package Astina\Bundle\RedirectManagerBundle\Service
* @author Philipp Kräutli <pkraeutli@astina.ch>
* @copyright 2014 Astina AG (http://astina.ch)
*/
class RedirectFinder implements RedirectFinderInterface
{
/**
Expand All @@ -23,6 +30,11 @@ public function __construct(RegistryInterface $doctrine)
$this->doctrine = $doctrine;
}

/**
* @param Request $request
*
* @return null|RedirectResponse
*/
public function findRedirect(Request $request)
{
$path = str_replace($request->getBaseUrl(), '/', $request->getRequestUri());
Expand Down Expand Up @@ -51,6 +63,11 @@ public function findRedirect(Request $request)
return new RedirectResponse($redirectUrl, $map->getRedirectHttpCode());
}

/**
* @param string $url
*
* @return int
*/
protected function isAbsoluteUrl($url)
{
return preg_match('/^https?:\/\//', $url);
Expand Down
10 changes: 9 additions & 1 deletion Service/RedirectFinderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,19 @@
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;

/**
* Class RedirectFinderInterface
*
* @package Astina\Bundle\RedirectManagerBundle\Service
* @author Philipp Kräutli <pkraeutli@astina.ch>
* @copyright 2014 Astina AG (http://astina.ch)
*/
interface RedirectFinderInterface
{
/**
* @param Request $request
*
* @return RedirectResponse
*/
public function findRedirect(Request $request);
}
}
Loading