3 * FusionForge navigation
5 * Copyright 2009 - 2010, Olaf Lenz
6 * Copyright 2011-2012,2016,2020-2021, Franck Villaume - TrivialDev
7 * Copyright 2014, Stéphane-Eymeric Bredthauer
9 * This file is part of FusionForge. FusionForge is free software;
10 * you can redistribute it and/or modify it under the terms of the
11 * GNU General Public License as published by the Free Software
12 * Foundation; either version 2 of the Licence, or (at your option)
15 * FusionForge is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License along
21 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 require_once $gfwww.'search/include/SearchManager.class.php';
28 * This class provides all the navigational elements to be used by the themes,
29 * like the site menu, the project menus, and the user links.
30 * Some of the methods return HTML code, some return abstract data
31 * structures, and some methods give you the choice. The HTML code
32 * always tries to be as generic as possible so that it can easily be
35 class Navigation extends FFError {
37 * Associative array of data for the project menus.
39 * @var array $project_menu_data.
41 var $project_menu_data;
44 * getTitle - Get the HTML code of the title of the page.
45 * If the array $params contains a value for the key 'title',
46 * this title is appended to the title generated here.
47 * If $asHTML is set to false, it will return only the title
50 * @param array $params
51 * @param bool $asHTML html or not
52 * @return string text or html code
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') . _(': ') . strip_tags($params['title']);
63 // return HTML code otherwise
64 return html_e('title', array(), $this->getTitle($params, false), true);
69 * Get the HTML code for the favicon links of the site (to be
70 * put into the <head>. If $asHTML is false, it will return
71 * the URL of the favicon.
73 * @todo: Make favicon configurable
78 function getFavIcon($asHTML = true) {
80 return util_make_uri('/images/icon.png');
82 return html_e('link', array('rel' => 'icon', 'type' => 'image/png', 'href' => $this->getFavIcon(false))).
83 html_e('link', array('rel' => 'shortcut icon', 'type' => 'image/png', 'href' => $this->getFavIcon(false)));
88 * Get the HTML code for the RSS feeds of the site (to be put
89 * into the <head>. If $asHTML is false, it will return an
90 * array with the following structure: $result['titles']:
91 * list of titles of the feeds; $result['urls'] list of urls
96 function getRSS($asHTML = true) {
99 $res['titles'] = array();
100 $res['urls'] = array();
102 $res['titles'][] = forge_get_config ('forge_name').' - Project News Highlights RSS';
103 $res['urls'][] = util_make_uri('/export/rss20_news.php');
105 $res['titles'][] = forge_get_config ('forge_name').' - New Projects RSS';
106 $res['urls'][] = util_make_uri('/export/rss20_projects.php');
108 if (isset($GLOBALS['group_id']) && $GLOBALS['group_id'] > 0) {
109 $res['titles'][] = forge_get_config ('forge_name') . ' - New Activity RSS';
110 $res['urls'][] = util_make_uri('/export/rss20_activity.php?group_id='.$GLOBALS['group_id']);
114 $feeds = $this->getRSS(false);
115 for ($j = 0; $j < count($feeds['urls']); $j++) {
116 echo html_e('link', array('rel' => 'alternate', 'title' => util_html_secure($feeds['titles'][$j]),
117 'href' => $feeds['urls'][$j], 'type' => 'application/rss+xml'));
123 * Get the searchBox HTML code.
125 function getSearchBox() {
126 global $words, $forum_id, $group_id, $group_project_id, $atid, $exact, $type_of_search, $HTML;
130 // if there is no search currently, set the default
131 if (!isset($type_of_search) ) {
135 $res .= html_ao('div', array('role' => 'search'));
136 $res .= $HTML->openForm(array('id' => 'searchBox', 'action' => '/search/', 'method' => 'get'));
137 $res .= html_ao('div', array());
139 SEARCH__PARAMETER_GROUP_ID => $group_id,
140 SEARCH__PARAMETER_ARTIFACT_ID => $atid,
141 SEARCH__PARAMETER_FORUM_ID => $forum_id,
142 SEARCH__PARAMETER_GROUP_PROJECT_ID => $group_project_id
145 $searchManager =& getSearchManager();
146 $searchManager->setParametersValues($parameters);
147 $searchEngines =& $searchManager->getAvailableSearchEngines();
149 $res .= html_ao('select', array('name' => 'type_of_search'));
150 for($i = 0, $max = count($searchEngines); $i < $max; $i++) {
151 $searchEngine =& $searchEngines[$i];
152 $attrs = array('value' => $searchEngine->getType());
153 if ( $type_of_search == $searchEngine->getType()) {
154 $attrs['selected'] = 'selected';
156 $res .= html_e('option', $attrs, $searchEngine->getLabel($parameters), false);
158 $res .= html_ac(html_ap() - 1);
160 $parameters = $searchManager->getParameters();
161 foreach($parameters AS $name => $value) {
162 $res .= html_e('input', array('type' => 'hidden', 'value' => $value, 'name' => $name));
164 $res .= html_e('input', array('type' => 'text', 'size' => 12, 'id' => 'searchBox-words', 'name' => 'words', 'value' => $words, 'required' => 'required'));
165 $res .= html_e('input', array('type' => 'submit', 'name' => 'Search', 'value' => _('Search')));
167 if (isset($group_id) && $group_id) {
168 $res .= util_make_link('/search/advanced_search.php?group_id='.$group_id, _('Advanced search'));
170 $res .= html_ac(html_ap() - 1);
171 $res .= $HTML->closeForm();
172 $res .= html_ac(html_ap() - 1);
178 * Get an array of the user links (Login/Logout/My Account/Register) with the following structure:
179 * $result['titles']: list of the titles. $result['urls']: list of the urls.
181 function getUserLinks() {
183 if (session_loggedin()) {
184 $u = user_get_object(user_getid());
185 $res['titles'][] = sprintf("%s (%s)", _('Log Out'), $u->getRealName());
186 $res['urls'][] = util_make_uri('/account/logout.php');
188 $res['titles'][] = _('My Account');
189 $res['urls'][] = util_make_uri('/account/');
191 $url = '/account/login.php';
192 if(getStringFromServer('REQUEST_METHOD') != 'POST') {
193 $url .= '?return_to=';
194 $url .= urlencode(getStringFromServer('REQUEST_URI'));
196 $res['titles'][] = _('Log In');
197 $res['urls'][] = util_make_url($url);
199 if (!forge_get_config ('user_registration_restricted')) {
200 $res['titles'][] = _('New Account');
201 $res['urls'][] = util_make_url('/account/register.php');
208 * Get an array of the menu of the site with the following structure:
209 * $result['titles']: list of titles of the links.
210 * $result['urls']: list of urls.
211 * $result['tooltips']: list of tooltips (html title).
212 * $result['selected']: number of the selected menu entry.
214 function getSiteMenu() {
215 //WARNING: REQUEST_URI does not include prefix. DO NOT use util_make_uri in test to find the selected tab.
216 $request_uri = getStringFromServer('REQUEST_URI');
219 $menu['titles'] = array();
220 $menu['urls'] = array();
221 $menu['tooltips'] = array();
225 if (forge_get_config('use_home')) {
226 $menu['titles'][] = _('Home');
227 $menu['urls'][] = util_make_uri('/');
228 $menu['tooltips'][] = _('Main Page');
232 if (forge_get_config('use_my')) {
233 $menu['titles'][] = _('My Page');
234 $menu['urls'][] = util_make_uri('/my/');
235 $menu['tooltips'][] = _('Your Page, widgets selected by you to follow your items.');
236 if (strstr($request_uri, '/my/')
237 || strstr($request_uri, '/account/')
238 || strstr($request_uri, '/register/')
239 || strstr($request_uri, '/themes/')
240 || strstr($request_uri, '/forum/myforums.php')
241 || strstr($request_uri, '/widgets/widgets.php?owner=u')
244 $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, '/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, '/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, '/people/')) {
271 $selected=count($menu['urls'])-1;
276 $before = count($menu['urls']);
277 $hookParams = array();
278 $hookParams['DIRS'] = &$menu['urls'];
279 $hookParams['TITLES'] = &$menu['titles'];
280 $hookParams['TOOLTIPS'] = &$menu['tooltips'];
281 plugin_hook("outermenu", $hookParams);
283 // try to find selected entry
284 for ($j = $before; $j < count($menu['urls']); $j++) {
285 $url = $menu['urls'][$j];
286 if (strstr($request_uri, $url)) {
292 // Admin and Reporting
293 if (forge_check_global_perm('forge_admin')) {
294 $menu['titles'][] = _('Site Admin');
295 $menu['urls'][] = util_make_uri('/admin/');
296 $menu['tooltips'][] = _('Administration Submenu to handle global configuration, users & projects.');
297 if ((strpos($request_uri, '/admin/') === 0) || strstr($request_uri, 'type=globaladmin')) {
298 $selected = count($menu['urls'])-1;
301 if (forge_check_global_perm('forge_stats', 'read')) {
302 $menu['titles'][] = _('Reporting');
303 $menu['urls'][] = util_make_uri('/reporting/');
304 $menu['tooltips'][] = _('Statistics about visits, users & projects in time frame.');
305 if (strstr($request_uri, '/reporting/')) {
306 $selected = count($menu['urls'])-1;
311 if (isset($GLOBALS['group_id']) &&
312 !strstr($request_uri, '/search/?type_of_search=alldocs') &&
313 !strstr($request_uri, '/search/?type_of_search=skill') &&
314 !strstr($request_uri, '/search/?type_of_search=people') &&
315 !strstr($request_uri, '/search/?type_of_search=soft')) {
316 // get group info using the common result set
317 $project = group_get_object($GLOBALS['group_id']);
318 if (is_int($project) && $project == 0) {
319 if (preg_match('/root=/',$request_uri)) {
320 $project_name = preg_replace('/.*?root=/', '', $request_uri);
321 $project = group_get_object_by_name($project_name);
324 if ($project && is_object($project)) {
325 if (!$project->isError()) {
326 $menu['titles'][] = $project->getPublicName();
327 $menu['tooltips'][] = _('Project home page, widgets selected to follow specific items.');
328 $menu['urls'][] = util_make_uri('/projects/') .$project->getUnixName().'/';
329 $selected = count($menu['urls'])-1;
334 $menu['selected'] = $selected;
339 * Get a reference to an array of the projects menu for the project with the id $group_id with the following structure:
340 * $result['starturl']: URL of the projects starting page;
341 * $result['name']: public name of the project;
342 * $result['titles']: list of titles of the menu entries;
343 * $result['tooltips']: list of tooltips (html title) of the menu entries;
344 * $result['urls']: list of urls of the menu entries;
345 * $result['adminurls']: list of urls to the admin pages of the menu entries.
346 * If the user has no admin permissions, the corresponding adminurl is false.
347 * $result['selected']: number of the menu entry that is currently selected.
349 * @param string $toptab
352 function getProjectMenu($group_id, $toptab = "") {
353 // rebuild menu if it has never been built before, or
354 // if the toptab was set differently
355 if (!isset($this->project_menu_data[$group_id])
356 || ($toptab != "")) {
357 // get the group and permission objects
358 $group = group_get_object($group_id);
359 if (!$group || !is_object($group)) {
362 if ($group->isError()) {
363 //wasn't found or some other problem
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 $url = util_make_uri('/projects/' . $group->getUnixName() .'/');
381 $menu['urls'][] = $url;
382 $menu['adminurls'][] = false;
383 if ($toptab == "home") {
384 $selected = (count($menu['urls'])-1);
387 // setting these allows to change the initial project page
388 $menu['starturl'] = $url;
391 if (forge_check_perm ('project_admin', $group_id)) {
392 $menu['titles'][] = _('Admin');
393 $menu['tooltips'][] = _('Project Admin');
394 $menu['urls'][] = util_make_uri('/project/admin/?group_id=' . $group_id);
395 $menu['adminurls'][] = false;
396 if ($toptab == "admin") {
397 $selected = (count($menu['urls'])-1);
402 // check for use_home_tab?
403 $tabs_dirs[]='http://'. $this->getHomePage();
404 $tabs_titles[]=_('Home Page');
408 if ($group->usesActivity()) {
409 $menu['titles'][] = _('Activity');
410 $menu['tooltips'][] = _('Last activities per category.');
411 $menu['urls'][] = util_make_uri('/activity/?group_id=' . $group_id);
412 $menu['adminurls'][] = false;
413 if ($toptab == "activity") {
414 $selected = (count($menu['urls'])-1);
419 if ($group->usesForum()) {
420 $menu['titles'][] = _('Forums');
421 $menu['tooltips'][] = _('Tech & help forums.');
422 $menu['urls'][] = util_make_uri('/forum/?group_id=' . $group_id);
423 if (forge_check_perm ('forum_admin', $group_id)) {
424 $menu['adminurls'][] = util_make_uri('/forum/admin/?group_id='.$group_id);
426 $menu['adminurls'][] = false;
428 if ($toptab == "forums") {
429 $selected = (count($menu['urls'])-1);
434 if ($group->usesTracker()) {
435 $menu['titles'][] = _('Tracker');
436 $menu['tooltips'][] = _('Issues, tickets, bugs.');
437 $menu['urls'][] = util_make_uri('/tracker/?group_id=' . $group_id);
438 if (forge_check_perm ('tracker_admin', $group_id)) {
439 $menu['adminurls'][] = util_make_uri('/tracker/admin/?group_id='.$group_id);
441 $menu['adminurls'][] = false;
443 if ($toptab == "tracker" ||
445 $toptab == "support" ||
446 $toptab == "patch") {
447 $selected = (count($menu['urls'])-1);
452 if ($group->usesMail()) {
453 $menu['titles'][] = _('Lists');
454 $menu['tooltips'][] = _('Mailing Lists');
455 $menu['urls'][] = util_make_uri('/mail/?group_id=' . $group_id);
456 if (forge_check_perm ('project_admin', $group_id)) {
457 $menu['adminurls'][] = util_make_uri('/mail/admin/?group_id='.$group_id);
459 $menu['adminurls'][] = false;
461 if ($toptab == "mail") {
462 $selected = (count($menu['urls'])-1);
466 // Project/Task Manager
467 if ($group->usesPM()) {
468 $menu['titles'][] = _('Tasks');
469 $menu['tooltips'][] = _('Project Management');
470 $menu['urls'][] = util_make_uri('/pm/?group_id=' . $group_id);
471 if (forge_check_perm ('pm_admin', $group_id)) {
472 $menu['adminurls'][] = util_make_uri('/pm/admin/?group_id='.$group_id);
474 $menu['adminurls'][] = false;
476 if ($toptab == "pm") {
477 $selected = (count($menu['urls'])-1);
482 if ($group->usesDocman()) {
483 $menu['titles'][] = _('Docs');
484 $menu['tooltips'][] = _('Document Management.');
485 $menu['urls'][] = util_make_uri('/docman/?group_id=' . $group_id);
486 if (forge_check_perm ('docman', $group_id, 'admin')) {
487 $menu['adminurls'][] = util_make_uri('/docman/?group_id='.$group_id.'&view=admin');
489 $menu['adminurls'][] = false;
491 if ($toptab == "docman") {
492 $selected = (count($menu['urls'])-1);
497 if ($group->usesSurvey()) {
498 $menu['titles'][] = _('Surveys');
499 $menu['tooltips'][] = _('Online surveys, project needs your point of view.');
500 $menu['urls'][] = util_make_uri('/survey/?group_id=' . $group_id);
501 if (forge_check_perm ('project_admin', $group_id)) {
502 $menu['adminurls'][] = util_make_uri('/survey/admin/?group_id='.$group_id);
504 $menu['adminurls'][] = false;
506 if ($toptab == "surveys") {
507 $selected = (count($menu['urls'])-1);
512 if ($group->usesNews()) {
513 $menu['titles'][] = _('News');
514 $menu['tooltips'][] = _('Flash head line from the project.');
515 $menu['urls'][] = util_make_uri('/news/?group_id=' . $group_id);
516 if (forge_check_perm ('project_admin', $group_id)) {
517 $menu['adminurls'][] = util_make_uri('/news/admin/?group_id='.$group_id);
519 $menu['adminurls'][] = false;
521 if ($toptab == "news") {
522 $selected = (count($menu['urls'])-1);
527 if ($group->usesSCM()) {
528 $menu['titles'][] = _('SCM');
529 $menu['tooltips'][] = _('Source Content Management, peer-review and source discovery.');
530 $menu['urls'][] = util_make_uri('/scm/?group_id=' . $group_id);
532 if (forge_check_perm ('project_admin', $group_id)) {
533 $menu['adminurls'][] = util_make_uri('/scm/admin/?group_id='.$group_id);
535 $menu['adminurls'][] = false;
537 if ($toptab == "scm") {
538 $selected = (count($menu['urls'])-1);
542 // groupmenu_after_scm hook
543 $hookParams = array();
544 $hookParams['group_id'] = $group_id ;
545 $hookParams['DIRS'] =& $menu['urls'];
546 $hookParams['ADMIN'] =& $menu['adminurls'];
547 $hookParams['TITLES'] =& $menu['titles'];
548 $hookParams['TOOLTIPS'] =& $menu['tooltips'];
549 $hookParams['toptab'] =& $toptab;
550 $hookParams['selected'] =& $selected;
551 plugin_hook ("groupmenu_scm", $hookParams);
554 for ($i = 0; $i < count($menu['urls']) - count($menu['adminurls']); $i++) {
555 $menu['adminurls'][] = false;
559 if ($group->usesFRS()) {
560 $menu['titles'][] = _('Files');
561 $menu['tooltips'][] = _('All published files organized per version.');
562 $menu['urls'][] = util_make_uri('/frs/?group_id=' . $group_id);
563 if (forge_check_perm ('frs_admin', $group_id, 'admin')) {
564 $menu['adminurls'][] = util_make_uri('/frs/?view=admin&group_id='.$group_id);
566 $menu['adminurls'][] = false;
568 if ($toptab == "frs") {
569 $selected = (count($menu['urls'])-1);
574 $hookParams = array();
575 $hookParams['group'] = $group_id;
576 $hookParams['DIRS'] =& $menu['urls'];
577 $hookParams['ADMIN'] =& $menu['adminurls'];
578 $hookParams['TITLES'] =& $menu['titles'];
579 $hookParams['TOOLTIPS'] =& $menu['tooltips'];
580 $hookParams['toptab'] =& $toptab;
581 $hookParams['selected'] =& $selected;
582 plugin_hook("groupmenu", $hookParams);
585 for ($i = 0; $i < count($menu['urls']) - count($menu['adminurls']); $i++) {
586 $menu['adminurls'][] = false;
589 // store selected menu item (if any)
590 $menu['selected'] = $selected;
592 return $this->project_menu_data[$group_id];
596 * Create the HTML code for the banner "Powered By
597 * FusionForge". If $asHTML is set to false, it will return an
598 * array with the following structure: $result['url']: URL for
599 * the link on the banner; $result['image']: URL of the banner
600 * image; $result['title']: HTML code that outputs the banner;
601 * $result['html']: HTML code that creates the banner and the link.
602 * @param bool $asHTML
605 function getPoweredBy($asHTML=true) {
606 $res['url'] = 'http://fusionforge.org/';
607 $res['image'] = util_make_uri('/images/pow-fusionforge.png');
608 $res['title'] = html_abs_image($res['image'], null, null, array("alt" => "Powered By FusionForge"));
609 $res['html'] = util_make_link($res['url'], $res['title'], array(), true);
617 /** Create the HTML code for the "Show Source" link if
618 * forge_get_config('show_source') is set, otherwise "". If $asHTML is set
619 * to false, it returns NULL when forge_get_config('show_source') is not
620 * set, otherwise an array with the following structure:
621 * $result['url']: URL of the link to the source code viewer;
622 * $result['title']: Title of the link.
623 * @param bool $asHTML
624 * @return null|string
626 function getShowSource($asHTML=true) {
627 if (forge_get_config('show_source')) {
628 $res['url'] = util_make_uri('/source.php?file='.getStringFromServer('SCRIPT_NAME'));
629 $res['title'] = _('Show source');
631 return ($asHTML ? "" : NULL);
636 return util_make_link($res['url'], $res['title'],
637 array('class' => 'showsource'),
645 // c-file-style: "bsd"