3 * FusionForge navigation
5 * Copyright 2009 - 2010, Olaf Lenz
6 * Copyright 2011-2012,2016, 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;
43 function __construct() {
44 parent::__construct();
48 * getTitle - Get the HTML code of the title of the page.
49 * If the array $params contains a value for the key 'title',
50 * this title is appended to the title generated here.
51 * If $asHTML is set to false, it will return only the title
54 * @param array $params
55 * @param bool $asHTML html or not
56 * @return string text or html code
58 function getTitle($params, $asHTML = true) {
61 if (!isset($params['title'])) {
62 return forge_get_config('forge_name');
64 return forge_get_config('forge_name') . _(': ') . $params['title'];
67 // return HTML code otherwise
68 return html_e('title', array(), $this->getTitle($params, false), true);
73 * Get the HTML code for the favicon links of the site (to be
74 * put into the <head>. If $asHTML is false, it will return
75 * the URL of the favicon.
77 * @todo: Make favicon configurable
82 function getFavIcon($asHTML = true) {
84 return util_make_uri('/images/icon.png');
86 return html_e('link', array('rel' => 'icon', 'type' => 'image/png', 'href' => $this->getFavIcon(false))).
87 html_e('link', array('rel' => 'shortcut icon', 'type' => 'image/png', 'href' => $this->getFavIcon(false)));
92 * Get the HTML code for the RSS feeds of the site (to be put
93 * into the <head>. If $asHTML is false, it will return an
94 * array with the following structure: $result['titles']:
95 * list of titles of the feeds; $result['urls'] list of urls
100 function getRSS($asHTML = true) {
103 $res['titles'] = array();
104 $res['urls'] = array();
106 $res['titles'][] = forge_get_config ('forge_name').' - Project News Highlights RSS';
107 $res['urls'][] = util_make_uri('/export/rss20_news.php');
109 $res['titles'][] = forge_get_config ('forge_name').' - New Projects RSS';
110 $res['urls'][] = util_make_uri('/export/rss20_projects.php');
112 if (isset($GLOBALS['group_id']) && $GLOBALS['group_id'] > 0) {
113 $res['titles'][] = forge_get_config ('forge_name') . ' - New Activity RSS';
114 $res['urls'][] = util_make_uri('/export/rss20_activity.php?group_id='.$GLOBALS['group_id']);
118 $feeds = $this->getRSS(false);
119 for ($j = 0; $j < count($feeds['urls']); $j++) {
120 echo html_e('link', array('rel' => 'alternate', 'title' => util_html_secure($feeds['titles'][$j]),
121 'href' => $feeds['urls'][$j], 'type' => 'application/rss+xml'));
127 * Get the searchBox HTML code.
129 function getSearchBox() {
130 global $words, $forum_id, $group_id, $group_project_id, $atid, $exact, $type_of_search, $HTML;
133 if (get_magic_quotes_gpc()) {
134 $defaultWords = stripslashes($words);
136 $defaultWords = $words;
139 $defaultWords = htmlspecialchars($defaultWords);
141 // if there is no search currently, set the default
142 if (!isset($type_of_search) ) {
146 $res .= html_ao('div', array('role' => 'search'));
147 $res .= $HTML->openForm(array('id' => 'searchBox', 'action' => '/search/', 'method' => 'get'));
148 $res .= html_ao('div', array());
150 SEARCH__PARAMETER_GROUP_ID => $group_id,
151 SEARCH__PARAMETER_ARTIFACT_ID => $atid,
152 SEARCH__PARAMETER_FORUM_ID => $forum_id,
153 SEARCH__PARAMETER_GROUP_PROJECT_ID => $group_project_id
156 $searchManager =& getSearchManager();
157 $searchManager->setParametersValues($parameters);
158 $searchEngines =& $searchManager->getAvailableSearchEngines();
160 $res .= html_ao('select', array('name' => 'type_of_search'));
161 for($i = 0, $max = count($searchEngines); $i < $max; $i++) {
162 $searchEngine =& $searchEngines[$i];
163 $attrs = array('value' => $searchEngine->getType());
164 if ( $type_of_search == $searchEngine->getType()) {
165 $attrs['selected'] = 'selected';
167 $res .= html_e('option', $attrs, $searchEngine->getLabel($parameters), false);
169 $res .= html_ac(html_ap() - 1);
171 $parameters = $searchManager->getParameters();
172 foreach($parameters AS $name => $value) {
173 $res .= html_e('input', array('type' => 'hidden', 'value' => $value, 'name' => $name));
175 $res .= html_e('input', array('type' => 'text', 'size' => 12, 'id' => 'searchBox-words', 'name' => 'words', 'value' => $defaultWords, 'required' => 'required'));
176 $res .= html_e('input', array('type' => 'submit', 'name' => 'Search', 'value' => _('Search')));
178 if (isset($group_id) && $group_id) {
179 $res .= util_make_link('/search/advanced_search.php?group_id='.$group_id, _('Advanced search'));
181 $res .= html_ac(html_ap() - 1);
182 $res .= $HTML->closeForm();
183 $res .= html_ac(html_ap() - 1);
189 * Get an array of the user links (Login/Logout/My Account/Register) with the following structure:
190 * $result['titles']: list of the titles. $result['urls']: list of the urls.
192 function getUserLinks() {
194 if (session_loggedin()) {
195 $u = user_get_object(user_getid());
196 $res['titles'][] = sprintf("%s (%s)", _('Log Out'), $u->getRealName());
197 $res['urls'][] = util_make_uri('/account/logout.php');
199 $res['titles'][] = _('My Account');
200 $res['urls'][] = util_make_uri('/account/');
202 $url = '/account/login.php';
203 if(getStringFromServer('REQUEST_METHOD') != 'POST') {
204 $url .= '?return_to=';
205 $url .= urlencode(getStringFromServer('REQUEST_URI'));
207 $res['titles'][] = _('Log In');
208 $res['urls'][] = util_make_url($url);
210 if (!forge_get_config ('user_registration_restricted')) {
211 $res['titles'][] = _('New Account');
212 $res['urls'][] = util_make_url('/account/register.php');
219 * Get an array of the menu of the site with the following structure:
220 * $result['titles']: list of titles of the links.
221 * $result['urls']: list of urls.
222 * $result['tooltips']: list of tooltips (html title).
223 * $result['selected']: number of the selected menu entry.
225 function getSiteMenu() {
226 //WARNING: REQUEST_URI does not include prefix. DO NOT use util_make_uri in test to find the selected tab.
227 $request_uri = getStringFromServer('REQUEST_URI');
230 $menu['titles'] = array();
231 $menu['urls'] = array();
232 $menu['tooltips'] = array();
236 if (forge_get_config('use_home')) {
237 $menu['titles'][] = _('Home');
238 $menu['urls'][] = util_make_uri('/');
239 $menu['tooltips'][] = _('Main Page');
243 if (forge_get_config('use_my')) {
244 $menu['titles'][] = _('My Page');
245 $menu['urls'][] = util_make_uri('/my/');
246 $menu['tooltips'][] = _('Your Page, widgets selected by you to follow your items.');
247 if (strstr($request_uri, '/my/')
248 || strstr($request_uri, '/account/')
249 || strstr($request_uri, '/register/')
250 || strstr($request_uri, '/themes/')
251 || strstr($request_uri, '/forum/myforums.php')
254 $selected = count($menu['urls'])-1;
258 if (forge_get_config('use_trove') || forge_get_config('use_project_tags') || forge_get_config('use_project_full_list')) {
259 $menu['titles'][] = _('Projects');
260 $menu['urls'][] = util_make_uri('/softwaremap/');
261 $menu['tooltips'][] = _('Map of projects, by categories or types.');
262 if (strstr($request_uri, '/softwaremap/')) {
263 $selected = count($menu['urls'])-1;
267 if (forge_get_config('use_snippet')) {
268 $menu['titles'][] = _('Code Snippets');
269 $menu['urls'][] = util_make_uri('/snippet/');
270 $menu['tooltips'][] = _('Tooling library. Small coding tips.');
271 if (strstr($request_uri, '/snippet/')) {
272 $selected = count($menu['urls'])-1;
276 if (forge_get_config('use_people')) {
277 $menu['titles'][] = _('Project Openings');
278 $menu['urls'][] = util_make_uri('/people/');
279 $menu['tooltips'][] = _('Hiring Market Place.');
280 if (strstr($request_uri, '/people/')) {
281 $selected=count($menu['urls'])-1;
286 $before = count($menu['urls']);
287 $hookParams['DIRS'] = &$menu['urls'];
288 $hookParams['TITLES'] = &$menu['titles'];
289 $hookParams['TOOLTIPS'] = &$menu['tooltips'];
290 plugin_hook("outermenu", $hookParams);
292 // try to find selected entry
293 for ($j = $before; $j < count($menu['urls']); $j++) {
294 $url = $menu['urls'][$j];
295 if (strstr($request_uri, $url)) {
301 // Admin and Reporting
302 if (forge_check_global_perm('forge_admin')) {
303 $menu['titles'][] = _('Site Admin');
304 $menu['urls'][] = util_make_uri('/admin/');
305 $menu['tooltips'][] = _('Administration Submenu to handle global configuration, users & projects.');
306 if (strstr($request_uri, '/admin/') || strstr($request_uri, 'type=globaladmin')) {
307 $selected = count($menu['urls'])-1;
310 if (forge_check_global_perm('forge_stats', 'read')) {
311 $menu['titles'][] = _('Reporting');
312 $menu['urls'][] = util_make_uri('/reporting/');
313 $menu['tooltips'][] = _('Statistics about visits, users & projects in time frame.');
314 if (strstr($request_uri, '/reporting/')) {
315 $selected = count($menu['urls'])-1;
320 if (isset($GLOBALS['group_id']) &&
321 !strstr($request_uri, '/search/?type_of_search=alldocs') &&
322 !strstr($request_uri, '/search/?type_of_search=skill') &&
323 !strstr($request_uri, '/search/?type_of_search=people') &&
324 !strstr($request_uri, '/search/?type_of_search=soft')) {
325 // get group info using the common result set
326 $project = group_get_object($GLOBALS['group_id']);
327 if (is_int($project) && $project == 0) {
328 if (preg_match('/root=/',$request_uri)) {
329 $project_name = preg_replace('/.*?root=/', '', $request_uri);
330 $project = group_get_object_by_name($project_name);
333 if ($project && is_object($project)) {
334 if (!$project->isError()) {
335 $menu['titles'][] = $project->getPublicName();
336 $menu['tooltips'][] = _('Project home page, widgets selected to follow specific items.');
337 if (isset ($GLOBALS['sys_noforcetype']) && $GLOBALS['sys_noforcetype']) {
338 $menu['urls'][] = util_make_uri('/project/?group_id') .$project->getID();
340 $menu['urls'][] = util_make_uri('/projects/') .$project->getUnixName().'/';
342 $selected = count($menu['urls'])-1;
347 $menu['selected'] = $selected;
352 * Get a reference to an array of the projects menu for the project with the id $group_id with the following structure:
353 * $result['starturl']: URL of the projects starting page;
354 * $result['name']: public name of the project;
355 * $result['titles']: list of titles of the menu entries;
356 * $result['tooltips']: list of tooltips (html title) of the menu entries;
357 * $result['urls']: list of urls of the menu entries;
358 * $result['adminurls']: list of urls to the admin pages of the menu entries.
359 * If the user has no admin permissions, the corresponding adminurl is false.
360 * $result['selected']: number of the menu entry that is currently selected.
362 * @param string $toptab
365 function getProjectMenu($group_id, $toptab = "") {
366 // rebuild menu if it has never been built before, or
367 // if the toptab was set differently
368 if (!isset($this->project_menu_data[$group_id])
369 || ($toptab != "")) {
370 // get the group and permission objects
371 $group = group_get_object($group_id);
372 if (!$group || !is_object($group)) {
375 if ($group->isError()) {
376 //wasn't found or some other problem
382 $menu =& $this->project_menu_data[$group_id];
383 $menu['titles'] = array();
384 $menu['tooltips'] = array();
385 $menu['urls'] = array();
386 $menu['adminurls'] = array();
388 $menu['name'] = $group->getPublicName();
391 $menu['titles'][] = _('Summary');
392 $menu['tooltips'][] = _('Project Homepage. Widgets oriented');
393 if (isset($GLOBALS['sys_noforcetype']) && $GLOBALS['sys_noforcetype']) {
394 $url = util_make_uri('/project/?group_id=' . $group_id);
396 $url = util_make_uri('/projects/' . $group->getUnixName() .'/');
398 $menu['urls'][] = $url;
399 $menu['adminurls'][] = false;
400 if ($toptab == "home") {
401 $selected = (count($menu['urls'])-1);
404 // setting these allows to change the initial project page
405 $menu['starturl'] = $url;
408 if (forge_check_perm ('project_admin', $group_id)) {
409 $menu['titles'][] = _('Admin');
410 $menu['tooltips'][] = _('Project Admin');
411 $menu['urls'][] = util_make_uri('/project/admin/?group_id=' . $group_id);
412 $menu['adminurls'][] = false;
413 if ($toptab == "admin") {
414 $selected = (count($menu['urls'])-1);
419 // check for use_home_tab?
420 $tabs_dirs[]='http://'. $this->getHomePage();
421 $tabs_titles[]=_('Home Page');
425 if ($group->usesActivity()) {
426 $menu['titles'][] = _('Activity');
427 $menu['tooltips'][] = _('Last activities per category.');
428 $menu['urls'][] = util_make_uri('/activity/?group_id=' . $group_id);
429 $menu['adminurls'][] = false;
430 if ($toptab == "activity") {
431 $selected = (count($menu['urls'])-1);
436 if ($group->usesForum()) {
437 $menu['titles'][] = _('Forums');
438 $menu['tooltips'][] = _('Tech & help forums.');
439 $menu['urls'][] = util_make_uri('/forum/?group_id=' . $group_id);
440 if (forge_check_perm ('forum_admin', $group_id)) {
441 $menu['adminurls'][] = util_make_uri('/forum/admin/?group_id='.$group_id);
443 $menu['adminurls'][] = false;
445 if ($toptab == "forums") {
446 $selected = (count($menu['urls'])-1);
451 if ($group->usesTracker()) {
452 $menu['titles'][] = _('Tracker');
453 $menu['tooltips'][] = _('Issues, tickets, bugs.');
454 $menu['urls'][] = util_make_uri('/tracker/?group_id=' . $group_id);
455 if (forge_check_perm ('tracker_admin', $group_id)) {
456 $menu['adminurls'][] = util_make_uri('/tracker/admin/?group_id='.$group_id);
458 $menu['adminurls'][] = false;
460 if ($toptab == "tracker" ||
462 $toptab == "support" ||
463 $toptab == "patch") {
464 $selected = (count($menu['urls'])-1);
469 if ($group->usesMail()) {
470 $menu['titles'][] = _('Lists');
471 $menu['tooltips'][] = _('Mailing Lists');
472 $menu['urls'][] = util_make_uri('/mail/?group_id=' . $group_id);
473 if (forge_check_perm ('project_admin', $group_id)) {
474 $menu['adminurls'][] = util_make_uri('/mail/admin/?group_id='.$group_id);
476 $menu['adminurls'][] = false;
478 if ($toptab == "mail") {
479 $selected = (count($menu['urls'])-1);
483 // Project/Task Manager
484 if ($group->usesPM()) {
485 $menu['titles'][] = _('Tasks');
486 $menu['tooltips'][] = _('Project Management');
487 $menu['urls'][] = util_make_uri('/pm/?group_id=' . $group_id);
488 if (forge_check_perm ('pm_admin', $group_id)) {
489 $menu['adminurls'][] = util_make_uri('/pm/admin/?group_id='.$group_id);
491 $menu['adminurls'][] = false;
493 if ($toptab == "pm") {
494 $selected = (count($menu['urls'])-1);
499 if ($group->usesDocman()) {
500 $menu['titles'][] = _('Docs');
501 $menu['tooltips'][] = _('Document Management.');
502 $menu['urls'][] = util_make_uri('/docman/?group_id=' . $group_id);
503 if (forge_check_perm ('docman', $group_id, 'admin')) {
504 $menu['adminurls'][] = util_make_uri('/docman/?group_id='.$group_id.'&view=admin');
506 $menu['adminurls'][] = false;
508 if ($toptab == "docman") {
509 $selected = (count($menu['urls'])-1);
514 if ($group->usesSurvey()) {
515 $menu['titles'][] = _('Surveys');
516 $menu['tooltips'][] = _('Online surveys, project needs your point of view.');
517 $menu['urls'][] = util_make_uri('/survey/?group_id=' . $group_id);
518 if (forge_check_perm ('project_admin', $group_id)) {
519 $menu['adminurls'][] = util_make_uri('/survey/admin/?group_id='.$group_id);
521 $menu['adminurls'][] = false;
523 if ($toptab == "surveys") {
524 $selected = (count($menu['urls'])-1);
529 if ($group->usesNews()) {
530 $menu['titles'][] = _('News');
531 $menu['tooltips'][] = _('Flash head line from the project.');
532 $menu['urls'][] = util_make_uri('/news/?group_id=' . $group_id);
533 if (forge_check_perm ('project_admin', $group_id)) {
534 $menu['adminurls'][] = util_make_uri('/news/admin/?group_id='.$group_id);
536 $menu['adminurls'][] = false;
538 if ($toptab == "news") {
539 $selected = (count($menu['urls'])-1);
544 if ($group->usesSCM()) {
545 $menu['titles'][] = _('SCM');
546 $menu['tooltips'][] = _('Source Content Management, peer-review and source discovery.');
547 $menu['urls'][] = util_make_uri('/scm/?group_id=' . $group_id);
549 if (forge_check_perm ('project_admin', $group_id)) {
550 $menu['adminurls'][] = util_make_uri('/scm/admin/?group_id='.$group_id);
552 $menu['adminurls'][] = false;
554 if ($toptab == "scm") {
555 $selected = (count($menu['urls'])-1);
559 // groupmenu_after_scm hook
560 $hookParams = array();
561 $hookParams['group_id'] = $group_id ;
562 $hookParams['DIRS'] =& $menu['urls'];
563 $hookParams['ADMIN'] =& $menu['adminurls'];
564 $hookParams['TITLES'] =& $menu['titles'];
565 $hookParams['TOOLTIPS'] =& $menu['tooltips'];
566 $hookParams['toptab'] =& $toptab;
567 $hookParams['selected'] =& $selected;
568 plugin_hook ("groupmenu_scm", $hookParams);
571 for ($i = 0; $i < count($menu['urls']) - count($menu['adminurls']); $i++) {
572 $menu['adminurls'][] = false;
576 if ($group->usesFRS()) {
577 $menu['titles'][] = _('Files');
578 $menu['tooltips'][] = _('All published files organized per version.');
579 $menu['urls'][] = util_make_uri('/frs/?group_id=' . $group_id);
580 if (forge_check_perm ('frs_admin', $group_id, 'admin')) {
581 $menu['adminurls'][] = util_make_uri('/frs/?view=admin&group_id='.$group_id);
583 $menu['adminurls'][] = false;
585 if ($toptab == "frs") {
586 $selected = (count($menu['urls'])-1);
591 $hookParams = array();
592 $hookParams['group'] = $group_id;
593 $hookParams['DIRS'] =& $menu['urls'];
594 $hookParams['ADMIN'] =& $menu['adminurls'];
595 $hookParams['TITLES'] =& $menu['titles'];
596 $hookParams['TOOLTIPS'] =& $menu['tooltips'];
597 $hookParams['toptab'] =& $toptab;
598 $hookParams['selected'] =& $selected;
599 plugin_hook("groupmenu", $hookParams);
602 for ($i = 0; $i < count($menu['urls']) - count($menu['adminurls']); $i++) {
603 $menu['adminurls'][] = false;
606 // store selected menu item (if any)
607 $menu['selected'] = $selected;
609 return $this->project_menu_data[$group_id];
613 * Create the HTML code for the banner "Powered By
614 * FusionForge". If $asHTML is set to false, it will return an
615 * array with the following structure: $result['url']: URL for
616 * the link on the banner; $result['image']: URL of the banner
617 * image; $result['title']: HTML code that outputs the banner;
618 * $result['html']: HTML code that creates the banner and the link.
619 * @param bool $asHTML
622 function getPoweredBy($asHTML=true) {
623 $res['url'] = 'http://fusionforge.org/';
624 $res['image'] = util_make_uri('/images/pow-fusionforge.png');
625 $res['title'] = html_abs_image($res['image'], null, null, array("alt" => "Powered By FusionForge"));
626 $res['html'] = util_make_link($res['url'], $res['title'], array(), true);
634 /** Create the HTML code for the "Show Source" link if
635 * forge_get_config('show_source') is set, otherwise "". If $asHTML is set
636 * to false, it returns NULL when forge_get_config('show_source') is not
637 * set, otherwise an array with the following structure:
638 * $result['url']: URL of the link to the source code viewer;
639 * $result['title']: Title of the link.
640 * @param bool $asHTML
641 * @return null|string
643 function getShowSource($asHTML=true) {
644 if (forge_get_config('show_source')) {
645 $res['url'] = util_make_uri('/source.php?file='.getStringFromServer('SCRIPT_NAME'));
646 $res['title'] = _('Show source');
648 return ($asHTML ? "" : NULL);
653 return util_make_link($res['url'], $res['title'],
654 array('class' => 'showsource'),
662 // c-file-style: "bsd"