Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
Add skeleton of the bundle and commands
  • Loading branch information
Stoakes committed Mar 8, 2017
0 parents commit 05ede56
Show file tree
Hide file tree
Showing 10 changed files with 1,846 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.idea
vendor
28 changes: 28 additions & 0 deletions Command/ConvertRouteLoader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
/**
* Created by PhpStorm.
* User: Antoine
* Date: 06/03/2017
* Time: 21:53
*/

namespace Stoakes\RoutingConverterBundle\Command;


use Symfony\Component\Config\Loader\Loader;
use Symfony\Component\Routing\Loader\YamlFileLoader;
use Symfony\Component\Routing\RouteCollection;

class ConvertRouteLoader extends YamlFileLoader
{
public function load($resource, $type = null)
{
$collection = new RouteCollection();

// $resource = '@AppBundle/Resources/config/import_routing.yml';
$type = 'yaml';

return parent::load($resource, $type);
}

}
171 changes: 171 additions & 0 deletions Command/MigrateRoutesCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
<?php

namespace Stoakes\RoutingConverterBundle\Command;

use Gnugat\Redaktilo\Editor;
use Gnugat\Redaktilo\EditorFactory;
use Gnugat\Redaktilo\Text;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Controller\ControllerResolver;
use Symfony\Component\Routing\Route;

class MigrateRoutesCommand extends ContainerAwareCommand
{
/**
* {@inheritdoc}
* php bin/console stoakes:convert_yml ./src/Mgate/DashboardBundle/Resources/config/routing.yml /suivi
*/
protected function configure()
{
$this
->setName('stoakes:convert_yml')
->addArgument('resource', InputArgument::REQUIRED, 'The routing.yml file to convert')
->addArgument('prefix', InputArgument::OPTIONAL, 'The prefix for the created routes')
->setDescription('Hello PhpStorm');
}

/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$fileLoader = new FileLocator(__DIR__ . '/../../../../');
$loader = new ConvertRouteLoader($fileLoader);
$routes = $loader->load($input->getArgument('resource'));

foreach ($routes->all() as $name => $route) {
$string = ' * @Route(name="' . $name . '", path="' . $input->getArgument('prefix') . '' . $route->getPath() . '"';

$string = $this->methodsHandler($route, $string);
$string = $this->requirementsHandler($route, $string);
$string = $this->defaultsHandler($route, $string);

$string .= ')';
echo $string . "\n";

$controller = $this->getController($route);
$classname = str_replace('\\', '/', get_class($controller[0]));
$actionText = $controller[1];

$editor = EditorFactory::createEditor();
$text = $editor->open('src/' . $classname . '.php');

if ($editor->hasBelow($text, '/' . $actionText . '/')) {

//go to the method declaration line
$editor->jumpBelow($text, '/' . $actionText . '/');
$lineAbove = $text->getLine($text->getCurrentLineNumber() - 1);
$indent = strlen($text->getLine()) - strlen(ltrim($text->getLine()));
$indentation = str_repeat(' ', $indent);

//is the line above a full commentary ? ie /** hello */
if (preg_match('#/\*\*(.*)\*/#', $lineAbove)) {
echo 'full';
} elseif (preg_match('#\*/#', $lineAbove)) { //is the line above an ending commentary ie contains */
$editor->insertAbove($text, $indentation . '' . $string, $text->getCurrentLineNumber() - 1);
} elseif (preg_match('/^ *$/', $lineAbove) || strlen(trim($lineAbove)) == 0) { //is the line above an empty line ?
$editor->insertAbove($text, $indentation . ' */', $text->getCurrentLineNumber());
$editor->insertAbove($text, $indentation . '' . $string, $text->getCurrentLineNumber());
$editor->insertAbove($text, $indentation . '/**', $text->getCurrentLineNumber());
} else { //content but not annotations
$editor->insertAbove($text, $indentation . ' */', $text->getCurrentLineNumber());
$editor->insertAbove($text, $indentation . '' . $string, $text->getCurrentLineNumber());
$editor->insertAbove($text, $indentation . '/**', $text->getCurrentLineNumber());
}
//handle route annotation import
$text = $this->importHandler($editor, $text);
$editor->save($text);

} else {
throw new \RuntimeException('unable to find ' . $actionText . ' in ' . $classname);
}


}


}


private function methodsHandler(Route $route, $string)
{
if ($route->getMethods()) {
$string .= ', methods={';
$i = 0;
foreach ($route->getMethods() as $method) {
if ($i != 0) {
$string .= ',';
}
$string .= '"' . $method . '"';
$i++;
}
$string .= '}';

}
return $string;
}

private function requirementsHandler(Route $route, $string)
{
if ($route->getRequirements()) {
$string .= ', requirements={';
$i = 0;
foreach ($route->getRequirements() as $key => $value) {
if ($i != 0) {
$string .= ', ';
}
$string .= '"' . $key . '": "' . $value . '"';
$i++;
}
$string .= '}';
}
return $string;
}

