Completed
Push — middleware-wip ( 9fd801...caa06b )
by Romain
03:05
created

PersistenceManager::fetchFirst()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 24
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 24
rs 8.6845
c 1
b 0
f 0
cc 4
eloc 13
nc 4
nop 1
1
<?php
2
/*
3
 * 2017 Romain CANON <[email protected]>
4
 *
5
 * This file is part of the TYPO3 FormZ project.
6
 * It is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License, either
8
 * version 3 of the License, or any later version.
9
 *
10
 * For the full copyright and license information, see:
11
 * http://www.gnu.org/licenses/gpl-3.0.html
12
 */
13
14
namespace Romm\Formz\Persistence;
15
16
use Romm\Formz\Domain\Model\FormMetadata;
17
use Romm\Formz\Exceptions\InvalidEntryException;
18
use Romm\Formz\Form\FormInterface;
19
use Romm\Formz\Form\FormObject\FormObject;
20
use Romm\Formz\Form\FormObject\FormObjectFactory;
21
22
/**
23
 * Manages persistence for a given form object.
24
 */
25
class PersistenceManager
26
{
27
    /**
28
     * @var FormObject
29
     */
30
    protected $formObject;
31
32
    /**
33
     * @var bool
34
     */
35
    protected $initializationDone = false;
36
37
    /**
38
     * @param FormObject $formObject
39
     */
40
    public function __construct(FormObject $formObject)
41
    {
42
        $this->formObject = $formObject;
43
    }
44
45
    /**
46
     * Loops on the registered persistence services and saves the given form
47
     * instance in each one.
48
     */
49
    public function save()
50
    {
51
        $this->initializePersistence();
52
53
        $form = $this->formObject->getForm();
54
        $metadata = $this->formObject->getFormMetadata();
55
        $identifier = $metadata->getIdentifier();
56
        $persistenceServices = $this->getSortedPersistenceServices();
57
58
        foreach ($persistenceServices as $persistence) {
59
            $persistence->save($metadata, $form);
60
        }
61
62
        if (count($persistenceServices) > 0) {
63
            $proxy = FormObjectFactory::get()->getProxy($form);
64
            $proxy->markFormAsPersistent();
65
        }
66
67
        /*
68
         * If the form identifier has changed during the saving process (for
69
         * instance the form has been saved in database and has a new uid), the
70
         * metadata is persisted to be sure the form identifier is saved in
71
         * database.
72
         */
73
        if ($identifier !== $metadata->getIdentifier()) {
74
            $metadata->commit();
75
        }
76
    }
77
78
    /**
79
     * Loops on the registered persistence services, and tries to fetch the
80
     * form. If a form is found, it is returned and the loop breaks. If not form
81
     * is found, `null` is returned.
82
     *
83
     * @param FormMetadata $metadata
84
     * @return FormInterface|null
85
     * @throws InvalidEntryException
86
     */
87
    public function fetchFirst(FormMetadata $metadata)
88
    {
89
        $this->initializePersistence();
90
91
        foreach ($this->getSortedPersistenceServices() as $persistence) {
92
            if ($persistence->has($metadata)) {
93
                $form = $persistence->fetch($metadata);
94
95
                if (false === $form instanceof FormInterface) {
96
                    throw InvalidEntryException::persistenceInvalidEntryFetched($persistence, $form);
97
                }
98
99
                $this->formObject->setForm($form);
100
101
                $proxy = FormObjectFactory::get()->getProxy($form);
102
                $proxy->setFormHash($metadata->getHash());
103
                $proxy->markFormAsPersistent();
104
105
                return $form;
106
            }
107
        }
108
109
        return null;
110
    }
111
112
    /**
113
     * Loops on persistence services and initializes them.
114
     */
115
    protected function initializePersistence()
116
    {
117
        if (false === $this->initializationDone) {
118
            $this->initializationDone = true;
119
120
            foreach ($this->formObject->getDefinition()->getPersistence() as $persistence) {
121
                $persistence->initialize();
122
            }
123
        }
124
    }
125
126
    /**
127
     * Sorts the persistence services, based on their priority property: the
128
     * ones with the highest priority will come first.
129
     *
130
     * @return PersistenceInterface[]
131
     */
132
    protected function getSortedPersistenceServices()
133
    {
134
        $items = $this->formObject->getDefinition()->getPersistence();
135
136
        usort($items, function (PersistenceInterface $a, PersistenceInterface $b) {
137
            $priorityA = (int)$a->getPriority();
138
            $priorityB = (int)$b->getPriority();
139
140
            if ($priorityA === $priorityB) {
141
                return 0;
142
            }
143
144
            return $priorityA < $priorityB ? 1 : -1;
145
        });
146
147
        return $items;
148
    }
149
}
150