Completed
Push — master ( 307c4b...cdea54 )
by Stig
06:50 queued 03:32
created

GitDispatcher::init()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 9
rs 9.6666
cc 2
eloc 5
nc 2
nop 0
1
<?php
2
3
/**
4
 * This dispatcher takes care of updating and returning information about this
5
 * projects git repository
6
 */
7
class GitDispatcher extends Dispatcher {
8
9
	const ACTION_GIT = 'git';
10
11
	/**
12
	 * @var array
13
	 */
14
	private static $action_types = [
15
		self::ACTION_GIT
16
	];
17
18
	/**
19
	 * @var array
20
	 */
21
	public static $allowed_actions = [
22
		'update',
23
		'show'
24
	];
25
26
	/**
27
	 * @var \DNProject
28
	 */
29
	protected $project = null;
30
31
	/**
32
	 * @var \DNEnvironment
33
	 */
34
	protected $environment = null;
35
36
	public function init() {
37
		parent::init();
38
39
		$this->project = $this->getCurrentProject();
40
41
		if(!$this->project) {
42
			return $this->project404Response();
43
		}
44
	}
45
46
	/**
47
	 *
48
	 * @param \SS_HTTPRequest $request
49
	 *
50
	 * @return \HTMLText|\SS_HTTPResponse
51
	 */
52
	public function index(\SS_HTTPRequest $request) {
53
		return $this->redirect(\Controller::join_links($this->Link(), 'show'), 302);
54
	}
55
56
	/**
57
	 * @param SS_HTTPRequest $request
58
	 * @return SS_HTTPResponse
59
	 */
60
	public function update(SS_HTTPRequest $request) {
61
		switch($request->httpMethod()) {
62
			case 'POST':
63
				$this->checkSecurityToken();
64
				return $this->createUpdate();
65
			case 'GET':
66
				return $this->getUpdateStatus($this->getRequest()->param('ID'));
67
			default:
68
				return $this->getAPIResponse(['message' => 'Method not allowed, requires POST or GET/{id}'], 405);
69
		}
70
	}
71
72
	/**
73
	 * @param SS_HTTPRequest $request
74
	 *
75
	 * @return string
76
	 */
77
	public function show(\SS_HTTPRequest $request) {
78
79
		$refs = [];
80
		$order = 0;
81
		$refs[] = [
82
			'id' => ++$order,
83
			'label' => "Branch version",
84
			"description" => "Deploy the latest version of a branch",
85
			"list" => $this->getGitBranches($this->project)
86
		];
87
88
		$refs[] = [
89
			'id' => ++$order,
90
			'label' => "Tag version",
91
			"description" => "Deploy a tagged release",
92
			"list" => $this->getGitTags($this->project)
93
		];
94
95
		// @todo: the original was a tree that was keyed by environment, the
96
		// front-end dropdown needs to be changed to support that. brrrr.
97
		$prevDeploys = [];
98
		foreach($this->getGitPrevDeploys($this->project) as $env) {
99
			foreach($env as $deploy) {
100
				$prevDeploys[] = $deploy;
101
			}
102
		}
103
		$refs[] = [
104
			'id' => ++$order,
105
			'label' => "Redeploy a release that was previously deployed (to any environment",
106
			"description" => "Deploy a previous release",
107
			"list" => $prevDeploys
108
		];
109
110
		return $this->getAPIResponse(['refs' => $refs], 200);
111
	}
112
113
	/**
114
	 * @return string
115
	 */
116
	public function Link() {
117
		return \Controller::join_links($this->project->Link(), self::ACTION_GIT);
118
	}
119
120
	/**
121
	 * @param string $name
122
	 *
123
	 * @return array
124
	 */
125
	public function getModel($name = '') {
126
		return [];
127
	}
128
129
	/**
130
	 * @param int $ID
131
	 * @return SS_HTTPResponse
132
	 */
133
	protected function getUpdateStatus($ID) {
134
		$ping = DNGitFetch::get()->byID($ID);
135
		if(!$ping) {
136
			return $this->getAPIResponse(['message' => 'GIT update ('. $ID . ') not found'], 404);
137
		}
138
		$output = [
139
			'id' => $ID,
140
			'status' => $ping->ResqueStatus(),
141
			'message' => array_filter(explode(PHP_EOL, $ping->LogContent()))
142
		];
143
144
		return $this->getAPIResponse($output, 200);
145
	}
146
147
	/**
148
	 * @return SS_HTTPResponse
149
	 */
150 View Code Duplication
	protected function createUpdate() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
151
		/** @var DNGitFetch $fetch */
152
		$fetch = DNGitFetch::create();
153
		$fetch->ProjectID = $this->project->ID;
154
		$fetch->write();
155
		$fetch->start();
156
157
		$location = Director::absoluteBaseURL() . $this->Link() . '/update/' . $fetch->ID;
158
		$output = array(
159
			'message' => 'git fetch has been queued',
160
			'id' => $fetch->ID,
161
			'location' => $location,
162
		);
163
164
		$response = $this->getAPIResponse($output, 201);
165
		$response->addHeader('Location', $location);
166
		return $response;
167
	}
168
169
	/**
170
	 * @param $project
171
	 *
172
	 * @return array
173
	 */
174
	protected function getGitBranches($project) {
175
		$branches = [];
176
		foreach($project->DNBranchList() as $branch) {
177
			$branches[] = [
178
				'key' => $branch->SHA(),
179
				'value' => $branch->Name(),
180
			];
181
		}
182
		return $branches;
183
	}
184
185
	/**
186
	 * @param $project
187
	 *
188
	 * @return array
189
	 */
190
	protected function getGitTags($project) {
191
		$tags = [];
192
		foreach($project->DNTagList()->setLimit(null) as $tag) {
193
			$tags[] = [
194
				'key' => $tag->SHA(),
195
				'value' => $tag->Name(),
196
			];
197
		}
198
		return $tags;
199
	}
200
201
	/**
202
	 * @param $project
203
	 *
204
	 * @return array
205
	 */
206
	protected function getGitPrevDeploys($project) {
207
		$redeploy = [];
208 View Code Duplication
		foreach($project->DNEnvironmentList() as $dnEnvironment) {
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...
209
			$envName = $dnEnvironment->Name;
210
			$perEnvDeploys = [];
211
			foreach($dnEnvironment->DeployHistory() as $deploy) {
212
				$sha = $deploy->SHA;
213
214
				// Check if exists to make sure the newest deployment date is used.
215
				if(!isset($perEnvDeploys[$sha])) {
216
					$pastValue = sprintf(
217
						"%s (deployed %s)",
218
						substr($sha, 0, 8),
219
						$deploy->obj('LastEdited')->Ago()
220
					);
221
					$perEnvDeploys[$sha] = [
222
						'key' => $sha,
223
						'value' => $pastValue
224
					];
225
				}
226
			}
227
			if(!empty($perEnvDeploys)) {
228
				$redeploy[$envName] = array_values($perEnvDeploys);
229
			}
230
		}
231
		return $redeploy;
232
	}
233
234
}
235