private function defaultsHandler(Route $route, $string)
{
if (count($route->getDefaults()) > 1) { // there always are a _controller field.
$string .= ', defaults={';

$i = 0;
foreach ($route->getDefaults() as $key => $value) {
if ($key != '_controller') {
if ($i != 0) {
$string .= ', ';
}
$string .= '"' . $key . '": "' . $value . '"';

$i++;
}
}
$string .= '}';
}
return $string;
}

private function getController(Route $route)
{
$controller = $route->getDefault('_controller');
$req = new Request([], [], array('_controller' => $controller));
$controllerResolver = $this->getContainer()->get('debug.controller_resolver');
$controller = $controllerResolver->getController($req);

return $controller;
}

private function importHandler(Editor $editor, Text $text)
{
if (!$editor->hasBelow($text, 'use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;', 0)) {
$editor->jumpAbove($text, '#use S#'); //jump above first import. There are at least the controller import.
$editor->insertAbove($text, 'use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;');
}

return $text;
}

}
29 changes: 29 additions & 0 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Stoakes\RoutingConverterBundle\DependencyInjection;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

/**
* This is the class that validates and merges configuration from your app/config files.
*
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/configuration.html}
*/
class Configuration implements ConfigurationInterface
{
/**
* {@inheritdoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('stoakes_routing_converter');

// 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;
}
}
28 changes: 28 additions & 0 deletions DependencyInjection/StoakesRoutingConverterExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Stoakes\RoutingConverterBundle\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;

/**
* This is the class that loads and manages your bundle configuration.
*
* @link http://symfony.com/doc/current/cookbook/bundles/extension.html
*/
class StoakesRoutingConverterExtension extends Extension
{
/**
* {@inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
//$configuration = new Configuration();
//$config = $this->processConfiguration($configuration, $configs);

//$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
//$loader->load('services.yml');
}
}
70 changes: 70 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Routing Converter

Converts your routing.yml files to annotations.

## Example

**Before**

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

app_homepage:
path: /home/{id}
defaults: { _controller: AppBundle:Home:index}
requirements:
id: \d+
methods: [GET, HEAD]
````
**After**

````php
<?php
# AppBundle/Controller/HomeController.php

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

class HomeController{

/**
* @Route(name="app_homepage", path="/home/{id}", methods={"GET","HEAD"}, requirements={"id": "\d+"})
*/
public function indexAction($id){

}

}

````
## Installation

```
composer require stoakes/routing-converter
```

Then add to your `AppKernel.php`

````php
<?php

if (in_array($this->getEnvironment(), array('dev', 'test'))) {
$bundles[] =
new Stoakes\RoutingConverterBundle\StoakesRoutingConverterBundle();

}
````

Use it : `php bin/console stoakes:convert_yml PATH_TO_A_ROUTING.YML_FILE [PREFIX]`

`php bin/console stoakes:convert_yml ./src/AppBundle/Resources/config/routing.yml /fr
`

## How does it works

That bundle provides a convertion command that uses symfony core components (routing, http kernel) and redaktilo to modify your Controllers.

## Tests

You : " - Hey that bundle is untested !!"

Me : " - I am working it. However I have created it in 2 evenings to convert routing in one of my app, and it works quite well"
4 changes: 4 additions & 0 deletions Resources/config/services.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
services:
# stoakes_routing_converter.example:
# class: Stoakes\RoutingConverterBundle\Example
# arguments: ["@service_id", "plain_value", "%parameter%"]
9 changes: 9 additions & 0 deletions StoakesRoutingConverterBundle.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace Stoakes\RoutingConverterBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

class StoakesRoutingConverterBundle extends Bundle
{
}
42 changes: 42 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"name": "stoakes/routing-converter",
"description": "Routing.yml to annotations converter for Symfony",
"license": "MIT",
"type": "symfony-bundle",
"keywords": [
"routing",
"annotation",
"converter",
"symfony"
],
"homepage": "https://github.com/stoakes/routing-converter",
"authors": [
{
"name": "Antoine Beyet",
"email": "[email protected]"
}
],
"require": {
"php": ">=5.3.0",
"gnugat/redaktilo": "~1.0",
"symfony/console": "~2.3|~3.0",
"symfony/framework-bundle": "~2.3|~3.0",
"symfony/http-foundation": "~2.3|~3.0",
"symfony/http-kernel": "~2.3|~3.0",
"symfony/routing": "~2.3|~3.0",
"symfony/config": "~2.3|~3.0"
},
"require-dev": {
},
"config": {
"sort-packages": true
},
"autoload": {
"psr-4": {
"Stoakes\\Bundle\\RoutingConverterBundle\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
}
}
Loading

0 comments on commit 05ede56

Please sign in to comment.