fc97b049a7b2bd687849ba92015b6c87604fcc47
[grauphel.git] / controller / guicontroller.php
1 <?php
2 /**
3  * Part of grauphel
4  *
5  * PHP version 5
6  *
7  * @category  Tools
8  * @package   Grauphel
9  * @author    Christian Weiske <cweiske@cweiske.de>
10  * @copyright 2014 Christian Weiske
11  * @license   http://www.gnu.org/licenses/agpl.html GNU AGPL v3
12  * @link      http://cweiske.de/grauphel.htm
13  */
14 namespace OCA\Grauphel\Controller;
15
16 use \OCP\AppFramework\Controller;
17 use \OCP\AppFramework\Http\TemplateResponse;
18 use \OCA\Grauphel\Lib\Client;
19 use \OCA\Grauphel\Lib\TokenStorage;
20 use \OCA\Grauphel\Lib\Response\ErrorResponse;
21
22 /**
23  * Owncloud frontend
24  *
25  * @category  Tools
26  * @package   Grauphel
27  * @author    Christian Weiske <cweiske@cweiske.de>
28  * @copyright 2014 Christian Weiske
29  * @license   http://www.gnu.org/licenses/agpl.html GNU AGPL v3
30  * @version   Release: @package_version@
31  * @link      http://cweiske.de/grauphel.htm
32  */
33 class GuiController extends Controller
34 {
35     /**
36      * constructor of the controller
37      *
38      * @param string   $appName Name of the app
39      * @param IRequest $request Instance of the request
40      */
41     public function __construct($appName, \OCP\IRequest $request, $user, $urlGen)
42     {
43         parent::__construct($appName, $request);
44         $this->user   = $user;
45         $this->urlGen = $urlGen;
46
47         //default http header: we assume something is broken
48         header('HTTP/1.0 500 Internal Server Error');
49     }
50
51     /**
52      * Main page /
53      *
54      * Tomdroid wants this to be a public page. Sync fails otherwise.
55      *
56      * @NoAdminRequired
57      * @NoCSRFRequired
58      * @PublicPage
59      */
60     public function index()
61     {
62         $this->checkDeps();
63
64         $res = new TemplateResponse('grauphel', 'index');
65         $res->setParams(
66             array(
67                 'apiroot' => $this->getApiRootUrl(),
68                 'apiurl'  => $this->urlGen->linkToRoute('grauphel.api.index')
69             )
70         );
71         $this->addNavigation($res);
72         $this->addStats($res);
73         return $res;
74     }
75
76     /**
77      * Show contents of a note
78      *
79      * @NoAdminRequired
80      * @NoCSRFRequired
81      */
82     public function note($guid)
83     {
84         $res = new TemplateResponse('grauphel', 'gui-note');
85
86         $note = $this->getNotes()->load($guid, false);
87         if ($note === null) {
88             return new ErrorResponse('Note does not exist');
89         }
90
91         $converter = new \OCA\Grauphel\Lib\Converter\Html();
92         $converter->internalLinkHandler = array($this, 'noteLinkHandler');
93         $res->setParams(
94             array(
95                 'note' => $note,
96                 'note-content' => $converter->convert(
97                     $note->{'note-content'}
98                 ),
99                 'links' => array(
100                     'json' => $this->urlGen->linkToRoute(
101                         'grauphel.api.note', array(
102                             'guid' => $guid, 'username' => $this->user->getUid()
103                         )
104                     ),
105                     'xml' => $this->urlGen->linkToRoute(
106                         'grauphel.notes.xml', array('guid' => $guid)
107                     ),
108                 )
109             )
110         );
111
112         $selectedRawtag = null;
113         if (count($note->tags) > 0) {
114             $selectedRawtag = $note->tags[0];
115         }
116
117         $this->addNavigation($res, $selectedRawtag);
118         return $res;
119     }
120
121     public function noteLinkHandler($noteTitle)
122     {
123         $guid = $this->getNotes()->loadGuidByTitle($noteTitle);
124         if ($guid === null) {
125             return '#';
126         }
127         return $this->urlGen->linkToRoute(
128             'grauphel.gui.note', array('guid' => $guid)
129         );
130     }
131
132     /**
133      * Show all notes of a tag
134      *
135      * @NoAdminRequired
136      * @NoCSRFRequired
137      */
138     public function tag($rawtag)
139     {
140         $notes = $this->getNotes()->loadNotesOverview(null, $rawtag);
141         usort(
142             $notes,
143             function($noteA, $noteB) {
144                 return strcmp($noteA['title'], $noteB['title']);
145             }
146         );
147
148         $res = new TemplateResponse('grauphel', 'tag');
149         $res->setParams(
150             array(
151                 'tag'    => $this->getPrettyTagName($rawtag),
152                 'rawtag' => $rawtag,
153                 'notes'  => $notes,
154             )
155         );
156         $this->addNavigation($res, $rawtag);
157
158         return $res;
159     }
160
161     /**
162      * Show access tokens
163      *
164      * @NoAdminRequired
165      * @NoCSRFRequired
166      */
167     public function tokens()
168     {
169         $tokens = new TokenStorage();
170         $res = new TemplateResponse('grauphel', 'tokens');
171         $res->setParams(
172             array(
173                 'tokens' => $tokens->loadForUser(
174                     $this->user->getUid(), 'access'
175                 ),
176                 'client' => new Client(),
177                 'username' => $this->user->getUid(),
178             )
179         );
180         $this->addNavigation($res, null);
181
182         return $res;
183     }
184
185     /**
186      * Allow the user to clear his database
187      *
188      * @NoAdminRequired
189      * @NoCSRFRequired
190      */
191     public function database($reset = null)
192     {
193         $res = new TemplateResponse('grauphel', 'gui-database');
194         $res->setParams(array('reset' => $reset));
195         $this->addNavigation($res, null);
196         $this->addStats($res);
197
198         return $res;
199     }
200
201     /**
202      * Resets the database by deleting all notes and deleting the user's
203      * sync data.
204      *
205      * @NoAdminRequired
206      */
207     public function databaseReset()
208     {
209         $reset = false;
210         if ($_POST['username'] != '' && $_POST['username'] == $this->user->getUid()) {
211             $notes = $this->getNotes();
212             $notes->deleteAll();
213             $notes->deleteSyncData();
214             $reset = true;
215         }
216
217         return $this->database($reset);
218     }
219
220     protected function addNavigation(TemplateResponse $res, $selectedRawtag = null)
221     {
222         $nav = new \OCP\Template('grauphel', 'appnavigation', '');
223         $nav->assign('apiroot', $this->getApiRootUrl());
224         $nav->assign('tags', array());
225
226         $params = $res->getParams();
227         $params['appNavigation'] = $nav;
228         $res->setParams($params);
229
230         if ($this->user === null) {
231             return;
232         }
233
234         $rawtags = $this->getNotes()->getTags();
235         sort($rawtags);
236         array_unshift(
237             $rawtags,
238             'grauphel:special:all', 'grauphel:special:untagged'
239         );
240
241         $tags = array();
242         foreach ($rawtags as $rawtag) {
243             $name = $this->getPrettyTagName($rawtag);
244             if ($name !== false) {
245                 $tags[] = array(
246                     'name' => $name,
247                     'id'   => $rawtag,
248                     'href' => $this->urlGen->linkToRoute(
249                         'grauphel.gui.tag', array('rawtag' => $rawtag)
250                     ),
251                     'selected' => $rawtag == $selectedRawtag,
252                 );
253             }
254         }
255         $nav->assign('tags', $tags);
256     }
257
258     protected function addStats(TemplateResponse $res)
259     {
260         if ($this->user === null) {
261             return;
262         }
263
264         $username = $this->user->getUid();
265         $notes  = $this->getNotes();
266         $tokens = new \OCA\Grauphel\Lib\TokenStorage();
267
268         $nav = new \OCP\Template('grauphel', 'indexStats', '');
269         $nav->assign('notes', count($notes->loadNotesOverview()));
270         $nav->assign('syncrev', $notes->loadSyncData()->latestSyncRevision);
271         $nav->assign('tokens', count($tokens->loadForUser($username, 'access')));
272
273         $params = $res->getParams();
274         $params['stats'] = $nav;
275         $res->setParams($params);
276     }
277
278     protected function checkDeps()
279     {
280         if (!class_exists('OAuthProvider')) {
281             throw new \Exception('PHP extension "oauth" is required');
282         }
283     }
284
285     protected function getApiRootUrl()
286     {
287         //we need to remove the trailing / for tomdroid and conboy
288         return rtrim(
289             $this->urlGen->getAbsoluteURL(
290                 $this->urlGen->linkToRoute('grauphel.gui.index')
291             ),
292             '/'
293         );
294     }
295
296     protected function getNotes()
297     {
298         $username = $this->user->getUid();
299         $notes  = new \OCA\Grauphel\Lib\NoteStorage($this->urlGen);
300         $notes->setUsername($username);
301         return $notes;
302     }
303
304     protected function getPrettyTagName($rawtag)
305     {
306         if (substr($rawtag, 0, 16) == 'system:notebook:') {
307             return substr($rawtag, 16);
308         } else if (substr($rawtag, 0, 17) == 'grauphel:special:') {
309             return '*' . substr($rawtag, 17) . '*';
310         }
311         return false;
312     }
313 }
314 ?>