Completed
Push — master ( 09b86b...ba0798 )
by Andreas
20:05 queued 12s
created

lib/Doctrine/ODM/MongoDB/Id/AlnumGenerator.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\ODM\MongoDB\Id;
6
7
use Doctrine\ODM\MongoDB\DocumentManager;
8
use const E_USER_DEPRECATED;
9
use const STR_PAD_LEFT;
10
use function bccomp;
11
use function bcdiv;
12
use function bcmod;
13
use function is_numeric;
14
use function sprintf;
15
use function str_pad;
16
use function strlen;
17
use function trigger_error;
18
19
/**
20
 * AlnumGenerator is responsible for generating cased alpha-numeric unique identifiers.
21
 * It extends IncrementGenerator in order to ensure uniqueness even with short strings.
22
 *
23
 * "Awkward safe mode" avoids combinations that results in 'dirty' words by removing
24
 * the vowels from chars index
25
 *
26
 * A minimum identifier length can be enforced by setting a numeric value to the "pad" option
27
 * (with only 6 chars you will have more than 56 billion unique id's, 15 billion in 'awkward safe mode')
28
 *
29
 * The character set used for ID generation can be explicitly set with the "chars" option (e.g. base36, etc.)
30
 *
31
 * @final
32
 */
33
class AlnumGenerator extends IncrementGenerator
34
{
35
    /** @var int|null */
36
    protected $pad = null;
37
38
    /** @var bool */
39
    protected $awkwardSafeMode = false;
40
41
    /** @var string */
42
    protected $chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
43
44
    /** @var string */
45
    protected $awkwardSafeChars = '0123456789BCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz';
46
47 1 View Code Duplication
    public function __construct()
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
48
    {
49 1
        if (self::class === static::class) {
50 1
            return;
51
        }
52
53
        @trigger_error(sprintf('The class "%s" extends "%s" which will be final in MongoDB ODM 2.0.', static::class, self::class), E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
54
    }
55
56
    /**
57
     * Set padding on generated id
58
     */
59
    public function setPad(int $pad) : void
60
    {
61
        $this->pad = $pad;
62
    }
63
64
    /**
65
     * Enable awkwardSafeMode character set
66
     */
67
    public function setAwkwardSafeMode(bool $awkwardSafeMode = false) : void
68
    {
69
        $this->awkwardSafeMode = $awkwardSafeMode;
70
    }
71
72
    /**
73
     * Set the character set used for ID generation
74
     */
75 1
    public function setChars(string $chars) : void
76
    {
77 1
        $this->chars = $chars;
78 1
    }
79
80
    /** @inheritDoc */
81 1
    public function generate(DocumentManager $dm, object $document)
82
    {
83 1
        $id    = (string) parent::generate($dm, $document);
84 1
        $index = $this->awkwardSafeMode ? $this->awkwardSafeChars : $this->chars;
85 1
        $base  = (string) strlen($index);
86
87 1
        $out = '';
88
        do {
89 1
            $out = $index[(int) bcmod($id, $base)] . $out;
90 1
            $id  = bcdiv($id, $base);
91 1
        } while (bccomp($id, '0') === 1);
92
93 1
        if (is_numeric($this->pad)) {
94
            $out = str_pad($out, $this->pad, '0', STR_PAD_LEFT);
95
        }
96
97 1
        return $out;
98
    }
99
}
100