BookmarkController::legacyEditBookmark()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 7
dl 0
loc 7
ccs 0
cts 7
cp 0
crap 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * ownCloud - bookmarks
5
 *
6
 * This file is licensed under the Affero General Public License version 3 or
7
 * later. See the COPYING file.
8
 *
9
 * @author Stefan Klemm <[email protected]>
10
 * @copyright Stefan Klemm 2014
11
 */
12
13
namespace OCA\Bookmarks\Controller\Rest;
14
15
use OCP\IL10N;
16
use \OCP\IRequest;
17
use \OCP\AppFramework\ApiController;
18
use \OCP\AppFramework\Http\JSONResponse;
19
use \OCP\AppFramework\Http;
20
use \OCP\IDb;
21
use \OCA\Bookmarks\Controller\Lib\Bookmarks;
22
use \OCA\Bookmarks\Controller\Lib\ExportResponse;
23
use \OCA\Bookmarks\Controller\Lib\Helper;
24
use OCP\Util;
25
26
class BookmarkController extends ApiController {
27
28
	private $userId;
29
	private $db;
30
	private $l10n;
31
32
	public function __construct($appName, IRequest $request, $userId, IDb $db, IL10N $l10n) {
33
		parent::__construct($appName, $request);
34
		$this->userId = $userId;
35
		$this->db = $db;
36
		$this->request = $request;
37
		$this->l10n = $l10n;
38
	}
39
40
	/**
41
	 * @param string $type
42
	 * @param string $tag
43
	 * @param int $page
44
	 * @param string $sort
45
	 * @return JSONResponse
46
	 *
47
	 * @NoAdminRequired
48
	 */
49
	public function legacyGetBookmarks($type = "bookmark", $tag = '', $page = 0, $sort = "bookmarks_sorting_recent") {
50
		return $this->getBookmarks($type, $tag, $page, $sort);
51
	}
52
53
	/**
54
	 * @param string $type
55
	 * @param string $tag
56
	 * @param int $page
57
	 * @param string $sort
58
	 * @return JSONResponse
59
	 *
60
	 * @NoAdminRequired
61
	 */
62
	public function getBookmarks($type = "bookmark", $tag = '', $page = 0, $sort = "bookmarks_sorting_recent") {
63
64
		if ($type == 'rel_tags') {
65
			$tags = Bookmarks::analyzeTagRequest($tag);
66
			$qtags = Bookmarks::findTags($this->userId, $this->db, $tags);
67
			return new JSONResponse(array('data' => $qtags, 'status' => 'success'));
68
		} else { // type == bookmark
69
			$filterTag = Bookmarks::analyzeTagRequest($tag);
70
71
			$offset = $page * 10;
72
73
			if ($sort == 'bookmarks_sorting_clicks') {
74
				$sqlSortColumn = 'clickcount';
75
			} else {
76
				$sqlSortColumn = 'lastmodified';
77
			}
78
			$bookmarks = Bookmarks::findBookmarks($this->userId, $this->db, $offset, $sqlSortColumn, $filterTag, true);
79
			return new JSONResponse(array('data' => $bookmarks, 'status' => 'success'));
80
		}
81
	}
82
83
	/**
84
	 * @param string $url
85
	 * @param array $item
86
	 * @param int $from_own
87
	 * @param string $title
88
	 * @param bool $is_public
89
	 * @param string $description
90
	 * @return JSONResponse
91
	 *
92
	 * @NoAdminRequired
93
	 */
94
	public function newBookmark($url = "", $item = array(), $from_own = 0, $title = "", $is_public = false, $description = "") {
95
		$url_http = $url_https = '';
96
		if ($from_own == 0) {
97
			// allow only http(s) and (s)ftp
98
			$protocols = '/^(https?|s?ftp)\:\/\//i';
99
			try {
100
				if (preg_match($protocols, $url)) {
101
					$data = Bookmarks::getURLMetadata($url);
102
					// if not (allowed) protocol is given, assume http and https (and fetch both)
103
				} else {
104
					// append https to url and fetch it
105
					$url_https = 'https://' . $url;
106
					$data_https = Bookmarks::getURLMetadata($url_https);
107
					// append http to url and fetch it
108
					$url_http = 'http://' . $url;
109
					$data_http = Bookmarks::getURLMetadata($url_http);
110
				}
111
			} catch (\Exception $e) {
112
				return new JSONResponse(array('status' => 'error'), Http::STATUS_BAD_REQUEST);
113
			}
114
115
			if ($title === '' && isset($data['title'])) { // prefer original url if working
116
				$title = $data['title'];
117
				//url remains unchanged
118
			} elseif (isset($data_https['title'])) { // test if https works
119
				$title = $title === '' ? $data_https['title'] : $title;
120
				$url = $url_https;
121
			} elseif (isset($data_http['title'])) { // otherwise test http for results
122
				$title = $title === '' ? $data_http['title'] : $title;
123
				$url = $url_http;
124
			}
125
		}
126
127
		// Check if it is a valid URL (after adding http(s) prefix)
128
		$urlData = parse_url($url);
129 View Code Duplication
		if ($urlData === false || !isset($urlData['scheme']) || !isset($urlData['host'])) {
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...
130
			return new JSONResponse(array('status' => 'error'), Http::STATUS_BAD_REQUEST);
131
		}
132
133
		$tags = isset($item['tags']) ? $item['tags'] : array();
134
135
		$id = Bookmarks::addBookmark($this->userId, $this->db, $url, $title, $tags, $description, $is_public);
136
		$bm = Bookmarks::findUniqueBookmark($id, $this->userId, $this->db);
137
		return new JSONResponse(array('item' => $bm, 'status' => 'success'));
138
	}
139
140
	/**
141
	 * @param int $id
142
	 * @param string $url
143
	 * @param array $item
144
	 * @param string $title
145
	 * @param bool $is_public Description
146
	 * @param null $record_id
147
	 * @param string $description
148
	 * @return Http\TemplateResponse
149
	 *
150
	 * @NoAdminRequired
151
	 */
152
	//TODO id vs record_id?
153
	public function legacyEditBookmark($id = null, $url = "", $item = array(), $title = "", $is_public = false, $record_id = null, $description = "") {
154
		if ($id == null) {
155
			return $this->newBookmark($url, $item, false, $title, $is_public, $description);
156
		} else {
157
			return $this->editBookmark($id, $url, $item, $title, $is_public, $record_id, $description);
158
		}
159
	}
160
161
	/**
162
	 * @param int $id
163
	 * @param string $url
164
	 * @param array $item
165
	 * @param string $title
166
	 * @param bool $is_public Description
167
	 * @param null $record_id
168
	 * @param string $description
169
	 * @return JSONResponse
170
	 *
171
	 * @NoAdminRequired
172
	 */
173
	public function editBookmark($id = null, $url = "", $item = array(), $title = "", $is_public = false, $record_id = null, $description = "") {
174
175
		// Check if it is a valid URL
176
		$urlData = parse_url($url);
177 View Code Duplication
		if ($urlData === false || !isset($urlData['scheme']) || !isset($urlData['host'])) {
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...
178
			return new JSONResponse(array(), Http::STATUS_BAD_REQUEST);
179
		}
180
181
		if ($record_id == null) {
182
			return new JSONResponse(array(), Http::STATUS_BAD_REQUEST);
183
		}
184
185
		$tags = isset($item['tags']) ? $item['tags'] : array();
186
187
		if (is_numeric($record_id)) {
188
			$id = Bookmarks::editBookmark($this->userId, $this->db, $record_id, $url, $title, $tags, $description, $is_public = false);
189
		}
190
191
		$bm = Bookmarks::findUniqueBookmark($id, $this->userId, $this->db);
192
		return new JSONResponse(array('item' => $bm, 'status' => 'success'));
193
	}
194
195
	/**
196
	 * @param int $id
197
	 * @return JSONResponse
198
	 *
199
	 * @NoAdminRequired
200
	 */
201
	public function legacyDeleteBookmark($id = -1) {
202
		return $this->deleteBookmark($id);
203
	}
204
205
	/**
206
	 * @param int $id
207
	 * @return \OCP\AppFramework\Http\JSONResponse
208
	 *
209
	 * @NoAdminRequired
210
	 */
211
	public function deleteBookmark($id = -1) {
212
		if ($id == -1) {
213
			return new JSONResponse(array(), Http::STATUS_BAD_REQUEST);
214
		}
215
216
		if (!Bookmarks::deleteUrl($this->userId, $this->db, $id)) {
217
			return new JSONResponse(array(), Http::STATUS_BAD_REQUEST);
218
		} else {
219
			return new JSONResponse(array('status' => 'success'), Http::STATUS_OK);
220
		}
221
	}
222
223
	/**
224
	  @NoAdminRequired
225
	 * 
226
	 * @param string $url
227
	 * @return \OCP\AppFramework\Http\JSONResponse
228
	 */
229
	public function clickBookmark($url = "") {
230
231
		// Check if it is a valid URL
232
		$urlData = parse_url($url);
233 View Code Duplication
		if ($urlData === false || !isset($urlData['scheme']) || !isset($urlData['host'])) {
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...
234
			return new JSONResponse(array(), Http::STATUS_BAD_REQUEST);
235
		}
236
237
		$query = $this->db->prepareQuery('
238
			UPDATE `*PREFIX*bookmarks`
239
			SET `clickcount` = `clickcount` + 1
240
			WHERE `user_id` = ?
241
				AND `url` LIKE ?
242
		');
243
244
		$params = array($this->userId, htmlspecialchars_decode($url));
245
		$query->execute($params);
246
247
		return new JSONResponse(array('status' => 'success'), Http::STATUS_OK);
248
	}
249
250
	/**
251
	  @NoAdminRequired
252
	 * 
253
	 * @return \OCP\AppFramework\Http\JSONResponse
254
	 */
255
	public function importBookmark() {
256
		$full_input = $this->request->getUploadedFile("bm_import");
257
258
		if (empty($full_input)) {
259
			Util::writeLog('bookmarks', "No file provided for import", Util::WARN);
260
			$error = array();
261
			$error[] = $this->l10n->t('No file provided for import');
262
		} else {
263
			$error = array();
264
			$file = $full_input['tmp_name'];
265
			if ($full_input['type'] == 'text/html') {
266
				$error = Bookmarks::importFile($this->userId, $this->db, $file);
267
				if (empty($error)) {
268
					return new JSONResponse(array('status' => 'success'));
269
				}
270
			} else {
271
				$error[] = $this->l10n->t('Unsupported file type for import');
272
			}
273
		}
274
275
		return new JSONResponse(array('status' => 'error', 'data' => $error));
276
	}
277
278
	/**
279
	  @NoAdminRequired
280
	 * 
281
	 * @return \OCP\AppFramework\Http\Response
282
	 */
283
	public function exportBookmark() {
284
285
		$file = <<<EOT
286
<!DOCTYPE NETSCAPE-Bookmark-file-1>
287
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
288
<!-- This is an automatically generated file.
289
It will be read and overwritten.
290
Do Not Edit! -->
291
<TITLE>Bookmarks</TITLE>
292
<H1>Bookmarks</H1>
293
<DL><p>
294
EOT;
295
		$bookmarks = Bookmarks::findBookmarks($this->userId, $this->db, 0, 'id', array(), true, -1);
296
		foreach ($bookmarks as $bm) {
297
			$title = $bm['title'];
298
			if (trim($title) === '') {
299
				$url_parts = parse_url($bm['url']);
300
				$title = isset($url_parts['host']) ? Helper::getDomainWithoutExt($url_parts['host']) : $bm['url'];
301
			}
302
			$file .= '<DT><A HREF="' . \OC_Util::sanitizeHTML($bm['url']) . '" TAGS="' . implode(',', \OC_Util::sanitizeHTML($bm['tags'])) . '">';
303
			$file .= htmlspecialchars($title, ENT_QUOTES, 'UTF-8') . '</A>';
304
			if ($bm['description'])
305
				$file .= '<DD>' . htmlspecialchars($bm['description'], ENT_QUOTES, 'UTF-8');
306
			$file .= "\n";
307
		}
308
309
		return new ExportResponse($file);
310
	}
311
312
}
313