Completed
Pull Request — 2.0 (#5)
by David
03:12
created

PatchController::applyAllPatches()   D

Complexity

Conditions 9
Paths 17

Size

Total Lines 37
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 37
rs 4.909
cc 9
eloc 24
nc 17
nop 3
1
<?php
2
namespace Mouf\Utils\Patcher\Controllers;
3
4
use Mouf\Controllers\AbstractMoufInstanceController;
5
6
use Mouf\Database\TDBM\Utils\TDBMDaoGenerator;
7
8
use Mouf\Html\Widgets\MessageService\Service\UserMessageInterface;
9
use Mouf\MoufManager;
10
11
use Mouf\Mvc\Splash\Controllers\Controller;
12
13
use Mouf\Reflection\MoufReflectionProxy;
14
15
use Mouf\Html\HtmlElement\HtmlBlock;
16
use Mouf\InstanceProxy;
17
use Mouf\Utils\Patcher\PatchException;
18
use Mouf\Utils\Patcher\PatchInterface;
19
20
/**
21
 * The controller to track which patchs have been applied.
22
23
 */
24
class PatchController extends AbstractMoufInstanceController {
25
	
26
	/**
27
	 *
28
	 * @var HtmlBlock
29
	 */
30
	public $content;
31
	
32
	/**
33
	 * A list of patches returned by the getView method of the PatchService. 
34
	 * @var array
35
	 */
36
	protected $patchesArray;
37
	
38
	protected $nbAwaiting = 0;
39
	protected $nbError = 0;
40
41
	protected $nbPatchesByType = [];
42
	
43
	/**
44
	 * Page listing the patches to be applied.
45
	 *
46
	 * @Action
47
	 * @Logged
48
	 */
49
	public function defaultAction($name, $selfedit="false") {
50
		$this->initController($name, $selfedit);
51
		
52
		$patchService = new InstanceProxy($name, $selfedit == "true");
53
		$this->patchesArray = $patchService->getView();
54
		
55
		foreach ($this->patchesArray as $patch) {
56
			if ($patch['status'] == PatchInterface::STATUS_AWAITING) {
57
				$this->nbAwaiting++;
58
			} elseif ($patch['status'] == PatchInterface::STATUS_ERROR) {
59
				$this->nbError++;
60
			}
61
		}
62
		
63
		$this->content->addFile(__DIR__."/../../../../views/patchesList.php", $this);
64
		$this->template->toHtml();
65
	}
66
	
67
68
	/**
69
	 * Runs a patch.
70
	 * 
71
	 * @Action
72
	 * @Logged
73
	 * @param string $name
74
	 * @param string $uniqueName
75
	 * @param string $action
76
	 */
77
	public function runPatch($name, $uniqueName, $action, $selfedit) {
78
		
79
		$patchService = new InstanceProxy($name, $selfedit == "true");
80
		
81
		try {
82
		
83
			if ($action == 'apply') {
84
				$this->patchesArray = $patchService->apply($uniqueName);
85
			} else if ($action == 'revert') {
86
				$this->patchesArray = $patchService->revert($uniqueName);
87
			} else if ($action == 'skip') {
88
				$this->patchesArray = $patchService->skip($uniqueName);
89
			} else {
90
				throw new PatchException("Unknown action: '".$action."'");
91
			}
92
		} catch (\Exception $e) {
93
			$htmlMessage = "An error occured while applying the patch: ".$e->getMessage();
94
			set_user_message($htmlMessage);
95
		}
96
97
		header('Location: .?name='.urlencode($name));
98
	}
99
100
    /**
101
     * Displays the page to select the patch types to be applied.
102
     *
103
     * @Action
104
     * @Logged
105
     * @param string $name
106
     * @param string $selfedit
107
     */
108
    public function runAllPatches($name, $selfedit) {
109
        $this->initController($name, $selfedit);
110
111
        $patchService = new InstanceProxy($name, $selfedit == "true");
112
        $this->patchesArray = $patchService->getView();
113
114
        $types = $patchService->_getSerializedTypes();
115
116
        foreach ($types as $type) {
117
            $this->nbPatchesByType[$type['name']] = 0;
118
        }
119
120
        $nbNoneDefaultPatches = 0;
121
122
        foreach ($this->patchesArray as $patch) {
123
            if ($patch['status'] == PatchInterface::STATUS_AWAITING || $patch['status'] == PatchInterface::STATUS_ERROR) {
124
                $type = $patch['patch_type'];
125
                if ($type !== '') {
126
                    $nbNoneDefaultPatches++;
127
                }
128
                $this->nbPatchesByType[$type]++;
129
            }
130
        }
131
132
        // If all patches to be applied are default patches, let's do this right now.
133
        if ($nbNoneDefaultPatches === 0) {
134
            $this->applyAllPatches($name, [''], $selfedit);
135
            return;
136
        }
137
138
        ksort($this->nbPatchesByType);
139
140
        // Otherwise, let's display a screen to select the patch types to be applied.
141
        $this->content->addFile(__DIR__."/../../../../views/applyPatches.php", $this);
142
        $this->template->toHtml();
143
    }
144
145
146
    /**
147
     * Runs all patches in a row.
148
     *
149
     * @Action
150
     * @Logged
151
     * @param string $name
152
     * @param array $types
153
     * @param string $selfedit
154
     */
155
	public function applyAllPatches($name, array $types, $selfedit) {
156
		$patchService = new InstanceProxy($name, $selfedit == "true");
157
		$this->patchesArray = $patchService->getView();
158
159
		// Array of cound of applied and skip patched. Key is the patch type.
160
		$appliedPatchArray = [];
161
        $skippedPatchArray = [];
162
163
		try {
164
			foreach ($this->patchesArray as $patch) {
165
                if ($patch['status'] == PatchInterface::STATUS_AWAITING || $patch['status'] == PatchInterface::STATUS_ERROR) {
166
                    $type = $patch['patch_type'];
167
                    if (in_array($type, $types) || $type === '') {
168
                        $patchService->apply($patch['uniqueName']);
169
                        if (!isset($appliedPatchArray[$type])) {
170
                            $appliedPatchArray[$type] = 0;
171
                        }
172
                        $appliedPatchArray[$type]++;
173
                    } else {
174
                        $patchService->skip($patch['uniqueName']);
175
                        if (!isset($skippedPatchArray[$type])) {
176
                            $skippedPatchArray[$type] = 0;
177
                        }
178
                        $skippedPatchArray[$type]++;
179
                    }
180
                }
181
			}
182
183
		} catch (\Exception $e) {
184
			$htmlMessage = "An error occured while applying the patch: ".$e->getMessage();
185
			set_user_message($htmlMessage);
186
		}
187
188
        $this->displayNotificationMessage($appliedPatchArray, $skippedPatchArray);
189
190
        header('Location: .?name='.urlencode($name));
191
	}
192
193
	private function displayNotificationMessage(array $appliedPatchArray, array $skippedPatchArray)
194
    {
195
        $nbPatchesApplied = array_sum($appliedPatchArray);
196
        $nbPatchesSkipped = array_sum($skippedPatchArray);
197
        $msg = '';
198 View Code Duplication
        if ($nbPatchesApplied !== 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
199
            $patchArr = [];
200
            foreach ($appliedPatchArray as $name => $number) {
201
                $name = $name ?: 'default';
202
                $patchArr[] = plainstring_to_htmlprotected($name).': '.$number;
203
            }
204
205
            $msg .= sprintf('%d patch(es) applied (%s)', $nbPatchesApplied, implode(', ', $patchArr));
206
        }
207 View Code Duplication
        if ($nbPatchesSkipped !== 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
208
            $patchArr = [];
209
            foreach ($skippedPatchArray as $name => $number) {
210
                $name = $name ?: 'default';
211
                $patchArr[] = plainstring_to_htmlprotected($name).': '.$number;
212
            }
213
214
            $msg .= sprintf('%d patch(es) skipped (%s)', $nbPatchesSkipped, implode(', ', $patchArr));
215
        }
216
217
        if ($msg !== '') {
218
            set_user_message($msg, UserMessageInterface::SUCCESS);
219
        }
220
    }
221
}