1<?php 2 3declare(strict_types=1); 4 5namespace OCA\Notes\Controller; 6 7use OCA\Notes\Service\NotesService; 8use OCA\Notes\Service\MetaService; 9use OCA\Notes\Service\SettingsService; 10 11use OCP\AppFramework\Controller; 12use OCP\IRequest; 13use OCP\IConfig; 14use OCP\IL10N; 15use OCP\AppFramework\Http; 16use OCP\AppFramework\Http\JSONResponse; 17 18class NotesController extends Controller { 19 20 /** @var NotesService */ 21 private $notesService; 22 /** @var MetaService */ 23 private $metaService; 24 /** @var SettingsService */ 25 private $settingsService; 26 /** @var Helper */ 27 private $helper; 28 /** @var IConfig */ 29 private $settings; 30 /** @var IL10N */ 31 private $l10n; 32 33 public function __construct( 34 string $AppName, 35 IRequest $request, 36 NotesService $notesService, 37 MetaService $metaService, 38 SettingsService $settingsService, 39 Helper $helper, 40 IConfig $settings, 41 IL10N $l10n 42 ) { 43 parent::__construct($AppName, $request); 44 $this->notesService = $notesService; 45 $this->metaService = $metaService; 46 $this->settingsService = $settingsService; 47 $this->helper = $helper; 48 $this->settings = $settings; 49 $this->l10n = $l10n; 50 } 51 52 /** 53 * @NoAdminRequired 54 */ 55 public function index(int $pruneBefore = 0) : JSONResponse { 56 return $this->helper->handleErrorResponse(function () use ($pruneBefore) { 57 $userId = $this->helper->getUID(); 58 $settings = $this->settingsService->getAll($userId); 59 60 $lastViewedNote = (int) $this->settings->getUserValue( 61 $userId, 62 $this->appName, 63 'notesLastViewedNote' 64 ); 65 $errorMessage = null; 66 $nac = null; 67 68 try { 69 $nac = $this->helper->getNotesAndCategories($pruneBefore, [ 'etag', 'content' ]); 70 } catch (\Throwable $e) { 71 $this->helper->logException($e); 72 $errorMessage = $this->l10n->t('Reading notes from filesystem has failed.').' ('.get_class($e).')'; 73 } 74 75 if ($errorMessage === null && $lastViewedNote 76 && is_array($nac) && is_array($nac['notesAll']) && !count($nac['notesAll']) 77 ) { 78 $this->settings->deleteUserValue($userId, $this->appName, 'notesLastViewedNote'); 79 $lastViewedNote = 0; 80 } 81 82 $result = [ 83 'notesData' => $nac ? array_values($nac['notesData']) : null, 84 'noteIds' => $nac ? array_keys($nac['notesAll']) : null, 85 'categories' => $nac['categories'] ?? null, 86 'settings' => $settings, 87 'lastViewedNote' => $lastViewedNote, 88 'errorMessage' => $errorMessage, 89 ]; 90 $etag = md5(json_encode($result)); 91 return (new JSONResponse($result)) 92 ->setLastModified($nac['lastUpdate'] ?? null) 93 ->setETag($etag) 94 ; 95 }); 96 } 97 98 99 /** 100 * @NoAdminRequired 101 */ 102 public function dashboard() : JSONResponse { 103 return $this->helper->handleErrorResponse(function () { 104 $maxItems = 7; 105 $userId = $this->helper->getUID(); 106 $notes = $this->notesService->getTopNotes($userId, $maxItems + 1); 107 $hasMoreNotes = count($notes) > $maxItems; 108 $notes = array_slice($notes, 0, $maxItems); 109 $items = array_map(function ($note) { 110 $excerpt = ''; 111 try { 112 $excerpt = $note->getExcerpt(); 113 } catch (\Throwable $e) { 114 } 115 return [ 116 'id' => $note->getId(), 117 'title' => $note->getTitle(), 118 'category' => $note->getCategory(), 119 'favorite' => $note->getFavorite(), 120 'excerpt' => $excerpt, 121 ]; 122 }, $notes); 123 return [ 124 'items' => $items, 125 'hasMoreItems' => $hasMoreNotes, 126 ]; 127 }); 128 } 129 130 131 /** 132 * @NoAdminRequired 133 */ 134 public function get(int $id) : JSONResponse { 135 return $this->helper->handleErrorResponse(function () use ($id) { 136 $note = $this->notesService->get($this->helper->getUID(), $id); 137 138 // save the last viewed note 139 $this->settings->setUserValue( 140 $this->helper->getUID(), 141 $this->appName, 142 'notesLastViewedNote', 143 strval($id) 144 ); 145 146 $noteData = $this->helper->getNoteData($note); 147 return (new JSONResponse($noteData)) 148 ->setETag($noteData['etag']) 149 ; 150 }); 151 } 152 153 154 /** 155 * @NoAdminRequired 156 */ 157 public function create(string $category) : JSONResponse { 158 return $this->helper->handleErrorResponse(function () use ($category) { 159 $note = $this->notesService->create($this->helper->getUID(), '', $category); 160 return $this->helper->getNoteData($note); 161 }); 162 } 163 164 165 /** 166 * @NoAdminRequired 167 */ 168 public function undo( 169 int $id, 170 string $title, 171 string $content, 172 string $category, 173 int $modified, 174 bool $favorite 175 ) : JSONResponse { 176 return $this->helper->handleErrorResponse(function () use ( 177 $id, 178 $title, 179 $content, 180 $category, 181 $modified, 182 $favorite 183 ) { 184 try { 185 // check if note still exists 186 $note = $this->notesService->get($this->helper->getUID(), $id); 187 $noteData = $this->helper->getNoteData($note); 188 if ($noteData['error']) { 189 throw new \Exception(); 190 } 191 return $noteData; 192 } catch (\Throwable $e) { 193 // re-create if note doesn't exit anymore 194 $note = $this->notesService->create($this->helper->getUID(), $title, $category); 195 $note->setContent($content); 196 $note->setModified($modified); 197 $note->setFavorite($favorite); 198 return $this->helper->getNoteData($note); 199 } 200 }); 201 } 202 203 204 /** 205 * @NoAdminRequired 206 */ 207 public function autotitle(int $id) : JSONResponse { 208 return $this->helper->handleErrorResponse(function () use ($id) { 209 $note = $this->notesService->get($this->helper->getUID(), $id); 210 $oldTitle = $note->getTitle(); 211 $newTitle = $this->notesService->getTitleFromContent($note->getContent()); 212 if ($oldTitle !== $newTitle) { 213 $note->setTitle($newTitle); 214 } 215 return $note->getTitle(); 216 }); 217 } 218 219 220 /** 221 * @NoAdminRequired 222 */ 223 public function update(int $id, string $content) : JSONResponse { 224 return $this->helper->handleErrorResponse(function () use ($id, $content) { 225 $note = $this->helper->getNoteWithETagCheck($id, $this->request); 226 $note->setContent($content); 227 return $this->helper->getNoteData($note); 228 }); 229 } 230 231 232 /** 233 * @NoAdminRequired 234 */ 235 public function updateProperty( 236 int $id, 237 string $property, 238 ?int $modified = null, 239 ?string $title = null, 240 ?string $category = null, 241 ?bool $favorite = null 242 ) : JSONResponse { 243 return $this->helper->handleErrorResponse(function () use ( 244 $id, 245 $property, 246 $modified, 247 $title, 248 $category, 249 $favorite 250 ) { 251 $note = $this->notesService->get($this->helper->getUID(), $id); 252 $result = null; 253 switch ($property) { 254 case 'modified': 255 if ($modified !== null) { 256 $note->setModified($modified); 257 } 258 $result = $note->getModified(); 259 break; 260 261 case 'title': 262 if ($title !== null) { 263 $note->setTitle($title); 264 } 265 $result = $note->getTitle(); 266 break; 267 268 case 'category': 269 if ($category !== null) { 270 $note->setCategory($category); 271 } 272 $result = $note->getCategory(); 273 break; 274 275 case 'favorite': 276 if ($favorite !== null) { 277 $note->setFavorite($favorite); 278 } 279 $result = $note->getFavorite(); 280 break; 281 282 default: 283 return new JSONResponse([], Http::STATUS_BAD_REQUEST); 284 } 285 return $result; 286 }); 287 } 288 289 290 /** 291 * @NoAdminRequired 292 */ 293 public function destroy(int $id) : JSONResponse { 294 return $this->helper->handleErrorResponse(function () use ($id) { 295 $this->notesService->delete($this->helper->getUID(), $id); 296 return []; 297 }); 298 } 299} 300