3 * FusionForge navigation
5 * Copyright 2009 - 2010, Olaf Lenz
6 * Copyright 2011, Franck Villaume - TrivialDev
8 * This file is part of FusionForge. FusionForge is free software;
9 * you can redistribute it and/or modify it under the terms of the
10 * GNU General Public License as published by the Free Software
11 * Foundation; either version 2 of the Licence, or (at your option)
14 * FusionForge is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 require_once $gfwww.'search/include/SearchManager.class.php';
27 * This class provides all the navigational elements to be used by the themes,
28 * like the site menu, the project menus, and the user links.
29 * Some of the methods return HTML code, some return abstract data
30 * structures, and some methods give you the choice. The HTML code
31 * always tries to be as generic as possible so that it can easily be
34 class Navigation extends Error {
36 * Associative array of data for the project menus.
38 * @var array $project_menu_data.
40 var $project_menu_data;
43 function Navigation() {
48 /** Get the HTML code of the title of the page. If the array
49 * $params contains a value for the key 'title', this title
50 * is appended to the title generated here. If $asHTML is
51 * set to false, it will return only the title in plain
54 function getTitle($params, $asHTML = true) {
57 if (!isset($params['title'])) {
58 return forge_get_config('forge_name');
60 return forge_get_config('forge_name') . ': ' . $params['title'];
63 // return HTML code otherwise
64 return '<title>' . $this->getTitle($params, false) . '</title>';
68 /** Get the HTML code for the favicon links of the site (to be
69 * put into the <head>. If $asHTML is false, it will return
70 * the URL of the favicon.
72 * @todo: Make favicon configurable
74 function getFavIcon($asHTML = true) {
76 return util_make_url('/images/icon.png');
78 return '<link rel="icon" type="image/png" href="'
79 . $this->getFavIcon(false) .'" />'
80 . '<link rel="shortcut icon" type="image/png" href="'
81 . $this->getFavIcon(false) .'" />';
85 /** Get the HTML code for the RSS feeds of the site (to be put
86 * into the <head>. If $asHTML is false, it will return an
87 * array with the following structure: $result['titles']:
88 * list of titles of the feeds; $result['urls'] list of urls
91 function getRSS($asHTML = true) {
94 $res['titles'] = array();
95 $res['urls'] = array();
97 $res['titles'][] = forge_get_config ('forge_name').' - Project News Highlights RSS';
98 $res['urls'][] = util_make_url('/export/rss_sfnews.php');
100 $res['titles'][] = forge_get_config ('forge_name').' - Project News Highlights RSS 2.0';
101 $res['urls'][] = util_make_url('/export/rss20_news.php');
103 $res['titles'][] = forge_get_config ('forge_name').' - New Projects RSS';
104 $res['urls'][] = util_make_url('/export/rss_sfprojects.php');
106 if (isset($GLOBALS['group_id'])) {
107 $res['titles'][] = forge_get_config ('forge_name') . ' - New Activity RSS';
108 $res['urls'][] = util_make_url('/export/rss20_activity.php?group_id='.$GLOBALS['group_id']);
112 $feeds = $this->getRSS(false);
113 for ($j = 0; $j < count($feeds['urls']); $j++) {
115 <link rel="alternate" title="' .
116 util_html_secure($feeds['titles'][$j]) .
117 '" href="' . $feeds['urls'][$j] .
118 '" type="application/rss+xml"/>';
124 * Get the searchBox HTML code.
126 function getSearchBox() {
127 global $words, $forum_id, $group_id, $group_project_id, $atid, $exact, $type_of_search;
130 if (get_magic_quotes_gpc()) {
131 $defaultWords = stripslashes($words);
133 $defaultWords = $words;
136 $defaultWords = htmlspecialchars($defaultWords);
138 // if there is no search currently, set the default
139 if (!isset($type_of_search) ) {
143 $res .= '<form id="searchBox" action="'.util_make_uri('/search/').'" method="get">
146 SEARCH__PARAMETER_GROUP_ID => $group_id,
147 SEARCH__PARAMETER_ARTIFACT_ID => $atid,
148 SEARCH__PARAMETER_FORUM_ID => $forum_id,
149 SEARCH__PARAMETER_GROUP_PROJECT_ID => $group_project_id
152 $searchManager =& getSearchManager();
153 $searchManager->setParametersValues($parameters);
154 $searchEngines =& $searchManager->getAvailableSearchEngines();
156 $res .= '<label for="searchBox-words">
157 <select name="type_of_search">';
158 for($i = 0, $max = count($searchEngines); $i < $max; $i++) {
159 $searchEngine =& $searchEngines[$i];
160 $res .= '<option value="' . $searchEngine->getType() . '"'
161 . ( $type_of_search == $searchEngine->getType() ? ' selected="selected"' : '' )
162 . '>' . $searchEngine->getLabel($parameters) . '</option>' . "\n";
164 $res .= '</select></label>';
166 $parameters = $searchManager->getParameters();
167 foreach($parameters AS $name => $value) {
168 $res .= '<input type="hidden" value="'.$value.'" name="'.$name.'" />' . "\n";
170 $res .= '<input type="text" size="12" id="searchBox-words" name="words" value="'
171 . $defaultWords . '" />' . "\n";
172 $res .= '<input type="submit" name="Search" value="'._('Search').'" />' . "\n";
174 if (isset($group_id) && $group_id) {
175 $res .= util_make_link('/search/advanced_search.php?group_id=' .
176 $group_id, _('Advanced search'));
185 * Get an array of the user links (Login/Logout/My Account/Register) with the following structure:
186 * $result['titles']: list of the titles. $result['urls']: list of the urls.
188 function getUserLinks() {
190 if (session_loggedin()) {
191 $u =& user_get_object(user_getid());
192 $res['titles'][] = sprintf("%s (%s)", _('Log Out'), $u->getRealName());
193 $res['urls'][] = util_make_uri('/account/logout.php');
195 $res['titles'][] = _('My Account');
196 $res['urls'][] = util_make_uri('/account/');
198 $url = '/account/login.php';
199 if(getStringFromServer('REQUEST_METHOD') != 'POST') {
200 $url .= '?return_to=';
201 $url .= urlencode(getStringFromServer('REQUEST_URI'));
203 $res['titles'][] = _('Log In');
204 $res['urls'][] = util_make_url($url);
206 if (!forge_get_config ('user_registration_restricted')) {
207 $res['titles'][] = _('New Account');
208 $res['urls'][] = util_make_url('/account/register.php');
215 * Get an array of the menu of the site with the following structure:
216 * $result['titles']: list of titles of the links.
217 * $result['urls']: list of urls.
218 * $result['tooltips']: list of tooltips (html title).
219 * $result['selected']: number of the selected menu entry.
221 function getSiteMenu() {
222 $request_uri = getStringFromServer('REQUEST_URI');
225 $menu['titles'] = array();
226 $menu['urls'] = array();
227 $menu['tooltips'] = array();
231 $menu['titles'][] = _('Home');
232 $menu['urls'][] = util_make_uri('/');
233 $menu['tooltips'][] = _('Main Page');
236 $menu['titles'][] = _('My Page');
237 $menu['urls'][] = util_make_uri('/my/');
238 $menu['tooltips'][] = _('Your Page, widgets selected by you to follow your items.');
239 if (strstr($request_uri, util_make_uri('/my/'))
240 || strstr($request_uri, util_make_uri('/account/'))
241 || strstr($request_uri, util_make_uri('/register/'))
242 || strstr($request_uri, util_make_uri('/themes/'))
245 $selected = count($menu['urls'])-1;
248 if (forge_get_config('use_trove') || forge_get_config('use_project_tags') || forge_get_config('use_project_full_list')) {
249 $menu['titles'][] = _('Projects');
250 $menu['urls'][] = util_make_uri('/softwaremap/');
251 $menu['tooltips'][] = _('Map of projects, by categories or types.');
252 if (strstr($request_uri, util_make_uri('/softwaremap/'))) {
253 $selected = count($menu['urls'])-1;
257 if (forge_get_config('use_snippet')) {
258 $menu['titles'][] = _('Code Snippets');
259 $menu['urls'][] = util_make_uri('/snippet/');
260 $menu['tooltips'][] = _('Tooling library. Small coding tips.');
261 if (strstr($request_uri, util_make_uri('/snippet/'))) {
262 $selected = count($menu['urls'])-1;
266 if (forge_get_config('use_people')) {
267 $menu['titles'][] = _('Project Openings');
268 $menu['urls'][] = util_make_uri('/people/');
269 $menu['tooltips'][] = _('Hiring Market Place.');
270 if (strstr($request_uri, util_make_uri('/people/'))) {
271 $selected=count($menu['urls'])-1;
276 $before = count($menu['urls']);
277 $plugin_urls = array();
278 $hookParams['DIRS'] = &$menu['urls'];
279 $hookParams['ADMIN'] =& $menu['adminurls'];
280 $hookParams['TITLES'] = &$menu['titles'];
281 $hookParams['TOOLTIPS'] = &$menu['tooltips'];
282 plugin_hook("outermenu", $hookParams);
284 // try to find selected entry
285 for ($j = $before; $j < count($plugin_urls); $j++) {
286 $url = $menu['urls'][$j];
287 if (strstr($request_uri, parse_url ($url, PHP_URL_PATH))) {
293 // Admin and Reporting
294 if (forge_check_global_perm('forge_admin')) {
295 $user_is_super = true;
296 $menu['titles'][] = _('Site Admin');
297 $menu['urls'][] = util_make_url('/admin/');
298 $menu['tooltips'][] = _('Administration Submenu to handle global configuration, users & projects.');
299 if (strstr($request_uri, util_make_uri('/admin/'))) {
300 $selected = count($menu['urls'])-1;
303 if (forge_check_global_perm ('forge_stats', 'read')) {
304 $menu['titles'][] = _('Reporting');
305 $menu['urls'][] = util_make_uri('/reporting/');
306 $menu['tooltips'][] = _('Statistics about visits, users & projects in time frame.');
307 if (strstr($request_uri, util_make_uri('/reporting/'))) {
308 $selected = count($menu['urls'])-1;
313 if (isset($GLOBALS['group_id'])) {
314 // get group info using the common result set
315 $project =& group_get_object($GLOBALS['group_id']);
316 if ($project && is_object($project)) {
317 if ($project->isError()) {
318 } elseif (!$project->isProject()) {
320 $menu['titles'][] = $project->getPublicName();
321 $menu['tooltips'][] = _('Project home page, widgets selected to follow specific items.');
322 if (isset ($GLOBALS['sys_noforcetype']) && $GLOBALS['sys_noforcetype']) {
323 $menu['urls'][]=util_make_uri('/project/?group_id') .$project->getId();
325 $menu['urls'][]=util_make_uri('/projects/') .$project->getUnixName().'/';
327 $selected=count($menu['urls'])-1;
332 $menu['selected'] = $selected;
338 * Get a reference to an array of the projects menu for the project with the id $group_id with the following structure:
339 * $result['starturl']: URL of the projects starting page;
340 * $result['name']: public name of the project;
341 * $result['titles']: list of titles of the menu entries;
342 * $result['tooltips']: list of tooltips (html title) of the menu entries;
343 * $result['urls']: list of urls of the menu entries;
344 * $result['adminurls']: list of urls to the admin pages of the menu entries.
345 * If the user has no admin permissions, the correpsonding adminurl is false.
346 * $result['selected']: number of the menu entry that is currently selected.
348 function getProjectMenu($group_id, $toptab = "") {
349 // rebuild menu if it has never been built before, or
350 // if the toptab was set differently
351 if (!isset($this->project_menu_data[$group_id])
353 || ($toptab != $this->project_menu_data[$group_id]['last_toptab'])) {
354 // get the group and permission objects
355 $group = group_get_object($group_id);
356 if (!$group || !is_object($group)) {
359 if ($group->isError()) {
360 //wasn't found or some other problem
363 if (!$group->isProject()) {
369 $menu =& $this->project_menu_data[$group_id];
370 $menu['titles'] = array();
371 $menu['tooltips'] = array();
372 $menu['urls'] = array();
373 $menu['adminurls'] = array();
375 $menu['name'] = $group->getPublicName();
378 $menu['titles'][] = _('Summary');
379 $menu['tooltips'][] = _('Project Homepage. Widgets oriented');
380 if (isset($GLOBALS['sys_noforcetype']) && $GLOBALS['sys_noforcetype']) {
381 $url = util_make_uri('/project/?group_id=' . $group_id);
383 $url = util_make_uri('/projects/' . $group->getUnixName() .'/');
385 $menu['urls'][] = $url;
386 $menu['adminurls'][] = false;
387 if ($toptab == "home") {
388 $selected = (count($menu['urls'])-1);
391 // setting these allows to change the initial project page
392 $menu['starturl'] = $url;
395 if (forge_check_perm ('project_admin', $group_id)) {
396 $menu['titles'][] = _('Admin');
397 $menu['tooltips'][] = _('Project Administration.');
398 $menu['urls'][] = util_make_uri('/project/admin/?group_id=' . $group_id);
399 $menu['adminurls'][] = false;
400 if ($toptab == "admin") {
401 $selected = (count($menu['urls'])-1);
406 // check for use_home_tab?
407 $TABS_DIRS[]='http://'. $this->getHomePage();
408 $TABS_TITLES[]=_('Home Page');
411 // Project Activity tab
412 $menu['titles'][] = _('Activity');
413 $menu['tooltips'][] = _('Last activities per category.');
414 $menu['urls'][] = util_make_uri('/activity/?group_id=' . $group_id);
415 $menu['adminurls'][] = false;
416 if ($toptab == "activity") {
417 $selected = (count($menu['urls'])-1);
421 if ($group->usesForum()) {
422 $menu['titles'][] = _('Forums');
423 $menu['tooltips'][] = _('Tech & help forums.');
424 $menu['urls'][] = util_make_uri('/forum/?group_id=' . $group_id);
425 if (forge_check_perm ('forum_admin', $group_id)) {
426 $menu['adminurls'][] = util_make_url('/forum/admin/?group_id='.$group_id);
428 $menu['adminurls'][] = false;
430 if ($toptab == "forums") {
431 $selected = (count($menu['urls'])-1);
436 if ($group->usesTracker()) {
437 $menu['titles'][] = _('Tracker');
438 $menu['tooltips'][] = _('Issues, tickets, bugs.');
439 $menu['urls'][] = util_make_uri('/tracker/?group_id=' . $group_id);
440 if (forge_check_perm ('tracker_admin', $group_id)) {
441 $menu['adminurls'][] = util_make_url('/tracker/admin/?group_id='.$group_id);
443 $menu['adminurls'][] = false;
445 if ($toptab == "tracker" ||
447 $toptab == "support" ||
448 $toptab == "patch") {
449 $selected = (count($menu['urls'])-1);
454 if ($group->usesMail()) {
455 $menu['titles'][] = _('Lists');
456 $menu['tooltips'][] = _('Mailing Lists.');
457 $menu['urls'][] = util_make_uri('/mail/?group_id=' . $group_id);
458 if (forge_check_perm ('project_admin', $group_id)) {
459 $menu['adminurls'][] = util_make_url('/mail/admin/?group_id='.$group_id);
461 $menu['adminurls'][] = false;
463 if ($toptab == "mail") {
464 $selected = (count($menu['urls'])-1);
468 // Project/Task Manager
469 if ($group->usesPm()) {
470 $menu['titles'][] = _('Tasks');
471 $menu['tooltips'][] = _('Project Management.');
472 $menu['urls'][] = util_make_uri('/pm/?group_id=' . $group_id);
473 if (forge_check_perm ('pm_admin', $group_id)) {
474 $menu['adminurls'][] = util_make_uri('/pm/admin/?group_id='.$group_id);
476 $menu['adminurls'][] = false;
478 if ($toptab == "pm") {
479 $selected = (count($menu['urls'])-1);
484 if ($group->usesDocman()) {
485 $menu['titles'][] = _('Docs');
486 $menu['tooltips'][] = _('Document Management.');
487 $menu['urls'][] = util_make_uri('/docman/?group_id=' . $group_id);
488 if (forge_check_perm ('docman', $group_id, 'approve')) {
489 $menu['adminurls'][] = util_make_uri('/docman/?group_id='.$group_id.'&view=admin');
491 $menu['adminurls'][] = false;
493 if ($toptab == "docman") {
494 $selected = (count($menu['urls'])-1);
499 if ($group->usesSurvey()) {
500 $menu['titles'][] = _('Surveys');
501 $menu['tooltips'][] = _('Online surveys, project needs your point of view.');
502 $menu['urls'][] = util_make_uri('/survey/?group_id=' . $group_id);
503 if (forge_check_perm ('project_admin', $group_id)) {
504 $menu['adminurls'][] = util_make_uri('/survey/admin/?group_id='.$group_id);
506 $menu['adminurls'][] = false;
508 if ($toptab == "surveys") {
509 $selected = (count($menu['urls'])-1);
514 if ($group->usesNews()) {
515 $menu['titles'][] = _('News');
516 $menu['tooltips'][] = _('Flash head line from the project.');
517 $menu['urls'][] = util_make_uri('/news/?group_id=' . $group_id);
518 if (forge_check_perm ('project_admin', $group_id)) {
519 $menu['adminurls'][] = util_make_uri('/news/admin/?group_id='.$group_id);
521 $menu['adminurls'][] = false;
523 if ($toptab == "news") {
524 $selected = (count($menu['urls'])-1);
529 if ($group->usesSCM()) {
530 $menu['titles'][] = _('SCM');
531 $menu['tooltips'][] = _('Source Content Management, peer-review and source discovery.');
532 $menu['urls'][] = util_make_uri('/scm/?group_id=' . $group_id);
534 if (forge_check_perm ('project_admin', $group_id)) {
535 $menu['adminurls'][] = util_make_uri('/scm/admin/?group_id='.$group_id);
537 $menu['adminurls'][] = false;
539 if ($toptab == "scm") {
540 $selected = (count($menu['urls'])-1);
544 // groupmenu_after_scm hook
545 $hookParams = array();
546 $hookParams['group_id'] = $group_id ;
547 $hookParams['DIRS'] =& $menu['urls'];
548 $hookParams['ADMIN'] =& $menu['adminurls'];
549 $hookParams['TITLES'] =& $menu['titles'];
550 $hookParams['TOOLTIPS'] =& $menu['tooltips'];
551 $hookParams['toptab'] =& $toptab;
552 $hookParams['selected'] =& $selected;
553 plugin_hook ("groupmenu_scm", $hookParams);
556 for ($i = 0; $i < count($menu['urls']) - count($menu['adminurls']); $i++) {
557 $menu['adminurls'][] = false;
561 if ($group->usesFRS()) {
562 $menu['titles'][] = _('Files');
563 $menu['tooltips'][] = _('All published files organized per version.');
564 $menu['urls'][] = util_make_uri('/frs/?group_id=' . $group_id);
565 if (forge_check_perm ('frs', $group_id, 'write')) {
566 $menu['adminurls'][] = util_make_uri('/frs/admin/?group_id='.$group_id);
568 $menu['adminurls'][] = false;
570 if ($toptab == "frs") {
571 $selected = (count($menu['urls'])-1);
576 $hookParams = array();
577 $hookParams['group'] = $group_id;
578 $hookParams['DIRS'] =& $menu['urls'];
579 $hookParams['ADMIN'] =& $menu['adminurls'];
580 $hookParams['TITLES'] =& $menu['titles'];
581 $hookParams['TOOLTIPS'] =& $menu['tooltips'];
582 $hookParams['toptab'] =& $toptab;
583 $hookParams['selected'] =& $selected;
584 plugin_hook("groupmenu", $hookParams);
587 for ($i = 0; $i < count($menu['urls']) - count($menu['adminurls']); $i++) {
588 $menu['adminurls'][] = false;
591 // store selected menu item (if any)
592 $menu['selected'] = $selected;
594 $menu['last_toptab'] = $toptab;
597 return $this->project_menu_data[$group_id];
601 * Create the HTML code for the banner "Powered By
602 * FusionForge". If $asHTML is set to false, it will return an
603 * array with the following structure: $result['url']: URL for
604 * the link on the banner; $result['image']: URL of the banner
605 * image; $result['title']: HTML code that outputs the banner;
606 * $result['html']: HTML code that creates the banner and the link.
608 function getPoweredBy($asHTML=true) {
609 $res['url'] = 'http://fusionforge.org/';
610 $res['image'] = util_make_uri('/images/pow-fusionforge.png');
611 $res['title'] = '<img src="'
613 . '" alt="Powered By FusionForge" border="0" />';
614 $res['html'] = util_make_link($res['url'], $res['title'], array(), true);
622 /** Create the HTML code for the "Show Source" link if
623 * forge_get_config('show_source') is set, otherwise "". If $asHTML is set
624 * to false, it returns NULL when forge_get_config('show_source') is not
625 * set, otherwise an array with the following structure:
626 * $result['url']: URL of the link to the source code viewer;
627 * $result['title']: Title of the link.
629 function getShowSource($asHTML=true) {
630 if (forge_get_config('show_source')) {
631 $res['url'] = util_make_url('/source.php?file='.getStringFromServer('SCRIPT_NAME'));
632 $res['title'] = _('Show source');
634 return ($asHTML ? "" : NULL);
639 return util_make_link($res['url'], $res['title'],
640 array('class' => 'showsource'),
648 // c-file-style: "bsd"