Completed
Push — master ( beafec...bac082 )
by Sean
03:35
created

GitDispatcher::index()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
eloc 2
nc 1
nop 1
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->createFetch();
65
			case 'GET':
66
				return $this->getFetch($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 getFetch($ID) {
134
		$ping = DNGitFetch::get()->byID($ID);
135
		if(!$ping) {
136
			return $this->getAPIResponse(['message' => 'Fetch 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 createFetch() {
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' => 'Fetch queued as job ' . $fetch->ResqueToken,
160
			'href' => $location,
161
		);
162
163
		$response = $this->getAPIResponse($output, 201);
164
		$response->addHeader('Location', $location);
165
		return $response;
166
	}
167
168
	/**
169
	 * @param $project
170
	 *
171
	 * @return array
172
	 */
173
	protected function getGitBranches($project) {
174
		$branches = [];
175
		foreach($project->DNBranchList() as $branch) {
176
			$branches[] = [
177
				'key' => $branch->SHA(),
178
				'value' => $branch->Name(),
179
			];
180
		}
181
		return $branches;
182
	}
183
184
	/**
185
	 * @param $project
186
	 *
187
	 * @return array
188
	 */
189
	protected function getGitTags($project) {
190
		$tags = [];
191
		foreach($project->DNTagList()->setLimit(null) as $tag) {
192
			$tags[] = [
193
				'key' => $tag->SHA(),
194
				'value' => $tag->Name(),
195
			];
196
		}
197
		return $tags;
198
	}
199
200
	/**
201
	 * @param $project
202
	 *
203
	 * @return array
204
	 */
205
	protected function getGitPrevDeploys($project) {
206
		$redeploy = [];
207 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...
208
			$envName = $dnEnvironment->Name;
209
			$perEnvDeploys = [];
210
			foreach($dnEnvironment->DeployHistory() as $deploy) {
211
				$sha = $deploy->SHA;
212
213
				// Check if exists to make sure the newest deployment date is used.
214
				if(!isset($perEnvDeploys[$sha])) {
215
					$pastValue = sprintf(
216
						"%s (deployed %s)",
217
						substr($sha, 0, 8),
218
						$deploy->obj('LastEdited')->Ago()
219
					);
220
					$perEnvDeploys[$sha] = [
221
						'key' => $sha,
222
						'value' => $pastValue
223
					];
224
				}
225
			}
226
			if(!empty($perEnvDeploys)) {
227
				$redeploy[$envName] = array_values($perEnvDeploys);
228
			}
229
		}
230
		return $redeploy;
231
	}
232
233
}
234