Passed
Push — develop ( 2eb13f...360a3e )
by Andrea
22:40 queued 17:58
created

DatabaseUtils   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 161
Duplicated Lines 0 %

Test Coverage

Coverage 83.78%

Importance

Changes 0
Metric Value
eloc 74
dl 0
loc 161
ccs 62
cts 74
cp 0.8378
rs 10
c 0
b 0
f 0
wmc 28

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B isDateChanged() 0 15 7
B isArrayChanged() 0 13 7
A isRecordChanged() 0 14 5
A getFieldType() 0 12 2
A isSchemaChanged() 0 21 1
A truncateTable() 0 31 5
1
<?php
2
3
namespace Cdf\BiCoreBundle\Utils\Database;
4
5
use DateTime;
6
use Doctrine\ORM\EntityManagerInterface;
7
use Doctrine\ORM\EntityManager;
8
use Symfony\Component\HttpKernel\KernelInterface;
9
use Symfony\Bundle\FrameworkBundle\Console\Application;
10
use Symfony\Component\Console\Input\ArrayInput;
11
use Symfony\Component\Console\Output\BufferedOutput;
12
use \Exception;
0 ignored issues
show
Bug introduced by
The type \Exception was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use function count;
14
15
class DatabaseUtils
16
{
17
    /* @var $em EntityManager */
0 ignored issues
show
Documentation Bug introduced by
The doc comment $em at position 0 could not be parsed: Unknown type name '$em' at position 0 in $em.
Loading history...
18
19
    private EntityManagerInterface $em;
20
    private KernelInterface $kernel;
21
22 2
    public function __construct(KernelInterface $kernel, EntityManagerInterface $em)
23
    {
24 2
        $this->kernel = $kernel;
25 2
        $this->em = $em;
26
    }
27
28
    /**
29
     *
30
     * @param mixed $entity
31
     * @param string $field
32
     * @return string
33
     */
34 2
    public function getFieldType($entity, $field)
35
    {
36 2
        $classname = get_class($entity);
37 2
        if ($classname === false) {
38
            throw new Exception("Entity class not found: " . $entity);
39
        }
40 2
        $metadata = $this->em->getClassMetadata($classname);
41 2
        $fieldMetadata = $metadata->fieldMappings[$field];
42
43 2
        $fieldType = $fieldMetadata['type'];
44
45 2
        return $fieldType;
46
    }
47
48
    /**
49
     *
50
     * @param mixed $entity
51
     * @param string $fieldname
52
     * @param mixed $oldvalue
53
     * @param mixed $newvalue
54
     * @return bool
55
     */
56 1
    public function isRecordChanged($entity, $fieldname, $oldvalue, $newvalue)
57
    {
58 1
        $fieldtype = $this->getFieldType(new $entity(), $fieldname);
59 1
        if ('boolean' === $fieldtype) {
60 1
            return $oldvalue !== $newvalue;
61
        }
62 1
        if ('datetime' === $fieldtype || 'date' === $fieldtype) {
63 1
            return $this->isDateChanged($oldvalue, $newvalue);
64
        }
65 1
        if (is_array($oldvalue)) {
66 1
            return $this->isArrayChanged($oldvalue, $newvalue);
67
        }
68
69 1
        return $oldvalue !== $newvalue;
70
    }
71
72
    /**
73
     *
74
     * @param mixed $oldvalue
75
     * @param mixed $newvalue
76
     * @return boolean
77
     */
78 1
    public function isDateChanged($oldvalue, $newvalue)
79
    {
80 1
        $datenewvalue = new DateTime();
81 1
        $datenewvalue->setTimestamp($newvalue);
82 1
        $twoboth = !$oldvalue && !$newvalue;
83 1
        if ($twoboth) {
84 1
            return false;
85
        }
86 1
        $onlyonenull = (!$oldvalue && $newvalue) || ($oldvalue && !$newvalue);
87 1
        if ($onlyonenull) {
88
            return true;
89
        }
90 1
        $changed = ($oldvalue != $datenewvalue);
91
92 1
        return $changed;
93
    }
94
95
    /**
96
     *
97
     * @param mixed $oldvalue
98
     * @param mixed $newvalue
99
     * @return boolean
100
     */
101 1
    public function isArrayChanged($oldvalue, $newvalue)
102
    {
103 1
        $twoboth = !$oldvalue && !$newvalue;
104 1
        if ($twoboth) {
105
            return false;
106
        }
107 1
        $onlyonenull = (!$oldvalue && $newvalue) || ($oldvalue && !$newvalue);
108 1
        if ($onlyonenull) {
109 1
            return true;
110
        }
111 1
        $numdiff = array_diff($oldvalue, $newvalue);
112
113 1
        return count($numdiff) > 0;
114
    }
115
116
    /**
117
     *
118
     * @param string $entityclass
119
     * @param bool $cascade
120
     * @return mixed
121
     */
122 1
    public function truncateTable($entityclass, $cascade = false)
123
    {
124 1
        $cmd = $this->em->getClassMetadata($entityclass);
125 1
        $connection = $this->em->getConnection();
126 1
        $dbPlatform = $connection->getDatabasePlatform();
127 1
        $dbtype = $connection->getDriver()->getDatabasePlatform()->getName();
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\DBAL\Platforms\...ractPlatform::getName() has been deprecated: Identify platforms by their class. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

127
        $dbtype = /** @scrutinizer ignore-deprecated */ $connection->getDriver()->getDatabasePlatform()->getName();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
128 1
        $retval = false;
129
130
        switch ($dbtype) {
131 1
            case 'mysql':
132
                $connection->query('SET FOREIGN_KEY_CHECKS=0');
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\DBAL\Connection::query() has been deprecated: This API is deprecated and will be removed after 2022 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

132
                /** @scrutinizer ignore-deprecated */ $connection->query('SET FOREIGN_KEY_CHECKS=0');

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
133
                $q = $dbPlatform->getTruncateTableSql($cmd->getTableName(), $cascade);
134
                $retval = $connection->executeUpdate($q);
135
                $connection->query('SET FOREIGN_KEY_CHECKS=1');
136
                break;
137 1
            case 'postgresql':
138 1
                $cascadesql = $cascade ? 'CASCADE' : '';
139 1
                $tablename = $cmd->getTableName();
140 1
                if ($cmd->getSchemaName()) {
141
                    $tablename = $cmd->getSchemaName() . '.' . $tablename;
142
                }
143 1
                $retval = $connection->executeQuery(sprintf('TRUNCATE TABLE %s ' . $cascadesql, $tablename));
144 1
                break;
145
            default:
146
                $q = $dbPlatform->getTruncateTableSql($cmd->getTableName(), $cascade);
147
                $retval = $connection->executeUpdate($q);
148
                break;
149
        }
150 1
        $this->em->clear();
151
152 1
        return $retval;
153
    }
154
155 2
    public function isSchemaChanged(): bool
156
    {
157 2
        $application = new Application($this->kernel);
158 2
        $application->setAutoExit(false);
159
160 2
        $input = new ArrayInput(array(
161
            'command' => 'doctrine:schema:update',
162
            '--dump-sql' => true,
163
            '--no-debug' => true,
164 2
            '--env' => $this->kernel->getEnvironment(),
165
        ));
166
167
        // You can use NullOutput() if you don't need the output
168 2
        $output = new BufferedOutput();
169 2
        $application->run($input, $output);
170
171
        // return the output, don't use if you used NullOutput()
172 2
        $content = $output->fetch();
173 2
        $changed = strpos($content, 'Nothing to update');
174
175 2
        return 0 !== $changed;
176
    }
177
}
178