DeleteEntityWorker::execute()   D
last analyzed

Complexity

Conditions 14
Paths 24

Size

Total Lines 92
Code Lines 61

Duplication

Lines 0
Ratio 0 %

Importance

Changes 13
Bugs 5 Features 0
Metric Value
c 13
b 5
f 0
dl 0
loc 92
rs 4.9516
cc 14
eloc 61
nc 24
nop 1

How to fix   Long Method    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
 * Fwk
4
 *
5
 * Copyright (c) 2011-2012, Julien Ballestracci <[email protected]>.
6
 * All rights reserved.
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 *
11
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
12
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
13
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
15
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
16
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
17
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
19
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
21
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
22
 * POSSIBILITY OF SUCH DAMAGE.
23
 *
24
 * PHP Version 5.3
25
 * 
26
 * @category   Database
27
 * @package    Fwk\Db
28
 * @subpackage Workers
29
 * @author     Julien Ballestracci <[email protected]>
30
 * @copyright  2011-2012 Julien Ballestracci <[email protected]>
31
 * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
32
 * @link       http://www.phpfwk.com
33
 */
34
namespace Fwk\Db\Workers;
35
36
use Fwk\Db\Events\AfterDeleteEvent;
37
use Fwk\Db\Events\BeforeDeleteEvent;
38
use Fwk\Db\Exceptions\UnregisteredEntityException;
39
use Fwk\Db\Query;
40
use Fwk\Db\Registry\RegistryState;
41
use Fwk\Db\WorkerInterface;
42
use Fwk\Db\Accessor;
43
use Fwk\Db\Connection;
44
45
/**
46
 * Save Entity WorkerInterface
47
 * 
48
 * This worker is used when an entity or relation have to be deleted.
49
 * 
50
 * @category Workers
51
 * @package  Fwk\Db
52
 * @author   Julien Ballestracci <[email protected]>
53
 * @license  http://www.opensource.org/licenses/bsd-license.php  BSD License
54
 * @link     http://www.phpfwk.com
55
 */
56
class DeleteEntityWorker extends AbstractWorker implements WorkerInterface
57
{
58
    /**
59
     * Executes the worker (SQL queries) and fire EntityEvents
60
     * 
61
     * @param Connection $connection Database connection
62
     * 
63
     * @return void
64
     */
65
    public function execute(Connection $connection)
66
    {
67
        $registry   = $this->getRegistry();
68
        $entry      = $registry->getEntry($this->entity);
69
        if (false === $entry) {
70
            throw new UnregisteredEntityException('Unregistered entity: '. get_class($this->entity));
71
        }
72
73
        $state      = $entry->getState();
74
        $table      = $connection->table($registry->getTableName());
75
        $query      = Query::factory();
76
        $queryParams = array();
77
        $access     = new Accessor($this->entity);
78
        $tableRegistry = $connection->table($registry->getTableName())->getRegistry();
79
80
        if (in_array($this->entity, self::$working, true)) {
81
            return;
82
        }
83
84
        if ($tableRegistry !== $registry && $tableRegistry->contains($this->entity)) {
85
            $state = $tableRegistry->getState($this->entity);
86
        }
87
88
        switch ($state) {
89
        case RegistryState::UNKNOWN:
90
            throw new \LogicException(sprintf('Entity is in unknown state (%s)', get_class($this->entity)));
91
92
        case RegistryState::REGISTERED:
93
            return;
94
95
        case RegistryState::FRESH:
96
        case RegistryState::CHANGED:
97
            array_push(self::$working, $this->entity);
98
            $registry->fireEvent(
99
                $this->entity, new BeforeDeleteEvent(
100
                    $connection,
101
                    $table,
102
                    $this->entity
103
                )
104
            );
105
106
            $changed    = $registry->getChangedValues($this->entity);
107
            $query->delete($table->getName())->where('1 = 1');
108
            $ids        = $entry->getIdentifiers();
109
            $idKeys     = $table->getIdentifiersKeys();
110
111
            if (!count($ids)) {
112
                static::removeFromWorking($this->entity);
113
                throw new \LogicException(
114
                    sprintf('Entity %s lacks identifiers and cannot be deleted.', get_class($this->entity))
115
                );
116
            }
117
            
118
            foreach ($changed as $key => $value) {
119
                if (\array_key_exists($key, $ids)) {
120
                    static::removeFromWorking($this->entity);
121
                    throw new \LogicException(
122
                        sprintf(
123
                            'Unable to delete entity because identifiers (%s) have been modified',
124
                            implode(', ', $ids)
125
                        )
126
                    );
127
                }
128
            }
129
130
            foreach ($idKeys as $key) {
131
                $query->andWhere(sprintf('`%s` = ?', $key));
132
                $value = $access->get($key);
133
                if (!$value) {
134
                    static::removeFromWorking($this->entity);
135
                    throw new \RuntimeException(
136
                        sprintf(
137
                            'Cannot delete entity object (%s) because it '. 
138
                            'lacks identifier (%s)', 
139
                            get_class($this->entity), 
140
                            $key
141
                        )
142
                    );
143
                }
144
                $queryParams[] = $value;
145
            }
146
147
            break;
148
        }
149
150
        $connection->execute($query, $queryParams);
151
        $registry->fireEvent(
152
            $this->entity, new AfterDeleteEvent($connection, $table, $this->entity)
153
        );
154
        $registry->remove($this->entity);
155
        static::removeFromWorking($this->entity);
156
    }
157
}