Passed
Pull Request — master (#706)
by
unknown
12:36
created

Auditor::execute()   B

Complexity

Conditions 10
Paths 9

Size

Total Lines 40
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 10.0125

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 10
eloc 21
c 1
b 1
f 0
nc 9
nop 1
dl 0
loc 40
ccs 19
cts 20
cp 0.95
crap 10.0125
rs 7.6666

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace OwenIt\Auditing;
4
5
use Illuminate\Support\Facades\Config;
6
use Illuminate\Support\Manager;
7
use InvalidArgumentException;
8
use OwenIt\Auditing\Contracts\Auditable;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, OwenIt\Auditing\Auditable. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
9
use OwenIt\Auditing\Contracts\AuditDriver;
10
use OwenIt\Auditing\Drivers\Database;
11
use OwenIt\Auditing\Events\Audited;
12
use OwenIt\Auditing\Events\Auditing;
13
use OwenIt\Auditing\Exceptions\AuditingException;
14
15
class Auditor extends Manager implements Contracts\Auditor
16
{
17
    /**
18
     * {@inheritdoc}
19
     */
20 2
    public function getDefaultDriver()
21
    {
22 2
        return 'database';
23
    }
24
25
    /**
26
     * {@inheritdoc}
27
     */
28 126
    protected function createDriver($driver)
29
    {
30
        try {
31 126
            return parent::createDriver($driver);
32 4
        } catch (InvalidArgumentException $exception) {
33 4
            if (class_exists($driver)) {
34 2
                return $this->container->make($driver);
35
            }
36
37 2
            throw $exception;
38
        }
39
    }
40
41
    /**
42
     * {@inheritdoc}
43
     */
44 126
    public function auditDriver(Auditable $model): AuditDriver
45
    {
46 126
        $driver = $this->driver($model->getAuditDriver());
47
48 124
        if (!$driver instanceof AuditDriver) {
49 2
            throw new AuditingException('The driver must implement the AuditDriver contract');
50
        }
51
52 122
        return $driver;
53
    }
54
55
    /**
56
     * {@inheritdoc}
57
     */
58 126
    public function execute(Auditable $model)
59
    {
60 126
        if (!$model->readyForAuditing()) {
61 60
            return;
62
        }
63
64 126
        $driver = $this->auditDriver($model);
65
66 122
        if (!$this->fireAuditingEvent($model, $driver)) {
67 2
            return;
68
        }
69
70
        // If we want to avoid storing Audits with empty old_values & new_values, return null here.
71 120
        if (!Config::get('audit.empty_values')) {
72
            if (
73 4
                empty($model->toAudit()['new_values']) &&
74 4
                empty($model->toAudit()['old_values']) &&
75 4
                !in_array($model->getAuditEvent(), Config::get('audit.allowed_empty_values'))
76
            ) {
77 2
                return;
78
            }
79
        }
80
81
        //Don't store audits if there are no changes, expect for 'retrieved' events
82
        if (
83 120
            $model->toAudit()['new_values'] == $model->toAudit()['old_values'] &&
84 120
            !in_array($model->getAuditEvent(), ['retrieved'])
85
        ) {
86 4
            return;
87
        }
88
89 120
        $audit = $driver->audit($model);
90 120
        if (!$audit) {
91
            return;
92
        }
93
94 120
        $driver->prune($model);
95
96 120
        $this->container->make('events')->dispatch(
97 120
            new Audited($model, $driver, $audit)
98
        );
99
    }
100
101
    /**
102
     * Create an instance of the Database audit driver.
103
     *
104
     * @return \OwenIt\Auditing\Drivers\Database
105
     */
106 122
    protected function createDatabaseDriver(): Database
107
    {
108 122
        return $this->container->make(Database::class);
109
    }
110
111
    /**
112
     * Fire the Auditing event.
113
     *
114
     * @param \OwenIt\Auditing\Contracts\Auditable $model
115
     * @param \OwenIt\Auditing\Contracts\AuditDriver $driver
116
     *
117
     * @return bool
118
     */
119 122
    protected function fireAuditingEvent(Auditable $model, AuditDriver $driver): bool
120
    {
121
        return $this
122 122
                ->container
123 122
                ->make('events')
124 122
                ->until(new Auditing($model, $driver)) !== false;
125
    }
126
}
127