Skip to content

Commit e3bd7ba

Browse files
author
Robin Cawser
committed
initial commit 1.0
1 parent 3ec9f77 commit e3bd7ba

10 files changed

Lines changed: 305 additions & 3 deletions

File tree

composer.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
"email":"robin@vivait.co.uk"
88
}
99
],
10+
"minimum-stability": "dev",
11+
"prefer-stable": true,
1012
"require": {
1113
"php": ">=5.3.3",
1214
"doctrine/common": "~2.2"
@@ -19,8 +21,7 @@
1921
},
2022
"autoload":{
2123
"psr-0":{
22-
"Vivait\\StringGeneratorBundle":""
24+
"Vivait\\StringGeneratorBundle":"src/"
2325
}
24-
},
25-
"target-dir":"Vivait/StringGeneratorBundle"
26+
}
2627
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace spec\Vivait\StringGeneratorBundle\Generator;
4+
5+
use PhpSpec\ObjectBehavior;
6+
7+
class StringGeneratorSpec extends ObjectBehavior
8+
{
9+
function it_is_initializable()
10+
{
11+
$this->shouldHaveType('Vivait\StringGeneratorBundle\Generator\StrindfggGenerator');
12+
}
13+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
namespace Vivait\StringGeneratorBundle\Annotation;
4+
5+
use Doctrine\Common\Annotations\Annotation;
6+
7+
/**
8+
* @Annotation
9+
*
10+
* Class StringGenerator
11+
* @package Vivait\StringGeneratorBundle\Annotation
12+
*/
13+
class StringGenerator extends Annotation
14+
{
15+
/**
16+
* @var string
17+
*/
18+
public $prefix;
19+
20+
/**
21+
* @var int
22+
*/
23+
public $length = 8;
24+
25+
/**
26+
* @var boolean
27+
*/
28+
public $unique = true;
29+
30+
/**
31+
* @var string
32+
*/
33+
public $separator = "-";
34+
35+
/**
36+
* @var string
37+
*/
38+
public $prefix_callback;
39+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
namespace Vivait\StringGeneratorBundle\DependencyInjection;
4+
5+
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
6+
use Symfony\Component\Config\Definition\ConfigurationInterface;
7+
8+
/**
9+
* This is the class that validates and merges configuration from your app/config files
10+
*
11+
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class}
12+
*/
13+
class Configuration implements ConfigurationInterface
14+
{
15+
/**
16+
* {@inheritDoc}
17+
*/
18+
public function getConfigTreeBuilder()
19+
{
20+
$treeBuilder = new TreeBuilder();
21+
$rootNode = $treeBuilder->root('vivait_string_generator');
22+
$rootNode
23+
->children()
24+
->scalarNode('generator_class')
25+
->cannotBeEmpty()
26+
->defaultValue('Vivait\StringGeneratorBundle\Generator\StringGenerator')
27+
->end()
28+
->end()
29+
;
30+
31+
return $treeBuilder;
32+
}
33+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace Vivait\StringGeneratorBundle\DependencyInjection;
4+
5+
use Symfony\Component\DependencyInjection\ContainerBuilder;
6+
use Symfony\Component\Config\FileLocator;
7+
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
8+
use Symfony\Component\DependencyInjection\Loader;
9+
10+
/**
11+
* This is the class that loads and manages your bundle configuration
12+
*
13+
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
14+
*/
15+
class VivaitStringGeneratorExtension extends Extension
16+
{
17+
/**
18+
* {@inheritDoc}
19+
*/
20+
public function load(array $configs, ContainerBuilder $container)
21+
{
22+
$configuration = new Configuration();
23+
$config = $this->processConfiguration($configuration, $configs);
24+
25+
$container->setParameter('vivait_string_generator.generator_class', $config['generator_class']);
26+
27+
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
28+
$loader->load('services.yml');
29+
}
30+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php
2+
3+
namespace Vivait\StringGeneratorBundle\EventListener;
4+
5+
use Doctrine\Common\Annotations\Reader;
6+
use Doctrine\ORM\Event\LifecycleEventArgs;
7+
use Vivait\StringGeneratorBundle\Annotation as Vivait;
8+
use Vivait\StringGeneratorBundle\Model\GeneratorInterface;
9+
10+
class StringGeneratorListener
11+
{
12+
private $reader;
13+
private $repo;
14+
/**
15+
* @var GeneratorInterface
16+
*/
17+
private $generator;
18+
19+
public function __construct(Reader $reader, GeneratorInterface $generator)
20+
{
21+
$this->reader = $reader;
22+
$this->generator = $generator;
23+
}
24+
25+
/**
26+
* @param LifecycleEventArgs $args
27+
*/
28+
public function prePersist(LifecycleEventArgs $args)
29+
{
30+
$entity = $args->getEntity();
31+
$em = $args->getEntityManager();
32+
$meta = $em->getClassMetadata(get_class($entity));
33+
$this->repo = $em->getRepository($meta->getName());
34+
35+
$obj = new \ReflectionObject($entity);
36+
37+
//Loop through each of entity's properties
38+
foreach ($obj->getProperties() as $property) {
39+
//Loop through the property's annotations
40+
foreach ($this->reader->getPropertyAnnotations($property) as $annotation) {
41+
42+
if ($annotation instanceof Vivait\StringGenerator) {
43+
if (method_exists($entity, $annotation->prefix_callback) && is_callable([$entity, $annotation->prefix_callback])) {
44+
$callback = $annotation->prefix_callback;
45+
$annotation->prefix = $entity->$callback();
46+
}
47+
48+
$id = $this->generateId(
49+
$property->name,
50+
$annotation
51+
);
52+
$meta->getReflectionProperty($property->name)->setValue($entity, $id);
53+
}
54+
}
55+
}
56+
}
57+
58+
/**
59+
* @param $property
60+
* @param $annotation
61+
* @return string
62+
*/
63+
private function generateId($property, Vivait\StringGenerator $annotation)
64+
{
65+
$this->generator
66+
->setLength($annotation->length);
67+
68+
$str = $this->generator->generate();
69+
70+
if ($annotation->prefix) {
71+
$str = sprintf("%s%s%s", $annotation->prefix, $annotation->separator, $str);
72+
}
73+
74+
if (!$annotation->unique) {
75+
return $str;
76+
}
77+
78+
if ($this->repo->findOneBy([$property => $str])) {
79+
return $this->generateId($property, $annotation);
80+
} else {
81+
return $str;
82+
}
83+
84+
}
85+
86+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
namespace Vivait\StringGeneratorBundle\Generator;
4+
5+
use Vivait\StringGeneratorBundle\Model\GeneratorInterface;
6+
7+
class StringGenerator implements GeneratorInterface
8+
{
9+
10+
/**
11+
* @var
12+
*/
13+
private $length;
14+
15+
/**
16+
* @var string
17+
*/
18+
private $chars;
19+
20+
public function __construct()
21+
{
22+
$this->chars = 'abcdefjhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345567890';
23+
}
24+
25+
/**
26+
* @param string $chars
27+
*/
28+
public function setChars($chars)
29+
{
30+
if(!$chars){
31+
throw new \OutOfBoundsException('$chars cannot be empty');
32+
}
33+
34+
$this->chars = $chars;
35+
}
36+
37+
/**
38+
* Set the length of the generated string
39+
* @param $length
40+
* @return $this
41+
*/
42+
public function setLength($length)
43+
{
44+
$this->length = $length;
45+
return $this;
46+
}
47+
48+
/**
49+
* Creates a random string based on a length and alphabet
50+
*
51+
* @return string
52+
*/
53+
public function generate()
54+
{
55+
$str = [];
56+
$alphaLength = strlen($this->chars) - 1;
57+
for ($i = 0; $i < $this->length; $i++) {
58+
$n = rand(0, $alphaLength);
59+
$str[] = $this->chars[$n];
60+
}
61+
62+
return implode($str);
63+
}
64+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace Vivait\StringGeneratorBundle\Model;
4+
5+
interface GeneratorInterface
6+
{
7+
/**
8+
* @param integer $length
9+
* @return $this
10+
*/
11+
public function setLength($length);
12+
13+
/**
14+
* @return string
15+
*/
16+
public function generate();
17+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
services:
2+
vivait_stringgenerator.generator:
3+
class: "%vivait_string_generator.generator_class%"
4+
public: false
5+
vivait_stringgenerator.generator.listener:
6+
class: Vivait\StringGeneratorBundle\EventListener\StringGeneratorListener
7+
public: false
8+
arguments: ["@annotation_reader", "@vivait_stringgenerator.generator"]
9+
tags:
10+
- { name: doctrine.event_listener, event: prePersist }
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace Vivait\StringGeneratorBundle;
4+
5+
use Symfony\Component\HttpKernel\Bundle\Bundle;
6+
7+
class VivaitStringGeneratorBundle extends Bundle
8+
{
9+
}

0 commit comments

Comments
 (0)