From: Roland Mas
Date: Thu, 22 Apr 2010 18:55:08 +0000 (+0000)
Subject: Contentless (almost) merge from 5.0
X-Git-Tag: v5.1~2492
X-Git-Url: https://scm.fusionforge.org/anonscm/gitweb?p=fusionforge%2Ffusionforge.git;a=commitdiff_plain;h=faa57cb5a4c4e5179a9e6e92dfa16cab4f54ac7b;hp=865addbc49e2fa7765deb15ff28804cb6853045c
Contentless (almost) merge from 5.0
---
diff --git a/.gitattributes b/.gitattributes
index 8781a69d43..a113bff771 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,15 +1,74 @@
* text=auto !eol
/.bzrignore -text
+3rd-party/Makefile -text
+3rd-party/PEAR/Archive_Tar-1.3.3.tgz -text svneol=unset#unset
+3rd-party/PEAR/Console_Getopt-1.2.3.tgz -text svneol=unset#unset
+3rd-party/PEAR/Mail-1.1.14.tgz -text svneol=unset#unset
+3rd-party/PEAR/Mail_Mbox-0.6.1.tgz -text svneol=unset#unset
+3rd-party/PEAR/Mail_Mime-1.5.2.tgz -text svneol=unset#unset
+3rd-party/PEAR/Mail_mimeDecode-1.5.0.tgz -text svneol=unset#unset
+3rd-party/PEAR/Structures_Graph-1.0.2.tgz -text svneol=unset#unset
+3rd-party/PEAR/XML_Util-1.2.1.tgz -text svneol=unset#unset
+3rd-party/db2latex-xsl/Makefile -text
+3rd-party/db2latex-xsl/Makefile.debian -text
+3rd-party/db2latex-xsl/db2latex-xsl_0.8pre1-6.1.diff.gz -text svneol=unset#unset
+3rd-party/db2latex-xsl/db2latex-xsl_0.8pre1-6.1.dsc -text
+3rd-party/db2latex-xsl/db2latex-xsl_0.8pre1-6.2.diff.gz -text svneol=unset#unset
+3rd-party/db2latex-xsl/db2latex-xsl_0.8pre1-6.2.dsc -text
+3rd-party/db2latex-xsl/db2latex-xsl_0.8pre1.orig.tar.gz -text svneol=unset#unset
+3rd-party/htmlpurifier/Makefile -text
+3rd-party/htmlpurifier/Makefile.debian -text
+3rd-party/htmlpurifier/htmlpurifier-4.0.0.tar.gz -text svneol=unset#unset
3rd-party/htmlpurifier/htmlpurifier.spec -text
+3rd-party/htmlpurifier/php-htmlpurifier_4.0.0+dfsg1-1.diff.gz -text svneol=unset#unset
+3rd-party/htmlpurifier/php-htmlpurifier_4.0.0+dfsg1-1.dsc -text
+3rd-party/htmlpurifier/php-htmlpurifier_4.0.0+dfsg1.orig.tar.gz -text svneol=unset#unset
+3rd-party/mailman/Makefile -text
+3rd-party/mailman/Makefile.debian -text
+3rd-party/mailman/mailman_2.1.13-2.diff.gz -text svneol=unset#unset
+3rd-party/mailman/mailman_2.1.13-2.dsc -text
+3rd-party/mailman/mailman_2.1.13-2coclico1.diff.gz -text svneol=unset#unset
+3rd-party/mailman/mailman_2.1.13-2coclico1.dsc -text
+3rd-party/mailman/mailman_2.1.13-2coclico4.diff.gz -text svneol=unset#unset
+3rd-party/mailman/mailman_2.1.13-2coclico4.dsc -text
+3rd-party/mailman/mailman_2.1.13.orig.tar.gz -text svneol=unset#unset
+3rd-party/nusoap/Makefile -text
+3rd-party/nusoap/Makefile.debian -text
+3rd-party/nusoap/nusoap_0.7.3-2.diff.gz -text svneol=unset#unset
+3rd-party/nusoap/nusoap_0.7.3-2.dsc -text
+3rd-party/nusoap/nusoap_0.7.3.orig.tar.gz -text svneol=unset#unset
+3rd-party/php-apache-log4php/Makefile -text
+3rd-party/php-apache-log4php/Makefile.debian -text
+3rd-party/php-apache-log4php/php-apache-log4php_2.0.0incubating-1.diff.gz -text svneol=unset#unset
+3rd-party/php-apache-log4php/php-apache-log4php_2.0.0incubating-1.dsc -text
+3rd-party/php-apache-log4php/php-apache-log4php_2.0.0incubating.orig.tar.gz -text svneol=unset#unset
+3rd-party/php-jpgraph/jpgraph-1.5.2-php5_and_liberation_fonts.patch -text
+3rd-party/php-jpgraph/jpgraph-rhel-fonts.patch -text
+3rd-party/php-jpgraph/libphp-jpgraph_1.5.2-12.diff.gz -text svneol=unset#unset
+3rd-party/php-jpgraph/libphp-jpgraph_1.5.2.orig.tar.gz -text svneol=unset#unset
+3rd-party/php-jpgraph/php-jpgraph.spec -text
+3rd-party/php-mail-mbox/Makefile -text
+3rd-party/php-mail-mbox/Makefile.debian -text
+3rd-party/php-mail-mbox/php-mail-mbox_0.6.3-1.diff.gz -text svneol=unset#unset
+3rd-party/php-mail-mbox/php-mail-mbox_0.6.3-1.dsc -text
+3rd-party/php-mail-mbox/php-mail-mbox_0.6.3-1coclico1.diff.gz -text svneol=unset#unset
+3rd-party/php-mail-mbox/php-mail-mbox_0.6.3-1coclico1.dsc -text
+3rd-party/php-mail-mbox/php-mail-mbox_0.6.3.orig.tar.gz -text svneol=unset#unset
/README -text
delivery/fusionforge/package/config -text
delivery/gforge/package/config -text
delivery/novaforge/package/config -text
/fix_phpunit.xslt -text
+gforge/AUTHORS -text
gforge/CHANGES -text
gforge/INSTALL.restricted -text
gforge/NEWS -text
gforge/backend/shell/apache.sh svneol=native#unset
+gforge/common/dao/CodendiDataAccess.class.php -text
+gforge/common/dao/include/DataAccess.class.php -text
+gforge/common/dao/include/DataAccessException.class.php -text
+gforge/common/dao/include/DataAccessObject.class.php -text
+gforge/common/dao/include/DataAccessResult.class.php -text
gforge/common/docman/Parsedata.class.php -text
gforge/common/docman/engine/parser_doc.php -text
gforge/common/docman/engine/parser_html.php -text
@@ -18,19 +77,33 @@ gforge/common/docman/engine/parser_oo.php -text
gforge/common/docman/engine/parser_pdf.php -text
gforge/common/docman/engine/parser_text.inc.php -text
gforge/common/docman/engine/parser_text.php -text
+gforge/common/event/Event.class.php -text
+gforge/common/include/Codendi_HTMLPurifier.class.php -text
+gforge/common/include/Codendi_Request.class.php -text
+gforge/common/include/HTTPRequest.class.php -text
+gforge/common/include/Navigation.class.php -text
+gforge/common/include/PluginInfo.class.php -text
+gforge/common/include/ProjectManager.class.php -text
gforge/common/include/TextSanitizer.class.php -text
-gforge/common/include/database-mysql.php -text
+gforge/common/include/UserManager.class.php -text
+gforge/common/include/config-vars.php -text
+gforge/common/include/config.php -text
gforge/common/include/group_section_texts.php -text
gforge/common/include/rbac_texts.php -text
gforge/common/include/tag_cloud.php -text
gforge/common/include/utils_crossref.php -text
+gforge/common/mail/Mail.class.php -text
gforge/common/reporting/ReportDownloads.class.php -text
+gforge/common/system_event/SystemEvent.class.php -text
+gforge/common/system_event/SystemEventManager.class.php -text
gforge/common/tracker/ArtifactWorkflow.class.php -text
+gforge/common/valid/Rule.class.php -text
+gforge/common/valid/Valid.class.php -text
+gforge/common/valid/ValidFactory.class.php -text
gforge/contrib/cmd-line-prototype.tar.gz -text
gforge/contrib/fusionforge.dia -text
gforge/contrib/migrate-from-gforge-as.pl -text
gforge/cronjobs/auth_unix.php -text
-gforge/cronjobs/create_home_dirs.php -text
gforge/cronjobs/create_scm_repos.php -text
gforge/cronjobs/ftp_create_group_access.php -text
gforge/cronjobs/gather_scm_stats.php -text
@@ -59,7 +132,11 @@ gforge/db/20090507-add_element_pos.sql -text
gforge/db/20090507-add_project_query.sql -text
gforge/db/20090507-browse_list.sql -text
gforge/db/20090507-install_workflow.php -text
+gforge/db/20100308-drop-forum-attachment-type.sql -text
gforge/db/20100308-forum-attachment-types.sql -text
+gforge/db/20100330-add-system-event.sql -text
+gforge/db/20100331-alter-system-event.sql -text
+gforge/db/20100402_add_query_options.sql -text
gforge/db/FTI-20061025.sql -text
gforge/db/gforge-data-mysql.sql -text
gforge/db/gforge-struct-mysql.sql -text
@@ -71,12 +148,12 @@ gforge/deb-specific/update-ldap.sh -text
gforge/debian/NEWS.Debian -text
gforge/debian/README.source -text
gforge/debian/compat -text
-gforge/debian/dsf-in/common.links -text
+gforge/debian/dsf-in/plugin-contribtracker.postinst -text
+gforge/debian/dsf-in/plugin-contribtracker.prerm -text
gforge/debian/dsf-in/plugin-extratabs.postinst -text
gforge/debian/dsf-in/plugin-extratabs.prerm -text
gforge/debian/dsf-in/plugin-globalsearch.postinst -text
gforge/debian/dsf-in/plugin-globalsearch.prerm -text
-gforge/debian/dsf-in/plugin-mediawiki.links -text
gforge/debian/dsf-in/plugin-mediawiki.postinst -text
gforge/debian/dsf-in/plugin-mediawiki.prerm -text
gforge/debian/dsf-in/plugin-projectlabels.postinst -text
@@ -90,10 +167,8 @@ gforge/debian/dsf-in/plugin-scmcpold.postinst -text
gforge/debian/dsf-in/plugin-scmcpold.prerm -text
gforge/debian/dsf-in/plugin-scmcvs.postinst -text
gforge/debian/dsf-in/plugin-scmcvs.prerm -text
-gforge/debian/dsf-in/plugin-scmdarcs.links -text
gforge/debian/dsf-in/plugin-scmdarcs.postinst -text
gforge/debian/dsf-in/plugin-scmdarcs.prerm -text
-gforge/debian/dsf-in/plugin-scmgit.links -text
gforge/debian/dsf-in/plugin-scmgit.postinst -text
gforge/debian/dsf-in/plugin-scmgit.prerm -text
gforge/debian/dsf-in/plugin-scmhg.postinst -text
@@ -113,8 +188,6 @@ gforge/debian/dsf-po/fi.po -text
gforge/debian/dsf-po/gl.po -text
gforge/debian/dsf-po/pt.po -text
gforge/debian/dsf-po/ru.po -text
-gforge/debian/gforge-plugin-contribtracker.postinst -text
-gforge/debian/gforge-plugin-contribtracker.prerm -text
gforge/debian/patches/disable-dav.dpatch -text
gforge/debian/patches/use-nusoap-from-distro.dpatch -text
gforge/debian/patches/use-snoopy-from-distro.dpatch -text
@@ -128,7 +201,12 @@ gforge/docs/docbook/docbook/entities/authors.ent -text svneol=unset#application/
gforge/docs/docbook/docbook/entities/authors/alain_peyrat.xml -text
gforge/docs/docbook/docbook/entities/xinclude.ent -text svneol=unset#application/octet-stream
gforge/docs/docbook/docbook/user_guide/project_functions/activity.xml -text
+gforge/docs/docbook/docbook/user_guide/project_functions/blocks.xml -text
+gforge/docs/fusionforge.doxygen -text
gforge/docs/images/sflogo2-105a.png -text
+gforge/docs/phpdoc/phpDocumentor.ini.patch -text
+gforge/etc/config.ini -text
+gforge/etc/database.py.example -text
gforge/etc/httpd.d/01common.ssl -text
gforge/etc/httpd.d/060maindirhttp.vhost -text
gforge/etc/httpd.d/06zmaindirhttp.vhost -text
@@ -139,6 +217,7 @@ gforge/etc/httpd.d/61plugin-scmdarcs -text
gforge/etc/httpd.d/61plugin-scmgit -text
gforge/etc/httpd.d/99maindirhttp -text
gforge/etc/local.d/60bbcode -text
+gforge/etc/templates/database.py -text
gforge/fusionforge-install-2.php -text
gforge/fusionforge-install-3-db.php -text
gforge/image-sources/README -text
@@ -193,8 +272,6 @@ gforge/packaging/control/135plugin-scmdarcs -text
gforge/packaging/control/135plugin-scmdarcs.shortdesc -text
gforge/packaging/control/136plugin-scmarch -text
gforge/packaging/control/136plugin-scmarch.shortdesc -text
-gforge/packaging/control/137plugin-scmcpold -text
-gforge/packaging/control/137plugin-scmcpold.shortdesc -text
gforge/packaging/control/160plugin-mediawiki -text
gforge/packaging/control/160plugin-mediawiki.shortdesc -text
gforge/packaging/control/170plugin-extratabs -text
@@ -230,7 +307,6 @@ gforge/packaging/dirs/plugin-mediawiki -text
gforge/packaging/dirs/plugin-projectlabels -text
gforge/packaging/dirs/plugin-scmarch -text
gforge/packaging/dirs/plugin-scmbzr -text
-gforge/packaging/dirs/plugin-scmcpold -text
gforge/packaging/dirs/plugin-scmcvs -text
gforge/packaging/dirs/plugin-scmdarcs -text
gforge/packaging/dirs/plugin-scmgit -text
@@ -255,7 +331,6 @@ gforge/packaging/install/plugin-mediawiki -text
gforge/packaging/install/plugin-projectlabels -text
gforge/packaging/install/plugin-scmarch -text
gforge/packaging/install/plugin-scmbzr -text
-gforge/packaging/install/plugin-scmcpold -text
gforge/packaging/install/plugin-scmcvs -text
gforge/packaging/install/plugin-scmdarcs -text
gforge/packaging/install/plugin-scmgit -text
@@ -264,6 +339,15 @@ gforge/packaging/install/plugin-scmsvn -text
gforge/packaging/install/shell-postgresql -text
gforge/packaging/install/web-apache2 -text
gforge/packaging/install/web-apache2-vhosts -text
+gforge/packaging/links/common -text
+gforge/packaging/links/plugin-scmdarcs -text
+gforge/packaging/links/plugin-scmgit -text
+gforge/packaging/links/web-apache2 -text
+gforge/plugins/blocks/common/blocks-init.php -text
+gforge/plugins/blocks/common/blocksPlugin.class.php -text
+gforge/plugins/blocks/db/blocks-init.sql -text
+gforge/plugins/blocks/etc/plugins/blocks/config.php -text
+gforge/plugins/blocks/www/index.php -text
gforge/plugins/contribtracker/INSTALL -text
gforge/plugins/contribtracker/bin/db-delete.pl -text
gforge/plugins/contribtracker/bin/db-upgrade.pl -text
@@ -274,7 +358,6 @@ gforge/plugins/contribtracker/www/actor_logo.php -text
gforge/plugins/contribtracker/www/global_admin.php -text
gforge/plugins/contribtracker/www/index.php -text
gforge/plugins/contribtracker/www/project_admin.php -text
-gforge/plugins/createplugin.sh -text
gforge/plugins/cvstracker/db/cvstracker-init-mysql.sql -text
gforge/plugins/cvstracker/gforge-plugin-cvstracker.spec -text svneol=unset#application/octet-stream
gforge/plugins/cvstracker/rpm-specific/cron.d/gforge-plugin-cvstracker -text svneol=unset#application/octet-stream
@@ -933,11 +1016,16 @@ gforge/plugins/globalsearch/www/edit_assoc_sites.php -text
gforge/plugins/globalsearch/www/index.php -text
gforge/plugins/ldapextauth/rpm-specific/.keepme -text svneol=unset#application/octet-stream
gforge/plugins/mediawiki/README -text
-gforge/plugins/mediawiki/bin/drop-wiki.sh -text
+gforge/plugins/mediawiki/bin/drop-wiki.php -text
+gforge/plugins/mediawiki/bin/mw-wrapper.php -text
gforge/plugins/mediawiki/common/MediaWikiPlugin.class.php -text
gforge/plugins/mediawiki/common/mediawiki-init.php -text
-gforge/plugins/mediawiki/cronjobs/create-wikis.sh -text
+gforge/plugins/mediawiki/cronjobs/create-wikis.php -text
+gforge/plugins/mediawiki/etc/cron.d/mediawiki -text
gforge/plugins/mediawiki/etc/httpd.d/03mediawiki -text
+gforge/plugins/mediawiki/etc/plugins/mediawiki/LocalSettings.php -text
+gforge/plugins/mediawiki/etc/plugins/mediawiki/ProjectSettings.template.php -text
+gforge/plugins/mediawiki/etc/plugins/mediawiki/config.php -text
gforge/plugins/mediawiki/mediawiki-skin/FusionForge.php -text
gforge/plugins/mediawiki/mediawiki-skin/FusionForge.php.patch -text
gforge/plugins/mediawiki/mediawiki-skin/FusionForge.php.reference -text
@@ -946,7 +1034,7 @@ gforge/plugins/mediawiki/mediawiki-skin/README.beforemodifying -text
gforge/plugins/mediawiki/mediawiki-skin/fusionforge/main.css -text
gforge/plugins/mediawiki/mediawiki-skin/fusionforge/main.css.patch -text
gforge/plugins/mediawiki/mediawiki-skin/fusionforge/main.css.reference -text
-gforge/plugins/mediawiki/www/LocalSettings.php -text
+gforge/plugins/mediawiki/scripts/mediawiki-plugin-init.php -text
gforge/plugins/mediawiki/www/frame.php -text
gforge/plugins/online_help/common/online_help-init.php -text
gforge/plugins/online_help/common/online_helpPlugin.class.php -text
@@ -1052,17 +1140,18 @@ gforge/plugins/scmbzr/common/BzrPlugin.class.php -text
gforge/plugins/scmbzr/common/scmbzr-init.php -text
gforge/plugins/scmbzr/etc/plugins/scmbzr/config.php -text
gforge/plugins/scmbzr/etc/plugins/scmbzr/serve-branches.conf -text
-gforge/plugins/scmcpold/common/CpoldPlugin.class.php -text
-gforge/plugins/scmcpold/common/scmcpold-init.php -text
-gforge/plugins/scmcpold/etc/plugins/scmcpold/config.php -text
gforge/plugins/scmcvs/cron.d/fusionforge-plugin-scmcvs -text
gforge/plugins/scmcvs/fusionforge-plugin-scmcvs.spec -text
gforge/plugins/scmdarcs/common/DarcsPlugin.class.php -text
gforge/plugins/scmdarcs/common/scmdarcs-init.php -text
gforge/plugins/scmdarcs/etc/plugins/scmdarcs/config.php -text
+gforge/plugins/scmgit/bin/db-delete.pl -text
+gforge/plugins/scmgit/bin/db-upgrade.pl -text
gforge/plugins/scmgit/common/GitPlugin.class.php -text
gforge/plugins/scmgit/common/scmgit-init.php -text
+gforge/plugins/scmgit/db/scmgit-init.sql -text
gforge/plugins/scmgit/etc/plugins/scmgit/config.php -text
+gforge/plugins/scmgit/www/index.php -text
gforge/plugins/scmhg/common/HgPlugin.class.php -text
gforge/plugins/scmhg/common/scmhg-init.php -text
gforge/plugins/scmhg/etc/plugins/scmhg/config.php -text
@@ -1353,6 +1442,7 @@ gforge/plugins/wiki/www/doc/README.phpwiki-auth -text
gforge/plugins/wiki/www/doc/README.phpwiki-cache -text
gforge/plugins/wiki/www/doc/README.security -text
gforge/plugins/wiki/www/doc/THEMES -text
+gforge/plugins/wiki/www/doc/phpwiki.doxygen -text
gforge/plugins/wiki/www/doc/phpwiki_architecture.png -text
gforge/plugins/wiki/www/favicon.ico -text
gforge/plugins/wiki/www/g -text
@@ -3400,6 +3490,7 @@ gforge/translations/sv.po -text
gforge/translations/th.po -text
gforge/translations/zh_CN.po -text
gforge/translations/zh_TW.po -text
+gforge/utils/fixscripts/normalize_roles.php -text
gforge/utils/fusionforge-shell-postgresql.spec -text
gforge/utils/inject-files.php -text
gforge/utils/inject-groups.php -text
@@ -3408,6 +3499,7 @@ gforge/utils/install-nsspgsql.sh -text
gforge/utils/ldap/sql2ldifadd.pl -text
gforge/utils/ldap/sql2ldifmod.pl -text
gforge/utils/manage-translations.sh -text
+gforge/www/admin/pi.php -text
gforge/www/docman/include/vtemplate.class.php -text
gforge/www/docman/search.php -text
gforge/www/docman/search.tpl.html -text
@@ -3488,6 +3580,8 @@ gforge/www/images/smiles/icon_twisted.gif -text
gforge/www/images/smiles/icon_wink.gif -text
gforge/www/images/t.png -text
gforge/www/images/t2.png -text
+gforge/www/include/plugins_utils.php -text
+gforge/www/include/preplugins.php -text
gforge/www/include/unicode.php -text
gforge/www/js/common.js -text
gforge/www/js/sortable.js -text
@@ -3515,6 +3609,7 @@ gforge/www/plugins/fckeditor -text
gforge/www/plugins/helloworld -text
gforge/www/plugins/mailman -text
gforge/www/plugins/mantis -text
+gforge/www/plugins/mediawiki -text
gforge/www/plugins/online_help -text
gforge/www/plugins/projects_hierarchy -text
gforge/www/plugins/quota_management -text
@@ -3720,6 +3815,7 @@ gforge/www/themes/gforge/images/ic/trash.png -text
gforge/www/themes/gforge/images/ic/wiki20g.png -text svneol=unset#unset
gforge/www/themes/gforge/images/ic/write16w.png -text
gforge/www/themes/gforge/images/ic/xmail16w.png -text
+gforge/www/themes/gforge/images/logo200x200.png -text
gforge/www/themes/gforge/images/notes.png -text svneol=unset#unset
gforge/www/themes/gforge/images/spacer.gif -text svneol=unset#unset
gforge/www/themes/gforge/images/t.png -text
@@ -3873,41 +3969,233 @@ packaging/tag_delivery_create -text
packaging/tag_delivery_delete -text
packaging/tag_packaging_create -text
packaging/tag_packaging_delete -text
+plugins/coclico/Makefile -text
+plugins/coclico/Makefile.debian -text
+plugins/coclico/forumml/README.txt -text
+plugins/coclico/forumml/TODO -text
+plugins/coclico/forumml/bin/db-upgrade.pl -text
+plugins/coclico/forumml/bin/installFF.sh -text
+plugins/coclico/forumml/bin/mail_2_DB.php -text
+plugins/coclico/forumml/bin/mail_2_DB.pl -text
+plugins/coclico/forumml/bin/mail_2_DBFF.php -text
+plugins/coclico/forumml/bin/mail_2_DBFF.pl -text
+plugins/coclico/forumml/bin/ml_arch_2_DB.pl -text
+plugins/coclico/forumml/bin/ml_arch_2_DBFF.pl -text
+plugins/coclico/forumml/common/forumml-init.php -text
+plugins/coclico/forumml/db/forumml-init.sql -text
+plugins/coclico/forumml/db/install.sql -text
+plugins/coclico/forumml/debian/README.Debian -text
+plugins/coclico/forumml/debian/README.source -text
+plugins/coclico/forumml/debian/changelog -text
+plugins/coclico/forumml/debian/compat -text
+plugins/coclico/forumml/debian/control -text
+plugins/coclico/forumml/debian/copyright -text
+plugins/coclico/forumml/debian/docs -text
+plugins/coclico/forumml/debian/dsf-in/plugin-forumml.postinst -text
+plugins/coclico/forumml/debian/dsf-in/plugin-forumml.prerm -text
+plugins/coclico/forumml/debian/po/templates.pot -text
+plugins/coclico/forumml/debian/rules -text
+plugins/coclico/forumml/debian/source/format -text
+plugins/coclico/forumml/etc/forumml.inc.dist -text
+plugins/coclico/forumml/include/ForumMLGroupSearchEngine.class.php -text
+plugins/coclico/forumml/include/ForumMLHtmlSearchRenderer.class.php -text
+plugins/coclico/forumml/include/ForumMLInsert.class.php -text
+plugins/coclico/forumml/include/ForumMLPluginDescriptor.class.php -text
+plugins/coclico/forumml/include/ForumMLPluginInfo.class.php -text
+plugins/coclico/forumml/include/ForumMLSearchEngine.class.php -text
+plugins/coclico/forumml/include/ForumMLSearchQuery.class.php -text
+plugins/coclico/forumml/include/ForumML_Attachment.class.php -text
+plugins/coclico/forumml/include/ForumML_AttachmentDao.class.php -text
+plugins/coclico/forumml/include/ForumML_FileStorage.class.php -text
+plugins/coclico/forumml/include/ForumML_HTMLPurifier.class.php -text
+plugins/coclico/forumml/include/ForumML_MessageDao.class.php -text
+plugins/coclico/forumml/include/ForumML_MessageManager.class.php -text
+plugins/coclico/forumml/include/ForumML_mimeDecode.class.php -text
+plugins/coclico/forumml/include/forummlPlugin.class.php -text
+plugins/coclico/forumml/packaging/control/000source -text
+plugins/coclico/forumml/packaging/control/222plugin-forumml -text
+plugins/coclico/forumml/packaging/control/222plugin-forumml.shortdesc -text
+plugins/coclico/forumml/packaging/dirs/plugin-forumml -text
+plugins/coclico/forumml/packaging/docs/plugin-forumml -text
+plugins/coclico/forumml/packaging/install/plugin-forumml -text
+plugins/coclico/forumml/packaging/links/plugin-forumml -text
+plugins/coclico/forumml/selinux/forumml0.pp -text svneol=unset#unset
+plugins/coclico/forumml/selinux/forumml0.te -text
+plugins/coclico/forumml/selinux/forumml1.pp -text svneol=unset#unset
+plugins/coclico/forumml/selinux/forumml1.te -text
+plugins/coclico/forumml/selinux/forumml2.pp -text svneol=unset#unset
+plugins/coclico/forumml/selinux/forumml2.te -text
+plugins/coclico/forumml/selinux/forumml3.pp -text svneol=unset#unset
+plugins/coclico/forumml/selinux/forumml3.te -text
+plugins/coclico/forumml/selinux/forumml4.pp -text svneol=unset#unset
+plugins/coclico/forumml/selinux/forumml4.te -text
+plugins/coclico/forumml/selinux/forumml5.pp -text svneol=unset#unset
+plugins/coclico/forumml/selinux/forumml5.te -text
+plugins/coclico/forumml/selinux/forumml6.pp -text svneol=unset#unset
+plugins/coclico/forumml/selinux/forumml6.te -text
+plugins/coclico/forumml/selinux/forumml7.pp -text svneol=unset#unset
+plugins/coclico/forumml/selinux/forumml7.te -text
+plugins/coclico/forumml/selinux/forumml8.pp -text svneol=unset#unset
+plugins/coclico/forumml/selinux/forumml8.te -text
+plugins/coclico/forumml/site-content/en_US/forumml.tab -text
+plugins/coclico/forumml/site-content/fr_FR/forumml.tab -text
+plugins/coclico/forumml/tests/ForumML_FileStorageTest.php -text
+plugins/coclico/forumml/tests/ForumML_InsertTest.php -text
+plugins/coclico/forumml/tests/_fixtures/samples/attachment_only.mbox -text
+plugins/coclico/forumml/tests/_fixtures/samples/html_with_inline_content_and_attch_in_html_only.mbox -text
+plugins/coclico/forumml/tests/_fixtures/samples/html_with_inline_content_and_attch_in_text_plus_html.mbox -text
+plugins/coclico/forumml/tests/_fixtures/samples/html_with_inline_content_in_html_only.mbox -text
+plugins/coclico/forumml/tests/_fixtures/samples/html_with_inline_content_in_text_plus_html.mbox -text
+plugins/coclico/forumml/tests/_fixtures/samples/pure_html_in_html_only.mbox -text
+plugins/coclico/forumml/tests/_fixtures/samples/pure_html_text_plus_html.mbox -text
+plugins/coclico/forumml/tests/_fixtures/samples/pure_text.mbox -text
+plugins/coclico/forumml/tests/_fixtures/samples/text_plus_attachment.mbox -text
+plugins/coclico/forumml/translations/en.po -text
+plugins/coclico/forumml/translations/gforge.pot -text
+plugins/coclico/forumml/utils/manage-translations.sh -text
+plugins/coclico/forumml/www/forumml_utils.php -text
+plugins/coclico/forumml/www/index.php -text
+plugins/coclico/forumml/www/message.php -text
+plugins/coclico/forumml/www/scripts/cc_attach_js.php -text
+plugins/coclico/forumml/www/scripts/forumml.js -text
+plugins/coclico/forumml/www/themes/default/css/style.css -text
+plugins/coclico/forumml/www/themes/default/images/ic/attach.png -text svneol=unset#unset
+plugins/coclico/forumml/www/themes/default/images/ic/comment.png -text svneol=unset#unset
+plugins/coclico/forumml/www/themes/default/images/ic/comment_add.png -text svneol=unset#unset
+plugins/coclico/forumml/www/themes/default/images/ic/comments.png -text svneol=unset#unset
+plugins/coclico/forumml/www/themes/default/images/ic/msg.png -text svneol=unset#unset
+plugins/coclico/forumml/www/themes/default/images/ic/resultset_first.png -text svneol=unset#unset
+plugins/coclico/forumml/www/themes/default/images/ic/resultset_first_disabled.png -text svneol=unset#unset
+plugins/coclico/forumml/www/themes/default/images/ic/resultset_last.png -text svneol=unset#unset
+plugins/coclico/forumml/www/themes/default/images/ic/resultset_last_disabled.png -text svneol=unset#unset
+plugins/coclico/forumml/www/themes/default/images/ic/resultset_next.png -text svneol=unset#unset
+plugins/coclico/forumml/www/themes/default/images/ic/resultset_next_disabled.png -text svneol=unset#unset
+plugins/coclico/forumml/www/themes/default/images/ic/resultset_previous.png -text svneol=unset#unset
+plugins/coclico/forumml/www/themes/default/images/ic/resultset_previous_disabled.png -text svneol=unset#unset
+plugins/coclico/forumml/www/themes/default/images/ic/spinner-greenie.gif -text svneol=unset#unset
+plugins/coclico/forumml/www/themes/default/images/ic/trash.png -text svneol=unset#unset
+plugins/coclico/forumml/www/upload.php -text
+plugins/coclico/mailman/README.txt -text
+plugins/coclico/mailman/bin/db-delete.pl -text
+plugins/coclico/mailman/bin/db-upgrade.pl -text
+plugins/coclico/mailman/common/mailman-init.php -text
+plugins/coclico/mailman/cronjobs/manage_mailmanlists.php -text
+plugins/coclico/mailman/db/mailman-init.sql -text
+plugins/coclico/mailman/debian/README.Debian -text
+plugins/coclico/mailman/debian/README.source -text
+plugins/coclico/mailman/debian/changelog -text
+plugins/coclico/mailman/debian/compat -text
+plugins/coclico/mailman/debian/control -text
+plugins/coclico/mailman/debian/copyright -text
+plugins/coclico/mailman/debian/docs -text
+plugins/coclico/mailman/debian/dsf-in/plugin-mailman.postinst -text
+plugins/coclico/mailman/debian/dsf-in/plugin-mailman.prerm -text
+plugins/coclico/mailman/debian/po/templates.pot -text
+plugins/coclico/mailman/debian/rules -text
+plugins/coclico/mailman/debian/source/format -text
+plugins/coclico/mailman/etc/httpd.d/200list.vhost -text
+plugins/coclico/mailman/etc/httpd.d/20list -text
+plugins/coclico/mailman/etc/httpd.d/20zlist.vhost -text
+plugins/coclico/mailman/etc/httpd.d/21list.vhost.ssl -text
+plugins/coclico/mailman/etc/httpd.d/62plugin-list-mailman -text
+plugins/coclico/mailman/etc/plugins/mailman/config.php -text
+plugins/coclico/mailman/include/BackendMailmanList.class.php -text
+plugins/coclico/mailman/include/MailmanList.class.php -text
+plugins/coclico/mailman/include/MailmanListDao.class.php -text
+plugins/coclico/mailman/include/MailmanListFactory.class.php -text
+plugins/coclico/mailman/include/MailmanPluginDescriptor.class.php -text
+plugins/coclico/mailman/include/MailmanPluginInfo.class.php -text
+plugins/coclico/mailman/include/MailsForUser.class.php -text
+plugins/coclico/mailman/include/events/SystemEvent_MAILMAN_LIST_CREATE.class.php -text
+plugins/coclico/mailman/include/events/SystemEvent_MAILMAN_LIST_DELETE.class.php -text
+plugins/coclico/mailman/include/mailman-init.php -text
+plugins/coclico/mailman/include/mailmanPlugin.class.php -text
+plugins/coclico/mailman/packaging/control/000source -text
+plugins/coclico/mailman/packaging/control/222plugin-mailman -text
+plugins/coclico/mailman/packaging/control/222plugin-mailman.shortdesc -text
+plugins/coclico/mailman/packaging/cron.d/plugin-mailman -text
+plugins/coclico/mailman/packaging/dirs/plugin-mailman -text
+plugins/coclico/mailman/packaging/docs/plugin-mailman -text
+plugins/coclico/mailman/packaging/install/plugin-mailman -text
+plugins/coclico/mailman/packaging/links/plugin-mailman -text
+plugins/coclico/mailman/translations/en.po -text
+plugins/coclico/mailman/translations/gforge.pot -text
+plugins/coclico/mailman/usr/lib/mailman/Mailman/ExternalConnector.py -text
+plugins/coclico/mailman/usr/lib/mailman/Mailman/ForgeSecurityManager.py -text
+plugins/coclico/mailman/usr/lib/mailman/Mailman/MySQLConnector.py -text
+plugins/coclico/mailman/usr/lib/mailman/Mailman/PsycopgConnector.py -text
+plugins/coclico/mailman/utils/manage-translations.sh -text
+plugins/coclico/mailman/var/lib/mailman/lists/extend.py -text
+plugins/coclico/mailman/www/admin/deletelist.php -text
+plugins/coclico/mailman/www/admin/index.php -text
+plugins/coclico/mailman/www/index.html -text
+plugins/coclico/mailman/www/index.php -text
+plugins/coclico/mailman/www/mailman_utils.php -text
+plugins/coclico/mailman/www/themes/default/images/ic/add.png -text svneol=unset#unset
+plugins/coclico/mailman/www/themes/default/images/ic/delete.png -text svneol=unset#unset
+plugins/coclico/mailman/www/themes/default/images/ic/tick.png -text svneol=unset#unset
+plugins/templates/createplugin.sh -text
+plugins/templates/helloworld/bin/db-delete.pl -text
+plugins/templates/helloworld/bin/db-upgrade.pl -text
+plugins/templates/helloworld/cronjobs/manage_helloworld.php -text
+plugins/templates/helloworld/debian/README.Debian -text
+plugins/templates/helloworld/debian/README.source -text
+plugins/templates/helloworld/debian/changelog -text
+plugins/templates/helloworld/debian/compat -text
+plugins/templates/helloworld/debian/control -text
+plugins/templates/helloworld/debian/copyright -text
+plugins/templates/helloworld/debian/docs -text
+plugins/templates/helloworld/debian/dsf-in/plugin-helloworld.postinst -text
+plugins/templates/helloworld/debian/dsf-in/plugin-helloworld.prerm -text
+plugins/templates/helloworld/debian/po/templates.pot -text
+plugins/templates/helloworld/debian/rules -text
+plugins/templates/helloworld/debian/source/format -text
+plugins/templates/helloworld/etc/httpd.d/62plugin-helloworld -text
+plugins/templates/helloworld/packaging/control/000source -text
+plugins/templates/helloworld/packaging/control/222plugin-helloworld -text
+plugins/templates/helloworld/packaging/control/222plugin-helloworld.shortdesc -text
+plugins/templates/helloworld/packaging/dirs/plugin-helloworld -text
+plugins/templates/helloworld/packaging/docs/plugin-helloworld -text
+plugins/templates/helloworld/packaging/install/plugin-helloworld -text
+plugins/templates/helloworld/packaging/links/plugin-helloworld -text
+plugins/templates/helloworld/translations/en.po -text
+plugins/templates/helloworld/translations/gforge.pot -text
+plugins/templates/helloworld/utils/manage-translations.sh -text
+plugins/templates/helloworld/www/admin/index.php -text
+plugins/templates/scmcpold/common/CpoldPlugin.class.php -text
+plugins/templates/scmcpold/common/scmcpold-init.php -text
+plugins/templates/scmcpold/etc/plugins/scmcpold/config.php -text
+plugins/templates/scmcpold/packaging/control/137plugin-scmcpold -text
+plugins/templates/scmcpold/packaging/control/137plugin-scmcpold.shortdesc -text
+plugins/templates/scmcpold/packaging/dirs/plugin-scmcpold -text
+plugins/templates/scmcpold/packaging/install/plugin-scmcpold -text
tests/AllFullTests.php -text
tests/AllTests.php -text
tests/SeleniumTests.php -text
tests/TarCentos52Tests.php -text
-tests/build/documentation/AllTests.php -text
-tests/build/documentation/DocumentationTests.php -text
-tests/build/packages/AllTests.php -text
-tests/build/packages/BuildTests.php -text
-tests/code/deprecations/AllTests.php -text
-tests/code/deprecations/DeprecationsTests.php -text
-tests/code/syntax/AllTests.php -text
-tests/code/syntax/SyntaxTests.php -text
+tests/build/documentation/DocumentationTest.php -text
+tests/build/packages/BuildTest.php -text
+tests/code/deprecations/DeprecationsTest.php -text
+tests/code/syntax/SyntaxTest.php -text
tests/func/AllTests.php -text
-tests/func/Forums/AllTests.php -text
-tests/func/Forums/forums.php -text
-tests/func/News/AllTests.php -text
-tests/func/News/news.php -text
+tests/func/Forums/forumsTest.php -text
+tests/func/News/newsTest.php -text
+tests/func/PluginsBlocks/blocksTest.php -text
tests/func/README.TXT -text
-tests/func/Site/AllTests.php -text
-tests/func/Site/login.php -text
-tests/func/Site/projects.php -text
+tests/func/Site/loginTest.php -text
+tests/func/Site/projectsTest.php -text
tests/func/Site/top.php -text
-tests/func/Site/trove.php -text
+tests/func/Site/troveTest.php -text
tests/func/Soap/AllTests.php -text
tests/func/Soap/checks.php -text
tests/func/Soap/login.php -text
tests/func/Soap/usergroup.php -text
-tests/func/Tasks/AllTests.php -text
-tests/func/Tasks/createTask.php -text
+tests/func/Tasks/createTaskTest.php -text
tests/func/Testing/SeleniumGforge.php -text
tests/func/Testing/SeleniumRemoteSuite.php -text
-tests/func/Trackers/AllTests.php -text
-tests/func/Trackers/relation.php -text
-tests/func/Trackers/trackers.php -text
-tests/func/Trackers/workflow.php -text
+tests/func/Trackers/relationTest.php -text
+tests/func/Trackers/trackersTest.php -text
+tests/func/Trackers/workflowTest.php -text
tests/func/config.php.sample -text
tests/func/config.php.tests -text
tests/func/db_reload.php -text
@@ -3915,11 +4203,11 @@ tests/scripts/start_vm.sh -text
tests/scripts/start_vz.sh -text
tests/scripts/stop_vm.sh -text
tests/scripts/stop_vz.sh -text
-tests/unit/AllTests.php -text
-tests/unit/utils/AllTests.php -text
-tests/unit/utils/DbUtilsTests.php -text
-tests/unit/utils/TextSanitizerTests.php -text
-tests/unit/utils/UtilsTests.php -text
+tests/unit/config/ConfigTest.php -text
+tests/unit/utils/DbUtilsTest.php -text
+tests/unit/utils/HtmlPurifierTest.php -text
+tests/unit/utils/TextSanitizerTest.php -text
+tests/unit/utils/UtilsTest.php -text
tools/check_and_update_forum_role_settings.php -text
tools/export-tracker.tcl -text
tools/jpgraph_pietest.php -text
@@ -3967,4 +4255,5 @@ tools/tab2po/src/test/resources/translations/en.po.new -text
tools/tab2po/src/test/resources/translations/fr.po -text
tools/tab2po/src/test/resources/translations/fr.po.new -text
tools/tab2po/src/test/resources/translations/gforge.pot -text
+tools/unify_config.sh -text
tools/update-gettext-files.sh -text
diff --git a/3rd-party/Makefile b/3rd-party/Makefile
new file mode 100644
index 0000000000..c6e32d5d09
--- /dev/null
+++ b/3rd-party/Makefile
@@ -0,0 +1,9 @@
+DIRLIST=db2latex-xsl htmlpurifier mailman nusoap php-apache-log4php php-mail-mbox
+
+%:
+ @for dir in $(DIRLIST); do \
+ cd $(CURDIR)/$$dir ; $(MAKE) $@ ; \
+ done
+
+.PHONY:$(DIRLIST)
+
diff --git a/3rd-party/PEAR/Archive_Tar-1.3.3.tgz b/3rd-party/PEAR/Archive_Tar-1.3.3.tgz
new file mode 100644
index 0000000000..2cc3c08fb6
Binary files /dev/null and b/3rd-party/PEAR/Archive_Tar-1.3.3.tgz differ
diff --git a/3rd-party/PEAR/Console_Getopt-1.2.3.tgz b/3rd-party/PEAR/Console_Getopt-1.2.3.tgz
new file mode 100644
index 0000000000..156a0740d6
Binary files /dev/null and b/3rd-party/PEAR/Console_Getopt-1.2.3.tgz differ
diff --git a/3rd-party/PEAR/Mail-1.1.14.tgz b/3rd-party/PEAR/Mail-1.1.14.tgz
new file mode 100644
index 0000000000..f9283de7fa
Binary files /dev/null and b/3rd-party/PEAR/Mail-1.1.14.tgz differ
diff --git a/3rd-party/PEAR/Mail_Mbox-0.6.1.tgz b/3rd-party/PEAR/Mail_Mbox-0.6.1.tgz
new file mode 100644
index 0000000000..ee063b089d
Binary files /dev/null and b/3rd-party/PEAR/Mail_Mbox-0.6.1.tgz differ
diff --git a/3rd-party/PEAR/Mail_Mime-1.5.2.tgz b/3rd-party/PEAR/Mail_Mime-1.5.2.tgz
new file mode 100644
index 0000000000..c288ade229
Binary files /dev/null and b/3rd-party/PEAR/Mail_Mime-1.5.2.tgz differ
diff --git a/3rd-party/PEAR/Mail_mimeDecode-1.5.0.tgz b/3rd-party/PEAR/Mail_mimeDecode-1.5.0.tgz
new file mode 100644
index 0000000000..5b12f7c7dd
Binary files /dev/null and b/3rd-party/PEAR/Mail_mimeDecode-1.5.0.tgz differ
diff --git a/3rd-party/PEAR/Structures_Graph-1.0.2.tgz b/3rd-party/PEAR/Structures_Graph-1.0.2.tgz
new file mode 100644
index 0000000000..f46064632a
Binary files /dev/null and b/3rd-party/PEAR/Structures_Graph-1.0.2.tgz differ
diff --git a/3rd-party/PEAR/XML_Util-1.2.1.tgz b/3rd-party/PEAR/XML_Util-1.2.1.tgz
new file mode 100644
index 0000000000..6338719c66
Binary files /dev/null and b/3rd-party/PEAR/XML_Util-1.2.1.tgz differ
diff --git a/3rd-party/db2latex-xsl/Makefile b/3rd-party/db2latex-xsl/Makefile
new file mode 100644
index 0000000000..1459d96fba
--- /dev/null
+++ b/3rd-party/db2latex-xsl/Makefile
@@ -0,0 +1,22 @@
+DISTDEBIAN=$(shell [ -f /etc/debian_version ] && echo debian)
+DISTREDHAT=$(shell grep -qi 'Red Hat' /etc/issue && echo rh)
+DISTSUSE=$(shell grep -qi 'SuSE' /etc/issue && echo rh)
+DIST=$(DISTDEBIAN)$(DISTREDHAT)$(DISTSUSE)
+
+PKGDIR=db2latex-xsl-0.8pre1
+PKGDSC=$(shell ls *.dsc | sort -V -r | head -1)
+MINOR=$(shell grep ^Version $(PKGDSC) | head -1 | sed 's/.[^-]*-\(.*\)/\1/')
+PARAM=PKGDIR=$(PKGDIR) svnrev=$(MINOR)
+
+default: $(PKGDIR)
+ @make -f Makefile.$(DIST) $(PARAM) default
+ @cat ../../Makefile.$(DIST) | grep '^.*:.*#$$' | sed 's/FUSIONFORGE/$(FUSIONFORGE)/' | sed 's/^\(.*:\).*#\(.*\)#$$/\1 \2/'
+
+%: $(PKGDIR)
+ @make -f Makefile.$(DIST) $(PARAM) $@
+
+$(PKGDIR):
+ dpkg-source -x $(PKGDSC)
+
+clean:
+ rm -rf $(PKGDIR)
diff --git a/3rd-party/db2latex-xsl/Makefile.debian b/3rd-party/db2latex-xsl/Makefile.debian
new file mode 100644
index 0000000000..1219f2c0e9
--- /dev/null
+++ b/3rd-party/db2latex-xsl/Makefile.debian
@@ -0,0 +1 @@
+include ../../Makefile.debian
diff --git a/3rd-party/db2latex-xsl/db2latex-xsl_0.8pre1-6.1.diff.gz b/3rd-party/db2latex-xsl/db2latex-xsl_0.8pre1-6.1.diff.gz
new file mode 100644
index 0000000000..1383ac58b3
Binary files /dev/null and b/3rd-party/db2latex-xsl/db2latex-xsl_0.8pre1-6.1.diff.gz differ
diff --git a/3rd-party/db2latex-xsl/db2latex-xsl_0.8pre1-6.1.dsc b/3rd-party/db2latex-xsl/db2latex-xsl_0.8pre1-6.1.dsc
new file mode 100644
index 0000000000..5b42147525
--- /dev/null
+++ b/3rd-party/db2latex-xsl/db2latex-xsl_0.8pre1-6.1.dsc
@@ -0,0 +1,18 @@
+Format: 1.0
+Source: db2latex-xsl
+Binary: db2latex-xsl, db2latex-xsl-doc
+Architecture: all
+Version: 0.8pre1-6.1
+Maintainer: Debian XML/SGML Group
+Uploaders: W. Borgert , Ardo van Rangelrooij
+Standards-Version: 3.6.1
+Build-Depends-Indep: debhelper (>= 4.2), docbook-xsl (>= 1.64.1.0), xml-core, xsltproc, cdbs (>= 0.4.8)
+Checksums-Sha1:
+ 9c4b367b21552b7205ec242c559dc96ccdae9ed8 3527840 db2latex-xsl_0.8pre1.orig.tar.gz
+ e59b1e861d39b5fbb9d65d6b3cf1428f1bace45a 7030 db2latex-xsl_0.8pre1-6.1.diff.gz
+Checksums-Sha256:
+ 57be6b32779c75274764faac95603d8042538ebf14f6ba69cb7bc8fe45bb5a82 3527840 db2latex-xsl_0.8pre1.orig.tar.gz
+ 86af5b8c402ec188efd067bc147cde902a461d3c02b63c347cdedaa6ca89ae7e 7030 db2latex-xsl_0.8pre1-6.1.diff.gz
+Files:
+ d59d135fb0a0042c5ee435296e0c29c0 3527840 db2latex-xsl_0.8pre1.orig.tar.gz
+ 08581cb81ffa865000bc855c314d3d9d 7030 db2latex-xsl_0.8pre1-6.1.diff.gz
diff --git a/3rd-party/db2latex-xsl/db2latex-xsl_0.8pre1-6.2.diff.gz b/3rd-party/db2latex-xsl/db2latex-xsl_0.8pre1-6.2.diff.gz
new file mode 100644
index 0000000000..a6bbb230bf
Binary files /dev/null and b/3rd-party/db2latex-xsl/db2latex-xsl_0.8pre1-6.2.diff.gz differ
diff --git a/3rd-party/db2latex-xsl/db2latex-xsl_0.8pre1-6.2.dsc b/3rd-party/db2latex-xsl/db2latex-xsl_0.8pre1-6.2.dsc
new file mode 100644
index 0000000000..a7ee640008
--- /dev/null
+++ b/3rd-party/db2latex-xsl/db2latex-xsl_0.8pre1-6.2.dsc
@@ -0,0 +1,18 @@
+Format: 1.0
+Source: db2latex-xsl
+Binary: db2latex-xsl, db2latex-xsl-doc
+Architecture: all
+Version: 0.8pre1-6.2
+Maintainer: Debian XML/SGML Group
+Uploaders: W. Borgert , Ardo van Rangelrooij
+Standards-Version: 3.6.1
+Build-Depends: debhelper (>= 4.2), docbook-xsl (>= 1.64.1.0), xml-core, xsltproc, cdbs (>= 0.4.8)
+Checksums-Sha1:
+ 9c4b367b21552b7205ec242c559dc96ccdae9ed8 3527840 db2latex-xsl_0.8pre1.orig.tar.gz
+ e65f281045cbc39ceb2f224d87766421018fbb99 7230 db2latex-xsl_0.8pre1-6.2.diff.gz
+Checksums-Sha256:
+ 57be6b32779c75274764faac95603d8042538ebf14f6ba69cb7bc8fe45bb5a82 3527840 db2latex-xsl_0.8pre1.orig.tar.gz
+ fcf9e1c4612e2a15cf9b34537ddf92b8c8eb1065082916d7f3e05dc8af79be93 7230 db2latex-xsl_0.8pre1-6.2.diff.gz
+Files:
+ d59d135fb0a0042c5ee435296e0c29c0 3527840 db2latex-xsl_0.8pre1.orig.tar.gz
+ f26a33a09b1ec6b3f3597edc3cb11e6b 7230 db2latex-xsl_0.8pre1-6.2.diff.gz
diff --git a/3rd-party/db2latex-xsl/db2latex-xsl_0.8pre1.orig.tar.gz b/3rd-party/db2latex-xsl/db2latex-xsl_0.8pre1.orig.tar.gz
new file mode 100644
index 0000000000..5012eb48fa
Binary files /dev/null and b/3rd-party/db2latex-xsl/db2latex-xsl_0.8pre1.orig.tar.gz differ
diff --git a/3rd-party/htmlpurifier/Makefile b/3rd-party/htmlpurifier/Makefile
new file mode 100644
index 0000000000..d61d9de47a
--- /dev/null
+++ b/3rd-party/htmlpurifier/Makefile
@@ -0,0 +1,26 @@
+DISTDEBIAN=$(shell [ -f /etc/debian_version ] && echo debian)
+DISTREDHAT=$(shell grep -qi 'Red Hat' /etc/issue && echo rh)
+DISTSUSE=$(shell grep -qi 'SuSE' /etc/issue && echo rh)
+DIST=$(DISTDEBIAN)$(DISTREDHAT)$(DISTSUSE)
+
+DEBIANLIST=1lenny
+UBUNTULIST="1jaunty 1karmic 1lucid"
+
+PKGDIR=php-htmlpurifier-4.0.0+dfsg1
+PKGDSC=$(shell ls *.dsc | sort -V -r | head -1)
+MINOR=$(shell grep ^Version $(PKGDSC) | head -1 | sed 's/.[^-]*-\(.*\)/\1/')
+PARAM=PKGDIR=$(PKGDIR) svnrev=$(MINOR) DEBIANLIST=$(DEBIANLIST) UBUNTULIST=$(UBUNTULIST)
+
+default: $(PKGDIR)
+ @make -f Makefile.$(DIST) $(PARAM) default
+ @cat ../../Makefile.$(DIST) | grep '^.*:.*#$$' | sed 's/FUSIONFORGE/$(FUSIONFORGE)/' | sed 's/^\(.*:\).*#\(.*\)#$$/\1 \2/'
+
+%: $(PKGDIR)
+ @make -f Makefile.$(DIST) $(PARAM) $@
+
+$(PKGDIR):
+ #dget http://ftp.fr.debian.org/debian/pool/main/p/php-htmlpurifier/php-htmlpurifier_4.0.0+dfsg1-1.dsc
+ dpkg-source -x $(PKGDSC)
+
+clean:
+ rm -rf $(PKGDIR)
diff --git a/3rd-party/htmlpurifier/Makefile.debian b/3rd-party/htmlpurifier/Makefile.debian
new file mode 100644
index 0000000000..1219f2c0e9
--- /dev/null
+++ b/3rd-party/htmlpurifier/Makefile.debian
@@ -0,0 +1 @@
+include ../../Makefile.debian
diff --git a/3rd-party/htmlpurifier/htmlpurifier-4.0.0.tar.gz b/3rd-party/htmlpurifier/htmlpurifier-4.0.0.tar.gz
new file mode 100644
index 0000000000..7d955fca0e
Binary files /dev/null and b/3rd-party/htmlpurifier/htmlpurifier-4.0.0.tar.gz differ
diff --git a/3rd-party/htmlpurifier/htmlpurifier.spec b/3rd-party/htmlpurifier/htmlpurifier.spec
index 7cd2087bfc..cc2c0aa0f2 100644
--- a/3rd-party/htmlpurifier/htmlpurifier.spec
+++ b/3rd-party/htmlpurifier/htmlpurifier.spec
@@ -1,7 +1,7 @@
Summary: HTML Purifier is a standards-compliant HTML filter library written in PHP.
Name: htmlpurifier
Version: 4.0.0
-Release: 0
+Release: 1
License: LGPL
Group: Development/Languages
URL: http://htmlpurifier.org/
@@ -12,7 +12,7 @@ Source: http://htmlpurifier.org/releases/%{name}-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
BuildArch: noarch
-Requires: webserver, php
+Requires: php >= 5.0.5
%description
HTML Purifier is a standards-compliant HTML filter library written in PHP. HTML
@@ -59,7 +59,10 @@ This package includes the documentation for %{name}.
%doc art benchmarks configdoc CREDITS docs INSTALL INSTALL.fr.utf8 LICENSE NEWS README TODO VERSION WHATSNEW WYSIWYG
%changelog
-* Thu Sep 24 2009 Alain Peyrat - 4.0.0
+* Sun Mar 28 2010 Alain Peyrat - 4.0.0-1
+- Removed requirement to webserver, set php >= 5.0.5
+
+* Thu Sep 24 2009 Alain Peyrat - 4.0.0-0
- Updated to v4.0.0
- Changed installation path to /usr/share/php to use the share path with debian.
diff --git a/3rd-party/htmlpurifier/php-htmlpurifier_4.0.0+dfsg1-1.diff.gz b/3rd-party/htmlpurifier/php-htmlpurifier_4.0.0+dfsg1-1.diff.gz
new file mode 100644
index 0000000000..10822fb78d
Binary files /dev/null and b/3rd-party/htmlpurifier/php-htmlpurifier_4.0.0+dfsg1-1.diff.gz differ
diff --git a/3rd-party/htmlpurifier/php-htmlpurifier_4.0.0+dfsg1-1.dsc b/3rd-party/htmlpurifier/php-htmlpurifier_4.0.0+dfsg1-1.dsc
new file mode 100644
index 0000000000..41c2c098d9
--- /dev/null
+++ b/3rd-party/htmlpurifier/php-htmlpurifier_4.0.0+dfsg1-1.dsc
@@ -0,0 +1,40 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA384
+
+Format: 1.0
+Source: php-htmlpurifier
+Binary: php-htmlpurifier
+Architecture: all
+Version: 4.0.0+dfsg1-1
+Maintainer: Christian Bayle
+Uploaders: Thorsten Glaser , Roland Mas
+Homepage: http://htmlpurifier.org/
+Standards-Version: 3.8.4
+Build-Depends: debhelper (>= 5)
+Checksums-Sha1:
+ d446f6ce70ecdc0e87b06f5b1d097e4f2d52ce91 548560 php-htmlpurifier_4.0.0+dfsg1.orig.tar.gz
+ 73cf2be794f7f1b9f4bbde5a19063f314470a369 2954 php-htmlpurifier_4.0.0+dfsg1-1.diff.gz
+Checksums-Sha256:
+ 2d5ad322d5510e98d10513eb6f604cc83819550d92bd87b89202399889225ceb 548560 php-htmlpurifier_4.0.0+dfsg1.orig.tar.gz
+ a0802f460ae3b6bb130700ee6d6155de6682314502607b49129615d89ec9a334 2954 php-htmlpurifier_4.0.0+dfsg1-1.diff.gz
+Files:
+ 33435e8b8e0077913ae147ebb4ff4336 548560 php-htmlpurifier_4.0.0+dfsg1.orig.tar.gz
+ f7a74ce3da04e8110c9977b868d6d83a 2954 php-htmlpurifier_4.0.0+dfsg1-1.diff.gz
+
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.7 (MirBSD)
+
+iQIVAwUBS5+TPHa1NLLpkAfgAQmKKRAAvubXPB+puP8i17B+2n44Al7kNA8CddNd
+AfrIYS3lC2MopImQgegTJyNlTwjd8bMouQYEX5y1ZGtvjr1zHp/r2aWtjwqQmKjf
+Lr/F0DxjP1GNOwjbhR3bEy8gGqxGJ6SdSXaClIrYdDTQEfy51SGbOuiljb5wckxh
+GF76wuV7DdtI2T7lM7jwxCkGMPkhCp9hEc+14am5WilLvAEa4QcIn3oTw2aoK2lA
+/ggaKckV9RSfx+DPEJkwHV33tF/Wyqw/02dDKkc8EOkiOAD2bMfqJXz7g8YItzok
+lU9DcNmYu9GcM2MwI3yIrcMuZ72A5VZ3Ui/jxHjKe0/mjBwLt7aEN6hy1zIOHDQQ
+DLmjbBi9+7qFrbSv1ZG4eGsVEvSwskjvVVWZlMZfH2o1vOteFCuxbrDXHcnymDFT
+mCDtXfD6xF7Z2TBGhm9cmtrkVmMtYPVy1PHR3zvAhm6Kop81eDwpNGsJg78O/9L2
+tHO/iKliq7paEgz5GsfkmJREPboE9B2Mvnxr4RP3ksmS3pXy2MEQaoENXlNLn4h7
+JBoDeWzvR8O7lQPeMOuDJya/N8xs3ygj7UjVuyW59notEsV16/z0cU14rIjPENbu
+a2+8/ieOchoz5kb9gVnxapEnXgFl7MGBaO2Z8q/AAcKsjuC/s9x7wLplM2kT8Km7
+gjP/htra8Z8=
+=L19U
+-----END PGP SIGNATURE-----
diff --git a/3rd-party/htmlpurifier/php-htmlpurifier_4.0.0+dfsg1.orig.tar.gz b/3rd-party/htmlpurifier/php-htmlpurifier_4.0.0+dfsg1.orig.tar.gz
new file mode 100644
index 0000000000..76d66a146a
Binary files /dev/null and b/3rd-party/htmlpurifier/php-htmlpurifier_4.0.0+dfsg1.orig.tar.gz differ
diff --git a/3rd-party/mailman/Makefile b/3rd-party/mailman/Makefile
new file mode 100644
index 0000000000..a4804f2c67
--- /dev/null
+++ b/3rd-party/mailman/Makefile
@@ -0,0 +1,23 @@
+DISTDEBIAN=$(shell [ -f /etc/debian_version ] && echo debian)
+DISTREDHAT=$(shell grep -qi 'Red Hat' /etc/issue && echo rh)
+DISTSUSE=$(shell grep -qi 'SuSE' /etc/issue && echo rh)
+DIST=$(DISTDEBIAN)$(DISTREDHAT)$(DISTSUSE)
+
+PKGDIR=mailman-2.1.13
+PKGDSC=$(shell ls *.dsc | sort -V -r | head -1)
+MINOR=$(shell grep ^Version $(PKGDSC) | sed 's/.[^-]*-\(.*\)/\1/')
+
+PARAM=PKGDIR=$(PKGDIR) svnrev=$(MINOR)
+
+default: $(PKGDIR)
+ @make -f Makefile.$(DIST) $(PARAM) default
+ @cat ../../Makefile.$(DIST) | grep '^.*:.*#$$' | sed 's/FUSIONFORGE/$(FUSIONFORGE)/' | sed 's/^\(.*:\).*#\(.*\)#$$/\1 \2/'
+
+%: $(PKGDIR)
+ @make -f Makefile.$(DIST) $(PARAM) $@
+
+$(PKGDIR):
+ dpkg-source -x $(PKGDSC)
+
+clean:
+ rm -rf $(PKGDIR)
diff --git a/3rd-party/mailman/Makefile.debian b/3rd-party/mailman/Makefile.debian
new file mode 100644
index 0000000000..1219f2c0e9
--- /dev/null
+++ b/3rd-party/mailman/Makefile.debian
@@ -0,0 +1 @@
+include ../../Makefile.debian
diff --git a/3rd-party/mailman/mailman_2.1.13-2.diff.gz b/3rd-party/mailman/mailman_2.1.13-2.diff.gz
new file mode 100644
index 0000000000..43efc80482
Binary files /dev/null and b/3rd-party/mailman/mailman_2.1.13-2.diff.gz differ
diff --git a/3rd-party/mailman/mailman_2.1.13-2.dsc b/3rd-party/mailman/mailman_2.1.13-2.dsc
new file mode 100644
index 0000000000..2bdd39fa2b
--- /dev/null
+++ b/3rd-party/mailman/mailman_2.1.13-2.dsc
@@ -0,0 +1,37 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA256
+
+Format: 1.0
+Source: mailman
+Binary: mailman
+Architecture: any
+Version: 1:2.1.13-2
+Maintainer: Mailman for Debian
+Uploaders: Lionel Elie Mamane , Thijs Kinkhorst , Hector Garcia
+Homepage: http://www.list.org/
+Standards-Version: 3.8.4
+Vcs-Browser: http://svn.debian.org/wsvn/pkg-mailman/trunk
+Vcs-Svn: svn://svn.debian.org/svn/pkg-mailman/trunk
+Build-Depends: debhelper (>= 7), autoconf, python-dev, python-support, quilt
+Checksums-Sha1:
+ 923dd78a17cbab576354b53a80443fe05f134398 8166504 mailman_2.1.13.orig.tar.gz
+ 7397928c576d777bbb0e8d95d587536a0c1bef4e 131643 mailman_2.1.13-2.diff.gz
+Checksums-Sha256:
+ ddab5169c851e49134d8e58fd0d5fd3b920d8ddb5f52582c2ec95076c746a25e 8166504 mailman_2.1.13.orig.tar.gz
+ 59f24769e9c82e42c750bded9d2b552f1defe384432609cc95fcb0db0fea4a2c 131643 mailman_2.1.13-2.diff.gz
+Files:
+ 3235323ccb3e0135c10b7c66a440390b 8166504 mailman_2.1.13.orig.tar.gz
+ 56bf65220fc3946f37b258dcc4938692 131643 mailman_2.1.13-2.diff.gz
+Python-Version: current
+
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.10 (GNU/Linux)
+
+iQEcBAEBCAAGBQJLpTgbAAoJECIIoQCMVaAcduUH/07u08FZvhthHh/5ZVYhnDlR
+oWpOIvxpF6mWQdBuPAXcVpyLbyE970M5pmRaKdeq/sRAvWZSRPn2U+1vvxcVvSGq
+tVHONts1hGcZPoBe4fE4jS19WIaCPEFEcs872FGo2eO6l6EjJYCmCCzwvGFkVjeE
+hPv1egCFdDvYwUApJPBzn5qo9U9Ec2aDjXJiT6rpKQaZ1tzxVUyJwIvn7Pywo8OV
+BXt+4fRwTBXdPLANqAFU0M1EZ4JK6hAHYss0tIANwq9Ryc7eMdMi77hidBjHqCXA
+R2kLNSGY4lRcajde9uto4d5bWuiwxoBGKG+1iOC/bVr51NBitHJvDCY07WYc5Vc=
+=QO5q
+-----END PGP SIGNATURE-----
diff --git a/3rd-party/mailman/mailman_2.1.13-2coclico1.diff.gz b/3rd-party/mailman/mailman_2.1.13-2coclico1.diff.gz
new file mode 100644
index 0000000000..a8aa570f25
Binary files /dev/null and b/3rd-party/mailman/mailman_2.1.13-2coclico1.diff.gz differ
diff --git a/3rd-party/mailman/mailman_2.1.13-2coclico1.dsc b/3rd-party/mailman/mailman_2.1.13-2coclico1.dsc
new file mode 100644
index 0000000000..05ceffd1f7
--- /dev/null
+++ b/3rd-party/mailman/mailman_2.1.13-2coclico1.dsc
@@ -0,0 +1,22 @@
+Format: 1.0
+Source: mailman
+Binary: mailman
+Architecture: any
+Version: 1:2.1.13-2coclico1
+Maintainer: Mailman for Debian
+Uploaders: Lionel Elie Mamane , Thijs Kinkhorst , Hector Garcia
+Homepage: http://www.list.org/
+Standards-Version: 3.8.4
+Vcs-Browser: http://svn.debian.org/wsvn/pkg-mailman/trunk
+Vcs-Svn: svn://svn.debian.org/svn/pkg-mailman/trunk
+Build-Depends: debhelper (>= 7), autoconf, python-dev, python-support, quilt
+Checksums-Sha1:
+ 923dd78a17cbab576354b53a80443fe05f134398 8166504 mailman_2.1.13.orig.tar.gz
+ 97781d4dc6a36dce57b71b44d9bdfc384f1a9da9 139836 mailman_2.1.13-2coclico1.diff.gz
+Checksums-Sha256:
+ ddab5169c851e49134d8e58fd0d5fd3b920d8ddb5f52582c2ec95076c746a25e 8166504 mailman_2.1.13.orig.tar.gz
+ 1ba62fd446610823c45e28ddbb6326f4024767894900d73b47cf4a78767d928c 139836 mailman_2.1.13-2coclico1.diff.gz
+Files:
+ 3235323ccb3e0135c10b7c66a440390b 8166504 mailman_2.1.13.orig.tar.gz
+ 7ec79a1898d811e3f86dbaff0373d4c7 139836 mailman_2.1.13-2coclico1.diff.gz
+Python-Version: current
diff --git a/3rd-party/mailman/mailman_2.1.13-2coclico4.diff.gz b/3rd-party/mailman/mailman_2.1.13-2coclico4.diff.gz
new file mode 100644
index 0000000000..b4bb8c407f
Binary files /dev/null and b/3rd-party/mailman/mailman_2.1.13-2coclico4.diff.gz differ
diff --git a/3rd-party/mailman/mailman_2.1.13-2coclico4.dsc b/3rd-party/mailman/mailman_2.1.13-2coclico4.dsc
new file mode 100644
index 0000000000..ce69cf78df
--- /dev/null
+++ b/3rd-party/mailman/mailman_2.1.13-2coclico4.dsc
@@ -0,0 +1,22 @@
+Format: 1.0
+Source: mailman
+Binary: mailman
+Architecture: any
+Version: 1:2.1.13-2coclico4
+Maintainer: Mailman for Debian
+Uploaders: Lionel Elie Mamane , Thijs Kinkhorst , Hector Garcia
+Homepage: http://www.list.org/
+Standards-Version: 3.8.4
+Vcs-Browser: http://svn.debian.org/wsvn/pkg-mailman/trunk
+Vcs-Svn: svn://svn.debian.org/svn/pkg-mailman/trunk
+Build-Depends: debhelper (>= 7), autoconf, python-dev, python-support, quilt
+Checksums-Sha1:
+ 923dd78a17cbab576354b53a80443fe05f134398 8166504 mailman_2.1.13.orig.tar.gz
+ fa0a0aa1a80544887dc7c40e82691dc7105fe23b 139926 mailman_2.1.13-2coclico4.diff.gz
+Checksums-Sha256:
+ ddab5169c851e49134d8e58fd0d5fd3b920d8ddb5f52582c2ec95076c746a25e 8166504 mailman_2.1.13.orig.tar.gz
+ f7cf76cbf6a24b84cf7d12640216ae58c109425b0f6228e8edb523d4041db562 139926 mailman_2.1.13-2coclico4.diff.gz
+Files:
+ 3235323ccb3e0135c10b7c66a440390b 8166504 mailman_2.1.13.orig.tar.gz
+ 65cf5ef0050e6cc460816799768bd692 139926 mailman_2.1.13-2coclico4.diff.gz
+Python-Version: current
diff --git a/3rd-party/mailman/mailman_2.1.13.orig.tar.gz b/3rd-party/mailman/mailman_2.1.13.orig.tar.gz
new file mode 100644
index 0000000000..3883b70974
Binary files /dev/null and b/3rd-party/mailman/mailman_2.1.13.orig.tar.gz differ
diff --git a/3rd-party/nusoap/Makefile b/3rd-party/nusoap/Makefile
new file mode 100644
index 0000000000..0ccfa4b18b
--- /dev/null
+++ b/3rd-party/nusoap/Makefile
@@ -0,0 +1,26 @@
+DISTDEBIAN=$(shell [ -f /etc/debian_version ] && echo debian)
+DISTREDHAT=$(shell grep -qi 'Red Hat' /etc/issue && echo rh)
+DISTSUSE=$(shell grep -qi 'SuSE' /etc/issue && echo rh)
+DIST=$(DISTDEBIAN)$(DISTREDHAT)$(DISTSUSE)
+
+DEBIANLIST=1lenny
+UBUNTULIST="1jaunty 1karmic"
+
+PKGDIR=nusoap-0.7.3
+PKGDSC=$(shell ls *.dsc | sort -V -r | head -1)
+MINOR=$(shell grep ^Version $(PKGDSC) | head -1 | sed 's/.[^-]*-\(.*\)/\1/')
+PARAM=PKGDIR=$(PKGDIR) svnrev=$(MINOR) DEBIANLIST=$(DEBIANLIST) UBUNTULIST=$(UBUNTULIST)
+
+default: $(PKGDIR)
+ @make -f Makefile.$(DIST) $(PARAM) default
+ @cat ../../Makefile.$(DIST) | grep '^.*:.*#$$' | sed 's/FUSIONFORGE/$(FUSIONFORGE)/' | sed 's/^\(.*:\).*#\(.*\)#$$/\1 \2/'
+
+%: $(PKGDIR)
+ @make -f Makefile.$(DIST) $(PARAM) $@
+
+$(PKGDIR):
+ #apt-get source nusoap
+ dpkg-source -x $(PKGDSC)
+
+clean:
+ rm -rf $(PKGDIR)
diff --git a/3rd-party/nusoap/Makefile.debian b/3rd-party/nusoap/Makefile.debian
new file mode 100644
index 0000000000..1219f2c0e9
--- /dev/null
+++ b/3rd-party/nusoap/Makefile.debian
@@ -0,0 +1 @@
+include ../../Makefile.debian
diff --git a/3rd-party/nusoap/nusoap_0.7.3-2.diff.gz b/3rd-party/nusoap/nusoap_0.7.3-2.diff.gz
new file mode 100644
index 0000000000..2f3dabd309
Binary files /dev/null and b/3rd-party/nusoap/nusoap_0.7.3-2.diff.gz differ
diff --git a/3rd-party/nusoap/nusoap_0.7.3-2.dsc b/3rd-party/nusoap/nusoap_0.7.3-2.dsc
new file mode 100644
index 0000000000..167165afdd
--- /dev/null
+++ b/3rd-party/nusoap/nusoap_0.7.3-2.dsc
@@ -0,0 +1,29 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+Format: 1.0
+Source: nusoap
+Binary: libnusoap-php
+Architecture: all
+Version: 0.7.3-2
+Maintainer: Olivier Berger
+Homepage: http://nusoap.sourceforge.net/
+Standards-Version: 3.8.3
+Build-Depends: debhelper (>= 5)
+Checksums-Sha1:
+ 2a65857099dda2145df822ffe73f9a5e3b454f5f 154560 nusoap_0.7.3.orig.tar.gz
+ a45358a4617cd056fb5f2a287ae9eb38028494d6 2847 nusoap_0.7.3-2.diff.gz
+Checksums-Sha256:
+ 6f08db4a587ee379986ac879871ad6d990804eca3c7556b0640863cf929920f5 154560 nusoap_0.7.3.orig.tar.gz
+ 9f38fdc01e94cb0d58fb0c01b930dc10cf338b569e82c9cac8081f37de5966e2 2847 nusoap_0.7.3-2.diff.gz
+Files:
+ 4a9c43dce007fd6214c48b8bd46838b4 154560 nusoap_0.7.3.orig.tar.gz
+ 74c27666f493e637ad23d3e154ac536c 2847 nusoap_0.7.3-2.diff.gz
+
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.10 (GNU/Linux)
+
+iD8DBQFLA/XsDqdWtRRIQ/URAuNJAKCGryXIh+gl6vmPNcLzUdfJFdL0/gCfaGoq
+mpxSj+AmQNw1w4f7pogkYw0=
+=clB3
+-----END PGP SIGNATURE-----
diff --git a/3rd-party/nusoap/nusoap_0.7.3.orig.tar.gz b/3rd-party/nusoap/nusoap_0.7.3.orig.tar.gz
new file mode 100644
index 0000000000..5f7e177dd5
Binary files /dev/null and b/3rd-party/nusoap/nusoap_0.7.3.orig.tar.gz differ
diff --git a/3rd-party/php-apache-log4php/Makefile b/3rd-party/php-apache-log4php/Makefile
new file mode 100644
index 0000000000..926e13356c
--- /dev/null
+++ b/3rd-party/php-apache-log4php/Makefile
@@ -0,0 +1,33 @@
+DISTDEBIAN=$(shell [ -f /etc/debian_version ] && echo debian)
+DISTREDHAT=$(shell grep -qi 'Red Hat' /etc/issue && echo rh)
+DISTSUSE=$(shell grep -qi 'SuSE' /etc/issue && echo rh)
+DIST=$(DISTDEBIAN)$(DISTREDHAT)$(DISTSUSE)
+
+DEBIANLIST="2squeeze 3sid"
+UBUNTULIST="1karmic 1lucid"
+
+PKGDIR=php-apache-log4php-2.0.0incubating
+PKGDSC=$(shell ls *.dsc | sort -V -r | head -1)
+MINOR=$(shell grep ^Version $(PKGDSC) | sed 's/.[^-]*-\(.*\)/\1/')
+PARAM=PKGDIR=$(PKGDIR) svnrev=$(MINOR) DEBIANLIST=$(DEBIANLIST) UBUNTULIST=$(UBUNTULIST)
+
+default: $(PKGDIR)
+ @make -f Makefile.$(DIST) $(PARAM) default
+ @cat ../../Makefile.$(DIST) | grep '^.*:.*#$$' | sed 's/FUSIONFORGE/$(FUSIONFORGE)/' | sed 's/^\(.*:\).*#\(.*\)#$$/\1 \2/'
+
+%: $(PKGDIR)
+ @make -f Makefile.$(DIST) $(PARAM) $@
+
+$(PKGDIR):
+ dpkg-source -x $(PKGDSC)
+
+clean:
+ rm -rf $(PKGDIR)
+
+
+apache-log4php-2.0.0-incubating-src.tar.gz:
+ wget http://mirror.mkhelif.fr/apache/incubator/log4php/2.0.0/apache-log4php-2.0.0-incubating-src.tar.gz
+
+php-apache-log4php_2.0.0incubating.orig.tar.gz:
+ wget http://mirror.mkhelif.fr/apache/incubator/log4php/2.0.0/Apache_log4php-2.0.0-incubating-pear.tgz
+ mv Apache_log4php-2.0.0-incubating-pear.tgz php-apache-log4php_2.0.0incubating.orig.tar.gz
diff --git a/3rd-party/php-apache-log4php/Makefile.debian b/3rd-party/php-apache-log4php/Makefile.debian
new file mode 100644
index 0000000000..1219f2c0e9
--- /dev/null
+++ b/3rd-party/php-apache-log4php/Makefile.debian
@@ -0,0 +1 @@
+include ../../Makefile.debian
diff --git a/3rd-party/php-apache-log4php/php-apache-log4php_2.0.0incubating-1.diff.gz b/3rd-party/php-apache-log4php/php-apache-log4php_2.0.0incubating-1.diff.gz
new file mode 100644
index 0000000000..14020f3a43
Binary files /dev/null and b/3rd-party/php-apache-log4php/php-apache-log4php_2.0.0incubating-1.diff.gz differ
diff --git a/3rd-party/php-apache-log4php/php-apache-log4php_2.0.0incubating-1.dsc b/3rd-party/php-apache-log4php/php-apache-log4php_2.0.0incubating-1.dsc
new file mode 100644
index 0000000000..c7af13509e
--- /dev/null
+++ b/3rd-party/php-apache-log4php/php-apache-log4php_2.0.0incubating-1.dsc
@@ -0,0 +1,17 @@
+Format: 1.0
+Source: php-apache-log4php
+Binary: php-apache-log4php
+Architecture: all
+Version: 2.0.0incubating-1
+Maintainer: Christian Bayle
+Standards-Version: 3.8.3
+Build-Depends: debhelper (>= 7), dh-make-php (>= 0.2.3), cdbs
+Checksums-Sha1:
+ ecad2e39262cdd8201c170a9982c415b002b220c 73329 php-apache-log4php_2.0.0incubating.orig.tar.gz
+ 6d6cd9cc767f1635988c0089fd2f1c3c2955b276 1080 php-apache-log4php_2.0.0incubating-1.diff.gz
+Checksums-Sha256:
+ e5c6196cb94ec506380c77462b0e37ecfaee5ec855933ea9bde3b6c21d46dbc2 73329 php-apache-log4php_2.0.0incubating.orig.tar.gz
+ 02aefa6128d4c32fd9bc714e2cd4abb88456c6713a734316a54b6ed8ff089392 1080 php-apache-log4php_2.0.0incubating-1.diff.gz
+Files:
+ bf636864d5ee57c18d4651af5b24d7e3 73329 php-apache-log4php_2.0.0incubating.orig.tar.gz
+ fc51db7ea4938a7f2bc28e6dc174d89b 1080 php-apache-log4php_2.0.0incubating-1.diff.gz
diff --git a/3rd-party/php-apache-log4php/php-apache-log4php_2.0.0incubating.orig.tar.gz b/3rd-party/php-apache-log4php/php-apache-log4php_2.0.0incubating.orig.tar.gz
new file mode 100644
index 0000000000..866a5f4ec1
Binary files /dev/null and b/3rd-party/php-apache-log4php/php-apache-log4php_2.0.0incubating.orig.tar.gz differ
diff --git a/3rd-party/php-jpgraph/jpgraph-1.5.2-php5_and_liberation_fonts.patch b/3rd-party/php-jpgraph/jpgraph-1.5.2-php5_and_liberation_fonts.patch
new file mode 100644
index 0000000000..a5b1ca3bab
--- /dev/null
+++ b/3rd-party/php-jpgraph/jpgraph-1.5.2-php5_and_liberation_fonts.patch
@@ -0,0 +1,172 @@
+diff -Naur jpgraph-1.5.2.org/src/jpgraph_dir.php jpgraph-1.5.2/src/jpgraph_dir.php
+--- jpgraph-1.5.2.org/src/jpgraph_dir.php 2002-03-01 01:46:17.000000000 +0100
++++ jpgraph-1.5.2/src/jpgraph_dir.php 2008-12-09 21:55:28.000000000 +0100
+@@ -26,5 +26,6 @@
+
+ // Directory for TTF fonts. Must end with '/'
+ DEFINE("TTF_DIR","/usr/local/fonts/ttf/");
++DEFINE("LIBERATION_DIR","/usr/share/fonts/liberation/");
+
+ ?>
+diff -Naur jpgraph-1.5.2.org/src/jpgraph_gantt.php jpgraph-1.5.2/src/jpgraph_gantt.php
+--- jpgraph-1.5.2.org/src/jpgraph_gantt.php 2002-03-01 01:46:17.000000000 +0100
++++ jpgraph-1.5.2/src/jpgraph_gantt.php 2008-12-09 21:55:28.000000000 +0100
+@@ -1157,10 +1157,6 @@
+ $this->iCaptionMargin=$aMarg;
+ }
+
+- function GetLineNbr() {
+- return 0;
+- }
+-
+ function GetAbsHeight($aImg) {
+ return 0;
+ }
+@@ -1189,7 +1185,7 @@
+ $this->iProgress = $aProg;
+ }
+
+- function SetPattern($aPattern,$aColor="blue",$aDensity=98) {
++ function SetPattern($aPattern,$aColor="blue",$aDensity=100) {
+ $this->iPattern = $aPattern;
+ $this->iColor = $aColor;
+ $this->iDensity = $aDensity;
+diff -Naur jpgraph-1.5.2.org/src/jpgraph.php jpgraph-1.5.2/src/jpgraph.php
+--- jpgraph-1.5.2.org/src/jpgraph.php 2002-03-01 01:46:17.000000000 +0100
++++ jpgraph-1.5.2/src/jpgraph.php 2008-12-09 21:55:28.000000000 +0100
+@@ -30,7 +30,8 @@
+ // regenerate the image. Note that even if reading the cache is
+ // disabled the cached will still be updated with the newly generated
+ // image. Set also "USE_CACHE" below.
+-DEFINE("READ_CACHE",true);
++//DEFINE("READ_CACHE",true);
++DEFINE("READ_CACHE",false);
+
+ // Should the cache be used at all? By setting this to false no
+ // files will be generated in the cache directory.
+@@ -38,7 +39,8 @@
+ // false will still create the image in the cache directory
+ // just not use it. By setting USE_CACHE=false no files will even
+ // be generated in the cache directory.
+-DEFINE("USE_CACHE",true);
++//DEFINE("USE_CACHE",true);
++DEFINE("USE_CACHE",false);
+
+ // If the color palette is full should JpGraph try to allocate
+ // the closest match? If you plan on using background image or
+@@ -104,6 +106,7 @@
+ DEFINE("FF_COMIC",14);
+ DEFINE("FF_ARIAL",15);
+ DEFINE("FF_BOOK",16);
++DEFINE("FF_LIBERATION_SANS",17);
+
+ // TTF Font styles
+ DEFINE("FS_NORMAL",1);
+@@ -251,11 +254,11 @@
+ // Check what version of the GD library is being used
+ //
+ if(function_exists('imagecopyresampled') ) {
+- $gd2 = true;
++ $GLOBALS['gd2'] = true;
+ $copyfunc = "imagecopyresampled";
+ } elseif(function_exists('imagecopyresized')) {
+ $copyfunc = "imagecopyresized";
+- $gd2 = false;
++ $GLOBALS['gd2'] = false;
+ }
+ else {
+ JpGraphError::Raise("JpGraph Error: Your PHP installation does not
+@@ -272,7 +275,6 @@
+ // (top level), i.e it is safe to call this function
+ // from a script that uses JpGraph
+ function GenImgName() {
+- global $HTTP_SERVER_VARS;
+ $supported = imagetypes();
+ if( $supported & IMG_PNG )
+ $img_format="png";
+@@ -280,10 +282,10 @@
+ $img_format="gif";
+ elseif( $supported & IMG_JPG )
+ $img_format="jpeg";
+- if( !isset($HTTP_SERVER_VARS['PHP_SELF']) )
++ if( !isset($_SERVER['PHP_SELF']) )
+ JpGraphError::Raise("JpGraph Error: Can't access PHP_SELF, PHP global variable. You can't run PHP from command line
+ if you want to use the 'auto' naming of cache or image files.");
+- $fname=basename($HTTP_SERVER_VARS['PHP_SELF']);
++ $fname=basename($_SERVER['PHP_SELF']);
+ // Replace the ".php" extension with the image format extension
+ return substr($fname,0,strlen($fname)-4).".".$img_format;
+ }
+@@ -489,6 +491,7 @@
+
+ // Specify a background image
+ function SetBackgroundImage($aFileName,$aBgType=BKIMG_FILLPLOT,$aImgFormat="png") {
++/* CB Not any more bugging
+
+ if( $GLOBALS["gd2"] && !USE_TRUECOLOR ) {
+ JpGraphError::Raise("JpGraph Error: You are using GD 2.x and are
+@@ -500,6 +503,7 @@
+ using any truetype fonts with truecolor images will result in very
+ poor quality fonts.");
+ }
++*/
+
+ $this->background_image = $aFileName;
+ $this->background_image_type=$aBgType;
+@@ -1064,6 +1068,10 @@
+ $this->img->Rectangle(0,0,$this->img->width-1,$this->img->height-1);
+ }
+ }
++ // Set Margin by Christian Bayle
++ function SetMargin($lm,$rm,$tm,$bm) {
++ $this->img->SetMargin($lm,$rm,$tm,$bm);
++ }
+ } // Class
+
+
+@@ -1084,7 +1092,8 @@
+ FF_HANDWRT => TTF_DIR."handwriting",
+ FF_COMIC => TTF_DIR."comic",
+ FF_ARIAL => TTF_DIR."arial",
+- FF_BOOK => TTF_DIR."bookant");
++ FF_BOOK => TTF_DIR."bookant",
++ FF_LIBERATION_SANS => LIBERATION_DIR."LiberationSans-Regular");
+ }
+
+ //---------------
+@@ -3183,7 +3192,7 @@
+ }
+ }
+ }
+- elseif($this->font_family >= FF_COURIER && $this->font_family <= FF_BOOK) { // TTF font
++ elseif($this->font_family >= FF_COURIER && $this->font_family <= FF_LIBERATION_SANS) { // TTF font
+ $file = $this->ttf->File($this->font_family,$this->font_style);
+ $angle=$dir;
+ $bbox=ImageTTFBBox($this->font_size,$angle,$file,$txt);
+@@ -3208,7 +3217,7 @@
+ }
+ }
+ else
+- JpGraphError::Raise("JpGraph Error: Unknown font font family specification. ");
++ JpGraphError::Raise("JpGraph Error: Unknown font family specification: ". $this->font_family);
+ }
+
+ function SetMargin($lm,$rm,$tm,$bm) {
+@@ -3490,7 +3499,16 @@
+ }
+
+ function FilledCircle($xc,$yc,$r) {
+- imagefilledellipse($this->img,$xc,$yc,2*$r,2*$r,$this->current_color);
++ if( $GLOBALS['gd2'] ) {
++ imagefilledellipse($this->img,$xc,$yc,2*$r,2*$r,$this->current_color);
++ }
++ else {
++ for( $i=1; $i < 2*$r; $i += 2 ) {
++ $this->Arc($xc,$yc,$i,$i,0,360);
++ $this->Arc($xc,$yc,$i+1,$i,0,360);
++ $this->Arc($xc,$yc,$i+1,$i+1,0,360);
++ }
++ }
+ }
+
+ // Linear Color InterPolation
diff --git a/3rd-party/php-jpgraph/jpgraph-rhel-fonts.patch b/3rd-party/php-jpgraph/jpgraph-rhel-fonts.patch
new file mode 100644
index 0000000000..7222d12c4a
--- /dev/null
+++ b/3rd-party/php-jpgraph/jpgraph-rhel-fonts.patch
@@ -0,0 +1,55 @@
+diff -Naur jpgraph-1.5.2.org/src/jpgraph_dir.php jpgraph-1.5.2/src/jpgraph_dir.php
+--- jpgraph-1.5.2.org/src/jpgraph_dir.php 2010-03-30 23:47:09.000000000 +0200
++++ jpgraph-1.5.2/src/jpgraph_dir.php 2010-03-30 23:51:52.000000000 +0200
+@@ -25,9 +25,9 @@
+ DEFINE("APACHE_CACHE_DIR","/jpgraph_cache/");
+
+ // Directory for TTF fonts. Must end with '/'
+-DEFINE("TTF_DIR","/usr/share/fonts/truetype/msttcorefonts/");
++DEFINE("TTF_DIR","/usr/local/fonts/ttf/");
+
+-// Add Free liberation font as suggested by Alain Peyrat
+-DEFINE("LIBERATION_DIR","/usr/share/fonts/truetype/ttf-liberation/");
++// Add Free liberation font
++DEFINE("LIBERATION_DIR","/usr/share/fonts/liberation/");
+
+ ?>
+diff -Naur jpgraph-1.5.2.org/src/jpgraph.php jpgraph-1.5.2/src/jpgraph.php
+--- jpgraph-1.5.2.org/src/jpgraph.php 2010-03-30 23:47:09.000000000 +0200
++++ jpgraph-1.5.2/src/jpgraph.php 2010-03-30 23:55:57.000000000 +0200
+@@ -1095,13 +1095,13 @@
+ function TTF() {
+ // Base file names for available fonts
+ $this->font_fam=array(
+- FF_COURIER => TTF_DIR."Courier_New",
+- FF_VERDANA => TTF_DIR."Verdana",
+- FF_TIMES => TTF_DIR."Times",
+- FF_HANDWRT => TTF_DIR."Handwriting",
+- FF_COMIC => TTF_DIR."Comic",
+- FF_ARIAL => TTF_DIR."Arial",
+- FF_BOOK => TTF_DIR."Bookant",
++ FF_COURIER => TTF_DIR."courier",
++ FF_VERDANA => TTF_DIR."verdana",
++ FF_TIMES => TTF_DIR."times",
++ FF_HANDWRT => TTF_DIR."handwriting",
++ FF_COMIC => TTF_DIR."comic",
++ FF_ARIAL => TTF_DIR."arial",
++ FF_BOOK => TTF_DIR."bookant",
+ FF_LIBERATION_SANS => LIBERATION_DIR."LiberationSans-Regular");
+ }
+
+@@ -1114,11 +1114,11 @@
+ switch( $style ) {
+ case FS_NORMAL:
+ break;
+- case FS_BOLD: $f .= "_Bold";
++ case FS_BOLD: $f .= "bd";
+ break;
+- case FS_ITALIC: $f .= "_Italic";
++ case FS_ITALIC: $f .= "i";
+ break;
+- case FS_BOLDIT: $f .= "_Bold_Italic";
++ case FS_BOLDIT: $f .= "bi";
+ break;
+ default:
+ JpGraphError::Raise("JpGraph Error: Unknown TTF Style.");
diff --git a/3rd-party/php-jpgraph/libphp-jpgraph_1.5.2-12.diff.gz b/3rd-party/php-jpgraph/libphp-jpgraph_1.5.2-12.diff.gz
new file mode 100644
index 0000000000..41a2c852b0
Binary files /dev/null and b/3rd-party/php-jpgraph/libphp-jpgraph_1.5.2-12.diff.gz differ
diff --git a/3rd-party/php-jpgraph/libphp-jpgraph_1.5.2.orig.tar.gz b/3rd-party/php-jpgraph/libphp-jpgraph_1.5.2.orig.tar.gz
new file mode 100644
index 0000000000..e2e0ac3f74
Binary files /dev/null and b/3rd-party/php-jpgraph/libphp-jpgraph_1.5.2.orig.tar.gz differ
diff --git a/3rd-party/php-jpgraph/php-jpgraph.spec b/3rd-party/php-jpgraph/php-jpgraph.spec
new file mode 100644
index 0000000000..db7d53759c
--- /dev/null
+++ b/3rd-party/php-jpgraph/php-jpgraph.spec
@@ -0,0 +1,78 @@
+# $Id: php-jpgraph.spec 4308 2006-04-21 22:20:20Z dries $
+# Authority: dag
+
+%define real_name jpgraph
+
+Summary: OO Graph Library for PHP
+Name: php-jpgraph
+Version: 1.5.2
+Release: 1
+License: GPL
+Group: Development/Languages
+URL: http://www.aditus.nu/jpgraph/
+
+Source: http://members.chello.se/jpgraph/jpgdownloads/jpgraph-%{version}.tar.gz
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
+
+BuildArch: noarch
+Requires: php
+Obsoletes: jpgraph
+Provides: jpgraph
+
+Patch0: libphp-jpgraph_1.5.2-12.diff
+Patch1: jpgraph-rhel-fonts.patch
+
+
+%description
+JpGraph is an OO class library for PHP 4.1 (or higher). JpGraph makes it
+easy to draw both "quick and dirty" graphs with a minimum of code and
+complex professional graphs which requires a very fine grain control.
+
+JpGraph is equally well suited for both scientific and business type of graphs.
+
+An important feature of the library is that it assigns context sensitive
+default values for most of the parameters which radically minimizes the
+learning curve. The features are there when you need it - they don't get
+in your way when you don't need them!
+
+%package docs
+Summary: Documentation for package %{name}
+Group: Documentation
+
+%description docs
+JpGraph is an OO class library for PHP 4.1 (or higher). JpGraph makes it
+easy to draw both "quick and dirty" graphs with a minimum of code and
+complex professional graphs which requires a very fine grain control.
+
+This package includes the documentation for %{name}.
+
+%prep
+%setup -n %{real_name}-%{version}
+%patch0 -p1
+%patch1 -p1
+
+### Change the default TTF_DIR to Red Hat's TTF_DIR.
+%{__perl} -pi.orig -e 's|/usr/X11R6/lib/X11/fonts/truetype/|/usr/X11R6/lib/X11/fonts/TTF/|' src/jpgraph.php
+
+%build
+
+%install
+%{__rm} -rf %{buildroot}
+%{__install} -d -m0755 %{buildroot}%{_datadir}/%{real_name}
+%{__install} -p -m0644 src/jpgraph*.php %{buildroot}%{_datadir}/%{real_name}/
+
+%clean
+%{__rm} -rf %{buildroot}
+
+%files
+%defattr(-, root, root, 0755)
+%doc README
+%{_datadir}/%{real_name}/
+
+%files docs
+%defattr(-, root, root, 0755)
+%doc src/Examples/
+
+%changelog
+* Mon Mar 29 2010 Alain Peyrat - 1.5.2-1
+- Initial package, spec taken from DAG.
diff --git a/3rd-party/php-mail-mbox/Makefile b/3rd-party/php-mail-mbox/Makefile
new file mode 100644
index 0000000000..63b4471092
--- /dev/null
+++ b/3rd-party/php-mail-mbox/Makefile
@@ -0,0 +1,25 @@
+DISTDEBIAN=$(shell [ -f /etc/debian_version ] && echo debian)
+DISTREDHAT=$(shell grep -qi 'Red Hat' /etc/issue && echo rh)
+DISTSUSE=$(shell grep -qi 'SuSE' /etc/issue && echo rh)
+DIST=$(DISTDEBIAN)$(DISTREDHAT)$(DISTSUSE)
+
+PKGDIR=php-mail-mbox-0.6.3
+PKGDSC=$(shell ls *.dsc | sort -V -r | head -1)
+MINOR=$(shell grep ^Version $(PKGDSC) | sed 's/.[^-]*-\(.*\)/\1/')
+PARAM=PKGDIR=$(PKGDIR) svnrev=$(MINOR)
+
+default: $(PKGDIR)
+ @make -f Makefile.$(DIST) $(PARAM) default
+ @cat ../../Makefile.$(DIST) | grep '^.*:.*#$$' | sed 's/FUSIONFORGE/$(FUSIONFORGE)/' | sed 's/^\(.*:\).*#\(.*\)#$$/\1 \2/'
+
+%: $(PKGDIR)
+ @make -f Makefile.$(DIST) $(PARAM) $@
+
+$(PKGDIR):
+ #pear download channel://pear.php.net/Mail_Mbox-0.6.3
+ # gives Mail_Mbox-0.6.3.tgz
+ # then dh-make-pear Mail_Mbox-0.6.3.tgz
+ dpkg-source -x $(PKGDSC)
+
+clean:
+ rm -rf $(PKGDIR)
diff --git a/3rd-party/php-mail-mbox/Makefile.debian b/3rd-party/php-mail-mbox/Makefile.debian
new file mode 100644
index 0000000000..1219f2c0e9
--- /dev/null
+++ b/3rd-party/php-mail-mbox/Makefile.debian
@@ -0,0 +1 @@
+include ../../Makefile.debian
diff --git a/3rd-party/php-mail-mbox/php-mail-mbox_0.6.3-1.diff.gz b/3rd-party/php-mail-mbox/php-mail-mbox_0.6.3-1.diff.gz
new file mode 100644
index 0000000000..fbc62a63f4
Binary files /dev/null and b/3rd-party/php-mail-mbox/php-mail-mbox_0.6.3-1.diff.gz differ
diff --git a/3rd-party/php-mail-mbox/php-mail-mbox_0.6.3-1.dsc b/3rd-party/php-mail-mbox/php-mail-mbox_0.6.3-1.dsc
new file mode 100644
index 0000000000..2a0850f940
--- /dev/null
+++ b/3rd-party/php-mail-mbox/php-mail-mbox_0.6.3-1.dsc
@@ -0,0 +1,17 @@
+Format: 1.0
+Source: php-mail-mbox
+Binary: php-mail-mbox
+Architecture: all
+Version: 0.6.3-1
+Maintainer: Mélanie Le Bail
+Standards-Version: 3.8.3
+Build-Depends: debhelper (>= 7), dh-make-php (>= 0.2.3), cdbs
+Checksums-Sha1:
+ cd8aed7e1e0808201b05aaf05f9b2dcbcc442174 14331 php-mail-mbox_0.6.3.orig.tar.gz
+ 36ba7b43b57db210f859850d5406dc53b57fd8b9 1711 php-mail-mbox_0.6.3-1.diff.gz
+Checksums-Sha256:
+ 1e3a6cc0f7665e090c26b9ad4aca9fa6a24b248347dc6982991bfcb27a4a12eb 14331 php-mail-mbox_0.6.3.orig.tar.gz
+ 0618f07728d6bca042d7b8bc02f5a4d44289593bb682e11a67808bbec08fcff1 1711 php-mail-mbox_0.6.3-1.diff.gz
+Files:
+ e65b8828d2c49b14fe17de33b30589b1 14331 php-mail-mbox_0.6.3.orig.tar.gz
+ f73b269a9b9fad72bce0887b49f4dc1a 1711 php-mail-mbox_0.6.3-1.diff.gz
diff --git a/3rd-party/php-mail-mbox/php-mail-mbox_0.6.3-1coclico1.diff.gz b/3rd-party/php-mail-mbox/php-mail-mbox_0.6.3-1coclico1.diff.gz
new file mode 100644
index 0000000000..8cd5988fa4
Binary files /dev/null and b/3rd-party/php-mail-mbox/php-mail-mbox_0.6.3-1coclico1.diff.gz differ
diff --git a/3rd-party/php-mail-mbox/php-mail-mbox_0.6.3-1coclico1.dsc b/3rd-party/php-mail-mbox/php-mail-mbox_0.6.3-1coclico1.dsc
new file mode 100644
index 0000000000..4fc8026707
--- /dev/null
+++ b/3rd-party/php-mail-mbox/php-mail-mbox_0.6.3-1coclico1.dsc
@@ -0,0 +1,17 @@
+Format: 1.0
+Source: php-mail-mbox
+Binary: php-mail-mbox
+Architecture: all
+Version: 0.6.3-1coclico1
+Maintainer: Mélanie Le Bail
+Standards-Version: 3.8.3
+Build-Depends: debhelper (>= 7), dh-make-php (>= 0.2.3), cdbs
+Checksums-Sha1:
+ cd8aed7e1e0808201b05aaf05f9b2dcbcc442174 14331 php-mail-mbox_0.6.3.orig.tar.gz
+ 86122879b0cbfa3d47980079284c8fbd0f3471ed 1531 php-mail-mbox_0.6.3-1coclico1.diff.gz
+Checksums-Sha256:
+ 1e3a6cc0f7665e090c26b9ad4aca9fa6a24b248347dc6982991bfcb27a4a12eb 14331 php-mail-mbox_0.6.3.orig.tar.gz
+ 76de5794b742ea34ccbc756317a813dfeb67b874edd7224a6f27b9dcfad00029 1531 php-mail-mbox_0.6.3-1coclico1.diff.gz
+Files:
+ e65b8828d2c49b14fe17de33b30589b1 14331 php-mail-mbox_0.6.3.orig.tar.gz
+ 7aba97393f3b120172783636050a4a93 1531 php-mail-mbox_0.6.3-1coclico1.diff.gz
diff --git a/3rd-party/php-mail-mbox/php-mail-mbox_0.6.3.orig.tar.gz b/3rd-party/php-mail-mbox/php-mail-mbox_0.6.3.orig.tar.gz
new file mode 100644
index 0000000000..ce072321e8
Binary files /dev/null and b/3rd-party/php-mail-mbox/php-mail-mbox_0.6.3.orig.tar.gz differ
diff --git a/Makefile b/Makefile
index ff180880ea..6eb537bbab 100644
--- a/Makefile
+++ b/Makefile
@@ -1,11 +1,20 @@
+#
+# This Makefile may be used to create packages for distributions
+#
+
DISTDEBIAN=$(shell [ -f /etc/debian_version ] && echo debian)
DISTREDHAT=$(shell grep -qi 'Red Hat' /etc/issue && echo rh)
DISTSUSE=$(shell grep -qi 'SuSE' /etc/issue && echo rh)
DIST=$(DISTDEBIAN)$(DISTREDHAT)$(DISTSUSE)
ARCHIVE=$(CURDIR)/depot
+#ifeq ($(BUILDDIR),)
+# BUILDDIR=builddir
+#endif
BUILDRESULT=$(CURDIR)/result
+DOXYGEN=doxygen
+
VER=$(shell LANG=C grep '>software_version' gforge/common/include/FusionForge.class.php | cut -d\' -f2)
in_svn_repo:= $(wildcard .svn/)
ifeq ($(strip $(in_svn_repo)),)
@@ -25,12 +34,15 @@ endif
switch:
@echo "=========================================================================="
- @echo "Use one of the following target with "
- @echo "make -f Makefile.$(DIST) "
+ @echo "We have detected that your are running a '$(DIST)' distribution."
+ @echo "Use one of the following targets with "
+ @echo "$$ make -f Makefile.$(DIST) "
@echo "=========================================================================="
- @make -f Makefile.$(DIST)
+ @$(MAKE) -f Makefile.$(DIST)
check:
+ ## To run test in verbose mode :
+ #cd tests ; phpunit --verbose unit; phpunit --verbose code;
cd tests ; php AllTests.php
buildtar:
@@ -38,10 +50,6 @@ buildtar:
cd gforge; find . -type f -or -type l | grep -v '/.svn/' | grep -v '^./debian' | grep -v '^./deb-specific' | grep -v '^./rpm-specific' | grep -v '^./contrib' | grep -v '^./gforge.spec' | grep -v '^./README.setup' | grep -v '^./setup' | cpio -pdumB --quiet /tmp/$(VERSION)
cd /tmp/$(VERSION); utils/manage-translations.sh build
cd /tmp/; tar jcf $(BUILDRESULT)/$(VERSION).tar.bz2 $(VERSION)
- cd /tmp/$(VERSION); tar zxf $(ARCHIVE)/libphp-jpgraph_1.5.2.orig.tar.gz
- cd /tmp/$(VERSION); patch -p0 < $(ARCHIVE)/jpgraph-1.5.2-php5_and_liberation_fonts.patch
- cd /tmp/$(VERSION); mkdir jpgraph; mv jpgraph-1.5.2/src/* jpgraph; rm -fr jpgraph-1.5.2
- cd /tmp; tar jcf $(BUILDRESULT)/$(VERSION)-allinone.tar.bz2 $(VERSION)
rm -fr /tmp/$(VERSION)
build-unit-tests:
@@ -49,10 +57,13 @@ build-unit-tests:
cd tests; phpunit --log-xml $(BUILDDIR)/reports/phpunit.xml --log-pmd $(BUILDDIR)/reports/phpunit.pmd.xml --coverage-clover $(BUILDDIR)/reports/coverage/clover.xml --coverage-html $(BUILDDIR)/reports/coverage/ AllTests.php
cp $(BUILDDIR)/reports/phpunit.xml $(BUILDDIR)/reports/phpunit.xml.org; xalan -in $(BUILDDIR)/reports/phpunit.xml.org -xsl fix_phpunit.xslt -out $(BUILDDIR)/reports/phpunit.xml
+build-doc:
+ $(DOXYGEN) gforge/docs/fusionforge.doxygen
+ $(DOXYGEN) gforge/plugins/wiki/www/doc/phpwiki.doxygen
+
build-full-tests:
+ mkdir -p $(BUILDDIR)/build/packages $(BUILDDIR)/reports/coverage
find $(BUILDDIR)/build/packages -type f -exec rm -f {} \;
- mkdir -p $(BUILDDIR)/reports/coverage
- phpdoc --title 'API Documentation' -ue on -t $(BUILDDIR)/apidocs -d gforge/common -tb '/usr/share/php/data/phpUnderControl/data/phpdoc' -o HTML:Phpuc:phpuc
-phpcs --tab-width=4 --standard=PEAR --report=checkstyle gforge/common > $(BUILDDIR)/reports/checkstyle.xml
cd tests; phpunit --log-xml $(BUILDDIR)/reports/phpunit.xml --log-pmd $(BUILDDIR)/reports/phpunit.pmd.xml --coverage-clover $(BUILDDIR)/reports/coverage/clover.xml --coverage-html $(BUILDDIR)/reports/coverage/ AllFullTests.php
cp $(BUILDDIR)/reports/phpunit.xml $(BUILDDIR)/reports/phpunit.xml.org; xalan -in $(BUILDDIR)/reports/phpunit.xml.org -xsl fix_phpunit.xslt -out $(BUILDDIR)/reports/phpunit.xml
@@ -61,7 +72,7 @@ build-full-tests:
gforge/plugins/mediawiki/mediawiki-skin/FusionForge.php:
- cd gforge/plugins/mediawiki/mediawiki-skin ; make
+ $(MAKE) -C gforge/plugins/mediawiki/mediawiki-skin
%: gforge/plugins/mediawiki/mediawiki-skin/FusionForge.php
- @make -f Makefile.$(DIST) $@
+ $(MAKE) -f Makefile.$(DIST) $@
diff --git a/Makefile.debian b/Makefile.debian
index 917f296136..1edec6badd 100644
--- a/Makefile.debian
+++ b/Makefile.debian
@@ -1,21 +1,60 @@
#! /usr/bin/make -f
+#
+# TODO : document the role of this Makefile
+
+# Uses cowbuilder to build packages inside ./builder/, for different
+# distributions
+# Packages are versioned ...
+
+# Built packages will be put into ./result/
+#
+# ATTENTION : it requires you to run cowbuilder with sudo
+#
+
FUSIONFORGE=FusionForge
PKGDIR=gforge
PKGNAME=$(shell head -1 $(PKGDIR)/debian/changelog | sed 's/ .*//')
PKGLETTER=$(shell echo $(PKGNAME) | cut -c1)
ORIGIN=debian.fusionforge.org
+# BRANCH set to 'svn' if checkout from trunk or 'brc' otherwise
BRANCH=$(shell [ "$(shell echo $(basename $(CURDIR)) | sed 's/.*runk.*/trunk/')" = "trunk" ] && echo svn || echo brc)
-BUILDPLACE=$(CURDIR)/builder/buildplace
-BUILDFILES=$(CURDIR)/builder/buildfiles
+#
+ifeq (,$(shell echo "$$BUILDERDIR"))
+BUILDERDIR=$(CURDIR)/builder
+else
+BUILDERDIR=$(shell echo $$BUILDERDIR)
+endif
+ifeq (,$(shell echo "$$BUILDRESULT"))
BUILDRESULT=$(CURDIR)/result
-COWBUILDERBASE=$(CURDIR)/builder/cow
-PBUILDERTGZ=$(CURDIR)/builder/tgz
+else
+BUILDRESULT=$(shell echo $$BUILDRESULT)
+endif
+#
+ifeq (,$(shell echo "$$UBUMIRROR"))
+UBUMIRROR=http://archive.ubuntu.com/ubuntu
+else
+UBUMIRROR=$(shell echo $$UBUMIRROR)
+endif
+ifeq (,$(shell echo "$$DEBMIRROR"))
+DEBMIRROR=http://ftp.fr.debian.org/debian
+else
+DEBMIRROR=$(shell echo $$DEBMIRROR)
+endif
+#
TARBALLS=$(CURDIR)/tarballs
-APTCACHE=$(CURDIR)/builder/cache
-DISTRIB=$(shell echo $(XDISTRIB) | cut -c2-)
+#
+BUILDPLACE=$(BUILDERDIR)/buildplace
+BUILDFILES=$(BUILDERDIR)/buildfiles
+COWBUILDERBASE=$(BUILDERDIR)/cow
+PBUILDERTGZ=$(BUILDERDIR)/tgz
+APTCACHE=$(BUILDERDIR)/cache
+#
LOCALREPODEB=/var/www/debian-fusionforge-$(BRANCH)
LOCALREPOUBU=/var/www/ubuntu-fusionforge-$(BRANCH)
+#
+XDISTRIB:=3sid
+DISTRIB=$(shell echo $(XDISTRIB) | cut -c2-)
SIGNKEY=yes
DEBIANLIST=1lenny 2squeeze 3sid
DEBIANLISTP=1etch
@@ -24,23 +63,21 @@ UBUNTULIST=1hardy 1intrepid 1jaunty 1karmic
UBUNTULIST=1jaunty 1karmic 1lucid
UBUNTULISTP=1gutsy
UBULIST=$(UBUNTULIST) $(UBUNTULISTP)
-# Try if a local mirror is available
-LOCALMIRROR=http://localhost/ubuntu
-UBUNTUOP=$(shell wget -q -S http://localhost/ubuntu -O /dev/null 2>&1 && echo "--mirror $(LOCALMIRROR)" || echo "--mirror http://archive.ubuntu.com/ubuntu") --debootstrap debootstrap
-UBUNTUOP=--mirror http://archive.ubuntu.com/ubuntu --debootstrap debootstrap
-DEBIANOP=--debootstrapopts --include=apt --debootstrap debootstrap
+UBUNTUOP=--mirror $(UBUMIRROR) --debootstrap debootstrap
+DEBIANOP=--mirror $(DEBMIRROR) --debootstrapopts --include=apt --debootstrap debootstrap
ASKPASS=--ask-passphrase
ASKPASS=
MAJOR=$(shell head -1 $(PKGDIR)/debian/changelog | sed 's/.*(\(.*\)-[^-]*).*/\1/')
+# SMAJOR is MAJOR without epoch if any
+SMAJOR=$(shell echo $(MAJOR) | sed 's/^.://')
+
in_svn_repo:= $(wildcard .svn/)
ifeq ($(strip $(in_svn_repo)),)
-#in_bzr_repo:= $(shell bzr info | grep parent | cut -d: -f2-)
in_bzr_repo:= $(wildcard .bzr/)
ifeq ($(strip $(in_bzr_repo)),)
svnrev=unknown
else
- #svnrev=$(shell LANG=C bzr log -r-1 2>&1 | grep "svn revno" | cut -d" " -f3)
svnrev=bzr$(shell bzr revno)
endif
else
@@ -55,31 +92,48 @@ DEBUG=
DEBBUILDOPTS=--debbuildopts -sa
ARCH=$(shell dpkg-architecture -qDEB_BUILD_ARCH)
-UBUHOOK="--hookdir $(CURDIR)/hook/ubuntu"
# Some doc found there http://wiki.debian.org/cowbuilder
# Hook are not anymore necessary, but I keep as an example
UBUHOOK="--components 'main universe' --debootstrapopts --exclude=udev,pcmciautils,initramfs-tools"
UBUHOOK=--components "main universe" --hookdir $(CURDIR)/hook/ubuntu
+UBUHOOK=--components "main universe"
+DEBHOOK=
-ORIGFILE=$(PKGNAME)_$(MAJOR).orig.tar.gz
-DSCFILE=$(PKGNAME)_$(MAJOR)$(MINOR).dsc
-PDSCFILE=$(PKGNAME)_$(MAJOR)$(MINOR)+p.dsc
-CHANGEFILE=$(PKGNAME)_$(MAJOR)$(MINOR)_$(ARCH).changes
-PCHANGEFILE=$(PKGNAME)_$(MAJOR)$(MINOR)+p_$(ARCH).changes
+ORIGFILE=$(PKGNAME)_$(SMAJOR).orig.tar.gz
+DSCFILE=$(PKGNAME)_$(SMAJOR)$(MINOR).dsc
+PDSCFILE=$(PKGNAME)_$(SMAJOR)$(MINOR)+p.dsc
+CHANGEFILE=$(PKGNAME)_$(SMAJOR)$(MINOR)_$(ARCH).changes
+PCHANGEFILE=$(PKGNAME)_$(SMAJOR)$(MINOR)+p_$(ARCH).changes
# Quite heavy version, but still requires to be root
-COWBUILDERCMD=cd $(BUILDPLACE) && dpkg-source -x $(BUILDFILES)/$(DSCFILE) ; cd $(BUILDPLACE)/$(PKGNAME)-$(MAJOR) && pdebuild --pbuilder cowbuilder --buildresult $(BUILDRESULT) -- --basepath $(COWBUILDERBASE)/base-$(DISTRIB).cow --buildplace $(BUILDPLACE) --aptcache $(APTCACHE) ; rm -rf $(BUILDPLACE)/$(PKGNAME)-$(MAJOR)
+COWBUILDERCMD=cd $(BUILDPLACE) && dpkg-source -x $(BUILDFILES)/$(DSCFILE) ; cd $(BUILDPLACE)/$(PKGNAME)-$(SMAJOR) && pdebuild --pbuilder cowbuilder --buildresult $(BUILDRESULT) -- --basepath $(COWBUILDERBASE)/base-$(DISTRIB)-$(ARCH).cow --buildplace $(BUILDPLACE) --aptcache $(APTCACHE) ; rm -rf $(BUILDPLACE)/$(PKGNAME)-$(SMAJOR)
# This one is with sudo and probably faster
-COWBUILDERCMD=sudo /usr/sbin/cowbuilder --build --basepath $(COWBUILDERBASE)/base-$(DISTRIB).cow --configfile $(COWBUILDERBASE)/config $(BUILDFILES)/$(DSCFILE) $(DEBBUILDOPTS)
+COWBUILDERCMD=sudo /usr/sbin/cowbuilder --build --basepath $(COWBUILDERBASE)/base-$(DISTRIB)-$(ARCH).cow --configfile $(COWBUILDERBASE)/configfile-$(ARCH) $(BUILDFILES)/$(DSCFILE) $(DEBBUILDOPTS)
# This one is with pbuilder
-PBUILDERCMD=cd $(BUILDFILES) && sudo /usr/sbin/pbuilder --build --basetgz $(PBUILDERTGZ)/base-$(DISTRIB).tgz --configfile $(PBUILDERTGZ)/config $(BUILDFILES)/$(PDSCFILE)
+PBUILDERCMD=cd $(BUILDFILES) && sudo /usr/sbin/pbuilder --build --basetgz $(PBUILDERTGZ)/base-$(DISTRIB)-$(ARCH).tgz --configfile $(PBUILDERTGZ)/configfile-$(ARCH) $(BUILDFILES)/$(PDSCFILE)
default: list
list:
@echo ======================================================================================
- @echo '= Available targets are listed below ($(BRANCH))($(ARCH)) ='
+ @echo "= Available targets are listed below"
+ @echo "= Your current environment :"
+ @echo "= * checkout from : $(BRANCH)"
+ @echo "= (above 'checkout' meaning :"
+ @echo "= 'svn' for trunk"
+ @echo "= 'brc' for branches)"
+ @echo "= * PKGNAME = $(PKGNAME)"
+ @echo "= * PKGDIR = $(PKGDIR)"
+ @echo "= * major version : $(MAJOR)/$(SMAJOR)"
+ @echo "= * minor version : $(MINOR)"
+ @echo "= * architecture : $(ARCH)"
+ @echo "= * BUILDERDIR = $(BUILDERDIR)"
+ @echo "= * ORIGFILE = $(ORIGFILE)"
+ @echo "= * DSCFILE = $(DSCFILE)"
+ @echo "= * PDSCFILE = $(PDSCFILE)"
+ @echo "= * CHANGEFILE = $(CHANGEFILE)"
+ @echo "= * PCHANGEFILE = $(PCHANGEFILE)"
@echo ======================================================================================
@cat Makefile.debian | grep '^.*:.*#$$' | sed 's/FUSIONFORGE/$(FUSIONFORGE)/' | sed 's/^\(.*:\).*#\(.*\)#$$/\1 \2/'
@echo ======================================================================================
@@ -141,7 +195,8 @@ documentor_subdir=PhpDocumentor-1.4.3
# FUSIONFORGE
#
-orig: $(TARBALLS)/$(ORIGFILE) # Make FUSIONFORGE orig file
+orig: # Make Debian package .orig tarball #
+ $(MAKE) $(TARBALLS)/$(ORIGFILE)
#
# PHPDOCUMENTOR
@@ -149,6 +204,12 @@ orig: $(TARBALLS)/$(ORIGFILE) # Make FUSIONFORGE orig file
# Get phpdocumentor, install phpdocumentor, build $(PKGNAME) phpdoc
phpdoc: $(PKGDIR)/docs/phpdoc/docs
+doc:
+ (cd gforge/docs/docbook ; make debian)
+
+cleandoc:
+ (cd gforge/docs/docbook ; make clean)
+
phpdocumentor_get:
[ ! -f $(documentor_path)/$(documentor_file) ] && \
cd $(documentor_path) && \
@@ -174,34 +235,40 @@ deploy: repodeb repoubu # ***** Deploy packages in Debian and Ubuntu repositorie
repodeb: cowbuilddeb
@for dist in $(DEBIANLIST); do \
+ echo "$(MAKE) -f Makefile.debian localrepo reprepro XDISTRIB=$$dist LOCALREPO=$(LOCALREPODEB) DISTRIBLIST='$(DEBLIST)'" ; \
$(MAKE) -f Makefile.debian localrepo reprepro XDISTRIB=$$dist LOCALREPO=$(LOCALREPODEB) DISTRIBLIST="$(DEBLIST)" ; \
done
repoubu: cowbuildubu
@for dist in $(UBUNTULIST); do \
+ echo "$(MAKE) -f Makefile.debian localrepo reprepro XDISTRIB=$$dist LOCALREPO=$(LOCALREPOUBU) DISTRIBLIST='$(UBULIST)'" ; \
$(MAKE) -f Makefile.debian localrepo reprepro XDISTRIB=$$dist LOCALREPO=$(LOCALREPOUBU) DISTRIBLIST="$(UBULIST)" ; \
done
cowbuildtest:
- @echo "Will build $(PKGNAME)_$(MAJOR)$(MINOR)$(DISTRIB)"
+ @echo "Will build $(PKGNAME)_$(MAJOR)_$(MINOR)_$(DISTRIB)_$(ARCH)"
cowbuilddeb: # ***** This is the one to cowbuild debian packages ***** #
@for dist in $(DEBIANLIST); do \
- $(MAKE) -f Makefile.debian cowbuilddist XDISTRIB=$$dist DISTROOP="$(DEBIANOP)" ; \
+ echo "$(MAKE) -f Makefile.debian cowbuilddist XDISTRIB=$$dist DISTROOP='$(DEBIANOP)' HOOK='$(DEBHOOK)'" ; \
+ $(MAKE) -f Makefile.debian cowbuilddist XDISTRIB=$$dist DISTROOP="$(DEBIANOP)" HOOK='$(DEBHOOK)' ; \
done
cowbuildubu: # ***** This is the one to cowbuild ubuntu packages ***** #
@for dist in $(UBUNTULIST); do \
+ echo "$(MAKE) -f Makefile.debian cowbuilddist XDISTRIB=$$dist DISTROOP='$(UBUNTUOP)' HOOK='$(UBUHOOK)'" ; \
$(MAKE) -f Makefile.debian cowbuilddist XDISTRIB=$$dist DISTROOP="$(UBUNTUOP)" HOOK='$(UBUHOOK)' ; \
done
pbuilddeb: # pbuild debian packages (less recommended) #
@for dist in $(DEBIANLISTP); do \
+ echo "$(MAKE) -f Makefile.debian pbuilddist XDISTRIB=$$dist DISTROOP='$(DEBIANOP)' LOCALREPO=$(LOCALREPODEB)" ; \
$(MAKE) -f Makefile.debian pbuilddist XDISTRIB=$$dist DISTROOP="$(DEBIANOP)" LOCALREPO=$(LOCALREPODEB) ; \
done
pbuildubu: # pbuild ubuntu packages (less recommended) #
@for dist in $(UBUNTULISTP); do \
+ echo "$(MAKE) -f Makefile.debian pbuilddist XDISTRIB=$$dist DISTROOP='$(UBUNTUOP)' LOCALREPO=$(LOCALREPOUBU)" ; \
$(MAKE) -f Makefile.debian pbuilddist XDISTRIB=$$dist DISTROOP="$(UBUNTUOP)" LOCALREPO=$(LOCALREPOUBU) ; \
done
@@ -223,7 +290,7 @@ $(BUILDFILES)/$(DSCFILE):
grep -v rpm-specific | grep -v docs/phpdoc/docs | \
grep -v ^./debian/ | cpio -pdumB $(BUILDFILES)/
# Set version for given distrib
- cd $(BUILDFILES)/$(PKGDIR); dch -b -v $(MAJOR)$(MINOR) -D UNRELEASED "This is $(DISTRIB) autobuild"
+ cd $(BUILDFILES)/$(PKGDIR); dch -b -v $(MAJOR)$(MINOR) -D UNRELEASED "This is $(DISTRIB)-$(ARCH) autobuild"
perl -pi -e "s/UNRELEASED/$(DISTRIB)/" $(BUILDFILES)/$(PKGDIR)/debian/changelog
cd $(BUILDFILES) ; dpkg-source -b $(PKGDIR)
rm -rf $(BUILDFILES)/$(PKGDIR)
@@ -236,7 +303,7 @@ $(BUILDFILES)/$(PDSCFILE):
grep -v rpm-specific | grep -v docs/phpdoc/docs | \
grep -v ^./debian/ | cpio -pdumB $(BUILDFILES)/
# Set version for given distrib
- cd $(BUILDFILES)/$(PKGDIR); dch -b -v $(MAJOR)$(MINOR)+p -D UNRELEASED "This is $(DISTRIB) autobuild"
+ cd $(BUILDFILES)/$(PKGDIR); dch -b -v $(MAJOR)$(MINOR)+p -D UNRELEASED "This is $(DISTRIB)-$(ARCH) autobuild"
perl -pi -e "s/UNRELEASED/$(DISTRIB)/" $(BUILDFILES)/$(PKGDIR)/debian/changelog
cd $(BUILDFILES) ; dpkg-source -b $(PKGDIR)
rm -rf $(BUILDFILES)/$(PKGDIR)
@@ -254,46 +321,48 @@ $(TARBALLS)/$(ORIGFILE): $(TARBALLS)
grep -v plugins/wiki/www/lib/pear | \
cpio -o -H ustar | gzip > $(TARBALLS)/$(ORIGFILE)
-pbuilderenv: $(PBUILDERTGZ) $(PBUILDERTGZ)/base-$(DISTRIB).tgz
- @echo "=========> Ready for $(DISTRIB)"
+pbuilderenv: $(PBUILDERTGZ) $(PBUILDERTGZ)/base-$(DISTRIB)-$(ARCH).tgz
+ @echo "=========> Ready for $(DISTRIB)-$(ARCH)"
-cowbuilderenv: $(COWBUILDERBASE) $(COWBUILDERBASE)/base-$(DISTRIB).stamp.update
- @echo "=========> Ready for $(DISTRIB)"
+cowbuilderenv: $(COWBUILDERBASE)/doconfig-$(ARCH) $(COWBUILDERBASE)/base-$(DISTRIB)-$(ARCH).stamp.update
+ @echo "=========> Ready for $(DISTRIB)-$(ARCH)"
forceupdatecow: # Force update of cowbuilder env #
rm -f $(COWBUILDERBASE)/base-*.stamp.update
-$(COWBUILDERBASE)/base-$(DISTRIB).stamp.update: $(COWBUILDERBASE)/base-$(DISTRIB).stamp
- sudo /usr/sbin/cowbuilder --update $(HOOK) --distribution $(DISTRIB) --basepath $(COWBUILDERBASE)/base-$(DISTRIB).cow --configfile $(COWBUILDERBASE)/config $(DISTROOP)
+$(COWBUILDERBASE)/base-$(DISTRIB)-$(ARCH).stamp.update: $(COWBUILDERBASE)/base-$(DISTRIB)-$(ARCH).stamp
+ sudo /usr/sbin/cowbuilder --update $(HOOK) --distribution $(DISTRIB) --basepath $(COWBUILDERBASE)/base-$(DISTRIB)-$(ARCH).cow --configfile $(COWBUILDERBASE)/configfile-$(ARCH) $(DISTROOP)
touch $@
-$(PBUILDERTGZ)/base-$(DISTRIB).tgz: $(PBUILDERTGZ)/config
- sudo /usr/sbin/pbuilder --create --distribution $(DISTRIB) --basetgz $(PBUILDERTGZ)/base-$(DISTRIB).tgz --configfile $(PBUILDERTGZ)/config $(DISTROOP)
+$(PBUILDERTGZ)/base-$(DISTRIB)-$(ARCH).tgz: $(PBUILDERTGZ)/doconfig-$(ARCH)
+ [ -f $@ ] || sudo /usr/sbin/pbuilder --create --distribution $(DISTRIB) --basetgz $(PBUILDERTGZ)/base-$(DISTRIB).tgz --configfile $(PBUILDERTGZ)/configfile-$(ARCH) $(DISTROOP)
-$(COWBUILDERBASE)/base-$(DISTRIB).stamp: $(COWBUILDERBASE)/config
- sudo /usr/sbin/cowbuilder --create $(HOOK) --distribution $(DISTRIB) --basepath $(COWBUILDERBASE)/base-$(DISTRIB).cow --configfile $(COWBUILDERBASE)/config $(DISTROOP)
+$(COWBUILDERBASE)/base-$(DISTRIB)-$(ARCH).stamp:
+ [ -d $(COWBUILDERBASE)/base-$(DISTRIB)-$(ARCH).cow ] || sudo /usr/sbin/cowbuilder --create $(HOOK) --distribution $(DISTRIB) --basepath $(COWBUILDERBASE)/base-$(DISTRIB)-$(ARCH).cow --configfile $(COWBUILDERBASE)/configfile-$(ARCH) $(DISTROOP)
touch $@.update
touch $@
-$(PBUILDERTGZ)/config: /usr/sbin/pbuilder
- echo "APTCACHE=$(APTCACHE)" > $(PBUILDERTGZ)/config
- echo "BUILDPLACE=$(BUILDPLACE)" >> $(PBUILDERTGZ)/config
- echo "BUILDRESULT=$(BUILDRESULT)" >> $(PBUILDERTGZ)/config
+$(PBUILDERTGZ)/doconfig-$(ARCH): /usr/sbin/pbuilder
+ @mkdir -p $(PBUILDERTGZ)
+ @echo "APTCACHE=$(APTCACHE)" > $(PBUILDERTGZ)/configfile-$(ARCH)
+ @echo "BUILDPLACE=$(BUILDPLACE)" >> $(PBUILDERTGZ)/configfile-$(ARCH)
+ @echo "BUILDRESULT=$(BUILDRESULT)" >> $(PBUILDERTGZ)/configfile-$(ARCH)
-$(COWBUILDERBASE)/config: /usr/sbin/cowbuilder
- echo "APTCACHE=$(APTCACHE)" > $(COWBUILDERBASE)/config
- echo "BUILDPLACE=$(BUILDPLACE)" >> $(COWBUILDERBASE)/config
- echo "BUILDRESULT=$(BUILDRESULT)" >> $(COWBUILDERBASE)/config
+$(COWBUILDERBASE)/doconfig-$(ARCH): /usr/sbin/cowbuilder
+ @mkdir -p $(COWBUILDERBASE)
+ @echo "APTCACHE=$(APTCACHE)" > $(COWBUILDERBASE)/configfile-$(ARCH)
+ @echo "BUILDPLACE=$(BUILDPLACE)" >> $(COWBUILDERBASE)/configfile-$(ARCH)
+ @echo "BUILDRESULT=$(BUILDRESULT)" >> $(COWBUILDERBASE)/configfile-$(ARCH)
/usr/sbin/pbuilder:
- sudo apt-get install pbuilder
+ @echo "Error: you need to install package 'pbuilder', for instance with 'sudo apt-get install pbuilder'." ; /bin/false
ubukey:
gpg --keyserver keyserver.ubuntu.com --recv-keys 40976EAF437D05B5
gpg --export --armor 40976EAF437D05B5 | sudo apt-key add -
/usr/sbin/cowbuilder:
- sudo apt-get install cowdancer
+ @echo "Error: you need to install package 'cowdancer', for instance with 'sudo apt-get install cowdancer'." ; /bin/false
localrepo: $(LOCALREPO) $(LOCALREPO)/conf $(LOCALREPO)/conf/distributions
@@ -340,10 +409,10 @@ clean: # Clean $(BUILDPLACE) $(BUILDFILES) $(TARBALLS) (intermediate files) #
rm -rf $(BUILDPLACE) $(BUILDFILES) $(TARBALLS)
cleanenv: # Clean $(COWBUILDERBASE) $(PBUILDERTGZ) (chroots)#
- rm -rf $(COWBUILDERBASE) $(PBUILDERTGZ)
+ sudo rm -rf $(COWBUILDERBASE) $(PBUILDERTGZ)
cleancache: # Clean $(APTCACHE) (apt cache) #
- rm -rf $(APTCACHE)
+ sudo rm -rf $(APTCACHE)
cleanorig: # Clean $(TARBALLS)/$(ORIGFILE) #
rm -f $(TARBALLS)/$(ORIGFILE)
diff --git a/Makefile.rh b/Makefile.rh
index 640bafa0a0..c79aa57f88 100644
--- a/Makefile.rh
+++ b/Makefile.rh
@@ -1,5 +1,9 @@
#! /usr/bin/make -f
+#
+# TODO : document the role of this Makefile
+#
+
list:
@echo ======================================================================================
@echo '= Available target are listed below ='
@@ -30,7 +34,7 @@ svnplugin: cleansvn buildsvn # package svn plugin #
allmodules : libnsspgsql
#Exterals
-allexternals : htmlpurifier
+allexternals : htmlpurifier php-jpgraph
libnsspgsql : buildlibnsspgsql
@@ -113,7 +117,7 @@ target cleansvn buildsvn : override version=$(shell grep '^Version:' gforge/plug
cleansvn: # Clean files of gforge-plugin-scmcvs build #
@cd $(RPM_TMP)/SOURCES/; rm -rf fusionforge-plugin-scmsvn-$(version).tar.bz2 fusionforge-plugin-scmsvn-$(version)
@echo cleansvn Done
-
+
buildsvn: # Build rpm gforge-plugin-scmsvn package #
cd gforge/plugins/scmsvn; find . -type f | grep -v '/CVS/' | grep -v '/.svn/' | grep -v contrib | grep -v '/debian/' | cpio -pdumvB --quiet $(RPM_TMP)/SOURCES/fusionforge-plugin-scmsvn-$(version)
mkdir -p $(RPM_TMP)/SOURCES/fusionforge-plugin-scmsvn-$(version)/bin
@@ -179,12 +183,14 @@ buildlibnsspgsql: # Build rpm fusionforge-shell-postgresql package
cd $(RPM_TMP)/SOURCES/; rpmbuild -ts --nodeps fusionforge-shell-postgresql-$(version).tar.bz2
#
-# HTMLPURIFIER (third party plugin)
+# Building RPM for third party plugins
#
-htmlpurifier: rpmprep depot/htmlpurifier-4.0.0.tar.gz
- cp depot/htmlpurifier-4.0.0.tar.gz $(RPM_TMP)/SOURCES/
+htmlpurifier: rpmprep
+ cp 3rd-party/htmlpurifier/htmlpurifier-4.0.0.tar.gz $(RPM_TMP)/SOURCES/
rpmbuild --quiet --clean -ba 3rd-party/htmlpurifier/htmlpurifier.spec
-depot/htmlpurifier-4.0.0.tar.gz: rpmprep
- mkdir -p depot
- cd depot; wget -q -N http://htmlpurifier.org/releases/htmlpurifier-4.0.0.tar.gz
+php-jpgraph: rpmprep
+ cp 3rd-party/php-jpgraph/libphp-jpgraph_1.5.2.orig.tar.gz $(RPM_TMP)/SOURCES/jpgraph-1.5.2.tar.gz
+ zcat 3rd-party/php-jpgraph/libphp-jpgraph_1.5.2-12.diff.gz > $(RPM_TMP)/SOURCES/libphp-jpgraph_1.5.2-12.diff
+ cp 3rd-party/php-jpgraph/*.patch $(RPM_TMP)/SOURCES/
+ rpmbuild --quiet --clean -ba 3rd-party/php-jpgraph/php-jpgraph.spec
diff --git a/README b/README
index 8646496ba2..0c62aa6a6b 100644
--- a/README
+++ b/README
@@ -1,5 +1,5 @@
-What is Makefile.debian ?
+The code of FusionForge can be found in the gforge/ subdir.
-Process to recompile the official Debian packages from bzr ?
+TODO: What is the role of all the Makefiles?
--- Olivier Berger
\ No newline at end of file
+-- Olivier Berger
diff --git a/gforge/AUTHORS b/gforge/AUTHORS
index 65375669b2..9df8afe181 100644
--- a/gforge/AUTHORS
+++ b/gforge/AUTHORS
@@ -1,121 +1,48 @@
#
# FusionForge
-# Copyright 2008-2009 (c) FusionForge
-# Copyright 2002-2008 (c) GForge
# http://fusionforge.org
#
+#
-----------------------------------------------------------------------------
-The FusionForge Team
-----------------------------------------------------------------------------
-
-Tim Perdue
-Roland Mas <99.roland.mas@aist.enst.fr>
-Christian Bayle
-Tom Copeland
-Guillaume Smet
-Francisco Gimeno
-Sung Kim
+The FusionForge codebase was developed for many years in the frame of
+the GForge project (until 2009), then in the FusionForge project since
+2009.
-Past Members:
-Reinhard Spisser
-Ryan T. Sammartino
-Edward Ritter
-Michael Jennings
+It is copyrighted by individual authors mentioned in copyright notices
+of each files.
----------------------------------------------------------------------------
-We'd like to thank the following volunteers for their contributions
-of code, documentation, ideas, and time:
+The new FusionForge Team
----------------------------------------------------------------------------
-Darrell Brogdon
-John Maguire
-Trix Farrar
-Philippe Kiener
-Robert J. Sanford, Jr.
-François Elie
-Richard Offer
-Julien Goodwin
-Bob Lamoureux
-Olafur Osvaldsson
-Jim Nutt
-Scott Armstrong
-Eric Kerin
-Graham Batty
-Robert B. Hawkins
-Ronald Petty
-Simon Lei
-Paul Kneeland
-Patrick McFarland
-Jeff Fynboh
-Vicente J. Ruiz Jurado
-Dragos Moinescu
-Alwyn Schoeman
-Tony Guntharp
-Hidenari Miwa
-David McNicol
-Ed Hill
-Paul Gibbbs
-James Michael DuPont
-Patrick Lemmens
-Christophe Colombier
-Auke Jilderda
-Rene Klootwijk
-Antoine Nivard
-Joo-won Jung
-Justin Richer
-Franco Catrin L.
-Mathieu Peltier
-Bo Jangborg
-Ramon van Alteren
-Mitch Murphy
-Brett N DiFrischia
-Andreas Schrattenecker
-Eric Evans
-Shawn Soon-Son Kwon
-Frank Gevaerts
-Lars Ehrhardt
-Joseph Bironas
-Marco Schmidt
-Chris Ward
-Marc Kalberer
-Kenneth C. Cone, Sr.
-Hunte Swee
-David Hirst
-FabrÃÂcio Vertamatti
-Benoît Sibaud
-Lele Gaifax
-Mike Heath
-Jason Chen
-Tomas Pospisek
-Jáder Marasca
-Oliver Blume
-Vidyut Luther
-Eric Robert
-Chris Watts
-Dominik Haas
-Diggy Bell
-Jaime Diaz
-Paul Santa Maria
-Josiah Olivieri
-Andre Costa
-Konrad Wulf
-Igor Blanco
-Florent Guilleux
-Pedro Paixao
-Matt Hope
-Rob Lanphier
-Finjon Kiang
-Andrey Molchanov
-Ognyan Kulev
-J Aaron Farr
-Tony Pugliese
-Hal Deadman
-Tobias Rötschke
-Greg Hudson
-Jens Jorgensen
-Ramon van Alteren
-Florent Guilleux
-Jimou Lee
+TODO : name all contributors to FusionForge. The list below was
+extracted from the SVN stats.
+
+Roland Mas
+Grégory Cuellar
+Christian Bayle
Alain Peyrat
+Guillaume Smet
+Julien Heyman
+Ognyan Kulev
+Alexandre Neymann
+Reinhard Spisser
+Francisco Gimeno
+Mathieu Peltier
+Olivier Meunier
Olaf Lenz
+Franck Villaume
+Pierre Lacoste
+Thorsten Glaser
+Gonéri Le Bouder
+Mélanie Le Bail
+Olivier Berger
+Philip Schwartz
+
+
+See also AUTHORS.gforge and AUTHORS.sourceforge for prior contributors.
+
+# Local Variables:
+# coding: utf-8
+# End:
+
diff --git a/gforge/AUTHORS.gforge b/gforge/AUTHORS.gforge
new file mode 100644
index 0000000000..00ad9bce4f
--- /dev/null
+++ b/gforge/AUTHORS.gforge
@@ -0,0 +1,125 @@
+#
+# GForge
+# Copyright 2002-2005 (c) GForge
+# http://gforge.org
+#
+# $Id$
+#
+
+----------------------------------------------------------------------------
+The GForge Team
+----------------------------------------------------------------------------
+
+Tim Perdue
+Roland Mas <99.roland.mas@aist.enst.fr>
+Christian Bayle
+Tom Copeland
+Guillaume Smet
+Francisco Gimeno
+Sung Kim
+
+Past Members:
+Reinhard Spisser
+Ryan T. Sammartino
+Edward Ritter
+Michael Jennings
+
+----------------------------------------------------------------------------
+We'd like to thank the following volunteers for their contributions
+of code, documentation, ideas, and time:
+----------------------------------------------------------------------------
+
+Darrell Brogdon
+John Maguire
+Trix Farrar
+Philippe Kiener
+Robert J. Sanford, Jr.
+François Elie
+Richard Offer
+Julien Goodwin
+Bob Lamoureux
+Olafur Osvaldsson
+Jim Nutt
+Scott Armstrong
+Eric Kerin
+Graham Batty
+Robert B. Hawkins
+Ronald Petty
+Simon Lei
+Paul Kneeland
+Patrick McFarland
+Jeff Fynboh
+Vicente J. Ruiz Jurado
+Dragos Moinescu
+Alwyn Schoeman
+Tony Guntharp
+Hidenari Miwa
+David McNicol
+Ed Hill
+Paul Gibbbs
+James Michael DuPont
+Patrick Lemmens
+Christophe Colombier
+Auke Jilderda
+Rene Klootwijk
+Antoine Nivard
+Joo-won Jung
+Justin Richer
+Franco Catrin L.
+Mathieu Peltier
+Bo Jangborg
+Ramon van Alteren
+Mitch Murphy
+Brett N DiFrischia
+Andreas Schrattenecker
+Eric Evans
+Shawn Soon-Son Kwon
+Frank Gevaerts
+Lars Ehrhardt
+Joseph Bironas
+Marco Schmidt
+Chris Ward
+Marc Kalberer
+Kenneth C. Cone, Sr.
+Hunte Swee
+David Hirst
+FabrÃÂcio Vertamatti
+Benoît Sibaud
+Lele Gaifax
+Mike Heath
+Jason Chen
+Tomas Pospisek
+Jáder Marasca
+Oliver Blume
+Vidyut Luther
+Eric Robert
+Chris Watts
+Dominik Haas
+Diggy Bell
+Jaime Diaz
+Paul Santa Maria
+Josiah Olivieri
+Andre Costa
+Konrad Wulf
+Igor Blanco
+Florent Guilleux
+Pedro Paixao
+Matt Hope
+Rob Lanphier
+Finjon Kiang
+Andrey Molchanov
+Ognyan Kulev
+J Aaron Farr
+Tony Pugliese
+Hal Deadman
+Tobias Rötschke
+Greg Hudson
+Jens Jorgensen
+Ramon van Alteren
+Florent Guilleux
+Jimou Lee
+Alain Peyrat
+
+# Local Variables:
+# coding: utf-8
+# End:
diff --git a/gforge/CHANGES b/gforge/CHANGES
index e1cdf5300d..5d9bfb15cf 100644
--- a/gforge/CHANGES
+++ b/gforge/CHANGES
@@ -1,5 +1,14 @@
UNRELEASED:
+FusionForge-5.1:
+* Trackers: New progressbar to view completion state (when custom status field is used) (Alain Peyrat)
+* Trackers: Sorting improved to allow text & select fields (Alcatel-Lucent)
+* [#127] Patch to auto approve projects.
+* scmgit plugin now allows project members to request a personal git
+ repository as a clone of the current project's one
+* New blocks plugin, to add free HTML blocks on top of each tools of the project allowing
+ admins to add free descriptions (Alcate-Lucent), (better with fckeditor plugin).
+
FusionForge-5.0:
* New projectlabels plugin, to tag projects with snippets of
user-defined HTML (developed for/sponsored by Adullact)
diff --git a/gforge/README.setup b/gforge/README.setup
index ac071daa9d..c2956ec6c6 100644
--- a/gforge/README.setup
+++ b/gforge/README.setup
@@ -23,6 +23,7 @@ mv etc/local.inc etc/local.inc.example
mv etc/httpd.conf etc/httpd.conf.example
mv etc/httpd.secrets etc/httpd.secrets.example
mv etc/database.inc etc/database.inc.example
+mv etc/database.py etc/database.py.example
mv etc/local.pl etc/local.pl.example
rm etc/httpd.vhosts
#
diff --git a/gforge/common/dao/CodendiDataAccess.class.php b/gforge/common/dao/CodendiDataAccess.class.php
new file mode 100644
index 0000000000..b241d193cd
--- /dev/null
+++ b/gforge/common/dao/CodendiDataAccess.class.php
@@ -0,0 +1,45 @@
+.
+ */
+
+require_once('include/DataAccess.class.php');
+
+class CodendiDataAccess extends DataAccess {
+
+ protected function __construct() {
+
+ $this->DataAccess();
+ }
+
+ protected static $_instance;
+ public static function instance() {
+ if (!isset(self::$_instance)) {
+ $c = __CLASS__;
+ self::$_instance = new $c;
+ }
+ return self::$_instance;
+ }
+
+
+}
+
+
+?>
\ No newline at end of file
diff --git a/gforge/common/dao/include/DataAccess.class.php b/gforge/common/dao/include/DataAccess.class.php
new file mode 100644
index 0000000000..e62c9857de
--- /dev/null
+++ b/gforge/common/dao/include/DataAccess.class.php
@@ -0,0 +1,40 @@
+.
+ */
+
+require_once('DataAccessResult.class.php');
+require_once('DataAccessException.class.php');
+
+
+class DataAccess {
+
+ /**
+ * Constucts a new DataAccess object
+ */
+ function DataAccess() {
+
+ }
+ function quoteSmart($value, $params = array()) {
+
+ return $value;
+ }
+
+
+}
+?>
\ No newline at end of file
diff --git a/gforge/common/dao/include/DataAccessException.class.php b/gforge/common/dao/include/DataAccessException.class.php
new file mode 100644
index 0000000000..1835bcb604
--- /dev/null
+++ b/gforge/common/dao/include/DataAccessException.class.php
@@ -0,0 +1,22 @@
+.
+ */
+class DataAccessException extends Exception {
+}
+?>
diff --git a/gforge/common/dao/include/DataAccessObject.class.php b/gforge/common/dao/include/DataAccessObject.class.php
new file mode 100644
index 0000000000..2aaf7fee41
--- /dev/null
+++ b/gforge/common/dao/include/DataAccessObject.class.php
@@ -0,0 +1,46 @@
+table_name = 'CLASSNAME_MUST_BE_DEFINE_FOR_EACH_CLASS';
+
+ $this->da=$da;
+ }
+
+
+ //! An accessor
+ /**
+ * For SELECT queries
+ * @param $sql the query string
+ * @return mixed either false if error or object DataAccessResult
+ */
+ function &retrieve($sql,$params) {
+ $result =& new DataAccessResult(db_query_params($sql,$params));
+
+ return $result;
+ }
+
+ //! An accessor
+ /**
+ * For INSERT, UPDATE and DELETE queries
+ * @param $sql the query string
+ * @return boolean true if success
+ */
+ function update($sql,$params) {
+ $result = db_query_params($sql,$params);
+ return $result;
+ }
+
+
+
+}
+?>
diff --git a/gforge/common/dao/include/DataAccessResult.class.php b/gforge/common/dao/include/DataAccessResult.class.php
new file mode 100644
index 0000000000..64cbbdfa18
--- /dev/null
+++ b/gforge/common/dao/include/DataAccessResult.class.php
@@ -0,0 +1,87 @@
+result = $result;
+
+ $this->_current = -1;
+ $this->_row = false;
+ $this->rewind();
+
+ }
+
+ /**
+ * Returns an array from query row or false if no more rows
+ * @return mixed
+ */
+ function &getRow() {
+ $row = $this->current();
+ $this->next();
+ return $row;
+ }
+
+ /**
+ * Returns the number of rows affected
+ * @return int
+ */
+ function rowCount() {
+ return db_numrows($this->result);
+ }
+
+ /**
+ * Returns false if no errors or returns a MySQL error message
+ * @return mixed
+ */
+ function isError() {
+ $error=db_error();
+ if (!empty($error))
+ return $error;
+ else
+ return false;
+ }
+
+
+ // {{{ Iterator
+ function ¤t() {
+ return $this->_row;
+ }
+
+ function next() {
+ $this->_current++;
+ $this->_row = db_fetch_array($this->result);
+ }
+
+ function valid() {
+ return $this->_row !== false;
+ }
+
+ function rewind() {
+ if ($this->rowCount() > 0) {
+ db_reset_result($this->result, 0);
+ $this->next();
+ $this->_current = 0;
+ }
+ }
+
+ function key() {
+ return $this->_current;
+ }
+ // }}}
+}
+?>
diff --git a/gforge/common/docman/Document.class.php b/gforge/common/docman/Document.class.php
index c7b2ed3250..0a4ab859e0 100644
--- a/gforge/common/docman/Document.class.php
+++ b/gforge/common/docman/Document.class.php
@@ -101,7 +101,7 @@ class Document extends Error {
*
* @param string The filename of this document. Can be a URL.
* @param string The filetype of this document. If filename is URL, this should be 'URL';
- * @param string The contents of this document (should be addslashes()'d before entry).
+ * @param string The contents of this document.
* @param int The doc_group id of the doc_groups table.
* @param string The title of this document.
* @param int The language id of the supported_languages table.
@@ -146,7 +146,7 @@ class Document extends Error {
// key words for in-document search
$kw = new Parsedata ($this->engine_path);
- $kwords = $kw->get_parse_data (stripslashes($data1), htmlspecialchars($title), htmlspecialchars($description), $filetype);
+ $kwords = $kw->get_parse_data ($data1, htmlspecialchars($title), htmlspecialchars($description), $filetype);
$filesize = strlen($data);
@@ -164,7 +164,7 @@ class Document extends Error {
$filename,
$filetype,
$filesize,
- base64_encode(stripslashes($data)),
+ base64_encode($data),
$kwords,
$user_id));
if (!$result) {
@@ -434,7 +434,7 @@ class Document extends Error {
*
* @param string The filename of this document. Can be a URL.
* @param string The filetype of this document. If filename is URL, this should be 'URL';
- * @param string The contents of this document (should be addslashes()'d before entry).
+ * @param string The contents of this document.
* @param int The doc_group id of the doc_groups table.
* @param string The title of this document.
* @param int The language id of the supported_languages table.
@@ -491,10 +491,10 @@ class Document extends Error {
// key words for in-document search
$kw = new Parsedata ($this->engine_path);
- $kwords = $kw->get_parse_data (stripslashes($data1), htmlspecialchars($title), htmlspecialchars($description), $filetype);
+ $kwords = $kw->get_parse_data ($data1, htmlspecialchars($title), htmlspecialchars($description), $filetype);
$res = db_query_params ('UPDATE doc_data SET data=$1, filesize=$2, data_words=$3 WHERE group_id=$4 AND docid=$5',
- array (base64_encode(stripslashes($data)),
+ array (base64_encode($data),
strlen($data),
$kwords,
$this->Group->getID(),
diff --git a/gforge/common/event/Event.class.php b/gforge/common/event/Event.class.php
new file mode 100644
index 0000000000..2b91550b24
--- /dev/null
+++ b/gforge/common/event/Event.class.php
@@ -0,0 +1,30 @@
+.
+ */
+class Event {
+
+ /**
+ * Use this event to get the class name of an external event type (plugins)
+ * see git plugin for implementation example
+ */
+ const GET_SYSTEM_EVENT_CLASS = 'get_system_event_class';
+
+
+}
+?>
diff --git a/gforge/common/forum/Forum.class.php b/gforge/common/forum/Forum.class.php
index bd5c4351dc..f4bca83ce7 100644
--- a/gforge/common/forum/Forum.class.php
+++ b/gforge/common/forum/Forum.class.php
@@ -130,6 +130,7 @@ class Forum extends Error {
return false;
}
if ($send_all_posts_to) {
+ $send_all_posts_to = str_replace(';', ',', $send_all_posts_to);
$invalid_mails = validate_emails($send_all_posts_to);
if (count($invalid_mails) > 0) {
$this->setInvalidEmailError();
@@ -184,21 +185,6 @@ class Forum extends Error {
$this->group_forum_id=db_insertid($result,'forum_group_list','group_forum_id');
$this->fetchData($this->group_forum_id);
- // set the permission for the role's group
- $roles_group = $this->Group->getRolesId();
- for ($i=0; $igroup_forum_id,
- 1)) ;
- if (!$role_setting_res) {
- db_rollback();
- $this->setError('Error: Role setting for forum id ' . $this->group_forum_id . ' for groud id ' . $this->Group->getID() . ' ' .db_error());
- return false;
- }
- }
-
if ($create_default_message) {
$fm=new ForumMessage($this);
// Use the system side default language
@@ -212,6 +198,9 @@ class Forum extends Error {
}
}
db_commit();
+
+ $this->Group->normalizeAllRoles () ;
+
return true;
}
@@ -222,24 +211,8 @@ class Forum extends Error {
* @return boolean success.
*/
function fetchData($group_forum_id) {
- global $sys_database_type;
-
- if ($sys_database_type == "mysql") {
- $sql="
- SELECT fgl.*,
- (SELECT count(*) AS `count`
- FROM (
- SELECT DISTINCT group_forum_id, thread_id FROM forum
- ) AS tmp
- WHERE tmp.group_forum_id = fgl.group_forum_id
- ) AS threads
- FROM forum_group_list_vw AS fgl
- WHERE group_forum_id='$group_forum_id'";
- $res = db_query_mysql ($sql);
- } else {
- $res = db_query_params ('SELECT * FROM forum_group_list_vw WHERE group_forum_id=$1',
- array ($group_forum_id)) ;
- }
+ $res = db_query_params ('SELECT * FROM forum_group_list_vw WHERE group_forum_id=$1',
+ array ($group_forum_id)) ;
if (!$res || db_numrows($res) < 1) {
$this->setError(_('Invalid forum group identifier'));
return false;
@@ -273,21 +246,8 @@ class Forum extends Error {
* @return int The next thread_id #.
*/
function getNextThreadID() {
- global $sys_database_type;
-
- if ($sys_database_type == "mysql") {
- $sql="call newval('forum_thread_seq', @res)";
- $result=db_mquery($sql);
- if (!$result) {
- echo db_error();
- return false;
- }
- $sql="select @res";
- $result = db_query_mysql ($sql);
- } else {
- $result = db_query_params ('SELECT nextval($1)',
- array ('forum_thread_seq')) ;
- }
+ $result = db_query_params ('SELECT nextval($1)',
+ array ('forum_thread_seq')) ;
if (!$result || db_numrows($result) < 1) {
echo db_error();
return false;
@@ -447,18 +407,18 @@ class Forum extends Error {
* @return string return email address
*/
function getReturnEmailAddress() {
- global $sys_default_domain, $sys_use_gateways;
+
$address = '';
- if($sys_use_gateways) {
+ if(forge_get_config('use_gateways')) {
$address .= $this->getUnixName();
} else {
$address .= 'noreply';
}
$address .= '@';
- if($sys_use_gateways && isset($GLOBALS['sys_forum_return_domain'])) {
- $address .= $GLOBALS['sys_forum_return_domain'];
+ if(forge_get_config('use_gateways') && forge_get_config('forum_return_domain')) {
+ $address .= forge_get_config('forum_return_domain');
} else {
- $address .= $sys_default_domain;
+ $address .= forge_get_config('web_host');
}
return $address;
}
@@ -678,7 +638,11 @@ class Forum extends Error {
db_query_params ('DELETE FROM role_setting WHERE section_name=$1 AND ref_id=$2',
array ('forum',
$this->getID())) ;
+
db_commit();
+
+ $this->Group->normalizeAllRoles () ;
+
return true;
}
diff --git a/gforge/common/forum/ForumFactory.class.php b/gforge/common/forum/ForumFactory.class.php
index 730f8ae859..19c66336c5 100644
--- a/gforge/common/forum/ForumFactory.class.php
+++ b/gforge/common/forum/ForumFactory.class.php
@@ -78,84 +78,29 @@ class ForumFactory extends Error {
* @return array The array of Forum objects.
*/
function &getForums() {
- global $sys_database_type;
-
if ($this->forums) {
return $this->forums;
}
- if ($sys_database_type == "mysql") {
- if (session_loggedin()) {
- $perm =& $this->Group->getPermission( session_get_user() );
- if (!$perm || !is_object($perm) || !$perm->isMember()) {
- $public_flag='=1';
- $exists = '';
- } else {
- $public_flag='<3';
- if ($perm->isForumAdmin()) {
- $exists='';
- } else {
- $exists=" AND group_forum_id IN (SELECT role_setting.ref_id
- FROM role_setting, user_group
- WHERE role_setting.value::integer >= 0
- AND role_setting.section_name = 'forum'
- AND role_setting.ref_id=forum_group_list_vw.group_forum_id
-
- AND user_group.role_id = role_setting.role_id
- AND user_group.user_id='".user_getid()."') ";
- }
- }
- } else {
- $public_flag='=1';
- $exists = '';
- }
-
- $sql="SELECT fgl.*,
- (SELECT count(*) AS `count`
- FROM (
- SELECT DISTINCT group_forum_id, thread_id FROM forum
- ) AS tmp
- WHERE tmp.group_forum_id = fgl.group_forum_id
- ) AS threads
- FROM forum_group_list_vw AS fgl
- WHERE group_id='". $this->Group->getID() ."'
- AND is_public $public_flag
- $exists
- ORDER BY group_forum_id;";
-
- $result = db_query_mysql ($sql);
-
- $rows = db_numrows($result);
-
- if (!$result) {
- $this->setError(_('Forum not found').' : '.db_error());
- $this->forums = false;
- } else {
- while ($arr = db_fetch_array($result)) {
- $this->forums[] = new Forum($this->Group, $arr['group_forum_id'], $arr);
- }
- }
- return $this->forums;
- } else { // Not MySQL
- if (session_loggedin()) {
- $perm =& $this->Group->getPermission( session_get_user() );
- if (!$perm || !is_object($perm) || !$perm->isMember()) {
- $result = db_query_params ('SELECT * FROM forum_group_list_vw
+ if (session_loggedin()) {
+ $perm =& $this->Group->getPermission( session_get_user() );
+ if (!$perm || !is_object($perm) || !$perm->isMember()) {
+ $result = db_query_params ('SELECT * FROM forum_group_list_vw
WHERE group_id=$1
AND is_public=1
ORDER BY group_forum_id',
- array ($this->Group->getID())) ;
- } else {
- $public_flag='<3';
- if ($perm->isForumAdmin()) {
- $result = db_query_params ('SELECT * FROM forum_group_list_vw
+ array ($this->Group->getID())) ;
+ } else {
+ $public_flag='<3';
+ if ($perm->isForumAdmin()) {
+ $result = db_query_params ('SELECT * FROM forum_group_list_vw
WHERE group_id=$1
AND is_public < 3
ORDER BY group_forum_id',
- array ($this->Group->getID())) ;
- } else {
- $result = db_query_params ('SELECT * FROM forum_group_list_vw
+ array ($this->Group->getID())) ;
+ } else {
+ $result = db_query_params ('SELECT * FROM forum_group_list_vw
WHERE group_id=$1
AND is_public < 3
AND group_forum_id IN (SELECT role_setting.ref_id
@@ -166,31 +111,30 @@ AND group_forum_id IN (SELECT role_setting.ref_id
AND user_group.role_id = role_setting.role_id
AND user_group.user_id=$3)
ORDER BY group_forum_id',
- array ($this->Group->getID(),
- 'forum',
- user_getid())) ;
- }
+ array ($this->Group->getID(),
+ 'forum',
+ user_getid())) ;
}
- } else {
- $result = db_query_params ('SELECT * FROM forum_group_list_vw
+ }
+ } else {
+ $result = db_query_params ('SELECT * FROM forum_group_list_vw
WHERE group_id=$1
AND is_public=1
ORDER BY group_forum_id',
- array ($this->Group->getID())) ;
- }
-
- $rows = db_numrows($result);
-
- if (!$result) {
- $this->setError(_('Forum not found').' : '.db_error());
- $this->forums = false;
- } else {
- while ($arr = db_fetch_array($result)) {
- $this->forums[] = new Forum($this->Group, $arr['group_forum_id'], $arr);
- }
+ array ($this->Group->getID())) ;
+ }
+
+ $rows = db_numrows($result);
+
+ if (!$result) {
+ $this->setError(_('Forum not found').' : '.db_error());
+ $this->forums = false;
+ } else {
+ while ($arr = db_fetch_array($result)) {
+ $this->forums[] = new Forum($this->Group, $arr['group_forum_id'], $arr);
}
- return $this->forums;
}
+ return $this->forums;
}
@@ -200,80 +144,38 @@ ORDER BY group_forum_id',
* @return array The array of Forum objects.
*/
function &getForumsAdmin() {
- global $sys_database_type;
-
if ($this->forums) {
return $this->forums;
}
- if ($sys_database_type == "mysql") {
- if (session_loggedin()) {
- $perm =& $this->Group->getPermission( session_get_user() );
- if (!$perm || !is_object($perm) || !$perm->isForumAdmin()) {
- $this->setError(_("You don't have a permission to access this page"));
- $this->forums = false;
- } else {
- $sql="SELECT fgl.*,
- (SELECT count(*) AS `count`
- FROM (
- SELECT DISTINCT group_forum_id, thread_id FROM forum
- ) AS tmp
- WHERE tmp.group_forum_id = fgl.group_forum_id
- ) AS threads
- FROM forum_group_list_vw AS fgl
- WHERE group_id='". $this->Group->getID() . "'
- ORDER BY group_forum_id;";
-
- $result = db_query_mysql ($sql);
-
- $rows = db_numrows($result);
-
- if (!$result) {
- $this->setError(_('Forum not found').' : '.db_error());
- $this->forums = false;
- } else {
- while ($arr = db_fetch_array($result)) {
- $this->forums[] = new Forum($this->Group, $arr['group_forum_id'], $arr);
- }
- }
- }
- } else {
+ if (session_loggedin()) {
+ $perm =& $this->Group->getPermission( session_get_user() );
+ if (!$perm || !is_object($perm) || !$perm->isForumAdmin()) {
$this->setError(_("You don't have a permission to access this page"));
$this->forums = false;
- }
-
- return $this->forums;
-
- } else { // Not MySQL
- if (session_loggedin()) {
- $perm =& $this->Group->getPermission( session_get_user() );
- if (!$perm || !is_object($perm) || !$perm->isForumAdmin()) {
- $this->setError(_("You don't have a permission to access this page"));
- $this->forums = false;
- } else {
- $result = db_query_params ('SELECT * FROM forum_group_list_vw
+ } else {
+ $result = db_query_params ('SELECT * FROM forum_group_list_vw
WHERE group_id=$1
ORDER BY group_forum_id',
- array ($this->Group->getID())) ;
- }
- } else {
- $this->setError(_("You don't have a permission to access this page"));
- $this->forums = false;
+ array ($this->Group->getID())) ;
}
-
- $rows = db_numrows($result);
-
- if (!$result) {
- $this->setError(_('Forum not found').' : '.db_error());
- $this->forums = false;
- } else {
- while ($arr = db_fetch_array($result)) {
- $this->forums[] = new Forum($this->Group, $arr['group_forum_id'], $arr);
- }
+ } else {
+ $this->setError(_("You don't have a permission to access this page"));
+ $this->forums = false;
+ }
+
+ $rows = db_numrows($result);
+
+ if (!$result) {
+ $this->setError(_('Forum not found').' : '.db_error());
+ $this->forums = false;
+ } else {
+ while ($arr = db_fetch_array($result)) {
+ $this->forums[] = new Forum($this->Group, $arr['group_forum_id'], $arr);
}
- return $this->forums;
}
+ return $this->forums;
}
}
diff --git a/gforge/common/forum/ForumMessage.class.php b/gforge/common/forum/ForumMessage.class.php
index e04b9f0068..d16d9640be 100644
--- a/gforge/common/forum/ForumMessage.class.php
+++ b/gforge/common/forum/ForumMessage.class.php
@@ -664,7 +664,7 @@ class ForumMessage extends Error {
}
$body = sprintf(_("\nRead and respond to this message at: \n%s"), util_make_url ('/forum/message.php?msg_id='.$this->getID()));
- if ($GLOBALS['sys_use_mail']) {
+ if (forge_get_config('use_mail')) {
$body .= stripcslashes(sprintf(_('
Or reply to this e-mail entering your response between the following markers:
%1$s
@@ -690,28 +690,28 @@ Or reply to this e-mail entering your response between the following markers:
_("You are receiving this email because you elected to monitor this forum.".
"\nTo stop monitoring this forum, login to %s and visit: \n%s\n"),
$text,
- $GLOBALS['sys_name'],
+ forge_get_config ('forge_name'),
util_make_url('/forum/monitor.php?forum_id='.$this->Forum->getID().
'&group_id='.$this->Forum->Group->getID().'&stop=1')
);
- $extra_headers = "Return-Path: \n";
- $extra_headers .= "Errors-To: \n";
- $extra_headers .= "Sender: \n";
+ $extra_headers = "Return-Path: \n";
+ $extra_headers .= "Errors-To: \n";
+ $extra_headers .= "Sender: \n";
$extra_headers .= "Reply-To: ".$this->Forum->getReturnEmailAddress()."\n";
$extra_headers .= "Precedence: Bulk\n"
- ."List-Id: ".$this->Forum->getName()." Forum->getId()."@".$GLOBALS['sys_default_domain'].">\n"
+ ."List-Id: ".$this->Forum->getName()." Forum->getId()."@".forge_get_config('web_host').">\n"
."List-Help: ".util_make_url ('/forum/forum.php?id='.$this->Forum->getId())."\n"
- ."Message-Id: getId()."@".$GLOBALS['sys_default_domain'].">";
+ ."Message-Id: getId()."@".forge_get_config('web_host').">";
$parentid = $this->getParentId();
if (!empty($parentid)) {
$extra_headers .= "\nIn-Reply-To: ".$this->Forum->getReturnEmailAddress()."\n"
- ."References: getParentId()."@".$GLOBALS['sys_default_domain'].">";
+ ."References: getParentId()."@".forge_get_config('web_host').">";
}
$subject="[" . $this->Forum->getUnixName() ."][".$this->getID()."] ".util_unconvert_htmlspecialchars($this->getSubject());
- util_send_message($dest_email,$subject,$body,"noreply@".$GLOBALS['sys_default_domain'],'','Forum',$extra_headers);
+ util_send_message($dest_email,$subject,$body,"noreply@".forge_get_config('web_host'),'','Forum',$extra_headers);
}
// Switch back to the user language settings
@@ -750,19 +750,19 @@ Or reply to this e-mail entering your response between the following markers:
"\n\n______________________________________________________________________".
"\nYou are receiving this email because the forum you administrate has a new moderated message awaiting your approval.";
- //$extra_headers = 'Reply-to: '.$this->Forum->getUnixName().'@'.$GLOBALS['sys_default_domain'];
- $extra_headers = "Return-Path: \n";
- $extra_headers .= "Errors-To: \n";
- $extra_headers .= "Sender: \n";
+ //$extra_headers = 'Reply-to: '.$this->Forum->getUnixName().'@'.forge_get_config('web_host');
+ $extra_headers = "Return-Path: \n";
+ $extra_headers .= "Errors-To: \n";
+ $extra_headers .= "Sender: \n";
$extra_headers .= "Reply-To: ".$this->Forum->getReturnEmailAddress()."\n";
$extra_headers .= "Precedence: Bulk\n"
- ."List-Id: ".$this->Forum->getName()." Forum->getId()."@".$GLOBALS['sys_default_domain'].">\n"
+ ."List-Id: ".$this->Forum->getName()." Forum->getId()."@".forge_get_config('web_host').">\n"
."List-Help: ".util_make_url('/forum/forum.php?id='.$this->Forum->getId())."\n"
- ."Message-Id: getId()."@".$GLOBALS['sys_default_domain'].">";
+ ."Message-Id: getId()."@".forge_get_config('web_host').">";
$parentid = $this->getParentId();
if (!empty($parentid)) {
$extra_headers .= "\nIn-Reply-To: ".$this->Forum->getReturnEmailAddress()."\n"
- ."References: getParentId()."@".$GLOBALS['sys_default_domain'].">";
+ ."References: getParentId()."@".forge_get_config('web_host').">";
}
$subject="[" . $this->Forum->getUnixName() ."][".$this->getID()."] ".util_unconvert_htmlspecialchars($this->getSubject());
@@ -775,8 +775,8 @@ Or reply to this e-mail entering your response between the following markers:
$BCC =& implode(util_result_column_to_array($bccres),',').','.$this->Forum->getSendAllPostsTo();
$User = user_get_object($this->getPosterID());
//util_send_message('',$subject,$body,$User->getEmail(),$BCC,$this->getPosterRealName(),$extra_headers);
- util_send_message('',$subject,$body,"noreply@".$GLOBALS['sys_default_domain'],$BCC,'Forum',$extra_headers);
-// util_handle_message(array_unique($ids),$subject,$body,$this->Forum->getSendAllPostsTo(),'','forumgateway@'.$GLOBALS[sys_default_domain]);
+ util_send_message('',$subject,$body,"noreply@".forge_get_config('web_host'),$BCC,'Forum',$extra_headers);
+// util_handle_message(array_unique($ids),$subject,$body,$this->Forum->getSendAllPostsTo(),'','forumgateway@'.forge_get_config('web_host'));
return true;
}
@@ -853,21 +853,21 @@ Or reply to this e-mail entering your response between the following markers:
$body .=
"\n\n______________________________________________________________________".
"\nYou are receiving this email because you elected to monitor this forum.".
- "\nTo stop monitoring this forum, login to ".$GLOBALS['sys_name']." and visit: ".
+ "\nTo stop monitoring this forum, login to ".forge_get_config ('forge_name')." and visit: ".
"\n".util_make_url ('/forum/monitor.php?forum_id='.$this->Forum->getID() .'&group_id='.$this->Forum->Group->getID().'&stop=1');
- $extra_headers = "Return-Path: \n";
- $extra_headers .= "Errors-To: \n";
- $extra_headers .= "Sender: \n";
+ $extra_headers = "Return-Path: \n";
+ $extra_headers .= "Errors-To: \n";
+ $extra_headers .= "Sender: \n";
$extra_headers .= "Reply-To: ".$this->Forum->getReturnEmailAddress()."\n";
$extra_headers .= "Precedence: Bulk\n"
- ."List-Id: ".$this->Forum->getName()." Forum->getId()."@".$GLOBALS['sys_default_domain'].">\n"
+ ."List-Id: ".$this->Forum->getName()." Forum->getId()."@".forge_get_config('web_host').">\n"
."List-Help: ".util_make_url('/forum/forum.php?id='.$this->Forum->getId())."\n"
- ."Message-Id: getId()."@".$GLOBALS['sys_default_domain'].">";
+ ."Message-Id: getId()."@".forge_get_config('web_host').">";
$parentid = $this->getParentId();
if (!empty($parentid)) {
$extra_headers .= "\nIn-Reply-To: ".$this->Forum->getReturnEmailAddress()."\n"
- ."References: getParentId()."@".$GLOBALS['sys_default_domain'].">";
+ ."References: getParentId()."@".forge_get_config('web_host').">";
}
$subject="[" . $this->Forum->getUnixName() ."][".$this->getID()."] ".util_unconvert_htmlspecialchars($this->getSubject());
@@ -878,7 +878,7 @@ Or reply to this e-mail entering your response between the following markers:
}
$BCC =& implode(util_result_column_to_array($bccres),',').','.$this->Forum->getSendAllPostsTo();
$User = user_get_object($this->getPosterID());
- util_send_message('',$subject,$body,"noreply@".$GLOBALS['sys_default_domain'],$BCC,'Forum',$extra_headers);
+ util_send_message('',$subject,$body,"noreply@".forge_get_config('web_host'),$BCC,'Forum',$extra_headers);
return true;
}
diff --git a/gforge/common/frs/FRSFile.class.php b/gforge/common/frs/FRSFile.class.php
index 34e883333e..0aaf63dc43 100644
--- a/gforge/common/frs/FRSFile.class.php
+++ b/gforge/common/frs/FRSFile.class.php
@@ -127,7 +127,7 @@ class FRSFile extends Error {
}
- $path_name=$GLOBALS['sys_upload_dir'].'/'.$this->FRSRelease->FRSPackage->Group->getUnixName();
+ $path_name=forge_get_config('upload_dir').'/'.$this->FRSRelease->FRSPackage->Group->getUnixName();
if (!is_dir($path_name)) {
mkdir($path_name,0755);
} else {
@@ -153,7 +153,7 @@ class FRSFile extends Error {
}
$file_location=escapeshellcmd($file_location);
- $newfilelocation = $GLOBALS['sys_upload_dir'].'/'.
+ $newfilelocation = forge_get_config('upload_dir').'/'.
$this->FRSRelease->FRSPackage->Group->getUnixName().'/'.
$this->FRSRelease->FRSPackage->getFileName().'/'.
$this->FRSRelease->getFileName().'/';
@@ -327,7 +327,7 @@ class FRSFile extends Error {
return false;
}
- $file=$GLOBALS['sys_upload_dir'].'/'.
+ $file=forge_get_config('upload_dir').'/'.
$this->FRSRelease->FRSPackage->Group->getUnixName() . '/' .
$this->FRSRelease->FRSPackage->getFileName().'/'.
$this->FRSRelease->getFileName().'/'.
@@ -399,12 +399,12 @@ class FRSFile extends Error {
// Move physically file if needed
if ($release_id != $this->FRSRelease->getID()) {
- $old_file_location = $GLOBALS['sys_upload_dir'].'/'.
+ $old_file_location = forge_get_config('upload_dir').'/'.
$this->FRSRelease->FRSPackage->Group->getUnixName().'/'.
$this->FRSRelease->FRSPackage->getFileName().'/'.
$this->FRSRelease->getFileName().'/'.
$this->data_array['filename'];
- $new_file_location = $GLOBALS['sys_upload_dir'].'/'.
+ $new_file_location = forge_get_config('upload_dir').'/'.
$FRSRelease->FRSPackage->Group->getUnixName().'/'.
$FRSRelease->FRSPackage->getFileName().'/'.
$FRSRelease->getFileName().'/'.
diff --git a/gforge/common/frs/FRSPackage.class.php b/gforge/common/frs/FRSPackage.class.php
index e5588ea5d0..199d468f6a 100644
--- a/gforge/common/frs/FRSPackage.class.php
+++ b/gforge/common/frs/FRSPackage.class.php
@@ -131,7 +131,7 @@ class FRSPackage extends Error {
* @return boolean success.
*/
function create($name,$is_public=1) {
- global $sys_apache_user,$sys_apache_group;
+
if (strlen($name) < 3) {
$this->setError(_('FRSPackage Name Must Be At Least 3 Characters'));
return false;
@@ -172,7 +172,7 @@ class FRSPackage extends Error {
} else {
//make groupdir if it doesn't exist
- $groupdir = $GLOBALS['sys_upload_dir'].'/'.$this->Group->getUnixName();
+ $groupdir = forge_get_config('upload_dir').'/'.$this->Group->getUnixName();
if (!is_dir($groupdir)) {
@mkdir($groupdir);
}
@@ -183,8 +183,8 @@ class FRSPackage extends Error {
}
// this 2 should normally silently fail (because it's called with the apache user) but if it's root calling the create() method, then the owner and group for the directory should be changed
- @chown($newdirlocation,$sys_apache_user);
- @chgrp($newdirlocation,$sys_apache_group);
+ @chown($newdirlocation,forge_get_config('apache_user'));
+ @chgrp($newdirlocation,forge_get_config('apache_group'));
db_commit();
return true;
}
@@ -404,8 +404,8 @@ class FRSPackage extends Error {
return false;
}
$newdirname = $this->getFileName();
- $olddirlocation = $GLOBALS['sys_upload_dir'].'/'.$this->Group->getUnixName().'/'.$olddirname;
- $newdirlocation = $GLOBALS['sys_upload_dir'].'/'.$this->Group->getUnixName().'/'.$newdirname;
+ $olddirlocation = forge_get_config('upload_dir').'/'.$this->Group->getUnixName().'/'.$olddirname;
+ $newdirlocation = forge_get_config('upload_dir').'/'.$this->Group->getUnixName().'/'.$newdirname;
if(($olddirname!=$newdirname)){
if(is_dir($newdirlocation)){
@@ -466,7 +466,7 @@ class FRSPackage extends Error {
return false;
}
}
- $dir=$GLOBALS['sys_upload_dir'].'/'.
+ $dir=forge_get_config('upload_dir').'/'.
$this->Group->getUnixName() . '/' .
$this->getFileName().'/';
diff --git a/gforge/common/frs/FRSRelease.class.php b/gforge/common/frs/FRSRelease.class.php
index 20f2a523b3..30a8d3cb79 100644
--- a/gforge/common/frs/FRSRelease.class.php
+++ b/gforge/common/frs/FRSRelease.class.php
@@ -167,7 +167,7 @@ class FRSRelease extends Error {
db_rollback();
return false;
} else {
- $newdirlocation = $GLOBALS['sys_upload_dir'].'/'.$this->FRSPackage->Group->getUnixName().'/'.$this->FRSPackage->getFileName().'/'.$this->getFileName();
+ $newdirlocation = forge_get_config('upload_dir').'/'.$this->FRSPackage->Group->getUnixName().'/'.$this->FRSPackage->getFileName().'/'.$this->getFileName();
if (!is_dir($newdirlocation)) {
@mkdir($newdirlocation);
}
@@ -303,7 +303,7 @@ notified in the future, please login to %5$s and click this link:
$this->FRSPackage->Group->getUnixName(),
$this->FRSPackage->getName(),
util_make_url ("/frs/?group_id=". $this->FRSPackage->Group->getID() ."&release_id=". $this->getID()),
- $GLOBALS['sys_name'],
+ forge_get_config ('forge_name'),
util_make_url ("/frs/monitor.php?filemodule_id=".$this->FRSPackage->getID()."&group_id=".$this->FRSPackage->Group->getID()."&stop=1")));
// $text = util_line_wrap($text);
if (count($arr)) {
@@ -354,7 +354,7 @@ notified in the future, please login to %5$s and click this link:
return false;
}
}
- $dir=$GLOBALS['sys_upload_dir'].'/'.
+ $dir=forge_get_config('upload_dir').'/'.
$this->FRSPackage->Group->getUnixName() . '/' .
$this->FRSPackage->getFileName().'/'.
$this->getFileName().'/';
@@ -438,8 +438,8 @@ notified in the future, please login to %5$s and click this link:
return false;
}
$newfilename = $this->getFileName();
- $olddirlocation = $GLOBALS['sys_upload_dir'].'/'.$this->FRSPackage->Group->getUnixName().'/'.$this->FRSPackage->getFileName().'/'.$oldfilename;
- $newdirlocation = $GLOBALS['sys_upload_dir'].'/'.$this->FRSPackage->Group->getUnixName().'/'.$this->FRSPackage->getFileName().'/'.$newfilename;
+ $olddirlocation = forge_get_config('upload_dir').'/'.$this->FRSPackage->Group->getUnixName().'/'.$this->FRSPackage->getFileName().'/'.$oldfilename;
+ $newdirlocation = forge_get_config('upload_dir').'/'.$this->FRSPackage->Group->getUnixName().'/'.$this->FRSPackage->getFileName().'/'.$newfilename;
if (($oldfilename!=$newfilename) && is_dir($olddirlocation)) {
if (is_dir($newdirlocation)) {
diff --git a/gforge/common/include/Codendi_HTMLPurifier.class.php b/gforge/common/include/Codendi_HTMLPurifier.class.php
new file mode 100644
index 0000000000..add9b504fa
--- /dev/null
+++ b/gforge/common/include/Codendi_HTMLPurifier.class.php
@@ -0,0 +1,236 @@
+.
+ */
+
+/**
+ * Clean-up HTML code for user output.
+ *
+ * This class aims to purify the HTML code provided by a user for beeing
+ * displayed saftly (remove XSS and make the HTML std compliant).
+ * How to use it:
+ *
+ * require_once('pre.php');
+ * require_once('common/include/Codendi_HTMLPurifier.class.php');
+ * $crapy = 'testé ';
+ * $hp =& Codendi_HTMLPurifier::instance();
+ * $clean = $hp->purify($crapy);
+ *
+ */
+
+define('CODENDI_PURIFIER_CONVERT_HTML', 0);
+define('CODENDI_PURIFIER_STRIP_HTML', 1);
+define('CODENDI_PURIFIER_BASIC', 5);
+define('CODENDI_PURIFIER_BASIC_NOBR', 6);
+define('CODENDI_PURIFIER_LIGHT', 10);
+define('CODENDI_PURIFIER_FULL', 15);
+define('CODENDI_PURIFIER_JS_QUOTE', 20);
+define('CODENDI_PURIFIER_JS_DQUOTE', 25);
+define('CODENDI_PURIFIER_DISABLED', 100);
+
+class Codendi_HTMLPurifier {
+ /**
+ * Hold an instance of the class
+ */
+ private static $Codendi_HTMLPurifier_instance;
+
+ /**
+ * Constructor
+ */
+ private function __construct() {
+ }
+
+ /**
+ * Singleton access.
+ *
+ * @access: static
+ */
+ public static function instance() {
+ if (!isset(self::$Codendi_HTMLPurifier_instance)) {
+ $c = __CLASS__;
+ self::$Codendi_HTMLPurifier_instance = new $c;
+ }
+ return self::$Codendi_HTMLPurifier_instance;
+ }
+
+ /**
+ * Base configuration of HTML Purifier for codendi.
+ */
+ protected function getCodendiConfig() {
+ $config = HTMLPurifier_Config::createDefault();
+ $config->set('Core', 'Encoding', 'UTF-8');
+ // $config->set('HTML', 'Doctype', 'XHTML 1.0 Strict');
+ $config->set('Cache', 'SerializerPath', $GLOBALS['codendi_cache_dir']);
+ return $config;
+ }
+
+ /**
+ * Allow basic formatting markups.
+ *
+ */
+ function getLightConfig() {
+ $config = $this->getCodendiConfig();
+ $config->set('HTML', 'Allowed', $this->getLightConfigMarkups());
+ return $config;
+ }
+
+ /**
+ * Get allowed markups for light config
+ *
+ * This function defines the markups allowed for a light
+ * formatting. This includes markups for lists, for paragraphs, hypertext
+ * links, and content-based text.
+ * Allowed makups:
+ * - 'p', 'br'
+ * - 'a[href|title|class]'
+ * - 'ul', 'ol', 'li'
+ * - 'cite', 'code', 'blockquote', 'strong', 'em', 'pre', 'b', 'i'
+ */
+ function getLightConfigMarkups() {
+ $eParagraph = array('p', 'br');
+ $eLinks = array('a[href|title|class]');
+ $eList = array('ul', 'ol', 'li');
+ $eContentBasedTxt = array('cite', 'code', 'blockquote', 'strong', 'em',
+ 'pre', 'b', 'i');
+
+ $aa = array_merge($eParagraph, $eLinks, $eList, $eContentBasedTxt);
+ $allowed = implode(',', $aa);
+
+ return $allowed;
+ }
+
+ /**
+ *
+ */
+ function getStripConfig() {
+ $config = $this->getCodendiConfig();
+ $config->set('HTML', 'Allowed', '');
+ return $config;
+ }
+
+ /**
+ * HTML Purifier configuration factory
+ */
+ function getHPConfig($level) {
+ $config = null;
+ switch($level) {
+ case CODENDI_PURIFIER_LIGHT:
+ $config = $this->getLightConfig();
+ break;
+
+ case CODENDI_PURIFIER_FULL:
+ $config = $this->getCodendiConfig();
+ break;
+
+ case CODENDI_PURIFIER_STRIP_HTML:
+ $config = $this->getStripConfig();
+ break;
+ }
+ return $config;
+ }
+
+ /**
+ * Wrap call to util_make_links (for testing purpose).
+ */
+ function _makeLinks($str, $groupId) {
+ return util_make_links($str, $groupId);
+ }
+
+ /**
+ * Perform HTML purification depending of level purification required.
+ *
+ * There are 5 level of purification, from the most restrictive to most
+ * permissive:
+ * - CODENDI_PURIFIER_CONVERT_HTML (default)
+ * Transform HTML markups it in entities.
+ *
+ * - CODENDI_PURIFIER_STRIP_HTML
+ * Removes all HTML markups. Note: as we relly on HTML Purifier to
+ * perform this operation this option is not considered as secure as
+ * CONVERT_HTML. If you are looking for the most secure option please
+ * consider CONVERT_HTML.
+ *
+ * - CODENDI_PURIFIER_BASIC (need $groupId to be set for automagic links)
+ * Removes all user submitted HTML markups but:
+ * - transform typed URLs into clickable URLs.
+ * - transform autmagic links.
+ * - transform carrige return into HTML br markup.
+ *
+ * - CODENDI_PURIFIER_LIGHT
+ * First set of HTML formatting (@see getLightConfig() for allowed
+ * markups) plus all what is allowed by CODENDI_PURIFIER_BASIC.
+ *
+ * - CODENDI_PURIFIER_FULL
+ * Clean-up plain HTML using HTML Purifier rules (remove forms,
+ * javascript, ...). Warning: there is no longer codendi facilities
+ * (neither automagic links nor carrige return to br transformation).
+ *
+ * - CODENDI_PURIFIER_DISABLED
+ * No filter at all.
+ */
+ function purify($html, $level=0, $groupId=0) {
+ $clean = '';
+ switch($level) {
+ case CODENDI_PURIFIER_DISABLED:
+ $clean = $html;
+ break;
+
+ case CODENDI_PURIFIER_LIGHT:
+ $html = nl2br($this->_makeLinks($html, $groupId));
+ case CODENDI_PURIFIER_STRIP_HTML:
+ case CODENDI_PURIFIER_FULL:
+ require_once('HTMLPurifier.auto.php');
+ $hp =& HTMLPurifier::getInstance();
+ $config = $this->getHPConfig($level);
+ $clean = $hp->purify($html, $config);
+ // Quite big object, it's better to unset it (memory).
+ unset($config);
+ break;
+
+ case CODENDI_PURIFIER_BASIC:
+ $clean = nl2br($this->_makeLinks(htmlentities($html, ENT_QUOTES, 'UTF-8'), $groupId));
+ break;
+ case CODENDI_PURIFIER_BASIC_NOBR:
+ $clean = $this->_makeLinks(htmlentities($html, ENT_QUOTES, 'UTF-8'), $groupId);
+ break;
+
+ case CODENDI_PURIFIER_JS_QUOTE:
+ $clean = preg_replace('/\<\/script\>/umsi', "'+'script>", addslashes(preg_replace('/\\\n/ums', "
+", $html)));
+ break;
+ case CODENDI_PURIFIER_JS_DQUOTE:
+ $clean = preg_replace('/\<\/script\>/umsi', '"+"script>', addslashes(preg_replace('/\\\n/ums', '
+', $html)));
+ break;
+ case CODENDI_PURIFIER_CONVERT_HTML:
+ default:
+ $clean = htmlentities($html, ENT_QUOTES, 'UTF-8');
+ break;
+ }
+ return $clean;
+ }
+
+ function purifyMap($array, $level=0, $groupId=0) {
+ return array_map(array(&$this, "purify"), $array, array($level), array($groupId));
+ }
+
+}
+
+?>
diff --git a/gforge/common/include/Codendi_Request.class.php b/gforge/common/include/Codendi_Request.class.php
new file mode 100644
index 0000000000..3637843895
--- /dev/null
+++ b/gforge/common/include/Codendi_Request.class.php
@@ -0,0 +1,162 @@
+.
+ */
+
+/* abstract */ class Codendi_Request {
+ /**
+ * @var array
+ * @access private
+ */
+ var $_validated_input;
+
+ /**
+ * @var array
+ * @access private
+ */
+ var $_last_access_to_input;
+
+ /**
+ * @var array
+ */
+ var $params;
+
+ /**
+ * Constructor
+ */
+ function Codendi_Request($params) {
+ $this->params = $params;
+ $this->_validated_input = array();
+ $this->_last_access_to_input = array();
+ }
+
+
+ /**
+ * Get the value of $variable in $this->params (user submitted values).
+ *
+ * @param string $variable Name of the parameter to get.
+ * @return mixed If the variable exist, the value is returned (string)
+ * otherwise return false;
+ */
+ function get($variable) {
+
+ return $this->_get($variable, $this->params);
+ }
+
+ /**
+ * Add a param and/or set its value
+ *
+ */
+ function set($name, $value) {
+ $this->params[$name] = $value;
+ }
+
+
+ /**
+ * Get the value of $variable in $array.
+ *
+ * @access private
+ * @param string $variable Name of the parameter to get.
+ * @param array $array Name of the parameter to get.
+ */
+ function _get($variable, $array) {
+ if ($this->_exist($variable, $array)) {
+ return $array[$variable];
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Check if $variable exists in user submitted parameters.
+ *
+ * @param string $variable Name of the parameter.
+ * @return boolean
+ */
+ function exist($variable) {
+ return $this->_exist($variable, $this->params);
+ }
+
+ /**
+ * Check if $variable exists in $array.
+ *
+ * @access private
+ * @param string $variable Name of the parameter.
+ * @return boolean
+ */
+ function _exist($variable, $array) {
+ return isset($array[$variable]);
+ }
+ /**
+ * Apply validator on submitted user value.
+ *
+ * @param Valid Validator to apply
+ * @return boolean
+ */
+ function valid(&$validator) {
+ $this->_validated_input[$validator->getKey()] = true;
+ $attachmentId=5;
+ return $validator->validate($this->get($validator->getKey()));
+ }
+
+ /**
+ * Apply validator on all values of a submitted user array.
+ *
+ * @param Valid Validator to apply
+ * @return boolean
+ */
+ function validArray(&$validator) {
+ $this->_validated_input[$validator->getKey()] = true;
+ $isValid = true;
+ $array = $this->get($validator->getKey());
+ if (is_array($array)) {
+ if (count($array)>0) {
+ foreach ($array as $key => $v) {
+ if (!$validator->validate($v)) {
+ $isValid = false;
+ }
+ }
+ } else {
+ $isValid = $validator->validate(null);
+ }
+ } else {
+ $isValid = false;
+ }
+ return $isValid;
+ }
+ /**
+ * Apply validator on submitted user value and return the value if valid
+ * Else return default value
+ * @param string $variable Name of the parameter to get.
+ * @param mixed $validator Name of the validator (string, uint, email) or an instance of a validator
+ * @param mixed $default_value Value return if the validator is not valid. Optional, default is null.
+ */
+ function getValidated($variable, $validator = 'string', $default_value = null) {
+ /*$is_valid = false;
+ if ($v = ValidFactory::getInstance($validator, $variable)) {
+ $is_valid = $this->valid($v);
+ } else {
+ trigger_error('Validator '. $validator .' is not found', E_USER_ERROR);
+ }
+ return $is_valid ? $this->get($variable) : $default_value;*/
+ return $this->get($variable);
+ }
+
+
+}
+?>
diff --git a/gforge/common/include/FusionForge.class.php b/gforge/common/include/FusionForge.class.php
index d55769ea8b..b10861440a 100644
--- a/gforge/common/include/FusionForge.class.php
+++ b/gforge/common/include/FusionForge.class.php
@@ -36,7 +36,7 @@ class FusionForge extends Error {
$this->Error();
$this->software_name = 'FusionForge' ;
- $this->software_version = '5.0' ;
+ $this->software_version = '5.0.50' ;
return true;
}
diff --git a/gforge/common/include/Group.class.php b/gforge/common/include/Group.class.php
index 0881795bb8..529369409b 100644
--- a/gforge/common/include/Group.class.php
+++ b/gforge/common/include/Group.class.php
@@ -340,8 +340,8 @@ class Group extends Error {
$is_public,
$unix_name,
htmlspecialchars($description),
- $unix_name.".".$GLOBALS['sys_default_domain'],
- $unix_name.".".$GLOBALS['sys_default_domain'],
+ $unix_name.".".forge_get_config('web_host'),
+ $unix_name.".".forge_get_config('web_host'),
'P',
$unix_box,
$scm_box,
@@ -559,7 +559,7 @@ class Group extends Error {
$homepage = ltrim($homepage);
if (!$homepage) {
- $homepage=$GLOBALS['sys_default_domain'].'/projects/'.$this->getUnixName().'/';
+ $homepage=forge_get_config('web_host').'/projects/'.$this->getUnixName().'/';
}
if (strlen(htmlspecialchars($short_description))>255) {
@@ -872,6 +872,10 @@ class Group extends Error {
* @param string The name of the new SCM_BOX
*/
function setSCMBox($scm_box) {
+
+ if ($scm_box == $this->data_array['scm_box']) {
+ return true;
+ }
if ($scm_box) {
db_begin();
$res = db_query_params ('UPDATE groups SET scm_box=$1 WHERE group_id=$2', array ($scm_box, $this->getID ()));
@@ -1039,8 +1043,8 @@ class Group extends Error {
* @return boolean uses_scm.
*/
function usesSCM() {
- global $sys_use_scm;
- if ($sys_use_scm) {
+
+ if (forge_get_config('use_scm')) {
return $this->data_array['use_scm'];
} else {
return false;
@@ -1053,8 +1057,8 @@ class Group extends Error {
* @return boolean uses_mail.
*/
function usesMail() {
- global $sys_use_mail;
- if ($sys_use_mail) {
+
+ if (forge_get_config('use_mail')) {
return $this->data_array['use_mail'];
} else {
return false;
@@ -1067,8 +1071,8 @@ class Group extends Error {
* @return boolean uses_news.
*/
function usesNews() {
- global $sys_use_news;
- if ($sys_use_news) {
+
+ if (forge_get_config('use_news')) {
return $this->data_array['use_news'];
} else {
return false;
@@ -1081,8 +1085,8 @@ class Group extends Error {
* @return boolean uses_forum.
*/
function usesForum() {
- global $sys_use_forum;
- if ($sys_use_forum) {
+
+ if (forge_get_config('use_forum')) {
return $this->data_array['use_forum'];
} else {
return false;
@@ -1104,8 +1108,8 @@ class Group extends Error {
* @return boolean uses_frs.
*/
function usesFRS() {
- global $sys_use_frs;
- if ($sys_use_frs) {
+
+ if (forge_get_config('use_frs')) {
return $this->data_array['use_frs'];
} else {
return false;
@@ -1118,8 +1122,8 @@ class Group extends Error {
* @return boolean uses_tracker.
*/
function usesTracker() {
- global $sys_use_tracker;
- if ($sys_use_tracker) {
+
+ if (forge_get_config('use_tracker')) {
return $this->data_array['use_tracker'];
} else {
return false;
@@ -1132,8 +1136,8 @@ class Group extends Error {
* @return boolean uses_docman.
*/
function usesDocman() {
- global $sys_use_docman;
- if ($sys_use_docman) {
+
+ if (forge_get_config('use_docman')) {
return $this->data_array['use_docman'];
} else {
return false;
@@ -1146,8 +1150,8 @@ class Group extends Error {
* @return boolean uses_ftp.
*/
function usesFTP() {
- global $sys_use_ftp;
- if ($sys_use_ftp) {
+
+ if (forge_get_config('use_ftp')) {
return $this->data_array['use_ftp'];
} else {
return false;
@@ -1160,8 +1164,8 @@ class Group extends Error {
* @return boolean uses_survey.
*/
function usesSurvey() {
- global $sys_use_survey;
- if ($sys_use_survey) {
+
+ if (forge_get_config('use_survey')) {
return $this->data_array['use_survey'];
} else {
return false;
@@ -1174,8 +1178,8 @@ class Group extends Error {
* @return boolean uses_projman.
*/
function usesPM() {
- global $sys_use_pm;
- if ($sys_use_pm) {
+
+ if (forge_get_config('use_pm')) {
return $this->data_array['use_pm'];
} else {
return false;
@@ -1567,11 +1571,11 @@ class Group extends Error {
$hook_params['group_id'] = $this->getID();
plugin_hook ("group_delete", $hook_params);
- if (isset($GLOBALS['sys_upload_dir']) && $this->getUnixName()) {
- exec('/bin/rm -rf '.$GLOBALS['sys_upload_dir'].'/'.$this->getUnixName().'/');
+ if (forge_get_config('upload_dir') != '' && $this->getUnixName()) {
+ exec('/bin/rm -rf '.forge_get_config('upload_dir').'/'.$this->getUnixName().'/');
}
- if (isset($GLOBALS['sys_ftp_upload_dir']) && $this->getUnixName()) {
- exec('/bin/rm -rf '.$GLOBALS['sys_ftp_upload_dir'].'/'.$this->getUnixName().'/');
+ if (forge_get_config('ftp_upload_dir') != '' && $this->getUnixName()) {
+ exec('/bin/rm -rf '.forge_get_config('ftp_upload_dir').'/'.$this->getUnixName().'/');
}
//
// Delete reporting
@@ -1780,7 +1784,7 @@ class Group extends Error {
* @return boolean success.
*/
function removeUser($user_id) {
- global $SYS,$sys_database_type;
+ global $SYS;
if ($user_id==user_getid()) {
//users can remove themselves
@@ -1824,20 +1828,7 @@ class Group extends Error {
// first have to purge any assignments that would cause
// conflict with existing assignment to 100
//
- if ($sys_database_type == 'mysql') {
- $res=db_mquery("
- SELECT pt.project_task_id
- FROM project_task pt, project_group_list pgl, project_assigned_to pat
- WHERE pt.group_project_id = pgl.group_project_id
- AND pat.project_task_id=pt.project_task_id
- AND pt.status_id='1' AND pgl.group_id='".$this->getID()."'
- AND pat.assigned_to_id='$user_id' INTO @task_list;
- DELETE FROM project_assigned_to WHERE project_task_id IN ( @task_list ) AND assigned_to_id='100'");
- if ($res) {
- $res = db_next_result();
- }
- } else {
- $res = db_query_params ('DELETE FROM project_assigned_to
+ $res = db_query_params ('DELETE FROM project_assigned_to
WHERE project_task_id IN (SELECT pt.project_task_id
FROM project_task pt, project_group_list pgl, project_assigned_to pat
WHERE pt.group_project_id = pgl.group_project_id
@@ -1845,9 +1836,8 @@ class Group extends Error {
AND pt.status_id=1 AND pgl.group_id=$1
AND pat.assigned_to_id=$2)
AND assigned_to_id=100',
- array ($this->getID(),
- $user_id)) ;
- }
+ array ($this->getID(),
+ $user_id)) ;
if (!$res) {
$this->setError(sprintf(_('ERROR: DB: project_assigned_to %d: %s'),1,db_error()));
db_rollback();
@@ -2166,7 +2156,7 @@ class Group extends Error {
// Create MailingList
//
//
- if ($GLOBALS['sys_use_mail']) {
+ if (forge_get_config('use_mail')) {
$mlist = new MailingList($this);
if (!$mlist->create('commits',_('Commits'),1,$idadmin_group)) {
$this->setError(sprintf(_('ML: %s'),$mlist->getErrorMessage()));
@@ -2254,12 +2244,12 @@ Enjoy the system, and please tell others about %4$s. Let us know
if there is anything we can do to help you.
-- the %4$s crew'),
- $this->getPublicName(),
+ htmlspecialchars_decode($this->getPublicName()),
$this->getUnixName(),
util_make_url ('/project/admin/?group_id='.$this->getID()),
- $GLOBALS['sys_name']);
+ forge_get_config ('forge_name'));
- util_send_message($row_admins['email'], sprintf(_('%1$s Project Approved'), $GLOBALS['sys_name']), $message);
+ util_send_message($row_admins['email'], sprintf(_('%1$s Project Approved'), forge_get_config ('forge_name')), $message);
setup_gettext_from_context();
}
@@ -2302,7 +2292,7 @@ Project Unix Name: %2$s
Reasons for negative decision:
-'), $this->getPublicName(), $this->getUnixName(), $GLOBALS['sys_name']);
+'), $this->getPublicName(), $this->getUnixName(), forge_get_config ('forge_name'));
// Check to see if they want to send a custom rejection response
if ($response_id == 0) {
@@ -2314,7 +2304,7 @@ Reasons for negative decision:
"response_text");
}
- util_send_message($row_admins['email'], sprintf(_('%1$s Project Denied'), $GLOBALS['sys_name']), $response);
+ util_send_message($row_admins['email'], sprintf(_('%1$s Project Denied'), forge_get_config ('forge_name')), $response);
setup_gettext_from_context();
}
@@ -2352,7 +2342,7 @@ Reasons for negative decision:
array ('A'));
if (db_numrows($res) < 1) {
- $this->setError(_("There is no administrator to send the mail."));
+ $this->setError(_("There is no administrator to send the mail to."));
return false;
}
@@ -2369,13 +2359,13 @@ Submitter: %5$s (%6$s)
Please visit the following URL to approve or reject this project:
%4$s'),
- $GLOBALS['sys_name'],
- $this->getPublicName(),
- util_unconvert_htmlspecialchars($this->getRegistrationPurpose()),
+ forge_get_config ('forge_name'),
+ htmlspecialchars_decode($this->getPublicName()),
+ htmlspecialchars_decode($this->getRegistrationPurpose()),
util_make_url ('/admin/approve-pending.php'),
$submitter->getRealName(),
$submitter->getUnixName());
- util_send_message($admin_email, sprintf(_('New %1$s Project Submitted'), $GLOBALS['sys_name']), $message);
+ util_send_message($admin_email, sprintf(_('New %1$s Project Submitted'), forge_get_config ('forge_name')), $message);
setup_gettext_from_context();
}
@@ -2388,9 +2378,9 @@ Please visit the following URL to approve or reject this project:
Project Full Name: %2$s
Submitted Description: %3$s
-The %1$s admin team will now examine your project submission. You will be notified of their decision.'), $GLOBALS['sys_name'], $this->getPublicName(), util_unconvert_htmlspecialchars($this->getRegistrationPurpose()), $GLOBALS['sys_default_domain']);
+The %1$s admin team will now examine your project submission. You will be notified of their decision.'), forge_get_config ('forge_name'), $this->getPublicName(), util_unconvert_htmlspecialchars($this->getRegistrationPurpose()), forge_get_config('web_host'));
- util_send_message($email, sprintf(_('New %1$s Project Submitted'), $GLOBALS['sys_name']), $message);
+ util_send_message($email, sprintf(_('New %1$s Project Submitted'), forge_get_config ('forge_name')), $message);
setup_gettext_from_context();
return true;
@@ -2444,6 +2434,25 @@ The %1$s admin team will now examine your project submission. You will be notif
return $rolesId;
}
+ function getRoles () {
+ $result = array () ;
+
+ $roles = $this->getRolesId () ;
+ foreach ($roles as $role_id) {
+ $result[] = new Role ($this, $role_id) ;
+ }
+
+ return $result ;
+ }
+
+ function normalizeAllRoles () {
+ $roles = $this->getRoles () ;
+
+ foreach ($roles as $r) {
+ $r->normalizeData () ;
+ }
+ }
+
/**
* getUnixStatus - Status of activation of unix account.
*
@@ -2520,253 +2529,6 @@ The %1$s admin team will now examine your project submission. You will be notif
return $users;
}
-
- /**
- * getMenu - get an array that contains data for the group menu
- *
- * @param string contains the name of the selected menu item
- * @return array array containing:
- * 'titles': array that stores the titles of the menu entries
- * 'dirs': array that stores the URLs of the menu entries
- * 'start': URL of the starting page of the project
- * 'admindirs': array that stores the URLs of the admin pages
- * for the menu entries, if accessible, false otherwise
- * 'selected': number of the menu entry selected by $toptab
- * 'last_toptab': required internally: stores the
- * value of $toptab for the last call to getMenu()
- */
- function &getMenu($toptab = "") {
- // rebuild menu if it has never been built before, or
- // if the toptab was set differently
- if (!isset($this->menu_data)
- || ($toptab != "")
- || ($toptab != $this->menu_data['last_toptab']))
- {
- $selected = 0;
- $group = $this->getId();
-
- $this->menu_data = array () ;
- $this->menu_data['titles'] = array();
- $this->menu_data['dirs'] = array();
- $this->menu_data['admindirs'] = array();
-
- // Summary
- $this->menu_data['titles'][] = _('Summary');
- if (isset ($GLOBALS['sys_noforcetype']) && $GLOBALS['sys_noforcetype']) {
- $dir = util_make_url ('/project/?group_id=' . $group);
- } else {
- $dir = util_make_url ('/projects/' . $this->getUnixName() .'/');
- }
- $this->menu_data['dirs'][] = $dir;
- $this->menu_data['admindirs'][] = false;
- if ($toptab == "home") {
- $selected = (count($this->menu_data['dirs'])-1);
- }
- // setting 'start' allows to change the
- // projects start page
- $this->menu_data['start'] = $dir;
-
- // Project Admin
- $perm =& $this->getPermission( session_get_user() );
- if ($perm->isAdmin()) {
- $this->menu_data['titles'][] = _('Admin');
- $this->menu_data['dirs'][] = util_make_url ('/project/admin/?group_id=' . $group);
- $this->menu_data['admindirs'][] = false;
- if ($toptab == "admin") {
- $selected = (count($this->menu_data['dirs'])-1);
- }
- }
-
- /* Homepage
- // check for use_home_tab?
- $TABS_DIRS[]='http://'. $this->getHomePage();
- $TABS_TITLES[]=_('Home Page');
- */
-
- // Project Activity tab
- $this->menu_data['titles'][] = _('Activity');
- $this->menu_data['dirs'][] = util_make_url ('/activity/?group_id=' . $group);
- $this->menu_data['admindirs'][] = false;
- if ($toptab == "activity") {
- $selected = (count($this->menu_data['dirs'])-1);
- }
-
- // Forums
- if ($this->usesForum()) {
- $this->menu_data['titles'][] = _('Forums');
- $this->menu_data['dirs'][] = util_make_url ('/forum/?group_id=' . $group);
- if ($perm->isAdmin() || $perm->isForumAdmin()) {
- $this->menu_data['admindirs'][] = util_make_url('/forum/admin/?group_id='.$group);
- } else {
- $this->menu_data['admindirs'][] = false;
- }
- if ($toptab == "forums") {
- $selected = (count($this->menu_data['dirs'])-1);
- }
- }
-
- // Artifact Tracking
- if ($this->usesTracker()) {
- $this->menu_data['titles'][] = _('Tracker');
- $this->menu_data['dirs'][] = util_make_url ('/tracker/?group_id=' . $group);
- if ($perm->isAdmin() || $perm->isArtifactAdmin()) {
- $this->menu_data['admindirs'][] = util_make_url('/tracker/admin/?group_id='.$group);
- } else {
- $this->menu_data['admindirs'][] = false;
- }
- if ($toptab == "tracker" ||
- $toptab == "bugs" ||
- $toptab == "support" ||
- $toptab == "patch") {
- $selected = (count($this->menu_data['dirs'])-1);
- }
- }
-
-
- // Mailing Lists
- if ($this->usesMail()) {
- $this->menu_data['titles'][] = _('Lists');
- $this->menu_data['dirs'][] = util_make_url ('/mail/?group_id=' . $group);
- if ($perm->isAdmin()) {
- $this->menu_data['admindirs'][] = util_make_url('/mail/admin/?group_id='.$group);
- } else {
- $this->menu_data['admindirs'][] = false;
- }
- if ($toptab == "mail") {
- $selected = (count($this->menu_data['dirs'])-1);
- }
-
- }
-
- // Project/Task Manager
- if ($this->usesPm()) {
- $this->menu_data['titles'][] = _('Tasks');
- $this->menu_data['dirs'][] = util_make_url ('/pm/?group_id=' . $group);
- if ($perm->isAdmin() || $perm->isPMAdmin()) {
- $this->menu_data['admindirs'][] = util_make_url ('/pm/admin/?group_id='.$group);
- } else {
- $this->menu_data['admindirs'][] = false;
- }
- if ($toptab == "pm") {
- $selected = (count($this->menu_data['dirs'])-1);
- }
-
- }
-
- // Doc Manager
- if ($this->usesDocman()) {
- $this->menu_data['titles'][] = _('Docs');
- $this->menu_data['dirs'][] = util_make_url ('/docman/?group_id=' . $group);
- if ($perm->isAdmin() || $perm->isDocEditor()) {
- $this->menu_data['admindirs'][] = util_make_url ('/docman/admin/?group_id='.$group);
- } else {
- $this->menu_data['admindirs'][] = false;
- }
- if ($toptab == "docman") {
- $selected = (count($this->menu_data['dirs'])-1);
- }
-
- }
-
- // Surveys
- if ($this->usesSurvey()) {
- $this->menu_data['titles'][] = _('Surveys');
- $this->menu_data['dirs'][] = util_make_url ('/survey/?group_id=' . $group);
- if ($perm->isAdmin()) {
- $this->menu_data['admindirs'][] = util_make_url ('/survey/admin/?group_id='.$group);
- } else {
- $this->menu_data['admindirs'][] = false;
- }
- if ($toptab == "surveys") {
- $selected = (count($this->menu_data['dirs'])-1);
- }
- }
-
- // News
- if ($this->usesNews()) {
- $this->menu_data['titles'][] = _('News');
- $this->menu_data['dirs'][] = util_make_url ('/news/?group_id=' . $group);
- if ($perm->isAdmin()) {
- $this->menu_data['admindirs'][] = util_make_url ('/news/admin/?group_id='.$group);
- } else {
- $this->menu_data['admindirs'][] = false;
- }
- if ($toptab == "news") {
- $selected = (count($this->menu_data['dirs'])-1);
- }
- }
-
- // SCM systems
- if ($this->usesSCM()) {
- $this->menu_data['titles'][] = _('SCM');
- $this->menu_data['dirs'][] = util_make_url ('/scm/?group_id=' . $group);
- // eval cvs_flags?
- if ($perm->isAdmin()) {
- $this->menu_data['admindirs'][] = util_make_url ('/scm/admin/?group_id='.$group);
- } else {
- $this->menu_data['admindirs'][] = false;
- }
- if ($toptab == "scm") {
- $selected = (count($this->menu_data['dirs'])-1);
- }
- }
-
- // groupmenu_after_scm hook
- $hookParams = array();
- $hookParams['group_id'] = $group ;
- $hookParams['DIRS'] =& $this->menu_data['dirs'];
- $hookParams['TITLES'] =& $this->menu_data['titles'];
- $hookParams['toptab'] =& $toptab;
- $hookParams['selected'] =& $selected;
-
- plugin_hook ("groupmenu_scm", $hookParams) ;
-
- // fill up admindirs
- for ($i = 0;
- $i < count($this->menu_data['dirs']) - count($this->menu_data['admindirs']);
- $i++) {
- $this->menu_data['admindirs'][] = false;
- }
-
- // Downloads
- if ($this->usesFRS()) {
- $this->menu_data['titles'][] = _('Files');
- $this->menu_data['dirs'][] = util_make_url ('/frs/?group_id=' . $group);
- if ($perm->isAdmin() || $perm->isReleaseTechnician()) {
- $this->menu_data['admindirs'][] = util_make_url ('/frs/admin/?group_id='.$group);
- } else {
- $this->menu_data['admindirs'][] = false;
- }
- if ($toptab == "frs") {
- $selected = (count($this->menu_data['dirs'])-1);
- }
- }
-
- // groupmenu hook
- $hookParams = array();
- $hookParams['group'] = $group ;
- $hookParams['DIRS'] =& $this->menu_data['dirs'];
- $hookParams['TITLES'] =& $this->menu_data['titles'];
- $hookParams['toptab'] =& $toptab;
- $hookParams['selected'] =& $selected;
-
- plugin_hook ("groupmenu", $hookParams) ;
-
- // fill up admindirs
- for ($i = 0;
- $i < count($this->menu_data['dirs']) - count($this->menu_data['admindirs']);
- $i++) {
- $this->menu_data['admindirs'][] = false;
- }
-
- // store selected menu item (if any)
- $this->menu_data['selected'] = $selected;
- if ($toptab != "") {
- $this->menu_data['last_toptab'] = $toptab;
- }
- }
- return $this->menu_data ;
- }
}
/**
diff --git a/gforge/common/include/HTTPRequest.class.php b/gforge/common/include/HTTPRequest.class.php
new file mode 100644
index 0000000000..84fc0f3d7f
--- /dev/null
+++ b/gforge/common/include/HTTPRequest.class.php
@@ -0,0 +1,138 @@
+.
+ */
+
+
+require_once('common/include/Codendi_Request.class.php');
+
+
+/**
+ * @package Codendi
+ */
+class HTTPRequest extends Codendi_Request {
+
+ /**
+ * Constructor
+ */
+ function HTTPRequest() {
+ parent::Codendi_Request($_REQUEST);
+ }
+
+
+ /**
+ * Get the value of $variable in $this->params (server side values).
+ *
+ * @param string $variable Name of the parameter to get.
+ * @return mixed If the variable exist, the value is returned (string)
+ * otherwise return false;
+ */
+ function getFromServer($variable) {
+ return $this->_get($variable, $_SERVER);
+ }
+
+ /**
+ * Check if current request is send via 'post' method.
+ *
+ * This method is useful to test if the current request comes from a form.
+ *
+ * @return boolean
+ */
+ function isPost() {
+ if($_SERVER['REQUEST_METHOD'] == 'POST') {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Return true if browser used to submit the request is netscape 4.
+ *
+ * @return boolean
+ */
+ function browserIsNetscape4() {
+ return browser_is_netscape4();
+ }
+
+ /**
+ * Singleton method for the class.
+ *
+ * @return mixed HTTPRequest Object.
+ */
+ function &instance() {
+ static $_httprequest_instance;
+ if (!$_httprequest_instance) {
+ $_httprequest_instance = new HTTPRequest();
+ }
+ return $_httprequest_instance;
+ }
+
+ /**
+ * Validate file upload.
+ *
+ * @param Valid_File Validator for files.
+ * @return Boolean
+ */
+ function validFile(&$validator) {
+ if(is_a($validator, 'Valid_File')) {
+ $this->_validated_input[$validator->getKey()] = true;
+ return $validator->validate($_FILES, $validator->getKey());
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Remove slashes in $value. If $value is an array, remove slashes for each
+ * element.
+ *
+ * @access private
+ * @param mixed $value
+ * @return mixed
+ */
+ function _stripslashes($value) {
+ if (is_string($value)) {
+ $value = stripslashes($value);
+ } else if (is_array($value)) {
+ foreach($value as $key => $val) {
+ $value[$key] = $this->_stripslashes($val);
+ }
+ }
+ return $value;
+ }
+
+ /**
+ * Get the value of $variable in $array. If magic_quotes are enabled, the
+ * value is escaped.
+ *
+ * @access private
+ * @param string $variable Name of the parameter to get.
+ * @param array $array Name of the parameter to get.
+ */
+ function _get($variable, $array) {
+ if ($this->_exist($variable, $array)) {
+ return (get_magic_quotes_gpc()?$this->_stripslashes($array[$variable]):$array[$variable]);
+ } else {
+ return false;
+ }
+ }
+
+}
+
+?>
diff --git a/gforge/common/include/Navigation.class.php b/gforge/common/include/Navigation.class.php
new file mode 100644
index 0000000000..0c978bf860
--- /dev/null
+++ b/gforge/common/include/Navigation.class.php
@@ -0,0 +1,645 @@
+Error();
+ return true;
+ }
+
+ /** Get the HTML code of the title of the page. If the array
+ * $params contains a value for the key 'title', this title
+ * is appended to the title generated here. If $asHTML is
+ * set to false, it will return only the title in plain
+ * text. */
+ function getTitle($params, $asHTML=true) {
+ if (!$asHTML) {
+ // get the title
+ if (!$params['title']) {
+ return forge_get_config ('forge_name') ;
+ } else {
+ return forge_get_config ('forge_name') . ': ' . $params['title'];
+ }
+ } else {
+ // return HTML code otherwise
+ return '' . $this->getTitle($params, false) . ' ';
+ }
+ }
+
+ /** Get the HTML code for the favicon links of the site (to be
+ * put into the . If $asHTML is false, it will return
+ * the URL of the favicon.
+ *
+ * @todo: Make favicon configurable
+ */
+ function getFavIcon($asHTML=true) {
+ if (!$asHTML) {
+ return util_make_url('/images/icon.png');
+ } else {
+ return ' '
+ . ' ';
+ }
+ }
+
+ /** Get the HTML code for the RSS feeds of the site (to be put
+ * into the . If $asHTML is false, it will return an
+ * array with the following structure: $result['titles']:
+ * list of titles of the feeds; $result['urls'] list of urls
+ * of the feeds. */
+ function getRSS($asHTML=true) {
+ if (!$asHTML) {
+ $res = array() ;
+ $res['titles'] = array();
+ $res['urls'] = array();
+
+ $res['titles'][] = forge_get_config ('forge_name').' - Project News Highlights RSS';
+ $res['urls'][] = util_make_url('/export/rss_sfnews.php');
+
+ $res['titles'][] = forge_get_config ('forge_name').' - Project News Highlights RSS 2.0';
+ $res['urls'][] = util_make_url('/export/rss20_news.php');
+
+ $res['titles'][] = forge_get_config ('forge_name').' - New Projects RSS';
+ $res['urls'][] = util_make_url('/export/rss_sfprojects.php');
+
+ if (isset($GLOBALS['group_id'])) {
+ $res['titles'][] = forge_get_config ('forge_name') . ' - New Activity RSS';
+ $res['urls'][] = util_make_url('/export/rss20_activity.php?group_id='.$GLOBALS['group_id']);
+ }
+ return $res;
+ } else {
+ $feeds = $this->getRSS(false);
+ for ($j = 0; $j < count($feeds['urls']); $j++) {
+ echo '
+ ';
+ }
+ }
+ }
+
+ /** Get the searchBox HTML code. */
+ function getSearchBox() {
+ global $words,$forum_id,$group_id,$group_project_id,$atid,$exact,$type_of_search;
+
+ $res = "";
+ if (get_magic_quotes_gpc()) {
+ $defaultWords = stripslashes($words);
+ } else {
+ $defaultWords = $words;
+ }
+
+ $defaultWords = htmlspecialchars($defaultWords);
+
+ // if there is no search currently, set the default
+ if (!isset($type_of_search) ) {
+ $exact = 1;
+ }
+
+ $res .= '';
+
+ return $res;
+ }
+
+
+ /** Get an array of the user links (Login/Logout/My
+ Account/Register) with the following structure:
+ $result['titles']: list of the titles. $result['urls']: list
+ of the urls.
+ */
+ function getUserLinks() {
+ $res = array();
+ if (session_loggedin()) {
+ $u =& user_get_object(user_getid());
+ $res['titles'][] = sprintf("%s (%s)", _('Log Out'), $u->getRealName());
+ $res['urls'][] = util_make_url ('/account/logout.php');
+
+ $res['titles'][] = _('My Account');
+ $res['urls'][] = util_make_url ('/account/');
+ } else {
+ $url = '/account/login.php';
+ if(getStringFromServer('REQUEST_METHOD') != 'POST') {
+ $url .= '?return_to=';
+ $url .= urlencode(getStringFromServer('REQUEST_URI'));
+ }
+ $res['titles'][] = _('Log In');
+ $res['urls'][] = util_make_url($url);
+
+ if (!forge_get_config ('user_registration_restricted')) {
+ $res['titles'][] = _('New Account');
+ $res['urls'][] = util_make_url('/account/register.php');
+ }
+ }
+ return $res;
+ }
+
+ /** Get an array of the menu of the site with the following
+ * structure: $result['titles']: list of titles of the
+ * links. $result['urls']: list of urls. $result['selected']:
+ * number of the selected menu entry.
+ */
+ function getSiteMenu() {
+ global $sys_use_project_tags, $sys_use_project_full_list;
+
+ $request_uri = getStringFromServer('REQUEST_URI');
+
+ $menu = array();
+ $menu['titles'] = array();
+ $menu['urls'] = array();
+ $selected = 0;
+
+ // Home
+ $menu['titles'][] = _('Home');
+ $menu['urls'][] = util_make_url ('/');
+
+ // My Page
+ $menu['titles'][] = _('My Page');
+ $menu['urls'][] = util_make_url ('/my/');
+ if (strstr($request_uri, util_make_uri('/my/'))
+ || strstr($request_uri, util_make_uri('/account/'))
+ || strstr($request_uri, util_make_uri('/register/'))
+ || strstr($request_uri, util_make_uri('/themes/'))
+ )
+ {
+ $selected=count($menu['urls'])-1;
+ }
+
+ if (forge_get_config('use_trove') || $sys_use_project_tags || $sys_use_project_full_list) {
+ $menu['titles'][] = _('Projects');
+ $menu['urls'][] = util_make_url ('/softwaremap/') ;
+ if (strstr($request_uri, util_make_uri('/softwaremap/'))) {
+ $selected=count($menu['urls'])-1;
+ }
+ }
+
+ if (forge_get_config('use_snippet')) {
+ $menu['titles'][] = _('Code Snippets');
+ $menu['urls'][] = util_make_url ('/snippet/') ;
+ if (strstr($request_uri, util_make_uri('/snippet/'))) {
+ $selected=count($menu['urls'])-1;
+ }
+ }
+
+ if (forge_get_config('use_people')) {
+ $menu['titles'][] = _('Project Openings');
+ $menu['urls'][] = util_make_url ('/people/') ;
+ if (strstr($request_uri, util_make_uri('/people/'))) {
+ $selected=count($menu['urls'])-1;
+ }
+ }
+
+ // Outermenu hook
+ $before = count($menu['urls']);
+ $plugin_urls = array();
+ $hookParams['DIRS'] = &$menu['urls'];
+ $hookParams['TITLES'] = &$menu['titles'];
+ plugin_hook ("outermenu", $hookParams) ;
+
+ // try to find selected entry
+ for ($j = $before; $j < count($plugin_urls); $j++) {
+ $url = $menu['urls'][$j];
+ if (strstr($request_uri, parse_url ($url, PHP_URL_PATH))) {
+ $selected = $j;
+ break;
+ }
+ }
+
+ // Admin and Reporting
+ $user_is_super=false;
+ if (session_loggedin()) {
+ $projectmaster =& group_get_object(GROUP_IS_MASTER);
+ $projectstats =& group_get_object(GROUP_IS_STATS);
+ $permmaster =& $projectmaster->getPermission( session_get_user() );
+ $permstats =& $projectstats->getPermission( session_get_user() );
+
+ if ($permmaster->isAdmin()) {
+ $user_is_super = true;
+ $menu['titles'][] = _('Site Admin');
+ $menu['urls'][] = util_make_url('/admin/') ;
+ if (strstr($request_uri, util_make_uri('/admin/'))) {
+ $selected=count($menu['urls'])-1;
+ }
+ }
+ if ($permstats->isMember()) {
+ $menu['titles'][] = _('Reporting');
+ $menu['urls'][] = util_make_url ('/reporting/') ;
+ if (strstr($request_uri, util_make_uri('/reporting/'))) {
+ $selected=count($menu['urls'])-1;
+ }
+ }
+ }
+
+ // Project
+ if (isset($GLOBALS['group_id'])) {
+ // get group info using the common result set
+ $project =& group_get_object($GLOBALS['group_id']);
+ if ($project && is_object($project)) {
+ if ($project->isError()) {
+ } elseif (!$project->isProject()) {
+ } else {
+ $menu['titles'][] = $project->getPublicName();
+ if (isset ($GLOBALS['sys_noforcetype']) && $GLOBALS['sys_noforcetype']) {
+ $menu['urls'][]=util_make_url ('/project/?group_id') .$project->getId();
+ } else {
+ $menu['urls'][]=util_make_url ('/projects/') .$project->getUnixName().'/';
+ }
+ $selected=count($menu['urls'])-1;
+ }
+ }
+ }
+
+
+ $menu['selected'] = $selected;
+
+ return $menu;
+ }
+
+
+ /** Get a reference to an array of the projects menu for the
+ * project with the id $group_id with the following
+ * structure: $result['starturl']: URL of the
+ * projects starting page; $result['name']: public name of
+ * the project; $result['titles']: list of titles of the menu
+ * entries; $result['urls']: list of urls of the menu
+ * entries; $result['adminurls']: list of urls to the admin
+ * pages of the menu entries. If the user has no admin
+ * permissions, the correpsonding adminurl is
+ * false. $result['selected']: number of the menu entry that
+ * is currently selected.
+ */
+ function &getProjectMenu ($group_id, $toptab="") {
+ // rebuild menu if it has never been built before, or
+ // if the toptab was set differently
+ if (!isset($this->project_menu_data[$group_id])
+ || ($toptab != "")
+ || ($toptab != $this->project_menu_data[$group_id]['last_toptab']))
+ {
+ // get the group and permission objects
+ $group =& group_get_object($group_id);
+ if (!$group || !is_object($group)) {
+ return;
+ }
+ if ($group->isError()) {
+ //wasn't found or some other problem
+ return;
+ }
+ if (!$group->isProject()) {
+ return;
+ }
+
+ $perm =& $group->getPermission( session_get_user() );
+
+ $selected = 0;
+
+ $menu =& $this->project_menu_data[$group_id];
+ $menu['titles'] = array();
+ $menu['urls'] = array();
+ $menu['adminurls'] = array();
+
+ $menu['name'] = $group->getPublicName();
+
+ // Summary
+ $menu['titles'][] = _('Summary');
+ if (isset ($GLOBALS['sys_noforcetype']) && $GLOBALS['sys_noforcetype']) {
+ $url = util_make_url ('/project/?group_id=' . $group_id);
+ } else {
+ $url = util_make_url ('/projects/' . $group->getUnixName() .'/');
+ }
+ $menu['urls'][] = $url;
+ $menu['adminurls'][] = false;
+ if ($toptab == "home") {
+ $selected = (count($menu['urls'])-1);
+ }
+
+ // setting these allows to change the initial project page
+ $menu['starturl'] = $url;
+
+ // Project Admin
+ if ($perm->isAdmin()) {
+ $menu['titles'][] = _('Admin');
+ $menu['urls'][] = util_make_url ('/project/admin/?group_id=' . $group_id);
+ $menu['adminurls'][] = false;
+ if ($toptab == "admin") {
+ $selected = (count($menu['urls'])-1);
+ }
+ }
+
+ /* Homepage
+ // check for use_home_tab?
+ $TABS_DIRS[]='http://'. $this->getHomePage();
+ $TABS_TITLES[]=_('Home Page');
+ */
+
+ // Project Activity tab
+ $menu['titles'][] = _('Activity');
+ $menu['urls'][] = util_make_url ('/activity/?group_id=' . $group_id);
+ $menu['adminurls'][] = false;
+ if ($toptab == "activity") {
+ $selected = (count($menu['urls'])-1);
+ }
+
+ // Forums
+ if ($group->usesForum()) {
+ $menu['titles'][] = _('Forums');
+ $menu['urls'][] = util_make_url ('/forum/?group_id=' . $group_id);
+ if ($perm->isAdmin() || $perm->isForumAdmin()) {
+ $menu['adminurls'][] = util_make_url('/forum/admin/?group_id='.$group_id);
+ } else {
+ $menu['adminurls'][] = false;
+ }
+ if ($toptab == "forums") {
+ $selected = (count($menu['urls'])-1);
+ }
+ }
+
+ // Artifact Tracking
+ if ($group->usesTracker()) {
+ $menu['titles'][] = _('Tracker');
+ $menu['urls'][] = util_make_url ('/tracker/?group_id=' . $group_id);
+ if ($perm->isAdmin() || $perm->isArtifactAdmin()) {
+ $menu['adminurls'][] = util_make_url('/tracker/admin/?group_id='.$group_id);
+ } else {
+ $menu['adminurls'][] = false;
+ }
+ if ($toptab == "tracker" ||
+ $toptab == "bugs" ||
+ $toptab == "support" ||
+ $toptab == "patch") {
+ $selected = (count($menu['urls'])-1);
+ }
+ }
+
+
+ // Mailing Lists
+ if ($group->usesMail()) {
+ $menu['titles'][] = _('Lists');
+ $menu['urls'][] = util_make_url ('/mail/?group_id=' . $group_id);
+ if ($perm->isAdmin()) {
+ $menu['adminurls'][] = util_make_url('/mail/admin/?group_id='.$group_id);
+ } else {
+ $menu['adminurls'][] = false;
+ }
+ if ($toptab == "mail") {
+ $selected = (count($menu['urls'])-1);
+ }
+
+ }
+
+ // Project/Task Manager
+ if ($group->usesPm()) {
+ $menu['titles'][] = _('Tasks');
+ $menu['urls'][] = util_make_url ('/pm/?group_id=' . $group_id);
+ if ($perm->isAdmin() || $perm->isPMAdmin()) {
+ $menu['adminurls'][] = util_make_url ('/pm/admin/?group_id='.$group_id);
+ } else {
+ $menu['adminurls'][] = false;
+ }
+ if ($toptab == "pm") {
+ $selected = (count($menu['urls'])-1);
+ }
+
+ }
+
+ // Doc Manager
+ if ($group->usesDocman()) {
+ $menu['titles'][] = _('Docs');
+ $menu['urls'][] = util_make_url ('/docman/?group_id=' . $group_id);
+ if ($perm->isAdmin() || $perm->isDocEditor()) {
+ $menu['adminurls'][] = util_make_url ('/docman/admin/?group_id='.$group_id);
+ } else {
+ $menu['adminurls'][] = false;
+ }
+ if ($toptab == "docman") {
+ $selected = (count($menu['urls'])-1);
+ }
+
+ }
+
+ // Surveys
+ if ($group->usesSurvey()) {
+ $menu['titles'][] = _('Surveys');
+ $menu['urls'][] = util_make_url ('/survey/?group_id=' . $group_id);
+ if ($perm->isAdmin()) {
+ $menu['adminurls'][] = util_make_url ('/survey/admin/?group_id='.$group_id);
+ } else {
+ $menu['adminurls'][] = false;
+ }
+ if ($toptab == "surveys") {
+ $selected = (count($menu['urls'])-1);
+ }
+ }
+
+ // News
+ if ($group->usesNews()) {
+ $menu['titles'][] = _('News');
+ $menu['urls'][] = util_make_url ('/news/?group_id=' . $group_id);
+ if ($perm->isAdmin()) {
+ $menu['adminurls'][] = util_make_url ('/news/admin/?group_id='.$group_id);
+ } else {
+ $menu['adminurls'][] = false;
+ }
+ if ($toptab == "news") {
+ $selected = (count($menu['urls'])-1);
+ }
+ }
+
+ // SCM systems
+ if ($group->usesSCM()) {
+ $menu['titles'][] = _('SCM');
+ $menu['urls'][] = util_make_url ('/scm/?group_id=' . $group_id);
+ // eval cvs_flags?
+ if ($perm->isAdmin()) {
+ $menu['adminurls'][] = util_make_url ('/scm/admin/?group_id='.$group_id);
+ } else {
+ $menu['adminurls'][] = false;
+ }
+ if ($toptab == "scm") {
+ $selected = (count($menu['urls'])-1);
+ }
+ }
+
+ // groupmenu_after_scm hook
+ $hookParams = array();
+ $hookParams['group_id'] = $group_id ;
+ $hookParams['DIRS'] =& $menu['urls'];
+ $hookParams['TITLES'] =& $menu['titles'];
+ $hookParams['toptab'] =& $toptab;
+ $hookParams['selected'] =& $selected;
+
+ plugin_hook ("groupmenu_scm", $hookParams) ;
+
+ // fill up adminurls
+ for ($i = 0; $i < count($menu['urls']) - count($menu['adminurls']); $i++) {
+ $menu['adminurls'][] = false;
+ }
+
+ // Downloads
+ if ($group->usesFRS()) {
+ $menu['titles'][] = _('Files');
+ $menu['urls'][] = util_make_url ('/frs/?group_id=' . $group_id);
+ if ($perm->isAdmin() || $perm->isReleaseTechnician()) {
+ $menu['adminurls'][] = util_make_url ('/frs/admin/?group_id='.$group_id);
+ } else {
+ $menu['adminurls'][] = false;
+ }
+ if ($toptab == "frs") {
+ $selected = (count($menu['urls'])-1);
+ }
+ }
+
+ // groupmenu hook
+ $hookParams = array();
+ $hookParams['group'] = $group_id ;
+ $hookParams['DIRS'] =& $menu['urls'];
+ $hookParams['TITLES'] =& $menu['titles'];
+ $hookParams['toptab'] =& $toptab;
+ $hookParams['selected'] =& $selected;
+
+ plugin_hook ("groupmenu", $hookParams) ;
+
+ // fill up adminurls
+ for ($i = 0;
+ $i < count($menu['urls']) - count($menu['adminurls']);
+ $i++)
+ {
+ $menu['adminurls'][] = false;
+ }
+
+ // store selected menu item (if any)
+ $menu['selected'] = $selected;
+ if ($toptab != "") {
+ $menu['last_toptab'] = $toptab;
+ }
+ }
+ return $this->project_menu_data[$group_id] ;
+ }
+
+ /**
+ * Create the HTML code for the banner "Powered By
+ * FusionForge". If $asHTML is set to false, it will return an
+ * array with the following structure: $result['url']: URL for
+ * the link on the banner; $result['image']: URL of the banner
+ * image; $result['title']: HTML code that outputs the banner;
+ * $result['html']: HTML code that creates the banner and the link.
+ */
+ function getPoweredBy($asHTML=true) {
+ $res['url'] = 'http://fusionforge.org/';
+ $res['image'] = util_make_url ('/images/pow-fusionforge.png');
+ $res['title'] = ' ';
+ $res['html'] = util_make_link($res['url'], $res['title'], array(), true);
+ if ($asHTML) {
+ return $res['html'];
+ } else {
+ return $res;
+ }
+ }
+
+ /** Create the HTML code for the "Show Source" link if
+ * $sys_show_source is set, otherwise "". If $asHTML is set
+ * to false, it returns NULL when $sys_show_source is not
+ * set, otherwise an array with the following structure:
+ * $result['url']: URL of the link to the source code viewer;
+ * $result['title']: Title of the link.
+ */
+ function getShowSource($asHTML=true) {
+ global $sys_show_source;
+ if ($sys_show_source) {
+ $res['url'] = util_make_url('/source.php?file='.getStringFromServer('SCRIPT_NAME'));
+ $res['title'] = _('Show source');
+ } else {
+ return ($asHTML ? "" : NULL);
+ }
+ if (!$asHTML) {
+ return $res;
+ } else {
+ return util_make_link($res['url'], $res['title'],
+ array('class' => 'showsource'),
+ true);
+ }
+ }
+}
+
+// Local Variables:
+// mode: php
+// c-file-style: "bsd"
+// End:
+
+?>
\ No newline at end of file
diff --git a/gforge/common/include/Permission.class.php b/gforge/common/include/Permission.class.php
index c90ec5f7e4..abfd80f80d 100644
--- a/gforge/common/include/Permission.class.php
+++ b/gforge/common/include/Permission.class.php
@@ -258,7 +258,7 @@ class Permission extends Error {
}
/**
- * isPMAdmin - whether the current user has Task Manager admin perms.
+ * isPMAdmin - whether the current user has Tasks admin perms.
*
* @return boolean is_projman_admin.
*/
diff --git a/gforge/common/include/Plugin.class.php b/gforge/common/include/Plugin.class.php
index fd32452bca..f96d369b91 100644
--- a/gforge/common/include/Plugin.class.php
+++ b/gforge/common/include/Plugin.class.php
@@ -20,6 +20,9 @@
* along with FusionForge; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
+ *
+ * Portions Copyright (c) Xerox Corporation, Codendi Team, 2001-2009. All rights reserved
+ * Portions Copyright 2010 (c) Mélanie Le Bail
*/
class Plugin extends Error {
@@ -30,7 +33,7 @@ class Plugin extends Error {
* Plugin() - constructor
*
*/
- function Plugin () {
+ function Plugin ($id=0) {
$this->Error() ;
$this->name = false ;
$this->hooks = array () ;
@@ -44,6 +47,12 @@ class Plugin extends Error {
function GetHooks () {
return $this->hooks ;
}
+ /**
+ * _addHooks() - add a hook to the list of hooks
+ */
+ function _addHook ($name) {
+ return $this->hooks[]=$name ;
+ }
/**
* GetName() - get plugin name
@@ -98,6 +107,51 @@ class Plugin extends Error {
return $result ;
}
+
+ function getThemePath(){
+ return util_make_url('plugins/'.$this->name.'/themes/default');
+ }
+
+ function registerRoleValues(&$params, $values) {
+ $role =& $params['role'] ;
+ }
+
+}
+
+class PluginSpecificRoleSetting {
+ var $role ;
+ var $name = '' ;
+ var $section = '' ;
+ var $values = array () ;
+ var $default_values = array () ;
+
+ function PluginSpecificRoleSetting (&$role, $name) {
+ $this->role =& $role ;
+ $this->name = $name ;
+ }
+
+ function SetAllowedValues ($values) {
+ $this->role->role_values = array_replace_recursive ($this->role->role_values,
+ array ($this->name => $values)) ;
+ }
+
+ function SetDefaultValues ($defaults) {
+ foreach ($defaults as $rname => $v) {
+ $this->role->defaults[$rname][$this->name] = $v ;
+ }
+ }
+
+ function setValueDescriptions ($descs) {
+ global $rbac_permission_names ;
+ foreach ($descs as $k => $v) {
+ $rbac_permission_names[$this->name.$k] = $v ;
+ }
+ }
+
+ function setDescription ($desc) {
+ global $rbac_edit_section_names ;
+ $rbac_edit_section_names[$this->name] = $desc ;
+ }
}
// Local Variables:
diff --git a/gforge/common/include/PluginInfo.class.php b/gforge/common/include/PluginInfo.class.php
new file mode 100644
index 0000000000..fd1f930617
--- /dev/null
+++ b/gforge/common/include/PluginInfo.class.php
@@ -0,0 +1,56 @@
+.
+ */
+
+/**
+ * PluginInfo
+ */
+class PluginInfo {
+
+ var $plugin;
+ var $pluginDescriptor;
+ var $propertyDescriptors;
+
+ function PluginInfo($plugin) {
+ $this->plugin = $plugin;
+ }
+
+ function setPluginDescriptor($descriptor) {
+ }
+
+ function getPluginDescriptor() {
+ }
+ function getPropertyDescriptors() {
+ }
+
+ function _addPropertyDescriptor($descriptor) {
+ }
+ function _removePropertyDescriptor($descriptor) {
+ }
+
+ function loadProperties() {
+ }
+
+ function saveProperties() {
+ }
+
+ function getPropertyDescriptorForName($name) {
+ }
+}
+?>
diff --git a/gforge/common/include/PluginManager.class.php b/gforge/common/include/PluginManager.class.php
index 1e64a25c3f..3f49a97e01 100644
--- a/gforge/common/include/PluginManager.class.php
+++ b/gforge/common/include/PluginManager.class.php
@@ -18,7 +18,7 @@
*
* You should have received a copy of the GNU General Public License
* along with FusionForge; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
@@ -38,7 +38,15 @@ class PluginManager extends Error {
$this->plugins_to_hooks = array () ;
$this->hooks_to_plugins = array () ;
}
+ //to work with Codendi files
+ function instance() {
+ global $PLUGINMANAGER_OBJ;
+ if (!isset($PLUGINMANAGER_OBJ) || !$PLUGINMANAGER_OBJ) {
+ $PLUGINMANAGER_OBJ = new PluginManager ;
+ }
+ return $PLUGINMANAGER_OBJ ;
+ }
/**
* GetPlugins() - get a list of installed plugins
*
@@ -48,7 +56,7 @@ class PluginManager extends Error {
if (!isset($this->plugins_data)) {
$this->plugins_data = array () ;
$res = db_query_params ('SELECT plugin_id, plugin_name FROM plugins',
- array ());
+ array ());
$rows = db_numrows($res);
for ($i=0; $i<$rows; $i++) {
$plugin_id = db_result($res,$i,'plugin_id');
@@ -68,6 +76,10 @@ class PluginManager extends Error {
return @$this->plugins_objects [$pluginname] ;
}
+ //Added for Codendi compatibility
+ function getPluginByName ($pluginname) {
+ return @$this->plugins_objects [$pluginname] ;
+ }
/**
* PluginIsInstalled() - is a plugin installed?
*
@@ -83,13 +95,22 @@ class PluginManager extends Error {
}
return false ;
}
-
+ function isPluginAvailable ($plugin) {
+ $pluginname = $plugin->GetName();
+ $plugins_data = $this->getPlugins() ;
+ foreach ($plugins_data as $p_id => $p_name) {
+ if ($p_name == $pluginname) {
+ return true ;
+ }
+ }
+ return false ;
+ }
function activate($pluginname) {
$res = db_query_params('INSERT INTO plugins (plugin_name,plugin_desc) VALUES ($1,$2)',
- array($pluginname, "This is the $pluginname plugin"));
+ array($pluginname, "This is the $pluginname plugin"));
$res = db_query_params ('SELECT plugin_id, plugin_name FROM plugins WHERE plugin_name=$1',
- array ($pluginname));
+ array ($pluginname));
if (db_numrows($res) == 1) {
$plugin_id = db_result($res,0,'plugin_id');
$this->plugins_data[$plugin_id] = db_result($res,0,'plugin_name');
@@ -99,7 +120,7 @@ class PluginManager extends Error {
return $res;
}
- function desactivate($pluginname) {
+ function deactivate($pluginname) {
$res = db_query_params('DELETE FROM plugins WHERE plugin_name = $1', array($pluginname));
foreach ($this->plugins_data as $i => $n) {
@@ -117,9 +138,9 @@ class PluginManager extends Error {
*/
function LoadPlugin ($p_name) {
global $gfplugins;
-
+
$plugins_data = $this->GetPlugins() ;
- $include_path = $GLOBALS['sys_plugins_path'] ;
+ $include_path = forge_get_config('plugins_path') ;
$filename = $include_path . '/'. $p_name . "/common/".$p_name."-init.php" ;
if (file_exists ($filename)) {
require_once ($filename) ;
@@ -227,7 +248,11 @@ class PluginManager extends Error {
} else {
return 0 ;
}
-
+
+ }
+ function isPluginAllowedForProject($p, $group_id) {
+ $Group = group_get_object($group_id);
+ return $Group->usesPlugin($p->getName());
}
}
diff --git a/gforge/common/include/ProjectManager.class.php b/gforge/common/include/ProjectManager.class.php
new file mode 100644
index 0000000000..44e0d0a926
--- /dev/null
+++ b/gforge/common/include/ProjectManager.class.php
@@ -0,0 +1,67 @@
+.
+ */
+
+
+/**
+ * Provide access to projects
+ */
+class ProjectManager {
+
+ /**
+
+
+ /**
+ * Hold an instance of the class
+ */
+ private static $_instance;
+
+ /**
+ * A private constructor; prevents direct creation of object
+ */
+ private function __construct() {
+
+ }
+
+ /**
+ * ProjectManager is a singleton
+ * @return ProjectManager
+ */
+ public static function instance() {
+ if (!isset(self::$_instance)) {
+ $c = __CLASS__;
+ self::$_instance = new $c;
+ }
+ return self::$_instance;
+ }
+
+
+
+ /**
+ * @param $group_id int The id of the project to look for
+ * @return Project
+ */
+ public function & getProject($group_id) {
+
+ return group_get_object($group_id);
+ }
+
+
+}
+?>
diff --git a/gforge/common/include/Role.class.php b/gforge/common/include/Role.class.php
index 02f9646518..124d82fc58 100644
--- a/gforge/common/include/Role.class.php
+++ b/gforge/common/include/Role.class.php
@@ -31,22 +31,96 @@ class Role extends Error {
var $setting_array;
var $role_vals;
var $Group;
- var $role_values=array(
- 'projectadmin'=>array('0','A'),
- 'frs'=>array('0','1'),
- 'scm'=>array('-1','0','1'),
- 'docman'=>array('0','1'),
- 'forumadmin'=>array('0','2'),
- 'forum'=>array('-1','0','1','2'),
- 'trackeradmin'=>array('0','2'),
- 'tracker'=>array('-1','0','1','2','3'),
- 'pmadmin'=>array('0','2'),
- 'pm'=>array('-1','0','1','2','3'),
- 'webcal'=>array('0','1','2'));
-
- var $defaults;
-
+ var $role_values = array(
+ 'projectadmin' => array ('0','A'),
+ 'frs' => array ('0','1'),
+ 'scm' => array ('-1','0','1'),
+ 'docman' => array ('0','1'),
+ 'forumadmin' => array ('0','2'),
+ 'forum' => array ('-1','0','1','2'),
+ 'newforum' => array ('-1','0','1','2'),
+ 'trackeradmin' => array ('0','2'),
+ 'tracker' => array ('-1','0','1','2','3'),
+ 'newtracker' => array ('-1','0','1','2','3'),
+ 'pmadmin' => array ('0','2'),
+ 'pm' => array ('-1','0','1','2','3'),
+ 'newpm' => array ('-1','0','1','2','3'),
+ 'webcal' => array ('0','1','2'));
+ var $defaults = array(
+ 'Admin' => array( 'projectadmin'=>'A',
+ 'frs'=>'1',
+ 'scm'=>'1',
+ 'docman'=>'1',
+ 'forumadmin'=>'2',
+ 'forum'=>'2',
+ 'newforum'=>'2',
+ 'trackeradmin'=>'2',
+ 'tracker'=>'2',
+ 'newtracker'=>'2',
+ 'pmadmin'=>'2',
+ 'pm'=>'2',
+ 'newpm'=>'2',
+ 'webcal'=>'1' ),
+ 'Senior Developer'=> array( 'projectadmin'=>'0',
+ 'frs'=>'1',
+ 'scm'=>'1',
+ 'docman'=>'1',
+ 'forumadmin'=>'2',
+ 'forum'=>'2',
+ 'newforum'=>'2',
+ 'trackeradmin'=>'2',
+ 'tracker'=>'2',
+ 'newtracker'=>'2',
+ 'pmadmin'=>'2',
+ 'pm'=>'2',
+ 'newpm'=>'2',
+ 'webcal'=>'2' ),
+ 'Junior Developer'=> array( 'projectadmin'=>'0',
+ 'frs'=>'0',
+ 'scm'=>'1',
+ 'docman'=>'0',
+ 'forumadmin'=>'0',
+ 'forum'=>'1',
+ 'newforum'=>'1',
+ 'trackeradmin'=>'0',
+ 'tracker'=>'1',
+ 'newtracker'=>'1',
+ 'pmadmin'=>'0',
+ 'pm'=>'1',
+ 'newpm'=>'1',
+ 'webcal'=>'2' ),
+ 'Doc Writer' => array( 'projectadmin'=>'0',
+ 'frs'=>'0',
+ 'scm'=>'0',
+ 'docman'=>'1',
+ 'forumadmin'=>'0',
+ 'forum'=>'1',
+ 'newforum'=>'1',
+ 'trackeradmin'=>'0',
+ 'tracker'=>'0',
+ 'newtracker'=>'0',
+ 'pmadmin'=>'0',
+ 'pm'=>'0' ,
+ 'newpm'=>'0' ,
+ 'webcal'=>'2'),
+ 'Support Tech' => array( 'projectadmin'=>'0',
+ 'frs'=>'0',
+ 'scm'=>'0',
+ 'docman'=>'1',
+ 'forumadmin'=>'0',
+ 'forum'=>'1',
+ 'newforum'=>'1',
+ 'trackeradmin'=>'0',
+ 'tracker'=>'2',
+ 'newtracker'=>'2',
+ 'pmadmin'=>'0',
+ 'pm'=>'0' ,
+ 'newpm'=>'0' ,
+ 'webcal'=>'2')
+ );
+
+
/**
* Role($group,$id) - CONSTRUCTOR.
*
@@ -54,20 +128,6 @@ class Role extends Error {
* @param int The role_id.
*/
function Role ($Group,$role_id=false) {
- # Initialize the default group settings
- if ($GLOBALS['default_roles']) {
- $this->defaults=$GLOBALS['default_roles'];
- } else {
- $this->defaults=array(
- 'Admin'=>array( 'projectadmin'=>'A', 'frs'=>'1', 'scm'=>'1', 'docman'=>'1', 'forumadmin'=>'2', 'forum'=>'2', 'trackeradmin'=>'2', 'tracker'=>'2', 'pmadmin'=>'2', 'pm'=>'2', 'webcal'=>'1' ),
- 'Senior Developer'=>array( 'projectadmin'=>'0', 'frs'=>'1', 'scm'=>'1', 'docman'=>'1', 'forumadmin'=>'2', 'forum'=>'2', 'trackeradmin'=>'2', 'tracker'=>'2', 'pmadmin'=>'2', 'pm'=>'2', 'webcal'=>'2' ),
- 'Junior Developer'=>array( 'projectadmin'=>'0', 'frs'=>'0', 'scm'=>'1', 'docman'=>'0', 'forumadmin'=>'0', 'forum'=>'1', 'trackeradmin'=>'0', 'tracker'=>'1', 'pmadmin'=>'0', 'pm'=>'1', 'webcal'=>'2' ),
- 'Doc Writer'=>array( 'projectadmin'=>'0', 'frs'=>'0', 'scm'=>'0', 'docman'=>'1', 'forumadmin'=>'0', 'forum'=>'1', 'trackeradmin'=>'0', 'tracker'=>'0', 'pmadmin'=>'0', 'pm'=>'0' , 'webcal'=>'2'),
- 'Support Tech'=>array( 'projectadmin'=>'0', 'frs'=>'0', 'scm'=>'0', 'docman'=>'1', 'forumadmin'=>'0', 'forum'=>'1', 'trackeradmin'=>'0', 'tracker'=>'2', 'pmadmin'=>'0', 'pm'=>'0' , 'webcal'=>'2')
- );
- }
-
-
$this->Error();
if (!$Group || !is_object($Group) || $Group->isError()) {
$this->setError('Role::'.$Group->getErrorMessage());
@@ -79,7 +139,16 @@ class Role extends Error {
$hook_params['role'] =& $this;
plugin_hook ("role_get", $hook_params);
-
+ if (isset ($GLOBALS['default_roles'])) {
+ $this->defaults = array_merge_recursive ($this->defaults,
+ $GLOBALS['default_roles']) ;
+ foreach ($this->defaults as $k => $v) {
+ if (!array_key_exists ($GLOBALS['default_roles'], $k)) {
+ unset ($this->defaults[$k]) ;
+ }
+ }
+ }
+
if (!$role_id) {
//setting up an empty object
//probably going to call create()
@@ -262,6 +331,115 @@ class Role extends Error {
return true;
}
+ function normalizeDataForSection (&$new_sa, $section) {
+ if (array_key_exists ($section, $this->setting_array)) {
+ $new_sa[$section][0] = $this->setting_array[$section][0] ;
+ } elseif (array_key_exists ($this->data_array['role_name'], $this->defaults)
+ && array_key_exists ($section, $this->defaults[$this->data_array['role_name']])) {
+ $new_sa[$section][0] = $this->defaults[$this->data_array['role_name']][$section] ;
+ } else {
+ $new_sa[$section][0] = 0 ;
+ }
+ return $new_sa ;
+ }
+
+ function normalizeData () {
+ db_begin () ;
+ $this->fetchData ($this->getID()) ;
+
+ $new_sa = array () ;
+
+ // Add missing settings
+ // ...project-wide settings
+ $arr = array ('projectadmin', 'frs', 'scm', 'docman', 'forumadmin', 'trackeradmin', 'newtracker', 'pmadmin', 'newpm', 'webcal') ;
+ foreach ($arr as $section) {
+ $this->normalizeDataForSection ($new_sa, $section) ;
+ }
+
+ $hook_params = array ();
+ $hook_params['role'] =& $this;
+ $hook_params['new_sa'] =& $new_sa ;
+ plugin_hook ("role_normalize", $hook_params);
+
+ // ...tracker-related settings
+ $new_sa['tracker'] = array () ;
+ $res = db_query_params ('SELECT group_artifact_id FROM artifact_group_list WHERE group_id=$1',
+ array ($this->Group->getID())) ;
+ if (!$res) {
+ $this->setError('Error: Tracker '.db_error());
+ return false;
+ }
+ for ($j=0; $jsetting_array)
+ && array_key_exists ($tid, $this->setting_array['tracker']) ) {
+ $new_sa['tracker'][$tid] = $this->setting_array['tracker'][$tid] ;
+ } else {
+ $new_sa['tracker'][$tid] = $new_sa['newtracker'][0] ;
+ }
+ }
+
+ // ...forum-related settings
+ $new_sa['forum'] = array () ;
+ $res = db_query_params ('SELECT group_forum_id FROM forum_group_list WHERE group_id=$1',
+ array ($this->Group->getID())) ;
+ if (!$res) {
+ $this->setError('Error: Forum '.db_error());
+ return false;
+ }
+ for ($j=0; $jsetting_array)
+ && array_key_exists ($tid, $this->setting_array['forum']) ) {
+ $new_sa['forum'][$tid] = $this->setting_array['forum'][$tid] ;
+ } else {
+ $new_sa['forum'][$tid] = $new_sa['newforum'][0] ;
+ }
+ }
+
+ // ...subproject-related settings
+ $new_sa['pm'] = array () ;
+ $res = db_query_params ('SELECT group_project_id FROM project_group_list WHERE group_id=$1',
+ array ($this->Group->getID())) ;
+ if (!$res) {
+ $this->setError('Error: Subproject '.db_error());
+ return false;
+ }
+ for ($j=0; $jsetting_array)
+ && array_key_exists ($tid, $this->setting_array['pm']) ) {
+ $new_sa['pm'][$tid] = $this->setting_array['pm'][$tid] ;
+ } else {
+ $new_sa['pm'][$tid] = $new_sa['newpm'][0] ;
+ }
+ }
+
+ // Delete extra settings
+ db_query_params ('DELETE FROM role_setting WHERE role_id=$1 AND section_name <> ALL ($2)',
+ array ($this->getID(),
+ db_string_array_to_any_clause (array_keys ($this->role_values)))) ;
+ db_query_params ('DELETE FROM role_setting WHERE role_id=$1 AND section_name = $2 AND ref_id <> ALL ($3)',
+ array ($this->getID(),
+ 'tracker',
+ db_int_array_to_any_clause (array_keys ($new_sa['tracker'])))) ;
+ db_query_params ('DELETE FROM role_setting WHERE role_id=$1 AND section_name = $2 AND ref_id <> ALL ($3)',
+ array ($this->getID(),
+ 'forum',
+ db_int_array_to_any_clause (array_keys ($new_sa['forum'])))) ;
+ db_query_params ('DELETE FROM role_setting WHERE role_id=$1 AND section_name = $2 AND ref_id <> ALL ($3)',
+ array ($this->getID(),
+ 'pm',
+ db_int_array_to_any_clause (array_keys ($new_sa['pm'])))) ;
+
+ db_commit () ;
+
+ // Save
+ $this->update ($this->data_array['role_name'], $new_sa) ;
+
+ return true;
+ }
+
/**
* &getRoleVals - get all the values and language text strings for this section.
*
diff --git a/gforge/common/include/SCMPlugin.class.php b/gforge/common/include/SCMPlugin.class.php
index eafdbab89a..58f532788e 100644
--- a/gforge/common/include/SCMPlugin.class.php
+++ b/gforge/common/include/SCMPlugin.class.php
@@ -160,7 +160,7 @@ abstract class SCMPlugin extends Plugin {
}
function printPage ($params) {
- global $HTML, $sys_scm_snapshots_path;
+ global $HTML;
$project = $this->checkParams ($params) ;
if (!$project) {
diff --git a/gforge/common/include/User.class.php b/gforge/common/include/User.class.php
index 4fd746407c..4b7b6ccb6c 100644
--- a/gforge/common/include/User.class.php
+++ b/gforge/common/include/User.class.php
@@ -56,7 +56,7 @@ function &user_get_object_by_name($user_name,$res=false) {
*/
function user_get_object_by_email($email,$res=false) {
if (!validate_email($email)
- || !$GLOBALS['sys_require_unique_email']) {
+ || !forge_get_config('require_unique_email')) {
return false ;
}
if (!$res) {
@@ -241,7 +241,7 @@ class GFUser extends Error {
$this->setError(_('You must supply a theme'));
return false;
}
- if (! $GLOBALS['sys_require_unique_email']) {
+ if (! forge_get_config('require_unique_email')) {
if (!$unix_name) {
$this->setError(_('You must supply a username'));
return false;
@@ -294,13 +294,13 @@ class GFUser extends Error {
$this->setError(_('That username already exists.'));
return false;
}
- if ($GLOBALS['sys_require_unique_email']) {
+ if (forge_get_config('require_unique_email')) {
if (user_get_object_by_email ('$email')) {
$this->setError(_('User with this email already exists - use people search to recover your login.'));
return false;
}
}
- if ($GLOBALS['sys_require_unique_email'] && !$unix_name) {
+ if (forge_get_config('require_unique_email') && !$unix_name) {
// Let's generate a loginname for the user
// ...based on the email address:
$email_array = explode ('@', $email, 2) ;
@@ -430,10 +430,10 @@ Enjoy the site.
'),
$this->getUnixName(),
util_make_url ('/account/verify.php?confirm_hash=_'.$this->getConfirmHash()),
- $GLOBALS['sys_name']));
+ forge_get_config ('forge_name')));
util_send_message(
$this->getEmail(),
- sprintf(_('%1$s Account Registration'), $GLOBALS['sys_name']),
+ sprintf(_('%1$s Account Registration'), forge_get_config ('forge_name')),
$message
);
}
@@ -797,6 +797,11 @@ Enjoy the site.
function getMD5Passwd() {
return $this->data_array['user_pw'];
}
+
+ //Added to be compatible with codendi getUserPw function
+ function getUserPw() {
+ return $this->data_array['user_pw'];
+ }
/**
* getConfirmHash - the confirm hash in the db.
@@ -815,6 +820,15 @@ Enjoy the site.
function getEmail() {
return $this->data_array['email'];
}
+
+ /**
+ * getSha1Email - a SHA1 encoded hash of the email URI (including mailto: prefix)
+ *
+ * @return string The SHA1 encoded value for the email
+ */
+ function getSha1Email() {
+ return sha1('mailto:'.$this->getEmail());
+ }
/**
* getNewEmail - while changing an email address, it is stored here until confirmation.
@@ -845,7 +859,7 @@ Enjoy the site.
return false;
}
- if ($GLOBALS['sys_require_unique_email']) {
+ if (forge_get_config('require_unique_email')) {
if (db_numrows(db_query_params('SELECT user_id FROM users WHERE user_id!=$1 AND (lower(email) LIKE $2 OR lower(email_new) LIKE $2)',
array ($this->getID(),
strtolower($email)))) > 0) {
@@ -898,7 +912,7 @@ Enjoy the site.
return false;
}
- if ($GLOBALS['sys_require_unique_email']) {
+ if (forge_get_config('require_unique_email')) {
if (db_numrows(db_query_params('SELECT user_id FROM users WHERE user_id!=$1 AND (lower(email) LIKE $2 OR lower(email_new) LIKE $2)',
array ($this->getID(),
strtolower($email)))) > 0) {
@@ -926,7 +940,8 @@ Enjoy the site.
* @return string This user's real name.
*/
function getRealName() {
- return $this->getFirstName(). ' ' .$this->getLastName();
+ $last_name = $this->getLastName();
+ return $this->getFirstName(). ($last_name ? ' ' .$last_name:'');
}
/**
@@ -1478,10 +1493,10 @@ Enjoy the site.
} else {
$this->theme=$this->data_array['dirname'];
}
- if (is_file($GLOBALS['sys_themeroot'].$this->theme.'/Theme.class.php')) {
+ if (is_file(forge_get_config('themes_root').$this->theme.'/Theme.class.php')) {
$GLOBALS['sys_theme']=$this->theme;
} else {
- $this->theme=$GLOBALS['sys_theme'];
+ $this->theme=forge_get_config('default_theme');
}
return $this->theme;
}
@@ -1500,7 +1515,7 @@ Enjoy the site.
$res = db_query_params ('SELECT role_id FROM user_group WHERE user_id=$1 AND group_id=$2',
array ($this->getID(),
$group->getID())) ;
- if (!$res) {
+ if (!$res || db_numrows($res) < 1) {
$this->setError('User::getRole::DB - Could Not get role_id '.db_error());
return false;
}
@@ -1518,6 +1533,59 @@ Enjoy the site.
}
return $role;
}
+
+ function isMember($group_id, $type=0) {
+ if (!session_loggedin()) {
+ return false;
+ }
+
+ $project =& group_get_object($group_id);
+
+ if (!$project || !is_object($project)) {
+ exit_no_group();
+ }
+
+ $perm =& $project->getPermission( $this );
+ if (!$perm || !is_object($perm) || !$perm->isMember()) {
+ return false;
+ }
+
+ $type=strtoupper($type);
+
+ switch ($type) {
+ case 'P2' : {
+ //pm admin
+ return $perm->isPMAdmin();
+ break;
+ }
+ case 'F2' : {
+ //forum admin
+ return $perm->isForumAdmin();
+ break;
+ }
+ case '0' : {
+ //just in this group
+ return $perm->isMember();
+ break;
+ }
+ case 'A' : {
+ //admin for this group
+ return $perm->isAdmin();
+ break;
+ }
+ case 'D1' : {
+ //document editor
+ return $perm->isDocEditor();
+ break;
+ }
+ default : {
+ //fubar request
+ return false;
+ }
+ }
+ return false;
+
+ }
}
/*
diff --git a/gforge/common/include/UserManager.class.php b/gforge/common/include/UserManager.class.php
new file mode 100644
index 0000000000..a768bc6f28
--- /dev/null
+++ b/gforge/common/include/UserManager.class.php
@@ -0,0 +1,74 @@
+.
+ */
+
+require_once('User.class.php');
+
+
+class UserManager {
+
+
+ protected function __construct() {
+ }
+
+ protected static $_instance;
+ public static function instance() {
+ if (!isset(self::$_instance)) {
+ $c = __CLASS__;
+ self::$_instance = new $c();
+ }
+ return self::$_instance;
+ }
+
+
+ /**
+ * @param $session_hash string Optional parameter. If given, this will force
+ * the load of the user with the given session_hash.
+ * else it will check from the user cookies & ip
+ * @return User the user currently logged in (who made the request)
+ */
+ function getCurrentUser($session_hash = false) {
+ if (!session_get_user()) {
+ return new GFUser();
+ }
+ return session_get_user();
+ }
+
+ function getUserById($user_id) {
+ return user_get_object($user_id);
+ }
+
+ function getUserByEmail($user_id) {
+ return user_get_object_by_email($user_id);
+ }
+ function existEmail ($email) {
+ if (!validate_email($email)) {
+ return false;
+ }
+ $res = db_query_params('SELECT * FROM users WHERE email=$1', array($email));
+ if (!$res || db_numrows($res)<1) {
+ return false;
+ }
+ else {
+ return $email;
+ }
+ }
+}
+
+?>
diff --git a/gforge/common/include/account.php b/gforge/common/include/account.php
index c03416b5bb..ddbd71624b 100644
--- a/gforge/common/include/account.php
+++ b/gforge/common/include/account.php
@@ -45,7 +45,7 @@ function account_pwvalid($pw) {
*
*/
function account_namevalid($name) {
- global $sys_use_shell;
+
// no spaces
if (strrpos($name,' ') > 0) {
@@ -75,7 +75,7 @@ function account_namevalid($name) {
$GLOBALS['register_error'] = _('Name is reserved.');
return 0;
}
- if ($sys_use_shell) {
+ if (forge_get_config('use_shell')) {
if ( exec("getent passwd $name") != "" ){
$GLOBALS['register_error'] = _('That username already exists.');
return 0;
diff --git a/gforge/common/include/config-vars.php b/gforge/common/include/config-vars.php
new file mode 100644
index 0000000000..5a26d916ac
--- /dev/null
+++ b/gforge/common/include/config-vars.php
@@ -0,0 +1,75 @@
+software_name) ;
+ forge_define_config_item ('user_registration_restricted', 'core', false) ;
+*/
+
+?>
diff --git a/gforge/common/include/config.php b/gforge/common/include/config.php
new file mode 100644
index 0000000000..e494605cde
--- /dev/null
+++ b/gforge/common/include/config.php
@@ -0,0 +1,145 @@
+settings[$section])
+ || !isset (self::$instance->settings[$section][$var])) {
+ return NULL ;
+ }
+ return self::$instance->settings[$section][$var] ;
+ }
+
+ public function set_value ($section, $var, $value) {
+ if (!isset (self::$instance->settings[$section])) {
+ self::$instance->settings[$section] = array () ;
+ }
+
+ if (!isset (self::$instance->settings[$section][$var])) {
+ self::$instance->settings[$section][$var] = $value ;
+ }
+ }
+
+ function read_config_file ($file) {
+ if (file_exists($file)) {
+ $sections = parse_ini_file ($file, true) ;
+ if(is_array($sections)) {
+ foreach ($sections as $section => $options) {
+ if (!isset (self::$instance->settings[$section]))
+ continue ;
+ foreach ($options as $var => $value) {
+ if (!isset (self::$instance->settings[$section][$var]))
+ continue ;
+ self::$instance->settings[$section][$var] = $value ;
+ }
+ }
+ }
+ }
+ return ;
+ }
+
+ }
+
+if (!isset ($fusionforge_config)) {
+ $fusionforge_config = new FusionForgeConfig () ;
+}
+
+function forge_get_config ($var, $section = 'core') {
+ $c = FusionForgeConfig::get_instance () ;
+ return $c->get_value ($section, $var) ;
+}
+
+function forge_get_config_array () {
+ $c = FusionForgeConfig::get_instance () ;
+
+ $ret = array () ;
+
+ foreach (func_get_args() as $item) {
+ if (! is_array ($item)) {
+ $item = array ($item) ;
+ }
+ $var = $item[0] ;
+ if (isset ($item[1])) {
+ $section = $item[1] ;
+ } else {
+ $section = 'core' ;
+ }
+ $ret[] = $c->get_value ($section, $var) ;
+ }
+
+ return $ret ;
+}
+
+function forge_set_vars_from_config () {
+ $c = FusionForgeConfig::get_instance () ;
+
+ foreach (func_get_args() as $item) {
+ if (is_array ($item)) {
+ $var = $item[0] ;
+ $x = $var ;
+ if (isset ($item[1])) {
+ $section = $item[1] ;
+ $x = $section.'__'.$var ;
+ $value = forge_get_config ($var, $section) ;
+ }
+ } else {
+ $var = $item ;
+ $x = $item ;
+ $value = forge_get_config ($var) ;
+ }
+
+ global $$x ;
+ $$x = $value ;
+ }
+}
+
+
+function forge_define_config_item ($var, $section, $default) {
+ $c = FusionForgeConfig::get_instance () ;
+
+ return $c->set_value ($section, $var, $default) ;
+}
+
+function forge_read_config_file ($file) {
+ $c = FusionForgeConfig::get_instance () ;
+
+ return $c->read_config_file ($file) ;
+}
+
+// Local Variables:
+// mode: php
+// c-file-style: "bsd"
+// End:
+
+?>
diff --git a/gforge/common/include/cron_utils.php b/gforge/common/include/cron_utils.php
index a902944afb..a79b77b3c3 100644
--- a/gforge/common/include/cron_utils.php
+++ b/gforge/common/include/cron_utils.php
@@ -70,25 +70,25 @@ function cron_debug($string) {
}
function checkChroot() {
- global $sys_chroot;
- if(isset($sys_chroot) && !empty($sys_chroot) && is_dir($sys_chroot)) {
+
+ if(forge_get_config('chroot') != '' && is_dir(forge_get_config('chroot'))) {
return true;
}
return false;
}
function chrootPath($path) {
- global $sys_chroot;
+
if(checkChroot()) {
- $path = $sys_chroot.$path;
+ $path = forge_get_config('chroot').$path;
}
return $path;
}
function chrootCommand($command) {
- global $sys_chroot;
+
if(checkChroot()) {
- $command = 'chroot '.$sys_chroot.' '.$command;
+ $command = 'chroot '.forge_get_config('chroot').' '.$command;
}
return $command;
}
diff --git a/gforge/common/include/database-mysql.php b/gforge/common/include/database-mysql.php
deleted file mode 100644
index 973689c442..0000000000
--- a/gforge/common/include/database-mysql.php
+++ /dev/null
@@ -1,411 +0,0 @@
- 0) {
- if (!$offset || $offset < 0) {
- $offset=0;
- }
- $qstring=$qstring." LIMIT $offset,$limit";
- }
-// if ($GLOBALS['IS_DEBUG'])
-// $GLOBALS['G_DEBUGQUERY'] .= $qstring . " \n";
-
- db_log_dbentry('mysqli_select_db',"$gfconn, $sys_dbname");
- if (!mysqli_select_db($gfconn, $sys_dbname)) {
- db_log_dbexit('mysqli_select_db',false);
- db_log_exit('db_query');
- return NULL;
- }
- db_log_dbexit('mysqli_select_db',true);
-
- db_log_dbentry('mysqli_query',"$gfconn, $sys_dbname");
- $res = mysqli_query($gfconn, $qstring);
- db_log_dbexit('mysqli_query',$res);
-
- db_log_exit('db_query',"$res");
- return $res;
-}
-
-/**
- * db_mquery() - Query the database supporting multi-statements
- *
- * @param string SQL statement
- */
-function db_mquery($qstring) {
- global $sys_dbname, $gfconn;
-
-// if ($GLOBALS['IS_DEBUG'])
-// $GLOBALS['G_DEBUGQUERY'] .= $qstring . "
\n";
-
- db_log_entry('db_mquery',"$qstring");
-
- db_log_dbentry('mysqli_select_db',"$gfconn, $sys_dbname");
- if (!mysqli_select_db($gfconn, $sys_dbname)) {
- db_log_dbexit('mysqli_select_db',false);
- $err = mysqli_error($gfconn);
- if ($err) {
- db_log('DB Error = '.$err);
- }
- db_log_exit('db_mquery',NULL);
- return NULL;
- }
- db_log_dbexit('mysqli_select_db', true);
-
- db_log_dbentry('mysqli_multi_query',"$gfconn, $qstring");
- if (!mysqli_multi_query($gfconn, $qstring)) {
- db_log_dbexit('mysqli_multi_query','false');
- $err = mysqli_error($gfconn);
- if ($err) {
- db_log('DB Error = '.$err);
- }
- db_log_exit('db_mquery');
- return NULL;
- }
- db_log_dbexit('mysqli_multi_query',true);
-
- db_log_dbentry('mysqli_store_result',"$gfconn");
- if ($res = mysqli_store_result($gfconn)) {
- db_log_dbexit('mysqli_store_result',"$res");
- db_log_exit('db_mquery',"$res");
- return $res;
- } else {
- $err = mysqli_error($gfconn);
- if ($err) {
- db_log('DB Error = '.$err);
- }
- db_log_dbexit('mysqli_store_result');
- }
- db_log_exit('db_mquery',true);
- return true;
-}
-
-/**
- * db_next_result() - Get the next result from query with multiple statements.
- *
- * @param string SQL statement
- * @param int How many rows do you want returned
- * @param int Of matching rows, return only rows starting here
- */
-function db_next_result() {
- global $gfconn;
-
- db_log_entry('db_next_result',NULL);
-
- db_log_dbentry('mysqli_next_result',"$gfconn");
- $ret = mysqli_next_result($gfconn);
- db_log_dbexit('mysqli_next_result',"$ret");
- $err = mysqli_error($gfconn);
- if ($err) {
- db_log('DB Error = '.$err);
- }
-
- if ($ret) {
- db_log_dbentry('mysqli_store_result',"$gfconn");
- $res = mysqli_store_result($gfconn);
- db_log_dbexit('mysqli_store_result',"$res");
- if (!$res) {
- $res = 1;
- }
- } else {
- $err = mysqli_error($gfconn);
- if ($err) {
- db_log('DB Error = '.$err);
- }
- $res = NULL;
- }
- db_log_exit('db_next_result',$res);
- return $res;
-}
-
-/**
- * db_begin() - Begin a transaction
- *
- * Begin a transaction for databases that support them
- * may cause unexpected behavior in databases that don't
- */
-function db_begin() {
- return db_query_mysql("BEGIN WORK");
-}
-
-/**
- * db_commit() - Commit a transaction
- *
- * Commit a transaction for databases that support them
- * may cause unexpected behavior in databases that don't
- */
-function db_commit() {
- return db_query_mysql("COMMIT");
-}
-
-/**
- * db_rollback() - Roll back a transaction
- *
- * Rollback a transaction for databases that support them
- * may cause unexpected behavior in databases that don't
- */
-function db_rollback() {
- return db_query_mysql("ROLLBACK");
-}
-
-/**
- * db_numrows() - Returns the number of rows in this result set
- *
- * @param string Query result set handle
- */
-function db_numrows($qhandle) {
- // return only if qhandle exists, otherwise 0
- if ($qhandle) {
- return @mysqli_num_rows($qhandle);
- } else {
- return 0;
- }
-}
-
-/**
- * db_free_result() - Frees a database result properly
- *
- * @param string Query result set handle
- */
-function db_free_result($qhandle) {
- db_log_entry('db_free_result',"$qhandle");
- if (!is_object($qhandle)) {
- db_log_exit('db_free_result');
- return;
- }
- db_log_dbentry('mysqli_free_result',"$qhandle");
- $res = mysqli_free_result($qhandle);
- db_log_dbexit('mysqli_free_result',"$res");
- db_log_exit('db_free_result');
-}
-
-/**
- * db_reset_result() - Reset a result set.
- *
- * Reset is useful for db_fetch_array sometimes you need to start over
- *
- * @param string Query result set handle
- * @param int Row number
- */
-function db_reset_result($qhandle,$row=0) {
- return mysqli_data_seek($qhandle,$row);
-}
-
-/**
- * db_result() - Returns a field from a result set
- *
- * @param string Query result set handle
- * @param int Row number
- * @param string Field name
- */
-function db_result($qhandle,$row,$field) {
-
- if (!mysqli_data_seek($qhandle,$row)) {
- return NULL;
- }
-
- $row_data = mysqli_fetch_array($qhandle, MYSQLI_BOTH);
- if (!$row_data) {
- return NULL;
- }
- return $row_data[$field];
-}
-
-/**
- * db_numfields() - Returns the number of fields in this result set
- *
- * @param string Query result set handle
- */
-function db_numfields($lhandle) {
- return mysqli_num_fields($lhandle);
-}
-
-/**
- * db_fieldname() - Returns the name of a field in this result set
- *
- * @param string Query result set handle
- * @param int Column number
- */
-function db_fieldname($lhandle,$fnumber) {
- $fieldinfo=mysqli_fetch_field_direct($lhandle,$fnumber);
- if ($fieldinfo) {
- return $fieldinfo->name;
- } else {
- return NULL;
- }
-}
-
-/**
- * db_affected_rows() - Returns the number of rows changed in the last query
- *
- * @param string Query result set handle
- */
-function db_affected_rows() {
- global $gfconn;
-
- return mysqli_affected_rows($gfconn);
-}
-
-/**
- * db_fetch_array() - Fetch an array
- *
- * Returns an associative array from
- * the current row of this database result
- * Use db_reset_result to seek a particular row
- *
- * @param string Query result set handle
- */
-function db_fetch_array($qhandle) {
- return @mysqli_fetch_array($qhandle);
-}
-
-/**
- * db_insertid() - Returns the last primary key from an insert
- *
- * @param string Query result set handle
- * @param string Is the name of the table you inserted into
- * @param string Is the field name of the primary key
- */
-function db_insertid($qhandle,$table_name,$pkey_field_name) {
- global $gfconn;
-
- return mysqli_insert_id($gfconn);
-}
-
-/**
- * db_error() - Returns the last error from the database
- */
-function db_error() {
- global $gfconn;
-
- return mysqli_error($gfconn);
-}
-
-/**
- * system_cleanup() - In the future, we may wish to do a number
- * of cleanup functions at script termination.
- *
- * For now, we just abort any in-process transaction.
- */
-function system_cleanup() {
- global $_sys_db_transaction_level;
- if ($_sys_db_transaction_level > 0) {
- echo "Open transaction detected!!!";
- db_query_mysql("ROLLBACK");
- }
-}
-
-function db_drop_table_if_exists ($tn) {
- $sql = "DROP TABLE IF EXISTS $tn;";
- $rel = db_query_mysql ($sql);
- echo db_error();
-}
-
-function db_drop_sequence_if_exists ($tn) {
-}
-
-function db_log($message) {
- global $fhlog;
-
- if (!$fhlog) {
- $fhlog = fopen('/tmp/db.log', 'a');
- }
-
- if ($fhlog) {
- fwrite($fhlog, $message);
- fflush($fhlog);
- }
-}
-
-function db_log_entry($func, $args) {
- db_log("\nEntered ".$func.'('.$args.")\n");
-}
-
-function db_log_exit($func, $result = NULL) {
- db_log('Exited '.$func.' returned '.$result."\n");
-}
-
-function db_log_dbentry($func, $args) {
- db_log('Entered '.$func.'('.$args.")\n");
-}
-
-function db_log_dbexit($func, $result = NULL) {
- db_log('Exited '.$func.' returned '.$result."\n");
- if (!$result) {
- $err = db_error();
- if ($err) {
- db_log('Database error = '.$err."\n");
- }
- }
-}
-
-// Local Variables:
-// mode: php
-// c-file-style: "bsd"
-// End:
-
-?>
diff --git a/gforge/common/include/database-pgsql.php b/gforge/common/include/database-pgsql.php
index 440924ce85..62f7e4192c 100644
--- a/gforge/common/include/database-pgsql.php
+++ b/gforge/common/include/database-pgsql.php
@@ -107,6 +107,8 @@ function db_connect() {
/**
* db_query() - Query the database.
*
+ * @deprecated since 4.8. Use db_query_params() instead!
+ *
* @param text SQL statement.
* @param int How many rows do you want returned.
* @param int Of matching rows, return only rows starting here.
@@ -137,6 +139,42 @@ function db_query($qstring,$limit='-1',$offset=0,$dbserver=SYS_DB_PRIMARY) {
return $res;
}
+/**
+ * db_query_from_file() - Query the database, from a file.
+ *
+ * @param string File that contains the SQL statements.
+ * @param int How many rows do you want returned.
+ * @param int Of matching rows, return only rows starting here.
+ * @param int ability to spread load to multiple db servers.
+ * @return int result set handle.
+ */
+function db_query_from_file($file,$limit='-1',$offset=0,$dbserver=SYS_DB_PRIMARY) {
+ global $QUERY_COUNT;
+ $QUERY_COUNT++;
+
+ $qstring = file_get_contents($file);
+ if (!$qstring) {
+ error_log('db_query_from_file(): Cannot read file $file!');
+ return false;
+ }
+ if (!$limit || !is_numeric($limit) || $limit < 0) {
+ $limit=0;
+ }
+ if ($limit > 0) {
+ if (!$offset || !is_numeric($offset) || $offset < 0) {
+ $offset=0;
+ }
+ $qstring=$qstring." LIMIT $limit OFFSET $offset";
+ }
+ $res = @pg_query($dbserver,$qstring);
+ if (!$res) {
+ error_log('SQL: '. preg_replace('/\n\t+/', ' ',$qstring));
+ error_log('SQL> '.db_error());
+ }
+ //echo "\n |*| [$qstring]: ".db_error();
+ return $res;
+}
+
/**
* db_query_params() - Query the database, with parameters
*
@@ -190,6 +228,8 @@ function db_query_qpa ($qpa,$limit='-1',$offset=0,$dbserver=SYS_DB_PRIMARY) {
/**
* db_mquery() - Query the database.
*
+ * @deprecated since 4.8. Use db_query_params() instead!
+ *
* @param text SQL statement.
* @param int How many rows do you want returned.
* @param int Of matching rows, return only rows starting here.
diff --git a/gforge/common/include/forms.php b/gforge/common/include/forms.php
index 3fba214f55..da212ceb6e 100644
--- a/gforge/common/include/forms.php
+++ b/gforge/common/include/forms.php
@@ -30,28 +30,17 @@
*
*/
function form_generate_key() {
- global $sys_database_type;
-
$is_new=false;
db_begin();
// there's about 99.999999999% probability this loop will run only once :)
while(!$is_new) {
$key = md5(microtime() + rand() + $_SERVER["REMOTE_ADDR"]);
- if ( $sys_database_type == "mysql" ) {
- $sql = "SELECT * FROM form_keys WHERE `key`='".$key."'";
- $res=db_query_mysql($sql);
- } else {
- $res = db_query_params ('SELECT * FROM form_keys WHERE key=$1', array ($key));
- }
+ $res = db_query_params ('SELECT * FROM form_keys WHERE key=$1', array ($key));
if (!db_numrows($res)) {
$is_new=true;
}
}
- if ( $sys_database_type == "mysql" ) {
- $res = db_query_mysql("INSERT INTO form_keys (`key`,is_used,creation_date) VALUES ('".$key."',0,".time().")");
- } else {
- $res = db_query_params('INSERT INTO form_keys (key,is_used,creation_date) VALUES ($1, 0, $2)', array ($key,time()));
- }
+ $res = db_query_params('INSERT INTO form_keys (key,is_used,creation_date) VALUES ($1, 0, $2)', array ($key,time()));
if (!$res) {
db_rollback();
return false;
@@ -69,8 +58,6 @@ function form_generate_key() {
*
*/
function form_key_is_valid($key) {
- global $sys_database_type;
-
// Fail back mode if key is empty. This can happen when there is
// a problem with the generation. In this case, it may be better
// to disable this check instead of blocking all the application.
@@ -78,22 +65,12 @@ function form_key_is_valid($key) {
return true;
db_begin();
- if ( $sys_database_type == "mysql" ) {
- $sql = "SELECT * FROM form_keys WHERE `key`='$key' and is_used=0 FOR UPDATE";
- $res=db_query_mysql($sql);
- } else {
- $res = db_query_params ('SELECT * FROM form_keys WHERE key=$1 and is_used=0 FOR UPDATE', array ($key));
- }
+ $res = db_query_params ('SELECT * FROM form_keys WHERE key=$1 and is_used=0 FOR UPDATE', array ($key));
if (!$res || !db_numrows($res)) {
db_rollback();
return false;
}
- if ( $sys_database_type == "mysql" ) {
- $sql = "UPDATE form_keys SET is_used=1 WHERE `key`='$key'";
- $res=db_query_mysql($sql);
- } else {
- $res = db_query_params ('UPDATE form_keys SET is_used=1 WHERE key=$1', array ($key));
- }
+ $res = db_query_params ('UPDATE form_keys SET is_used=1 WHERE key=$1', array ($key));
if (!$res) {
db_rollback();
return false;
@@ -110,25 +87,13 @@ function form_key_is_valid($key) {
*
*/
function form_release_key($key) {
- global $sys_database_type;
-
db_begin();
- if ( $sys_database_type == "mysql" ) {
- $sql = "SELECT * FROM form_keys WHERE `key`='$key' FOR UPDATE";
- $res=db_query_mysql($sql);
- } else {
- $res = db_query_params ('SELECT * FROM form_keys WHERE key=$1 FOR UPDATE', array ($key));
- }
+ $res = db_query_params ('SELECT * FROM form_keys WHERE key=$1 FOR UPDATE', array ($key));
if (!$res || !db_numrows($res)) {
db_rollback();
return false;
}
- if ( $sys_database_type == "mysql" ) {
- $sql = "UPDATE form_keys SET is_used=0 WHERE `key`='$key'";
- $res=db_query_mysql($sql);
- } else {
- $res = db_query_params ('UPDATE form_keys SET is_used=0 WHERE key=$1', array ($key));
- }
+ $res = db_query_params ('UPDATE form_keys SET is_used=0 WHERE key=$1', array ($key));
if (!$res) {
db_rollback();
return false;
diff --git a/gforge/common/include/gettext.php b/gforge/common/include/gettext.php
index 0a26e54ed7..3591bec44a 100644
--- a/gforge/common/include/gettext.php
+++ b/gforge/common/include/gettext.php
@@ -94,8 +94,8 @@ function choose_language_from_context () {
}
// Okay, let's use the site-wide default language
- if ($GLOBALS['sys_lang']) {
- return $GLOBALS['sys_lang'] ;
+ if (forge_get_config('default_language')) {
+ return forge_get_config('default_language') ;
}
// Still no match? Really?
@@ -193,8 +193,8 @@ function setup_gettext_from_langname ($lang) {
function setup_gettext_from_sys_lang () {
$lang = "English";
- if ($GLOBALS['sys_lang']) {
- $lang = $GLOBALS['sys_lang'] ;
+ if (forge_get_config('default_language')) {
+ $lang = forge_get_config('default_language') ;
}
$locale = language_name_to_locale_code($lang).'.utf8';
diff --git a/gforge/common/include/rbac_texts.php b/gforge/common/include/rbac_texts.php
index 1b72750308..84984ba93f 100644
--- a/gforge/common/include/rbac_texts.php
+++ b/gforge/common/include/rbac_texts.php
@@ -26,9 +26,20 @@
* This file maps symbolic values to localised texts for the role permissions
*/
+require_once $gfcommon.'include/PluginManager.class.php';
+
function setup_rbac_strings () {
global $rbac_permission_names, $rbac_edit_section_names ;
- $rbac_permission_names = array (
+
+ if (!isset ($rbac_permission_names)) {
+ $rbac_permission_names = array () ;
+ }
+ if (!isset ($rbac_edit_section_names)) {
+ $rbac_edit_section_names = array () ;
+ }
+
+ $rbac_permission_names = array_replace_recursive ($rbac_permission_names,
+ array (
'frspackage0' => _('Private'),
'frspackage1' => _('Public'),
'frspackage' => _('File Release System'),
@@ -55,16 +66,30 @@ function setup_rbac_strings () {
'forum0' => _('Read'),
'forum1' => _('Post'),
'forum2' => _('Admin'),
+ 'newforum-1' => _('No Access'),
+ 'newforum0' => _('Read'),
+ 'newforum1' => _('Post'),
+ 'newforum2' => _('Admin'),
'tracker-1' => _('No Access'),
'tracker0' => _('Read'),
'tracker1' => _('Tech'),
'tracker2' => _('Tech & Admin'),
'tracker3' => _('Admin Only'),
+ 'newtracker-1' => _('No Access'),
+ 'newtracker0' => _('Read'),
+ 'newtracker1' => _('Tech'),
+ 'newtracker2' => _('Tech & Admin'),
+ 'newtracker3' => _('Admin Only'),
'pm-1' => _('No Access'),
'pm0' => _('Read'),
'pm1' => _('Tech'),
'pm2' => _('Tech & Admin'),
'pm3' => _('Admin Only'),
+ 'newpm-1' => _('No Access'),
+ 'newpm0' => _('Read'),
+ 'newpm1' => _('Tech'),
+ 'newpm2' => _('Tech & Admin'),
+ 'newpm3' => _('Admin Only'),
'docman0' => _('Read/Post'),
'docman1' => _('Admin'),
'projectadmin0' => _('None'),
@@ -78,20 +103,23 @@ function setup_rbac_strings () {
'webcal2' => _('See'),
'webcal1' => _('Modify'),
'webcal0' => _('No access')
+ )
);
- $rbac_edit_section_names = array (
+ $rbac_edit_section_names = array_replace_recursive ($rbac_edit_section_names,
+ array (
'forum' => _('Forum'),
+ 'newforum' => _('Default for new forums'),
'forumpublic' => _('Forum'),
'forumanon' => _('Anonymous Forum'),
'forumadmin' => _('Forum Admin'),
'pm' => _('Tasks'),
- 'newpm' => _('New Tasks'),
+ 'newpm' => _('Default for new tasks'),
'pmpublic' => _('Tasks'),
'pmadmin' => _('Tasks Admin'),
'projectpublic' => _('Project'),
'tracker' => _('Tracker'),
- 'newtracker' => _('New Trackers'),
+ 'newtracker' => _('Default for new trackers'),
'trackerpublic' => _('Tracker'),
'trackeranon' => _('Anonymous Tracker'),
'trackeradmin' => _('Tracker Admin'),
@@ -102,7 +130,10 @@ function setup_rbac_strings () {
'scm' => _('SCM'),
'scmpublic' => _('SCM'),
'docman' => _('Documentation Manager'),
+ )
) ;
+
+ plugin_hook ("role_translate_strings") ;
}
setup_rbac_strings () ;
diff --git a/gforge/common/include/session.php b/gforge/common/include/session.php
index 0151ae76d8..de413d3264 100644
--- a/gforge/common/include/session.php
+++ b/gforge/common/include/session.php
@@ -148,7 +148,7 @@ function session_login_valid_dbonly ($loginname, $passwd, $allowpending) {
global $feedback,$userstatus;
// Try to get the users from the database using user_id and (MD5) user_pw
- if ($GLOBALS['sys_require_unique_email']) {
+ if (forge_get_config('require_unique_email')) {
$res = db_query_params ('SELECT user_id,status,unix_pw FROM users WHERE (user_name=$1 OR email=$1) AND user_pw=$2',
array ($loginname,
md5($passwd))) ;
@@ -160,7 +160,7 @@ function session_login_valid_dbonly ($loginname, $passwd, $allowpending) {
if (!$res || db_numrows($res) < 1) {
// No user whose MD5 passwd matches the MD5 of the provided passwd
// Selecting by user_name/email only
- if ($GLOBALS['sys_require_unique_email']) {
+ if (forge_get_config('require_unique_email')) {
$res = db_query_params ('SELECT user_id,status,unix_pw FROM users WHERE user_name=$1 OR email=$1',
array ($loginname)) ;
} else {
@@ -316,10 +316,12 @@ function session_issecure() {
* @return true/false
*/
function session_cookie($name ,$value, $domain = '', $expiration = 0) {
- if ( $expiration != 0){
- setcookie($name, $value, time() + $expiration, '/', $domain, 0);
- } else {
- setcookie($name, $value, $expiration, '/', $domain, 0);
+ if (php_sapi_name() != 'cli') {
+ if ( $expiration != 0){
+ setcookie($name, $value, time() + $expiration, '/', $domain, 0);
+ } else {
+ setcookie($name, $value, $expiration, '/', $domain, 0);
+ }
}
}
@@ -342,7 +344,6 @@ function session_redirect($loc) {
* fails checks.
*
* @param array Associative array specifying criteria
- * @param string Override error string (optional)
* @return does not return if check is failed
*
*/
@@ -350,6 +351,12 @@ function session_require($req, $reason='') {
if (!session_loggedin()) {
exit_not_logged_in();
}
+
+ $user =& user_get_object(user_getid());
+ if (! $user->isActive()) {
+ session_logout();
+ exit_error('Error','Your account is no longer active ; you have been disconnected');
+ }
if (array_key_exists('group', $req)) {
$group =& group_get_object($req['group']);
@@ -364,9 +371,7 @@ function session_require($req, $reason='') {
exit_permission_denied($reason);
}
- //don't really like this, but as admin_flags is not mandatory
- //I add @ to remove the warning
- if (@$req['admin_flags']) {
+ if (isset($req['admin_flags']) && $req['admin_flags']) {
if (!$perm->isAdmin()) {
exit_permission_denied($reason);
}
diff --git a/gforge/common/include/utils.php b/gforge/common/include/utils.php
index efbb840931..3bde0872ba 100644
--- a/gforge/common/include/utils.php
+++ b/gforge/common/include/utils.php
@@ -102,6 +102,19 @@ function util_check_fileupload($filename) {
return true;
}
+/**
+ * util_check_url() - determines if given URL is valid.
+ *
+ * Currently, test is very basic, only the protocol is
+ * checked, allowed values are: http, https, ftp.
+ *
+ * @param string The URL
+ * @return boolean true if valid, false if not valid.
+ */
+function util_check_url($url) {
+ return (preg_match('/^(http|https|ftp):\/\//', $url) > 0);
+}
+
/**
* util_send_message() - Send email
* This function should be used in place of the PHP mail() function
@@ -116,13 +129,13 @@ function util_check_fileupload($filename) {
*
*/
function util_send_message($to,$subject,$body,$from='',$BCC='',$sendername='',$extra_headers='',$send_html_email=false) {
- global $sys_bcc_all_email_address,$sys_sendmail_path;
+ global $sys_sendmail_path;
if (!$to) {
- $to='noreply@'.$GLOBALS['sys_default_domain'];
+ $to='noreply@'.forge_get_config('web_host');
}
if (!$from) {
- $from='noreply@'.$GLOBALS['sys_default_domain'];
+ $from='noreply@'.forge_get_config('web_host');
}
@@ -137,8 +150,8 @@ function util_send_message($to,$subject,$body,$from='',$BCC='',$sendername='',$e
}
$body2 .= "To: $to".
"\nFrom: ".util_encode_mailaddr($from,$sendername,$charset);
- if (!empty($sys_bcc_all_email_address)) {
- $BCC.=",$sys_bcc_all_email_address";
+ if (forge_get_config('bcc_all_emails') != '') {
+ $BCC.=",".forge_get_config('bcc_all_emails');
}
if(!empty($BCC)) {
$body2 .= "\nBCC: $BCC";
@@ -975,6 +988,11 @@ function util_strip_accents($text) {
return utf8_encode($find);
}
+/**
+ * Constructs the forge's URL prefix out of $GLOBALS['sys_urlprefix']
+ *
+ * @return string
+ */
function normalized_urlprefix () {
$prefix = $GLOBALS['sys_urlprefix'] ;
$prefix = ereg_replace ("^/", "", $prefix) ;
@@ -985,17 +1003,29 @@ function normalized_urlprefix () {
return $prefix ;
}
+/**
+ * Construct full URL from a relative path
+ *
+ * @param string $path
+ * @return string URL
+ */
function util_make_url ($path) {
- if ($GLOBALS['sys_use_ssl'])
+ if (forge_get_config('use_ssl'))
$url = "https://" ;
else
$url = "http://" ;
- $url .= $GLOBALS['sys_default_domain'] ;
+ $url .= forge_get_config('web_host') ;
$url .= util_make_uri ($path) ;
return $url ;
}
+/**
+ * Construct proper (relative) URI (prepending prefix)
+ *
+ * @param string $path
+ * @return string URI
+ */
function util_make_uri ($path) {
$path = ereg_replace ("^/", "", $path) ;
$uri = normalized_urlprefix () ;
@@ -1017,10 +1047,25 @@ function util_make_link ($path, $text, $extra_params=false, $absolute=false) {
}
}
+/**
+ * Create an HTML link to a user's profile page
+ *
+ * @param string $username
+ * @param int $user_id
+ * @param string $text
+ * @return string
+ */
function util_make_link_u ($username, $user_id,$text) {
return '' . $text . ' ' ;
}
+/**
+ * Create URL for user's profile page
+ *
+ * @param string $username
+ * @param int $user_id
+ * @return string URL
+ */
function util_make_url_u ($username, $user_id) {
if (isset ($GLOBALS['sys_noforcetype']) && $GLOBALS['sys_noforcetype']) {
return util_make_url ("/developer/?user_id=$user_id");
@@ -1029,10 +1074,24 @@ function util_make_url_u ($username, $user_id) {
}
}
+/**
+ * Create a HTML link to a project's page
+ * @param string $groupame
+ * @param int $group_id
+ * @param string $text
+ * @return string
+ */
function util_make_link_g ($groupame, $group_id,$text) {
return '' . $text . ' ' ;
}
+/**
+ * Create URL for a project's page
+ *
+ * @param string $groupame
+ * @param int $group_id
+ * @return string
+ */
function util_make_url_g ($groupame, $group_id) {
if (isset ($GLOBALS['sys_noforcetype']) && $GLOBALS['sys_noforcetype']) {
return util_make_url ("/project/?group_id=$group_id");
@@ -1090,6 +1149,29 @@ function check_email_available($group, $email, &$response) {
return true;
}
+// array_replace_recursive only appeared in PHP 5.3.0
+if (!function_exists('array_replace_recursive')) {
+ function array_replace_recursive ($a1, $a2) {
+ $result = $a1 ;
+
+ if (!is_array ($a2)) {
+ return $a2 ;
+ }
+
+ foreach ($a2 as $k => $v) {
+ if (!is_array ($v) ||
+ !isset ($result[$k]) || !is_array ($result[$k])) {
+ $result[$k] = $v ;
+ }
+
+ $result[$k] = array_replace_recursive ($result[$k],
+ $v) ;
+ }
+
+ return $result ;
+ }
+}
+
// Local Variables:
// mode: php
// c-file-style: "bsd"
diff --git a/gforge/common/mail/Mail.class.php b/gforge/common/mail/Mail.class.php
new file mode 100644
index 0000000000..190bffdd9e
--- /dev/null
+++ b/gforge/common/mail/Mail.class.php
@@ -0,0 +1,261 @@
+setHeaderCharset('UTF-8');
+ $this->setBodyCharset('UTF-8');
+ $this->setMimeType('text/plain');
+ $this->setTo('', true);
+ $this->setBcc('', true);
+ $this->setCc('', true);
+ $this->setBody('', true);
+ $this->clearAdditionalHeaders();
+ }
+
+ var $_headerCharset;
+ function setHeaderCharset($charset) {
+ $this->_headerCharset = $charset;
+ }
+ function getHeaderCharset() {
+ return $this->_headerCharset;
+ }
+
+ var $_bodyCharset;
+ function setBodyCharset($charset) {
+ $this->_bodyCharset = $charset;
+ }
+ function getBodyCharset() {
+ return $this->_bodyCharset;
+ }
+
+ var $_subject;
+ function setSubject($subject) {
+ $this->_subject = $subject;
+ }
+ function getSubject() {
+ return $this->_subject;
+ }
+ function getEncodedSubject() {
+ return $this->_encodeHeader($this->_subject, $this->getHeaderCharset());
+ }
+
+ /**
+ * Function to encode a header if necessary
+ * according to RFC2047
+ * Filename.......: class.html.mime.mail.inc
+ * Project........: HTML Mime mail class
+ * Last Modified..: Date: 2002/07/24 13:14:10
+ * CVS Revision...: Revision: 1.4
+ * Copyright......: 2001, 2002 Richard Heyes
+ */
+ function _encodeHeader($input, $charset) {
+ preg_match_all('/(\s?\w*[\x80-\xFF]+\w*\s?)/', $input, $matches);
+ foreach ($matches[1] as $value) {
+ $replacement = preg_replace('/([\x80-\xFF])/e', '"=" . strtoupper(dechex(ord("\1")))', $value);
+ $input = str_replace($value, '=?' . $charset . '?Q?' . $replacement . '?=', $input);
+ }
+
+ return $input;
+ }
+
+ /**
+ * Given a header, this function will decode it
+ * according to RFC2047. Probably not *exactly*
+ * conformant, but it does pass all the given
+ * examples (in RFC2047).
+ *
+ * @param string Input header value to decode
+ * @return string Decoded header value
+ * @access private
+ */
+ function _decodeHeader($input)
+ {
+ // Remove white space between encoded-words
+ $input = preg_replace('/(=\?[^?]+\?(q|b)\?[^?]*\?=)(\s)+=\?/i', '\1=?', $input);
+
+ // For each encoded-word...
+ while (preg_match('/(=\?([^?]+)\?(q|b)\?([^?]*)\?=)/i', $input, $matches)) {
+
+ $encoded = $matches[1];
+ $charset = $matches[2];
+ $encoding = $matches[3];
+ $text = $matches[4];
+
+ switch (strtolower($encoding)) {
+ case 'b':
+ $text = base64_decode($text);
+ break;
+
+ case 'q':
+ $text = str_replace('_', ' ', $text);
+ preg_match_all('/=([a-f0-9]{2})/i', $text, $matches);
+ foreach($matches[1] as $value)
+ $text = str_replace('='.$value, chr(hexdec($value)), $text);
+ break;
+ }
+
+ $input = str_replace($encoded, $text, $input);
+ }
+
+ return $input;
+ }
+
+ var $_body;
+ function setBody($body) {
+ $this->_body = $body;
+ }
+ function getBody() {
+ return $this->_body;
+ }
+
+ var $_from;
+ function setFrom($from) {
+ $this->_from = $this->_validateRecipient($from);
+ }
+ function getFrom() {
+ return $this->_from;
+ }
+
+ /**
+ * Check if given mail is a valid (Ie. Active or Restricted) user.
+ *
+ * The given mail can by both user_name or email. Return form is always the
+ * user email.
+ *
+ * @param $list (IN) list of email addresses separated by , or ;
+ * @return list of email separated by ,
+ */
+ function _validateRecipient($list) {
+ $recipArray = split('[;,]', $list);
+ $retArray = array();
+ foreach($recipArray as $email) {
+ $email = trim($email);
+ if(!empty($email)) {
+ $user = UserManager::instance()->getUserByEmail($email);
+ if ($user) {
+ $allowed_status = array('A', 'R', 'P', 'V', 'W');
+ $one_with_status_allowed_found = false;
+ while ( !$one_with_status_allowed_found) {
+ if (in_array($user->getStatus(), $allowed_status)) {
+ $retArray[] = '"'.$this->_encodeHeader($user->getRealName(), $this->getHeaderCharset()).'" <'.$user->getEmail().'>';
+ $one_with_status_allowed_found = true;
+ }
+ }
+ } else {
+ $retArray[] = $email;
+ }
+ }
+ }
+ return implode(', ', $retArray);
+ }
+
+ var $_to;
+ function setTo($to, $raw=false) {
+ if($raw)
+ $this->_to = $to;
+ else
+ $this->_to = $this->_validateRecipient($to);
+ }
+ function getTo() {
+ return $this->_to;
+ }
+
+ var $_bcc;
+ function setBcc($bcc, $raw=false) {
+ if($raw)
+ $this->_bcc = $bcc;
+ else
+ $this->_bcc = $this->_validateRecipient($bcc);
+ }
+ function getBcc() {
+ return $this->_bcc;
+ }
+
+ var $_cc;
+ function setCc($cc, $raw=false) {
+ if($raw)
+ $this->_cc = $cc;
+ else
+ $this->_cc = $this->_validateRecipient($cc);
+
+ }
+ function getCc() {
+ return $this->_cc;
+ }
+
+ var $_mimeType;
+ function setMimeType($mimeType) {
+ $this->_mimeType = $mimeType;
+ }
+ function getMimeType() {
+ return $this->_mimeType;
+ }
+
+ var $_additionalHeaders;
+ function clearAdditionalHeaders() {
+ $this->_additionalHeaders = array();
+ }
+ function addAdditionalHeader($name, $value) {
+ $this->_additionalHeaders[$name] = $value;
+ }
+ function removeAdditionalHeader($name) {
+ if (isset($this->_additionalHeaders[$name])) {
+ unset($this->_additionalHeaders[$name]);
+ }
+ }
+
+ /**
+ * @returns TRUE if the mail was successfully accepted for delivery, FALSE otherwise.
+ * It is important to note that just because the mail was accepted for delivery,
+ * it does NOT mean the mail will actually reach the intended destination.
+ **/
+ function send() {
+ $sys_lf="\n";
+ if($this->getTo() === ''
+ && $this->getCc() === ''
+ && $this->getBcc() === '') {
+ return false;
+ }
+
+ $header = "From: ".$this->getFrom().$sys_lf;
+ $header .= "Content-type: ".$this->getMimeType()."; charset=".$this->getBodyCharset().$sys_lf;
+ $cc = $this->getCc();
+ if (strlen($cc) > 0) {
+ $header .= "Cc: ".$cc.$sys_lf;
+ }
+ $bcc = $this->getBcc();
+ if (strlen($bcc) > 0) {
+ $header .= "Bcc: ".$bcc.$sys_lf;
+ }
+ foreach($this->_additionalHeaders as $name => $value) {
+ $header .= $name.": ".$value.$sys_lf;
+ }
+ return $this->_sendmail($header);
+ }
+
+ /**
+ * Perform effective email send.
+ * @access protected
+ */
+ function _sendmail($header) {
+ $params = array('mail' => $this,
+ 'header' => $header);
+ //$em =& EventManager::instance();
+ //$em->processEvent('mail_sendmail', $params);
+
+ return mail($this->getTo(),
+ $this->getEncodedSubject(),
+ $this->getBody(),
+ $header
+ );
+ }
+
+
+
+}
+
+?>
diff --git a/gforge/common/mail/MailingList.class.php b/gforge/common/mail/MailingList.class.php
index b46106c435..269f28e251 100644
--- a/gforge/common/mail/MailingList.class.php
+++ b/gforge/common/mail/MailingList.class.php
@@ -125,9 +125,9 @@ class MailingList extends Error {
$realListName = strtolower($this->Group->getUnixName().'-'.$listName);
- if(!validate_email($realListName.'@'.$GLOBALS['sys_lists_host'])) {
+ if(!validate_email($realListName.'@'.forge_get_config('lists_host'))) {
$this->setError(_('Invalid List Name') . ': ' .
- $realListName.'@'.$GLOBALS['sys_lists_host']);
+ $realListName.'@'.forge_get_config('lists_host'));
return false;
}
@@ -193,10 +193,10 @@ You are encouraged to change this password as soon as possible.
Thank you for registering your project with %1$s.
-- the %1$s staff
-'), $GLOBALS['sys_name'], $GLOBALS['sys_lists_host'], $realListName, $this->getExternalInfoUrl(), $this->getExternalAdminUrl(), $listPassword);
- $mailSubject = sprintf(_('%1$s New Mailing List'), $GLOBALS['sys_name']);
+'), forge_get_config ('forge_name'), forge_get_config('lists_host'), $realListName, $this->getExternalInfoUrl(), $this->getExternalAdminUrl(), $listPassword);
+ $mailSubject = sprintf(_('%1$s New Mailing List'), forge_get_config ('forge_name'));
- util_send_message($userEmail, $mailSubject, $mailBody, 'admin@'.$GLOBALS['sys_default_domain']);
+ util_send_message($userEmail, $mailSubject, $mailBody, 'admin@'.forge_get_config('web_host'));
}
db_commit();
@@ -335,9 +335,9 @@ Thank you for registering your project with %1$s.
*/
function getArchivesUrl() {
if ($this->isPublic()) {
- return 'http://'.$GLOBALS['sys_lists_host'].'/pipermail/'.$this->getName().'/';
+ return 'http://'.forge_get_config('lists_host').'/pipermail/'.$this->getName().'/';
} else {
- return 'http://'.$GLOBALS['sys_lists_host'].'/mailman/private/'.$this->getName().'/';
+ return 'http://'.forge_get_config('lists_host').'/mailman/private/'.$this->getName().'/';
}
}
@@ -347,7 +347,7 @@ Thank you for registering your project with %1$s.
* @return string url of the info page
*/
function getExternalInfoUrl() {
- return 'http://'.$GLOBALS['sys_lists_host'].'/mailman/listinfo/'.$this->getName();
+ return 'http://'.forge_get_config('lists_host').'/mailman/listinfo/'.$this->getName();
}
/**
@@ -356,7 +356,7 @@ Thank you for registering your project with %1$s.
* @return string url of the admin
*/
function getExternalAdminUrl() {
- return 'http://'.$GLOBALS['sys_lists_host'].'/mailman/admin/'.$this->getName();
+ return 'http://'.forge_get_config('lists_host').'/mailman/admin/'.$this->getName();
}
/**
diff --git a/gforge/common/pm/ProjectGroup.class.php b/gforge/common/pm/ProjectGroup.class.php
index 816b5e8fb0..875ae68418 100644
--- a/gforge/common/pm/ProjectGroup.class.php
+++ b/gforge/common/pm/ProjectGroup.class.php
@@ -185,6 +185,9 @@ class ProjectGroup extends Error {
}
db_commit();
+
+ $this->Group->normalizeAllRoles () ;
+
return true;
}
@@ -377,6 +380,15 @@ class ProjectGroup extends Error {
}
}
+ $res = db_query_params ('DELETE FROM role_setting WHERE section_name=$1 AND ref_id=$2',
+ array ('pm',
+ $this->getID())) ;
+
+ if (!$res)
+ {
+ $this->setError('DATABASE '.db_error());
+ return false;
+ }
if (!$this->userIsAdmin()) {
$this->setPermissionDeniedError();
@@ -527,17 +539,10 @@ class ProjectGroup extends Error {
return false;
}
- $res = db_query_params ('DELETE FROM role_setting WHERE section_name=$1 AND ref_id=$2',
- array ('pm',
- $this->getID())) ;
+ db_commit();
- if (!$res)
- {
- $this->setError('DATABASE '.db_error());
- return false;
- }
+ $this->Group->normalizeAllRoles () ;
- db_commit();
return true;
}
diff --git a/gforge/common/pm/ProjectTask.class.php b/gforge/common/pm/ProjectTask.class.php
index 60feac6967..b7c42cc838 100644
--- a/gforge/common/pm/ProjectTask.class.php
+++ b/gforge/common/pm/ProjectTask.class.php
@@ -137,8 +137,6 @@ class ProjectTask extends Error {
*/
function create($summary,$details,$priority,$hours,$start_date,$end_date,
$category_id,$percent_complete,&$assigned_arr,&$depend_arr,$duration=0,$parent_id=0) {
- global $sys_database_type;
-
$v = new Validator();
$v->check($summary, "summary");
$v->check($details, "details");
@@ -163,68 +161,36 @@ class ProjectTask extends Error {
}
db_begin();
- if ($sys_database_type == "mysql") {
-
- $sql = "INSERT INTO project_task (group_project_id,created_by,summary,
- details,start_date,end_date,status_id,category_id,priority,percent_complete,hours,duration,parent_id)
- VALUES ('".$this->ProjectGroup->getID()."','".user_getid()."','".htmlspecialchars( $summary )."',
- '". htmlspecialchars($details) ."', '$start_date','$end_date','1','$category_id','$priority','$percent_complete','$hours','$duration','$parent_id')";
-
- $result = db_query_mysql( $sql );
- if (!$result || db_affected_rows($result) < 1) {
- $this->setError( 'ProjectTask::create() Posting Failed '.db_error().$sql );
- db_rollback();
- return false;
- }
-
- $result = db_query_mysql( "SELECT last_insert_id() AS id" );
- if (!$result) {
- $this->setError( 'ProjectTask::create() Get Created ID Failed '.db_error().$sql );
- db_rollback();
- return false;
- }
-
- $project_task_id=db_result($result, 0, 'id');
- if (!$project_task_id) {
- $this->setError( 'ProjectTask::create() Created ID is NULL Failed' );
- db_rollback();
- return false;
- }
-
- $this->data_array['project_task_id']=$project_task_id;
-
- } else {
- $res = db_query_params ('SELECT nextval($1) AS id',
- array ('project_task_pk_seq'));
- if (!$project_task_id=db_result($res,0,'id')) {
- $this->setError( 'Could Not Get Next Project Task ID' );
- db_rollback();
- return false;
- }
-
- $this->data_array['project_task_id']=$project_task_id;
-
- $result = db_query_params ('INSERT INTO project_task (project_task_id,group_project_id,created_by,summary,details,start_date,end_date,status_id,category_id,priority,percent_complete,hours,duration,parent_id) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14)',
- array ($project_task_id,
- $this->ProjectGroup->getID(),
- user_getid(),
- htmlspecialchars($summary),
- htmlspecialchars($details),
- $start_date,
- $end_date,
- 1,
- $category_id,
- $priority,
- $percent_complete,
- $hours,
- $duration,
- $parent_id)) ;
-
- if (!$result || db_affected_rows($result) < 1) {
- $this->setError('ProjectTask::create() Posting Failed '.db_error().$sql);
- db_rollback();
- return false;
- }
+ $res = db_query_params ('SELECT nextval($1) AS id',
+ array ('project_task_pk_seq'));
+ if (!$project_task_id=db_result($res,0,'id')) {
+ $this->setError( 'Could Not Get Next Project Task ID' );
+ db_rollback();
+ return false;
+ }
+
+ $this->data_array['project_task_id']=$project_task_id;
+
+ $result = db_query_params ('INSERT INTO project_task (project_task_id,group_project_id,created_by,summary,details,start_date,end_date,status_id,category_id,priority,percent_complete,hours,duration,parent_id) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14)',
+ array ($project_task_id,
+ $this->ProjectGroup->getID(),
+ user_getid(),
+ htmlspecialchars($summary),
+ htmlspecialchars($details),
+ $start_date,
+ $end_date,
+ 1,
+ $category_id,
+ $priority,
+ $percent_complete,
+ $hours,
+ $duration,
+ $parent_id)) ;
+
+ if (!$result || db_affected_rows($result) < 1) {
+ $this->setError('ProjectTask::create() Posting Failed '.db_error().$sql);
+ db_rollback();
+ return false;
}
if (!$this->setDependentOn($depend_arr)) {
diff --git a/gforge/common/reporting/ReportSetup.class.php b/gforge/common/reporting/ReportSetup.class.php
index 8eeb5cd1c1..37c7f7b9ea 100644
--- a/gforge/common/reporting/ReportSetup.class.php
+++ b/gforge/common/reporting/ReportSetup.class.php
@@ -41,8 +41,6 @@ function initialSetup() {
}
function createTables() {
- global $sys_database_type;
-
//time tracking
//DROP TABLE rep_time_category;
$sql[]="CREATE TABLE rep_time_category (
@@ -55,12 +53,8 @@ function createTables() {
report_date int not null,
user_id int not null,
project_task_id int not null,
- time_code int not null";
-
- if ($sys_database_type != "mysql") {
- $sql1.=" CONSTRAINT reptimetrk_timecode REFERENCES rep_time_category(time_code)";
- }
- $sql1.=",hours float not null);";
+ time_code int not null CONSTRAINT reptimetrk_timecode REFERENCES rep_time_category(time_code),
+ hours float not null);";
$sql[]=$sql1;
// $sql[]="CREATE UNIQUE INDEX reptimetrk_weekusrtskcde ON
// rep_time_tracking (week,user_id,project_task_id,time_code);";
@@ -959,8 +953,6 @@ function backfill_groups_cum_monthly($count=10000) {
* @return boolean Success.
*/
function user_act_daily($day) {
- global $sys_database_type;
-
db_query_params ('DELETE FROM rep_user_act_daily WHERE day=$1',
array($day)) ;
@@ -1065,8 +1057,6 @@ function backfill_user_act_daily($count=10000) {
* @return boolean Success.
*/
function user_act_weekly($week) {
- global $sys_database_type;
-
db_query_params ('DELETE FROM rep_user_act_weekly WHERE week=$1',
array($week)) ;
@@ -1113,8 +1103,6 @@ function backfill_user_act_weekly($count=10000) {
* @return boolean Success.
*/
function user_act_monthly($month,$end) {
- global $sys_database_type;
-
db_query_params ('DELETE FROM rep_user_act_monthly WHERE month=$1',
array($month)) ;
@@ -1162,8 +1150,6 @@ function backfill_user_act_monthly($count=10000) {
* @return boolean Success.
*/
function group_act_daily($day) {
- global $sys_database_type;
-
db_query_params ('DELETE FROM rep_group_act_daily WHERE day=$1',
array($day)) ;
@@ -1289,8 +1275,6 @@ function backfill_group_act_daily($count=10000) {
* @return boolean Success.
*/
function group_act_weekly($week) {
- global $sys_database_type;
-
db_query_params ('DELETE FROM rep_group_act_weekly WHERE week=$1',
array($week)) ;
@@ -1339,8 +1323,6 @@ function backfill_group_act_weekly($count=10000) {
* @return boolean Success.
*/
function group_act_monthly($month,$end) {
- global $sys_database_type;
-
db_query_params ('DELETE FROM rep_group_act_monthly WHERE month=$1',
array($month)) ;
diff --git a/gforge/common/reporting/report_utils.php b/gforge/common/reporting/report_utils.php
index 60482596b4..9579e82b6e 100644
--- a/gforge/common/reporting/report_utils.php
+++ b/gforge/common/reporting/report_utils.php
@@ -24,12 +24,12 @@
*/
function report_header($title) {
- global $HTML,$sys_name;
+ global $HTML ;
echo $HTML->header(array('title'=>" "._('Reporting').": " . $title));
if (isset($GLOBALS['feedback'])) {
echo html_feedback_top($GLOBALS['feedback']);
}
- echo "
".sprintf(_('%1$s Reporting'), $sys_name)." \n";
+ echo "".sprintf(_('%1$s Reporting'), forge_get_config ('forge_name'))." \n";
}
function report_footer() {
@@ -94,17 +94,11 @@ function report_months_box($Report, $name='month', $selected=false) {
}
function report_useract_box($name='dev_id', $selected='1', $start_with='') {
- global $sys_database_type;
-
if ($start_with) {
- if ( $sys_database_type == "mysql" ) {
- $res = db_query_mysql ("SELECT user_id,realname FROM users WHERE status='A' AND (exists (SELECT user_id FROM rep_user_act_daily WHERE user_id=users.user_id)) AND (lower(lastname) LIKE lower('$start_with%') OR lower(user_name) LIKE lower('$start_with%')) ORDER BY lastname") ;
- } else {
- $res = db_query_params ('SELECT user_id,realname FROM users WHERE status=$1 AND (exists (SELECT user_id FROM rep_user_act_daily WHERE user_id=users.user_id)) AND (lower(lastname) LIKE $2 OR lower(user_name) LIKE $3) ORDER BY lastname',
- array ('A',
- strtolower("$start_with%"),
- strtolower("$start_with%"))) ;
- }
+ $res = db_query_params ('SELECT user_id,realname FROM users WHERE status=$1 AND (exists (SELECT user_id FROM rep_user_act_daily WHERE user_id=users.user_id)) AND (lower(lastname) LIKE $2 OR lower(user_name) LIKE $3) ORDER BY lastname',
+ array ('A',
+ strtolower("$start_with%"),
+ strtolower("$start_with%"))) ;
} else {
$res = db_query_params ('SELECT user_id,realname FROM users WHERE status=$1 AND (exists (SELECT user_id FROM rep_user_act_daily WHERE user_id=users.user_id)) ORDER BY lastname',
array ('A')) ;
@@ -113,17 +107,11 @@ function report_useract_box($name='dev_id', $selected='1', $start_with='') {
}
function report_usertime_box($name='dev_id', $selected='1', $start_with='') {
- global $sys_database_type;
-
if ($start_with) {
- if ( $sys_database_type == "mysql" ) {
- $res = db_query_mysql ("SELECT user_id,realname FROM users WHERE status='A' AND (exists (SELECT user_id FROM rep_time_tracking WHERE user_id=users.user_id)) AND (lower(lastname) LIKE lower('$start_with%') OR lower(user_name) LIKE lower('$start_with%')) ORDER BY lastname") ;
- } else {
- $res = db_query_params ('SELECT user_id,realname FROM users WHERE status=$1 AND (exists (SELECT user_id FROM rep_time_tracking WHERE user_id=users.user_id)) AND (lower(lastname) LIKE $2 OR lower(user_name) LIKE $3) ORDER BY lastname',
- array ('A',
- strtolower("$start_with%"),
- strtolower("$start_with%"))) ;
- }
+ $res = db_query_params ('SELECT user_id,realname FROM users WHERE status=$1 AND (exists (SELECT user_id FROM rep_time_tracking WHERE user_id=users.user_id)) AND (lower(lastname) LIKE $2 OR lower(user_name) LIKE $3) ORDER BY lastname',
+ array ('A',
+ strtolower("$start_with%"),
+ strtolower("$start_with%"))) ;
} else {
$res = db_query_params ('SELECT user_id,realname FROM users WHERE status=$1 AND (exists (SELECT user_id FROM rep_time_tracking WHERE user_id=users.user_id)) ORDER BY lastname',
array ('A')) ;
@@ -146,29 +134,29 @@ function report_area_box($name='area', $selected='1', $Group=false) {
$sys_use_pm = $Group->usesPM();
$sys_use_frs = $Group->usesFRS();
} else {
- $sys_use_tracker = $GLOBALS['sys_use_tracker'];
- $sys_use_forum = $GLOBALS['sys_use_forum'];
- $sys_use_docman = $GLOBALS['sys_use_docman'];
- $sys_use_pm = $GLOBALS['sys_use_pm'];
- $sys_use_frs = $GLOBALS['sys_use_frs'];
+ $sys_use_tracker = forge_get_config('use_tracker');
+ $sys_use_forum = forge_get_config('use_forum');
+ $sys_use_docman = forge_get_config('use_docman');
+ $sys_use_pm = forge_get_config('use_pm');
+ $sys_use_frs = forge_get_config('use_frs');
}
- if ($sys_use_tracker) {
+ if (forge_get_config('use_tracker')) {
$arr[]='tracker';
$arr2[]=_('Tracker');
}
- if ($sys_use_forum) {
+ if (forge_get_config('use_forum')) {
$arr[]='forum';
$arr2[]=_('Forums');
}
- if ($sys_use_docman) {
+ if (forge_get_config('use_docman')) {
$arr[]='docman';
$arr2[]=_('Docs');
}
- if ($sys_use_pm) {
+ if (forge_get_config('use_pm')) {
$arr[]='taskman';
$arr2[]=_('Tasks');
}
- if ($sys_use_frs) {
+ if (forge_get_config('use_frs')) {
$arr[]='downloads';
$arr2[]=_('Downloads');
}
@@ -177,7 +165,7 @@ function report_area_box($name='area', $selected='1', $Group=false) {
}
function report_tracker_box($name='datatype', $selected='1') {
- if ($GLOBALS['sys_use_tracker']) {
+ if (forge_get_config('use_tracker')) {
$arr[]=_('Bugs');
$arr[]=_('Support');
$arr[]=_('Patches');
@@ -189,15 +177,15 @@ function report_tracker_box($name='datatype', $selected='1') {
$arr2[]='4';
$arr2[]='0';
}
- if ($GLOBALS['sys_use_forum']) {
+ if (forge_get_config('use_forum')) {
$arr[]=_('Forum Messages');
$arr2[]='5';
}
- if ($GLOBALS['sys_use_pm']) {
+ if (forge_get_config('use_pm')) {
$arr[]=_('Tasks');
$arr2[]='6';
}
- if ($GLOBALS['sys_use_frs']) {
+ if (forge_get_config('use_frs')) {
$arr[]=_('Downloads');
$arr2[]='7';
}
diff --git a/gforge/common/scm/SCMFactory.class.php b/gforge/common/scm/SCMFactory.class.php
index f1307c900d..bdb95b83dc 100644
--- a/gforge/common/scm/SCMFactory.class.php
+++ b/gforge/common/scm/SCMFactory.class.php
@@ -41,10 +41,10 @@ class SCMFactory extends Error {
* @return boolean success.
*/
function SCMFactory() {
- global $sys_use_scm;
+
$this->Error();
- if (!$sys_use_scm) {
+ if (!forge_get_config('use_scm')) {
$this->setError('SCMFactory::sys_use_scm');
return false;
}
diff --git a/gforge/common/search/ArtifactSearchQuery.class.php b/gforge/common/search/ArtifactSearchQuery.class.php
index e6e2026071..36bb61e46e 100644
--- a/gforge/common/search/ArtifactSearchQuery.class.php
+++ b/gforge/common/search/ArtifactSearchQuery.class.php
@@ -64,12 +64,11 @@ class ArtifactSearchQuery extends SearchQuery {
* @return array query+params array
*/
function getQuery() {
- global $sys_database_type;
- global $sys_use_fti;
+
$qpa = db_construct_qpa () ;
- if ($sys_use_fti) {
+ if (forge_get_config('use_fti')) {
$words=$this->getFormattedWords();
$artifactId = $this->artifactId;
@@ -133,13 +132,8 @@ class ArtifactSearchQuery extends SearchQuery {
' GROUP BY a.artifact_id) x, artifact a, users WHERE a.artifact_id=x.artifact_id AND users.user_id=a.submitted_by ORDER BY group_artifact_id ASC, rank DESC, a.artifact_id ASC') ;
}
} else {
- if ($sys_database_type == "mysql") {
- $qpa = db_construct_qpa ($qpa,
- 'SELECT DISTINCT a.group_artifact_id,a.artifact_id,a.summary,a.open_date,users.realname ') ;
- } else {
- $qpa = db_construct_qpa ($qpa,
- 'SELECT DISTINCT ON (a.group_artifact_id,a.artifact_id) a.group_artifact_id,a.artifact_id,a.summary,a.open_date,users.realname ') ;
- }
+ $qpa = db_construct_qpa ($qpa,
+ 'SELECT DISTINCT ON (a.group_artifact_id,a.artifact_id) a.group_artifact_id,a.artifact_id,a.summary,a.open_date,users.realname ') ;
$qpa = db_construct_qpa ($qpa,
'FROM artifact a LEFT OUTER JOIN artifact_message am USING (artifact_id), users WHERE a.group_artifact_id=$1 AND users.user_id=a.submitted_by AND ((',
array ($this->artifactId)) ;
@@ -163,17 +157,10 @@ class ArtifactSearchQuery extends SearchQuery {
* @return array query+params array
*/
function getSearchByIdQuery() {
- global $sys_database_type;
-
$qpa = db_construct_qpa () ;
- if ($sys_database_type == "mysql") {
- $qpa = db_construct_qpa ($qpa,
- 'SELECT DISTINCT a.group_artifact_id, a.artifact_id') ;
- } else {
- $qpa = db_construct_qpa ($qpa,
- 'SELECT DISTINCT ON (a.group_artifact_id,a.artifact_id) a.group_artifact_id, a.artifact_id') ;
- }
+ $qpa = db_construct_qpa ($qpa,
+ 'SELECT DISTINCT ON (a.group_artifact_id,a.artifact_id) a.group_artifact_id, a.artifact_id') ;
$qpa = db_construct_qpa ($qpa,
' FROM artifact a WHERE a.group_artifact_id=$1 AND a.artifact_id=$2',
array ($this->artifactId,
diff --git a/gforge/common/search/DocsSearchQuery.class.php b/gforge/common/search/DocsSearchQuery.class.php
index c1e1a3c84e..3b816f3f64 100644
--- a/gforge/common/search/DocsSearchQuery.class.php
+++ b/gforge/common/search/DocsSearchQuery.class.php
@@ -66,8 +66,8 @@ class DocsSearchQuery extends SearchQuery {
* @return array query+params array
*/
function getQuery() {
- global $sys_use_fti;
- if ($sys_use_fti) {
+
+ if (forge_get_config('use_fti')) {
return $this->getFTIQuery();
} else {
$qpa = db_construct_qpa () ;
diff --git a/gforge/common/search/ExportProjectSearchQuery.class.php b/gforge/common/search/ExportProjectSearchQuery.class.php
index e24c6f2616..0ab1fdd433 100644
--- a/gforge/common/search/ExportProjectSearchQuery.class.php
+++ b/gforge/common/search/ExportProjectSearchQuery.class.php
@@ -44,9 +44,9 @@ class ExportProjectSearchQuery extends SearchQuery {
* @return array query+params array
*/
function getQuery() {
- global $sys_use_fti;
+
$qpa = db_construct_qpa () ;
- if ($sys_use_fti) {
+ if (forge_get_config('use_fti')) {
$words = $this->getFormattedWords();
if(count($this->words)) {
$qpa = db_construct_qpa ($qpa,
diff --git a/gforge/common/search/ForumSearchQuery.class.php b/gforge/common/search/ForumSearchQuery.class.php
index e49b505fcc..550f0af9f2 100644
--- a/gforge/common/search/ForumSearchQuery.class.php
+++ b/gforge/common/search/ForumSearchQuery.class.php
@@ -63,11 +63,11 @@ class ForumSearchQuery extends SearchQuery {
* @return array query+params array
*/
function getQuery() {
- global $sys_use_fti;
+
$qpa = db_construct_qpa () ;
- if ($sys_use_fti) {
+ if (forge_get_config('use_fti')) {
$words = $this->getFormattedWords();
diff --git a/gforge/common/search/ForumsSearchQuery.class.php b/gforge/common/search/ForumsSearchQuery.class.php
index 2b9a9f53d2..0ceca2aa90 100644
--- a/gforge/common/search/ForumsSearchQuery.class.php
+++ b/gforge/common/search/ForumsSearchQuery.class.php
@@ -66,11 +66,11 @@ class ForumsSearchQuery extends SearchQuery {
* @return array query+params array
*/
function getQuery() {
- global $sys_use_fti;
+
$qpa = db_construct_qpa () ;
- if ($sys_use_fti) {
+ if (forge_get_config('use_fti')) {
$nonPublic = 'false';
$sections = '';
if ($this->showNonPublic) {
diff --git a/gforge/common/search/FrsSearchQuery.class.php b/gforge/common/search/FrsSearchQuery.class.php
index f225066bba..f77c10a8f5 100644
--- a/gforge/common/search/FrsSearchQuery.class.php
+++ b/gforge/common/search/FrsSearchQuery.class.php
@@ -65,11 +65,11 @@ class FrsSearchQuery extends SearchQuery {
* @return array query+params array
*/
function getQuery() {
- global $sys_use_fti;
+
$qpa = db_construct_qpa () ;
- if ($sys_use_fti) {
+ if (forge_get_config('use_fti')) {
if(count($this->words)) {
$qpa = db_construct_qpa () ;
$qpa = db_construct_qpa ($qpa,
diff --git a/gforge/common/search/NewsSearchQuery.class.php b/gforge/common/search/NewsSearchQuery.class.php
index 6ccf5c661b..651747b595 100644
--- a/gforge/common/search/NewsSearchQuery.class.php
+++ b/gforge/common/search/NewsSearchQuery.class.php
@@ -53,11 +53,11 @@ class NewsSearchQuery extends SearchQuery {
* @return array query+params array
*/
function getQuery() {
- global $sys_use_fti;
+
$qpa = db_construct_qpa () ;
- if ($sys_use_fti) {
+ if (forge_get_config('use_fti')) {
$group_id=$this->groupId;
if (count ($this->words)) {
diff --git a/gforge/common/search/PeopleSearchQuery.class.php b/gforge/common/search/PeopleSearchQuery.class.php
index 2d8153fb91..aedc049766 100644
--- a/gforge/common/search/PeopleSearchQuery.class.php
+++ b/gforge/common/search/PeopleSearchQuery.class.php
@@ -44,11 +44,11 @@ class PeopleSearchQuery extends SearchQuery {
* @return array query+params array
*/
function getQuery() {
- global $sys_use_fti;
+
$qpa = db_construct_qpa () ;
- if ($sys_use_fti) {
+ if (forge_get_config('use_fti')) {
if (count ($this->words)) {
$words = $this->getFormattedWords();
$qpa = db_construct_qpa ($qpa,
diff --git a/gforge/common/search/ProjectSearchQuery.class.php b/gforge/common/search/ProjectSearchQuery.class.php
index 4cd0ba554f..4ed5924483 100644
--- a/gforge/common/search/ProjectSearchQuery.class.php
+++ b/gforge/common/search/ProjectSearchQuery.class.php
@@ -44,11 +44,11 @@ class ProjectSearchQuery extends SearchQuery {
* @return array query+params array
*/
function getQuery() {
- global $sys_use_fti, $LUSER;
+ global $LUSER;
$qpa = db_construct_qpa () ;
- if ($sys_use_fti) {
+ if (forge_get_config('use_fti')) {
if (count ($this->words)) {
$words = $this->getFormattedWords();
$qpa = db_construct_qpa ($qpa,
diff --git a/gforge/common/search/SearchQuery.class.php b/gforge/common/search/SearchQuery.class.php
index f9e7bb5cb0..b7254b0a6e 100644
--- a/gforge/common/search/SearchQuery.class.php
+++ b/gforge/common/search/SearchQuery.class.php
@@ -167,14 +167,14 @@ class SearchQuery extends Error {
* executeQuery - execute the SQL query to get the results
*/
function executeQuery() {
- global $sys_use_fti;
+
if($this->searchId) {
$qpa = $this->getSearchByIdQuery();
} else {
$qpa = $this->getQuery();
}
- if ($sys_use_fti) {
+ if (forge_get_config('use_fti')) {
db_query_params ('select set_curcfg($1)',
array ('default'));
}
diff --git a/gforge/common/search/SkillSearchQuery.class.php b/gforge/common/search/SkillSearchQuery.class.php
index e3321984d0..c4def558b4 100644
--- a/gforge/common/search/SkillSearchQuery.class.php
+++ b/gforge/common/search/SkillSearchQuery.class.php
@@ -44,11 +44,11 @@ class SkillSearchQuery extends SearchQuery {
* @return array query+params array
*/
function getQuery() {
- global $sys_use_fti;
+
$qpa = db_construct_qpa () ;
- if ($sys_use_fti) {
+ if (forge_get_config('use_fti')) {
if(count($this->words)) {
$words = $this->getFormattedWords();
$qpa = db_construct_qpa ($qpa,
diff --git a/gforge/common/search/TasksSearchQuery.class.php b/gforge/common/search/TasksSearchQuery.class.php
index 5694b6535d..65bbfd28a6 100644
--- a/gforge/common/search/TasksSearchQuery.class.php
+++ b/gforge/common/search/TasksSearchQuery.class.php
@@ -66,11 +66,11 @@ class TasksSearchQuery extends SearchQuery {
* @return array query+params array
*/
function getQuery() {
- global $sys_use_fti;
+
$qpa = db_construct_qpa () ;
- if ($sys_use_fti) {
+ if (forge_get_config('use_fti')) {
if (count ($this->words)) {
$words = $this->getFormattedWords();
diff --git a/gforge/common/search/TrackersSearchQuery.class.php b/gforge/common/search/TrackersSearchQuery.class.php
index 4444ebc995..2e12e3458f 100644
--- a/gforge/common/search/TrackersSearchQuery.class.php
+++ b/gforge/common/search/TrackersSearchQuery.class.php
@@ -66,11 +66,11 @@ class TrackersSearchQuery extends SearchQuery {
* @return array query+params array
*/
function getQuery() {
- global $sys_use_fti;
+
$qpa = db_construct_qpa () ;
- if ($sys_use_fti) {
+ if (forge_get_config('use_fti')) {
if (count ($this->words)) {
$qpa = db_construct_qpa ($qpa,
'SELECT DISTINCT x.* FROM (SELECT artifact.artifact_id, artifact.group_artifact_id, artifact.summary, artifact.open_date, users.realname, artifact_group_list.name, (rank(artifact_idx.vectors, q)+rank(artifact_message_idx.vectors, q)) AS rank FROM artifact LEFT OUTER JOIN artifact_message USING (artifact_id), users, artifact_group_list, to_tsquery($1) q, artifact_idx, artifact_message_idx WHERE users.user_id = artifact.submitted_by AND artifact_idx.artifact_id = artifact.artifact_id AND artifact_message_idx.id = artifact_message.id AND artifact_message_idx.artifact_id = artifact_message_idx.artifact_id AND artifact_group_list.group_artifact_id = artifact.group_artifact_id AND artifact_group_list.group_id = $2 ',
diff --git a/gforge/common/survey/Survey.class.php b/gforge/common/survey/Survey.class.php
index beb230f55a..1fb9083ec3 100644
--- a/gforge/common/survey/Survey.class.php
+++ b/gforge/common/survey/Survey.class.php
@@ -100,11 +100,11 @@ class Survey extends Error {
*/
function create($survey_title, $add_questions, $is_active=0, $is_public=1, $is_result_public=0, $double_vote=0) {
if (!$survey_title) {
- $this->setError(_('UPDATE FAILED: Survey Title Required'));
+ $this->setError(_('Update Failed: Survey Title Required'));
return false;
/* We need at least one survey question at this point */
} else if (!$add_questions || !is_array($add_questions) || count($add_questions)<1) {
- $this->setError(_('UPDATE FAILED: Survey Questions Required'));
+ $this->setError(_('Update Failed: Survey Questions Required'));
return false;
}
@@ -144,7 +144,7 @@ class Survey extends Error {
*/
function update($survey_title, &$add_questions, &$del_questions, $is_active=0, $is_public=1, $is_result_public=0, $double_vote=0) {
if (!$survey_title) {
- $this->setError(_('UPDATE FAILED: Survey Title Required'));
+ $this->setError(_('Update Failed: Survey Title Required'));
return false;
/* We need at least one survey question at this point */
}
diff --git a/gforge/common/system_event/SystemEvent.class.php b/gforge/common/system_event/SystemEvent.class.php
new file mode 100644
index 0000000000..aa5872c817
--- /dev/null
+++ b/gforge/common/system_event/SystemEvent.class.php
@@ -0,0 +1,38 @@
+.
+ *
+ *
+ */
+
+
+
+/**
+ * System Event class
+ *
+ */
+abstract class SystemEvent {
+
+ const PRIORITY_MEDIUM = 2;
+ const STATUS_NEW= 1;
+ const STATUS_RUNNING= 2;
+ const STATUS_DONE= 3;
+}
+
+?>
+
diff --git a/gforge/common/system_event/SystemEventManager.class.php b/gforge/common/system_event/SystemEventManager.class.php
new file mode 100644
index 0000000000..86968a226e
--- /dev/null
+++ b/gforge/common/system_event/SystemEventManager.class.php
@@ -0,0 +1,89 @@
+.
+ *
+ *
+ */
+
+/**
+* Manager of system events
+*
+* Base class to manage system events
+*/
+class SystemEventManager {
+
+
+
+ // Constructor
+ function SystemEventManager() {
+
+ }
+
+ protected static $_instance;
+ /**
+ * SystemEventManager is singleton
+ */
+ public static function instance() {
+ if (!isset(self::$_instance)) {
+ $c = __CLASS__;
+ self::$_instance = new $c;
+ }
+ return self::$_instance;
+ }
+
+ /**
+ * Create a new event, store it in the db and send notifications
+ */
+ public function createEvent($type, $parameters, $priority) {
+ return db_query_params('INSERT INTO system_event (type, parameters,create_date,log) VALUES ($1,$2,$3,$4)',
+ array($type,
+ $parameters,
+ $_SERVER['REQUEST_TIME'],
+ 'NEW')
+ );
+ }
+
+ /**
+ * Table to display the status of the last n events
+ *
+ * @param int $offset the offset of the pagination
+ * @param int $limit the number of event to includ in the table
+ * @param boolean $full display a full table or only a summary
+ * @param array $filter_status the filter on status
+ * @param array $filter_type the filter on type
+ *
+ * @return array events
+ */
+ public function fetchEvents($offset = 0, $limit = 10, $full = false, $filter_status = false, $filter_type = false, $filter_params = false) {
+ $results = db_query_params('SELECT * FROM system_event WHERE type IN ($1) AND status IN($2) AND parameters=$3;',array($filter_type, $filter_status,$filter_params));
+ while($row = db_fetch_array($results))
+ {
+ $events[]=$row;
+ }
+ if (isset($events)) {
+ return $events;
+ }
+ else {
+ return null;
+ }
+
+ }
+}
+
+?>
+
diff --git a/gforge/common/tracker/Artifact.class.php b/gforge/common/tracker/Artifact.class.php
index 305179a99b..792f0a4f66 100644
--- a/gforge/common/tracker/Artifact.class.php
+++ b/gforge/common/tracker/Artifact.class.php
@@ -1011,13 +1011,13 @@ class Artifact extends Error {
$changes['assigned_to'] = 1;
$update = true;
}
- if ($summary && ($this->getSummary() != htmlspecialchars(stripslashes($summary)))) {
+ if ($summary && ($this->getSummary() != htmlspecialchars($summary))) {
$this->addHistory('summary', $this->getSummary());
$qpa = db_construct_qpa($qpa, ' summary=$1,', array(htmlspecialchars($summary)));
$changes['summary'] = 1;
$update = true;
}
- if ($description && ($this->getDetails() != htmlspecialchars(stripslashes($description)))) {
+ if ($description && ($this->getDetails() != htmlspecialchars($description))) {
$this->addHistory('details', $this->getDetails());
$qpa = db_construct_qpa($qpa, ' details=$1,', array(htmlspecialchars($description)));
$changes['details'] = 1;
@@ -1575,6 +1575,8 @@ class Artifact extends Error {
util_send_message('',$subject,$body,$from,$BCC,'',$extra_headers);
}
+ $this->sendSubjectMsg = $subject;
+ $this->sendBodyMsg = $body;
//util_handle_message($monitor_ids,$subject,$body,$BCC);
diff --git a/gforge/common/tracker/ArtifactExtraField.class.php b/gforge/common/tracker/ArtifactExtraField.class.php
index be8498a9f9..c552c15c6a 100644
--- a/gforge/common/tracker/ArtifactExtraField.class.php
+++ b/gforge/common/tracker/ArtifactExtraField.class.php
@@ -491,8 +491,8 @@ class ArtifactExtraField extends Error {
if (strlen($alias) == 0) return true; // empty alias
// invalid chars?
- if (preg_match("/[^[:alnum:]_\\-]/", $alias)) {
- $this->setError(_('The alias contains invalid characters. Only letters, numbers, hypens (-) and underscores (_) allowed.'));
+ if (preg_match("/[^[:alnum:]_@\\-]/", $alias)) {
+ $this->setError(_('The alias contains invalid characters. Only letters, numbers, hypens (-), arobase (@) and underscores (_) allowed.'));
return false;
} else if (in_array($alias, $reserved_alias)) { // alias is reserved?
$this->setError(sprintf(_('\'%1$s\' is a reserved alias. Please provide another name.'), $alias));
@@ -517,7 +517,7 @@ class ArtifactExtraField extends Error {
// called "Quality test", make an alias called "quality_test").
// The alias can be seen as a "unix name" for this field
$alias = preg_replace("/ /", "_", $name);
- $alias = preg_replace("/[^[:alnum:]_]/", "", $alias);
+ $alias = preg_replace("/[^[:alnum:]_@]/", "", $alias);
$alias = strtolower($alias);
} elseif (!$this->validateAlias($alias)) {
// alias is invalid...
diff --git a/gforge/common/tracker/ArtifactFactory.class.php b/gforge/common/tracker/ArtifactFactory.class.php
index 37be311eb1..1a3293e2ae 100644
--- a/gforge/common/tracker/ArtifactFactory.class.php
+++ b/gforge/common/tracker/ArtifactFactory.class.php
@@ -286,8 +286,6 @@ class ArtifactFactory extends Error {
* @return array The array of Artifact objects.
*/
function &getArtifacts() {
- global $sys_database_type;
-
if (!empty($this->artifacts)) {
return $this->artifacts;
}
diff --git a/gforge/common/tracker/ArtifactQuery.class.php b/gforge/common/tracker/ArtifactQuery.class.php
index 0f8810d766..93588523d4 100644
--- a/gforge/common/tracker/ArtifactQuery.class.php
+++ b/gforge/common/tracker/ArtifactQuery.class.php
@@ -121,7 +121,8 @@ class ArtifactQuery extends Error {
* @param string Name of the saved query.
* @return true on success / false on failure.
*/
- function create($name,$status,$assignee,$moddaterange,$sort_col,$sort_ord,$extra_fields,$opendaterange=0,$closedaterange=0,$summary,$description,$followups,$query_type=0) {
+ function create($name,$status,$assignee,$moddaterange,$sort_col,$sort_ord,$extra_fields,$opendaterange=0,$closedaterange=0,
+ $summary,$description,$followups,$query_type=0,$query_options=array()) {
//
// data validation
//
@@ -416,7 +417,7 @@ class ArtifactQuery extends Error {
$type = $aef->getType();
if ($type == ARTIFACT_EXTRAFIELDTYPE_INTEGER) {
if (!preg_match('/^[><= \-\+0-9%]+$/', $vals[$i])) {
- $this->setError('Invalid Value for Integer type: '. stripslashes($vals[$i]));
+ $this->setError('Invalid Value for Integer type: '. $vals[$i]);
return false;
}
}
@@ -621,7 +622,8 @@ class ArtifactQuery extends Error {
* @param string The name of the saved query
* @return boolean success.
*/
- function update($name,$status,$assignee,$moddaterange,$sort_col,$sort_ord,$extra_fields,$opendaterange='',$closedaterange='',$summary,$description,$followups,$query_type=0) {
+ function update($name,$status,$assignee,$moddaterange,$sort_col,$sort_ord,$extra_fields,$opendaterange='',$closedaterange='',
+ $summary,$description,$followups,$query_type=0,$query_options=array()) {
if (!$name) {
$this->setMissingParamsError();
return false;
@@ -651,13 +653,13 @@ class ArtifactQuery extends Error {
db_begin();
$result = db_query_params ('UPDATE artifact_query
SET query_name=$1,
- query_type=$2
- WHERE artifact_query_id=$3
- AND user_id=$4',
+ query_type=$2,
+ query_options=$3
+ WHERE artifact_query_id=$4',
array (htmlspecialchars($name),
$query_type,
- $this->getID(),
- user_getid())) ;
+ join('|', $query_options),
+ $this->getID())) ;
if ($result && db_affected_rows($result) > 0) {
if (!$this->insertElements($this->getID(),$status,$assignee,$moddaterange,$sort_col,$sort_ord,$extra_fields,$opendaterange,$closedaterange,$summary,$description,$followups)) {
db_rollback();
diff --git a/gforge/common/tracker/ArtifactType.class.php b/gforge/common/tracker/ArtifactType.class.php
index 84d784b1b9..57bb57314c 100644
--- a/gforge/common/tracker/ArtifactType.class.php
+++ b/gforge/common/tracker/ArtifactType.class.php
@@ -270,6 +270,7 @@ class ArtifactType extends Error {
return false;
} else {
db_commit();
+ $this->Group->normalizeAllRoles () ;
return $id;
}
}
@@ -421,14 +422,14 @@ class ArtifactType extends Error {
* @return string return email address
*/
function getReturnEmailAddress() {
- global $sys_default_domain,$sys_use_gateways;
+
$address = '';
- if($sys_use_gateways) {
+ if(forge_get_config('use_gateways')) {
$address .= strtolower($this->getUnixName());
} else {
$address .= 'noreply';
}
- $address .= '@'.$sys_default_domain;
+ $address .= '@'.forge_get_config('web_host');
return $address;
}
@@ -880,6 +881,9 @@ class ArtifactType extends Error {
//echo '11'.db_error();
db_commit();
+
+ $this->Group->normalizeAllRoles () ;
+
return true;
}
diff --git a/gforge/common/valid/Rule.class.php b/gforge/common/valid/Rule.class.php
new file mode 100644
index 0000000000..73d1d2744b
--- /dev/null
+++ b/gforge/common/valid/Rule.class.php
@@ -0,0 +1,382 @@
+.
+ */
+
+/**
+ * @package Codendi
+ */
+class Rule {
+ /**
+ * @access private
+ */
+ var $error;
+
+ /**
+ * Check if $val is a valid not.
+ *
+ * @param String $val Value to check.
+ * @return Boolean
+ */
+ function isValid($val) {
+ trigger_error(get_class($this).'::isValid() => Not yet implemented', E_USER_ERROR);
+ }
+
+ /**
+ * Default error message if rule is not apply on value.
+ *
+ * @param String $val Value to check.
+ * @return Boolean
+ */
+ function getErrorMessage($key) {
+ return $this->error;
+ }
+}
+
+/**
+ * Validate date provided by Codendi calendar.
+ *
+ * Note: this date format is more restrictive than php check date because in
+ * this case, 2007-01-01 format (with zero in month or day) is not allowed.
+ */
+class Rule_Date
+extends Rule {
+ function isValid($val) {
+ if(preg_match('/^(\d{1,4})-(\d{1,2})-(\d{1,2}?)$/', $val, $m)) {
+ return checkdate($m[2], $m[3], $m[1]);
+ } else {
+ return false;
+ }
+ }
+}
+
+/**
+ * Abstract class that define left-hand operand for a comparison.
+ */
+class Rule_Comparator
+extends Rule {
+ /**
+ * @access private
+ */
+ var $ref;
+ function Rule_Comparator($ref) {
+ $this->ref = $ref;
+ }
+}
+
+/**
+ * Check that given value is strictly greater than the one defined in
+ * constructor.
+ */
+class Rule_GreaterThan
+extends Rule_Comparator {
+ function isValid($val) {
+ if(is_numeric($val) && $val > $this->ref) {
+ return true;
+ }
+ return false;
+ }
+}
+
+/**
+ * Check that given value is strictly less than the one defined in constructor.
+ */
+class Rule_LessThan
+extends Rule_Comparator {
+ function isValid($val) {
+ if(is_numeric($val) && $val < $this->ref) {
+ return true;
+ }
+ return false;
+ }
+}
+
+/**
+ * Check that given value is greater or equal to the one defined in
+ * constructor.
+ */
+class Rule_GreaterOrEqual
+extends Rule_Comparator {
+ function isValid($val) {
+ if(is_numeric($val) && $val >= $this->ref) {
+ return true;
+ }
+ return false;
+ }
+}
+
+/**
+ * Check that given value is strictly less or equal to the one defined in
+ * constructor.
+ */
+class Rule_lessOrEqual
+extends Rule_Comparator {
+ function isValid($val) {
+ if(is_numeric($val) && $val <= $this->ref) {
+ return true;
+ }
+ return false;
+ }
+}
+
+/**
+ * Check that given value belong to the array defined in constructor.
+ *
+ * There is no type check.
+ */
+class Rule_WhiteList
+extends Rule_Comparator {
+ function isValid($val) {
+ if(is_array($this->ref)
+ && count($this->ref) > 0
+ && in_array($val, $this->ref)) {
+ return true;
+ }
+ return false;
+ }
+}
+
+/**
+ * Check that given value is a valid signed 32 bits decimal integer.
+ */
+class Rule_Int
+extends Rule {
+ /**
+ * Check the format according to PHP definition of a decimal integer.
+ * @see http://php.net/int
+ * @access private
+ */
+ function checkFormat($val) {
+ if(preg_match('/^([+-]?[1-9][0-9]*|[+-]?0)$/', $val)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ function isValid($val) {
+ // Need to check with the regexp because of octal form '0123' that is
+ // equal to '123' with string '==' comparison.
+ if($this->checkFormat($val)) {
+ // Check (-2^31;2^31-1) range
+ if(strval(intval($val)) == $val) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+}
+
+/**
+ * Check that given value is a string.
+ */
+class Rule_String
+extends Rule {
+ function isValid($val) {
+ return is_string($val);
+ }
+}
+
+/**
+ * Check if given string contains neither a carrige return nor a null char.
+ */
+class Rule_NoCr
+extends Rule {
+ function isValid($val) {
+ if(is_string($val) && strpos($val, 0x0A) === false && strpos($val, 0x0D) === false
+ && strpos($val, 0x00) === false) {
+ return true;
+ }
+ return false;
+ }
+}
+
+/**
+ * Check if an email address is valid or not in Codendi context.
+ *
+ * This rule is influenced by a global variable 'sys_disable_subdomain'. If
+ * this variable is set (no subdomain for codendi) and only in this case, emails
+ * like 'user@codendi' are allowed.
+ *
+ * The faulty email address is available with $this->getErrorMessage();
+ */
+class Rule_Email
+extends Rule {
+ var $separator;
+
+ function Rule_Email($separator = null) {
+ $this->separator = $separator;
+ }
+
+ function isValid($val) {
+ if($this->separator !== null) {
+ // If separator is defined, split the string and check each email.
+ $emails = split($this->separator, $val);
+ $valid = true;
+ while((list($key,$email) = each($emails)) && $valid) {
+ $valid = $valid & $this->validEmail(trim(rtrim($email)));
+ }
+ } else {
+ // $val must contains only one email address
+ $valid = $this->validEmail($val);
+ }
+ return $valid;
+ }
+
+ /**
+ * Check email validity
+ *
+ * Important note: this is very important to keep the 'D' regexp modifier
+ * as this is the only way not to be bothered by injections of \n into the
+ * email address.
+ *
+ * Spaces are allowed at the beginning and the end of the address.
+ */
+ function validEmail($email) {
+ $valid_chars='-!#$%&\'*+0-9=?A-Z^_`a-z{|}~\.';
+ if (array_key_exists('sys_disable_subdomains', $GLOBALS)
+ && $GLOBALS['sys_disable_subdomains']) {
+ $valid_domain='['.$valid_chars.']+';
+ } else {
+ $valid_domain='['.$valid_chars.']+\.['.$valid_chars.']+';
+ }
+ $regexp = '/^['.$valid_chars.']+'.'@'.$valid_domain.'$/D';
+ return preg_match($regexp, $email);
+ }
+}
+
+/**
+ * Check if value match Codendi user names format.
+ *
+ * This rule doesn't check that user actually exists.
+ */
+class Rule_UserNameFormat
+extends Rule {
+
+ function containsIllegalChars($val) {
+ return (strspn($val,"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_") != strlen($val));
+ }
+
+ function isNotLegalName($val) {
+ return preg_match('/^((root)|(bin)|(daemon)|(adm)|(lp)|(sync)|(shutdown)|(halt)|(mail)|(news)'
+ .'|(uucp)|(operator)|(games)|(mysql)|(httpd)|(nobody)|(dummy)'
+ .'|(www)|(cvs)|(shell)|(ftp)|(irc)|(debian)|(ns)|(download))$/i', $val);
+ }
+
+ function isCvsAccount($val) {
+ return preg_match('/^anoncvs_/i', $val);
+ }
+
+ function lessThanMin($val) {
+ return (strlen($val) < 3);
+ }
+
+ function greaterThanMax($val) {
+ return (strlen($val) > 30);
+ }
+
+ function isValid($val) {
+ return !$this->isNotLegalName($val)
+ && !$this->isCvsAccount($val)
+ && !$this->lessThanMin($val)
+ && !$this->greaterThanMax($val)
+ && !$this->containsIllegalChars($val);
+ }
+}
+
+/**
+ * Check that file was correctly uploaded doesn't by pass Codendi limits.
+ *
+ * Tests mainly rely on PHP $_FILES error code but add a double check of file
+ * size because MAX_FILE_SIZE (used by PHP to check allowed size) is submitted
+ * by the client.
+ *
+ * By default the maxSize is defined by 'sys_max_size_upload' Codendi
+ * variable but may be customized with setMaxSize.
+ */
+//require_once("www/file/file_utils.php"); // Needed for 2 GB workaround
+class Rule_File
+extends Rule {
+ var $maxSize;
+ var $i18nPageName;
+
+ function Rule_File() {
+ $this->maxSize = $GLOBALS['sys_max_size_upload'];
+ $this->i18nPageName = 'rule_valid';
+ }
+
+ function setMaxSize($max) {
+ $this->maxSize = $max;
+ }
+
+ function geti18nError($key, $params="") {
+ return $GLOBALS['Language']->getText($this->i18nPageName, $key, $params);
+ }
+
+ /**
+ * Check file upload validity
+ *
+ * @param Array One entry in $_FILES superarray (e.g. $_FILES['test'])
+ * @return Boolean Is file upload valid or not.
+ */
+ function isValid($file) {
+ $ok = false;
+ if(is_array($file)) {
+ switch($file['error']) {
+ case UPLOAD_ERR_OK:
+ // all is OK
+ $ok = true;
+ break;
+ case UPLOAD_ERR_INI_SIZE:
+ case UPLOAD_ERR_FORM_SIZE:
+ $this->error = $this->geti18nError('error_upload_size', $file['error']);
+ break;
+ case UPLOAD_ERR_PARTIAL:
+ $this->error = $this->geti18nError('error_upload_partial', $file['error']);
+ break;
+ case UPLOAD_ERR_NO_FILE:
+ $this->error = $this->geti18nError('error_upload_nofile', $file['error']);
+ break;
+ //case UPLOAD_ERR_NO_TMP_DIR: PHP 5.0.3
+ //case UPLOAD_ERR_CANT_WRITE: PHP 5.1.0
+ //case UPLOAD_ERR_EXTENSION: PHP 5.2.0
+ default:
+ $this->error = $this->geti18nError('error_upload_unknown', $file['error']);
+ }
+ if($ok && $file['name'] == '') {
+ $ok = false;
+ $this->error = $this->geti18nError('error_upload');
+ }
+ if($ok) {
+ // Re-check filesize (do not trust uploaded MAX_FILE_SIZE)
+ if(file_utils_get_size($file['tmp_name']) > $this->maxSize) {
+ $ok = false;
+ $this->error = $this->geti18nError('error_upload_size', 1);
+ }
+ }
+ }
+ return $ok;
+ }
+}
+
+?>
diff --git a/gforge/common/valid/Valid.class.php b/gforge/common/valid/Valid.class.php
new file mode 100644
index 0000000000..b63a6ebf85
--- /dev/null
+++ b/gforge/common/valid/Valid.class.php
@@ -0,0 +1,229 @@
+.
+ */
+
+require_once('common/valid/Rule.class.php');
+
+/**
+ * @package Codendi
+ */
+class Valid {
+ /**
+ * @access private
+ */
+ var $errors;
+
+ /**
+ * @access private
+ */
+ var $key;
+
+ /**
+ * @access private
+ */
+ var $rules;
+
+ /**
+ * @access private
+ */
+ var $isRequired;
+
+ /**
+ * @access private
+ */
+ var $useFeedback;
+
+ /**
+ * @access private
+ */
+ var $globalErrorMessage;
+
+ /**
+ * @access private
+ */
+ var $isValid;
+
+ /**
+ * Constructor
+ */
+ function Valid($key = null) {
+ $this->key = $key;
+ $this->errors = array();
+ $this->rules = array();
+ $this->isRequired = false;
+ $this->useFeedback = true;
+ $this->globalErrorMessage = null;
+ $this->isValid;
+ }
+
+ /**
+ * Return the variable name on which rules must applies.
+ *
+ * @access private
+ */
+ function getKey() {
+ return $this->key;
+ }
+
+ /**
+ * Add a new rule in this validation.
+ *
+ * ou can add a custom error message that will bypass the default one that
+ * comes with the rule.
+ * @param Rule Reference on rule.
+ * @param String Error message.
+ */
+ function addRule(&$rule, $message=false) {
+ $this->rules[] =& $rule;
+ $this->errors[] = $message;
+ }
+
+ /**
+ * The value is required.
+ *
+ * All rules must succeed (as usual). Empty / null values are forbidden
+ * (raise an error). And all failure generate an error (instead of a
+ * warning).
+ */
+ function required() {
+ $this->isRequired = true;
+ }
+
+ /**
+ * Turn feedback off.
+ */
+ function disableFeedback() {
+ $this->useFeedback = false;
+ }
+
+ /**
+ * Set a global error message that will replace all other messages.
+ *
+ * Note: If no error, no message raised. The message is raised with either
+ * 'warning' or 'error' level according to required();
+ * @param String Error message
+ */
+ function setErrorMessage($msg) {
+ $this->globalErrorMessage = $msg;
+ }
+
+ /**
+ * Return true if given value is empty
+ *
+ * @access private
+ * @param mixed Value to test
+ * @return boolean
+ */
+ function isValueEmpty($value) {
+ return ($value === '' || $value === false || $value === null);
+ }
+
+ /**
+ * Append feebback in the global Response object.
+ * @access private
+ */
+ function addFeedback($level, $error) {
+ $GLOBALS['Response']->addFeedback($level, $error);
+ }
+
+ /**
+ * Generate error message according to settings.
+ *
+ * Takes in account user requirement 'required' and
+ * 'disableFeedback'. Empty error messages are disarded.
+ * @access private
+ */
+ function populateFeedback() {
+ if($this->useFeedback) {
+ $level = 'warning';
+ if($this->isRequired) {
+ $level = 'error';
+ }
+ if($this->globalErrorMessage !== null &&
+ !$this->isValid) {
+ $this->addFeedback($level, $this->globalErrorMessage);
+ } else {
+ foreach($this->errors as $error) {
+ if($error != '') {
+ $this->addFeedback($level, $error);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Prepare error message on Rule:isValid result.
+ *
+ * If the test succeeded, the error message is cleared (either custom or
+ * built-in messages).
+ * @access private
+ * @param Integer Index of the Rule that was applied.
+ * @param Boolean Result of the test.
+ */
+ function errorMessage($i, $result) {
+ if($result === true) {
+ $this->errors[$i] = '';
+ } else {
+ if($this->errors[$i] === false) {
+ $this->errors[$i] = $this->rules[$i]->getErrorMessage($this->key);
+ }
+ }
+ }
+
+ /**
+ * Apply each rule on the given value and prepare feedback.
+ *
+ * @access private
+ * @param mixed Value to test.
+ */
+ function checkEachRules($value) {
+ $isValid = true;
+ $rCtr = count($this->rules);
+ for($i = 0; $i < $rCtr; $i++) {
+ $valid = $this->rules[$i]->isValid($value);
+ $this->errorMessage($i, $valid);
+ $isValid = $isValid && $valid;
+ }
+ if($isValid && $this->isRequired && $this->isValueEmpty($value)) {
+ $this->isValid = false;
+ } else {
+ $this->isValid = $isValid;
+ }
+ $this->populateFeedback();
+ }
+
+ /**
+ * Run validation on given value.
+ *
+ * @param mixed Value to test.
+ */
+ function validate($value) {
+ if($this->isRequired
+ || (!$this->isRequired && !$this->isValueEmpty($value))) {
+ $this->checkEachRules($value);
+ return $this->isValid;
+ }
+ return true;
+ }
+}
+
+?>
diff --git a/gforge/common/valid/ValidFactory.class.php b/gforge/common/valid/ValidFactory.class.php
new file mode 100644
index 0000000000..62f2e38285
--- /dev/null
+++ b/gforge/common/valid/ValidFactory.class.php
@@ -0,0 +1,199 @@
+.
+ */
+
+require_once('common/valid/Valid.class.php');
+
+/**
+ * Check that value is a decimal integer greater or equal to zero.
+ * @package Codendi
+ */
+class Valid_UInt
+extends Valid {
+ function validate($value) {
+ $this->addRule(new Rule_Int());
+ $this->addRule(new Rule_GreaterOrEqual(0));
+ return parent::validate($value);
+ }
+
+}
+
+/**
+ * Check that group_id variable is valid
+ */
+class Valid_GroupId
+extends Valid {
+ function Valid_GroupId() {
+ parent::Valid('group_id');
+ //$this->setErrorMessage($GLOBALS['Language']->getText('include_exit','no_gid_err'));
+ }
+
+ function validate($value) {
+ $this->addRule(new Rule_Int());
+ $this->addRule(new Rule_GreaterThan(0));
+ return parent::validate($value);
+ }
+}
+
+/**
+ * Check that 'pv' parameter is set to an acceptable value.
+ */
+class Valid_Pv
+extends Valid {
+ function Valid_Pv() {
+ parent::Valid('pv');
+ }
+
+ function validate($value) {
+ $this->addRule(new Rule_WhiteList(array(0,1,2)));
+ return parent::validate($value);
+ }
+}
+
+/**
+ * Check that value is a string (should always be true).
+ */
+class Valid_Text
+extends Valid {
+ function validate($value) {
+ $this->addRule(new Rule_String());
+ return parent::validate($value);
+ }
+}
+
+/**
+ * Check that value is a string with neither carrige return nor null char.
+ */
+class Valid_String
+extends Valid_Text {
+ function validate($value) {
+ $this->addRule(new Rule_NoCr());
+ return parent::validate($value);
+ }
+}
+
+/**
+ * Wrapprt for 'WhiteList' rule
+ */
+class Valid_WhiteList
+extends Valid {
+ function Valid_WhiteList($key, $whitelist) {
+ parent::Valid($key);
+ $this->addRule(new Rule_WhiteList($whitelist));
+ }
+}
+
+/**
+ * Check that value match Codendi user short name format.
+ *
+ * This rule doesn't check that user actually exists.
+ */
+class Valid_UserNameFormat
+extends Valid_String {
+ function validate($value) {
+ $this->addRule(new Rule_UserNameFormat());
+ return parent::validate($value);
+ }
+}
+
+
+/**
+ * Check that submitted value is a simple string and a valid Codendi email.
+ */
+class Valid_Email
+extends Valid_String {
+ var $separator;
+
+ function Valid_Email($key=null, $separator=null) {
+ if(is_string($separator)) {
+ $this->separator = $separator;
+ } else {
+ $this->separator = null;
+ }
+ parent::Valid($key);
+ }
+
+ function validate($value) {
+ $this->addRule(new Rule_Email($this->separator));
+ return parent::validate($value);
+ }
+}
+
+/**
+ * Check uploaded file validity.
+ */
+class Valid_File
+extends Valid {
+
+ /**
+ * Is uploaded file empty or not.
+ *
+ * @param Array One entry of $_FILES
+ */
+ function isEmptyValue($file) {
+ if(!is_array($file)) {
+ return false;
+ } elseif(parent::isEmptyValue($file['name'])) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Check rules on given file.
+ *
+ * @param Array $_FILES superarray.
+ * @param String Index of file to check in $_FILES array.
+ * @return Boolean
+ */
+ function validate($files, $index) {
+ if(is_array($files) && isset($files[$index])) {
+ $this->addRule(new Rule_File());
+ return parent::validate($files[$index]);
+ } elseif($this->isRequired) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+}
+
+
+class ValidFactory {
+ /**
+ * If $validator is an instance of a Validator, do nothing and returns it
+ * If $validator is a string and a validator exists (Valid_String for 'string', Valid_UInt for 'uint', ...) then creates an instance and returns it
+ * Else returns null
+ */
+ /* public static */ function getInstance($validator, $key = null) {
+ if (is_a($validator, 'Valid')) {
+ return $validator;
+ } else if(is_string($validator) && class_exists('Valid_'.$validator)) {
+ $validator_classname = 'Valid_'.$validator;
+ $v = new $validator_classname($key);
+ return $v;
+ } else {
+ return null;
+ }
+ }
+}
+?>
diff --git a/gforge/cronjobs/auth_unix.php b/gforge/cronjobs/auth_unix.php
index 1c25e815db..d6c3253fc3 100644
--- a/gforge/cronjobs/auth_unix.php
+++ b/gforge/cronjobs/auth_unix.php
@@ -199,7 +199,7 @@ if ($err == "")
{
$line .= implode (",", $gmembers) . ",";
}
- $line .= $sys_apache_user . "\n";
+ $line .= forge_get_config('apache_user') . "\n";
fwrite ($h6, $line);
}
}
diff --git a/gforge/cronjobs/backup_site.php b/gforge/cronjobs/backup_site.php
index 76c337e008..9ffc703fe2 100755
--- a/gforge/cronjobs/backup_site.php
+++ b/gforge/cronjobs/backup_site.php
@@ -75,13 +75,13 @@ if($retval!=0){
* Backup uploads dir
**************************************/
$output="";
-if (file_exists($sys_upload_dir)) {
- @exec('tar -hjcvf '.$sys_path_to_backup.'uploads-tmp-'.$datetime.'.tar.bz2 '.$sys_upload_dir.' 2>&1' ,$output,$retval); //proceed upload dir tar file creation
+if (file_exists(forge_get_config('upload_dir'))) {
+ @exec('tar -hjcvf '.$sys_path_to_backup.'uploads-tmp-'.$datetime.'.tar.bz2 '.forge_get_config('upload_dir').' 2>&1' ,$output,$retval); //proceed upload dir tar file creation
if($retval!=0){
$err.= implode("\n", $output);
}
} else {
- $err.= 'Unable to find Upload Dir. Value on local.inc is:'.$sys_upload_dir;
+ $err.= 'Unable to find Upload Dir. Value on local.inc is:'.forge_get_config('upload_dir');
}
/**************************************
diff --git a/gforge/cronjobs/calculate_user_metric.php b/gforge/cronjobs/calculate_user_metric.php
index d2ca3a3a89..7a4667ba0f 100755
--- a/gforge/cronjobs/calculate_user_metric.php
+++ b/gforge/cronjobs/calculate_user_metric.php
@@ -69,15 +69,11 @@ db_begin();
db_query_params ('DELETE FROM user_metric0',
array()) ;
-
$err .= db_error();
-if ($sys_database_type != 'mysql') {
- db_query_params ('select setval($1,1)',
- array('user_metric0_pk_seq')) ;
-
- $err .= db_error();
-}
+db_query_params ('select setval($1,1)',
+ array('user_metric0_pk_seq')) ;
+$err .= db_error();
db_query_params ('INSERT INTO user_metric0
(user_id,times_ranked,avg_raters_importance,avg_rating,metric,percentile,importance_factor)
@@ -95,39 +91,16 @@ $err .= db_error();
db_query_params ('UPDATE user_metric0 SET ranking=ranking-1',
array()) ;
-
-if ($sys_database_type == 'mysql') {
- $sql="
- SELECT count(*) FROM user_metric0 INTO @total;
- UPDATE user_metric0 SET
- metric=(log(times_ranked)*avg_rating),
- percentile=(100-(100*(ranking-1.0)/@total));";
-
- db_mquery($sql);
- $err .= db_error();
- db_next_result();
- $err .= db_error();
-} else {
- $sql=";";
-
- db_query_params ('UPDATE user_metric0 SET metric=(log(times_ranked::float)*avg_rating::float)::float, percentile=(100-(100*((ranking::float-1)/(select count(*) from user_metric0))))::float',
- array());
- $err .= db_error();
-}
-
-if ($sys_database_type == 'mysql') {
- $sql="UPDATE user_metric0 SET importance_factor=(1+((percentile/100.0)*.5));";
- db_query_mysql($sql);
-} else {
- db_query_params ('UPDATE user_metric0 SET importance_factor=(1+((percentile::float/100)*.5))::float',
- array()) ;
-}
-
+db_query_params ('UPDATE user_metric0 SET metric=(log(times_ranked::float)*avg_rating::float)::float, percentile=(100-(100*((ranking::float-1)/(select count(*) from user_metric0))))::float',
+ array());
+$err .= db_error();
+db_query_params ('UPDATE user_metric0 SET importance_factor=(1+((percentile::float/100)*.5))::float',
+ array()) ;
$err .= db_error();
db_query_params ('SELECT * INTO TEMPORARY TABLE user_metric_cur FROM user_metric0',
array()) ;
-
+$err .= db_error();
for ($i=1; $i<9; $i++) {
$j=($i-1);
@@ -260,18 +233,12 @@ for ($i=1; $i<9; $i++) {
// Only do final percentile if row count is not zero
if (db_result($res,0,0)) {
- /*
- Update with final percentile and importance
- */
- if ($sys_database_type == 'mysql') {
- $sql="UPDATE user_metric_next SET
- percentile=(100-(100*((ranking-1.0)/". db_result($res,0,0) .")))";
- $res = db_query_mysql ($sql);
- } else {
- $res = db_query_params ('UPDATE user_metric_next SET
+ /*
+ Update with final percentile and importance
+ */
+ $res = db_query_params ('UPDATE user_metric_next SET
percentile=(100-(100*((ranking::float-1)/$1)))',
- array (db_result($res,0,0))) ;
- }
+ array (db_result($res,0,0))) ;
if (!$res || db_affected_rows($res) < 1) {
$err .= "Error in round $i setting percentile: " . db_error();
exit;
diff --git a/gforge/cronjobs/check_stale_tracker_items.php b/gforge/cronjobs/check_stale_tracker_items.php
index ec7dd95754..2a7a264149 100755
--- a/gforge/cronjobs/check_stale_tracker_items.php
+++ b/gforge/cronjobs/check_stale_tracker_items.php
@@ -33,19 +33,13 @@ require dirname(__FILE__).'/../www/env.inc.php';
require $gfwww.'include/squal_pre.php';
require $gfcommon.'include/cron_utils.php';
-if ($sys_database_type == 'mysql') {
- $res = db_query_mysql ('UPDATE artifact NATURAL JOIN artifact_group_list SET status_id = 2
- WHERE (status_timeout + close_date) < now() AND status_id = 4');
-} else {
- $res = db_query_params ('UPDATE artifact SET status_id = 2
+$res = db_query_params ('UPDATE artifact SET status_id = 2
WHERE artifact_id IN (
SELECT artifact_id
FROM artifact a NATURAL JOIN artifact_group_list agl
WHERE (agl.status_timeout + a.close_date) < $1
AND a.status_id=4)',
- array (time()));
-}
-
+ array (time()));
cron_entry(2,db_error());
diff --git a/gforge/cronjobs/create_home_dirs.php b/gforge/cronjobs/create_home_dirs.php
deleted file mode 100644
index eacaedc94f..0000000000
--- a/gforge/cronjobs/create_home_dirs.php
+++ /dev/null
@@ -1,165 +0,0 @@
-#! /usr/bin/php4 -f
-Default page for project not found
Default page for project not found, please create a homepage for your project.
';
- $err .= "Project homepage template " . $sys_custom_path . "/project_homepage_template.php not found";
- }
- //
- // Change some defaults in the template file
- //
- $contents = str_replace ("", $sys_default_domain, $contents);
- $contents = str_replace ("", $g->getDescription (), $contents);
- $contents = str_replace ("", $g->getPublicName (), $contents);
- $contents = str_replace ("", $g->getID (), $contents);
- $contents = str_replace ("", $g->getUnixName (), $contents);
- //
- // Write the file back out to the project home dir
- //
- $fw = fopen ($groupdir_prefix . "/" . $group . "/htdocs/index.php", "w");
- fwrite ($fw, $contents);
- fclose ($fw);
-
- }
- system ("chown -R root:" . $group. " " . $groupdir_prefix . "/" . $group);
- system ("chmod -R ug+rw " . $groupdir_prefix . "/" . $group);
- system ("find " . $groupdir_prefix . "/" . $group . " -type d -exec chmod g+s {} \;");
- system ("chmod -R o-rwx " . $groupdir_prefix . "/" . $group);
-}
-if (($reload_apache == true)
-&& (is_file ($sys_apache_pid_file) == true))
-{
- $apache_pid = intval (file_get_contents ($sys_apache_pid_file));
- if ((is_integer ($apache_pid) == true) && ($apache_pid > 0))
- {
- if (posix_kill ($apache_pid, 1) == false) // SIGHUP
- {
- $err .= "Failed to send SIGHUP to PID " . $apache_pid;
- }
- }
-}
-
-cron_entry(16,$err);
-
-?>
diff --git a/gforge/cronjobs/db_project_sums.php b/gforge/cronjobs/db_project_sums.php
index bfad64deb1..fa0478827a 100755
--- a/gforge/cronjobs/db_project_sums.php
+++ b/gforge/cronjobs/db_project_sums.php
@@ -42,7 +42,7 @@ $err='';
/*
Create an aggregation table that includes counts of forum messages
*/
-if ($sys_use_forum) {
+if (forge_get_config('use_forum')) {
db_begin();
db_query_params ('LOCK TABLE forum_agg_msg_count IN ACCESS EXCLUSIVE MODE',
@@ -71,18 +71,12 @@ GROUP BY fgl.group_forum_id',
}
db_commit();
-
- if ($sys_database_type != 'mysql') {
- db_query_params ('VACUUM ANALYZE forum_agg_msg_count',
- array()) ;
-
- }
}
/*
Create an aggregation table that includes counts of artifacts
*/
-if ($sys_use_tracker) {
+if (forge_get_config('use_tracker')) {
db_begin();
db_query_params ('LOCK TABLE artifact_counts_agg IN ACCESS EXCLUSIVE MODE',
@@ -109,11 +103,6 @@ GROUP BY agl.group_artifact_id',
$err .= db_error();
db_commit();
-
- if ($sys_database_type != 'mysql') {
- db_query_params ('VACUUM ANALYZE artifact_counts_agg',
- array()) ;
- }
}
/*
@@ -130,7 +119,7 @@ $res=db_query_params ('DELETE FROM project_sums_agg',
/*
Get counts of mailing lists
*/
-if ($sys_use_mail) {
+if (forge_get_config('use_mail')) {
$res=db_query_params ('INSERT INTO project_sums_agg
SELECT group_id,$1 AS type,count(*) AS count
FROM mail_group_list WHERE is_public = 1
@@ -142,7 +131,7 @@ GROUP BY group_id,type',
/*
Get counts of surveys
*/
-if ($sys_use_survey) {
+if (forge_get_config('use_survey')) {
$res=db_query_params ('INSERT INTO project_sums_agg
SELECT group_id,$1 AS type,count(*) AS count
FROM surveys
@@ -157,7 +146,7 @@ GROUP BY group_id,type',
/*
Forum message count
*/
-if ($sys_use_forum) {
+if (forge_get_config('use_forum')) {
$res=db_query_params ('INSERT INTO project_sums_agg
SELECT forum_group_list.group_id,$1 AS type, count(forum.msg_id) AS count
FROM forum,forum_group_list
@@ -181,15 +170,6 @@ GROUP BY group_id,type',
db_commit();
$err .= db_error();
-if ($sys_database_type != 'mysql') {
- db_query_params ('VACUUM ANALYZE project_sums_agg',
- array()) ;
-
- if (db_error()) {
- $err .= "Error: ".db_error();
- }
-}
-
cron_entry(3,$err);
?>
diff --git a/gforge/cronjobs/db_stats_agg.php b/gforge/cronjobs/db_stats_agg.php
index ec835a408a..0541fa381f 100755
--- a/gforge/cronjobs/db_stats_agg.php
+++ b/gforge/cronjobs/db_stats_agg.php
@@ -43,39 +43,7 @@ $res = db_query_params ('DELETE FROM stats_project_months',
array ());
$err .= db_error();
-if ($sys_database_type == 'mysql') {
- $sql="INSERT INTO stats_project_months
- SELECT month, group_id,
- avg(developers) AS developers, avg(group_ranking) AS group_ranking,
- avg(group_metric) AS group_metric,
- sum(logo_showings) AS logo_showings,
- sum(downloads) AS downloads,
- sum(site_views) AS site_views ,
- sum(subdomain_views) AS subdomain_views,
- sum(page_views) AS page_views,
- sum(file_releases) AS file_releases,
- sum(msg_posted) AS msg_posted,
- sum(msg_uniq_auth) AS msg_uniq_auth,
- sum(bugs_opened) AS bugs_opened,
- sum(bugs_closed) AS bugs_closed,
- sum(support_opened) AS support_opened,
- sum(support_closed) AS support_closed,
- sum(patches_opened) AS patches_opened,
- sum(patches_closed) AS patches_closed,
- sum(artifacts_opened) AS artifacts_opened,
- sum(artifacts_closed) AS artifacts_closed,
- sum(tasks_opened) AS tasks_opened,
- sum(tasks_closed) AS tasks_closed,
- sum(help_requests) AS help_requests,
- sum(cvs_checkouts) AS cvs_checkouts,
- sum(cvs_commits) AS cvs_commits,
- sum(cvs_adds) AS cvs_adds
-FROM stats_project_vw
-GROUP BY month,group_id
-";
- $res = db_query_mysql ($sql);
-} else {
- $res = db_query_params ('INSERT INTO stats_project_months
+$res = db_query_params ('INSERT INTO stats_project_months
SELECT month, group_id,
avg(developers)::int AS developers, avg(group_ranking)::int AS group_ranking,
avg(group_metric) AS group_metric,
@@ -103,8 +71,7 @@ GROUP BY month,group_id
sum(cvs_adds) AS cvs_adds
FROM stats_project_vw
GROUP BY month,group_id',
- array ()) ;
-}
+ array ()) ;
$err .= db_error();
db_commit();
diff --git a/gforge/cronjobs/ftp_create_group_access.php b/gforge/cronjobs/ftp_create_group_access.php
index 144426f8a0..67a61005d8 100644
--- a/gforge/cronjobs/ftp_create_group_access.php
+++ b/gforge/cronjobs/ftp_create_group_access.php
@@ -28,8 +28,8 @@ require $gfcommon.'include/cron_utils.php';
$users = array();
-$chroot_dir = $sys_chroot;
-$ftp_dir = $sys_ftp_upload_dir."/pub/";
+$chroot_dir = forge_get_config('chroot');
+$ftp_dir = forge_get_config('ftp_upload_dir')."/pub/";
$home_dir = $chroot_dir.$homedir_prefix."/";
diff --git a/gforge/cronjobs/homedirs.php b/gforge/cronjobs/homedirs.php
index ca64782380..d39e81b54c 100644
--- a/gforge/cronjobs/homedirs.php
+++ b/gforge/cronjobs/homedirs.php
@@ -114,14 +114,14 @@ foreach($users as $user) {
foreach($groups as $group) {
//test if the FTP upload dir exists and create it if not
- if (!is_dir($sys_ftp_upload_dir)) {
- @mkdir($sys_ftp_upload_dir,0755,true);
+ if (!is_dir(forge_get_config('ftp_upload_dir'))) {
+ @mkdir(forge_get_config('ftp_upload_dir'),0755,true);
}
//create an FTP upload dir for this project
- if ($sys_use_ftpuploads) {
- if (!is_dir($sys_ftp_upload_dir.'/'.$group)) {
- @mkdir($sys_ftp_upload_dir.'/'.$group);
+ if (forge_get_config('use_ftpuploads')) {
+ if (!is_dir(forge_get_config('ftp_upload_dir').'/'.$group)) {
+ @mkdir(forge_get_config('ftp_upload_dir').'/'.$group);
}
}
@@ -150,7 +150,7 @@ foreach($groups as $group) {
//
// Change some defaults in the template file
//
- //$contents=str_replace('',$sys_default_domain,$contents);
+ //$contents=str_replace('',forge_get_config('web_host'),$contents);
//$contents=str_replace('',$g->getDescription(),$contents);
//$contents=str_replace('',$g->getPublicName(),$contents);
//$contents=str_replace('',$g->getID(),$contents);
@@ -162,7 +162,7 @@ foreach($groups as $group) {
$contents=str_replace('##body##',
sprintf(
_("We're Sorry but this Project hasn't yet uploaded their personal webpage yet. Please check back soon for updates or visit the project page ."),
- "http://".$GLOBALS['sys_default_domain'].'/projects/'.$g->getUnixName()),
+ "http://".forge_get_config('web_host').'/projects/'.$g->getUnixName()),
$contents);
//
// Write the file back out to the project home dir
@@ -171,7 +171,7 @@ foreach($groups as $group) {
fwrite($fw,$contents);
fclose($fw);
}
- system("chown -R $sys_apache_user:$sys_apache_group $groupdir_prefix/$group");
+ system("chown -R ".forge_get_config('apache_user').":".forge_get_config('apache_group')." $groupdir_prefix/$group");
}
diff --git a/gforge/cronjobs/mail/mailaliases.php b/gforge/cronjobs/mail/mailaliases.php
index 83df708933..0af0e3cce4 100755
--- a/gforge/cronjobs/mail/mailaliases.php
+++ b/gforge/cronjobs/mail/mailaliases.php
@@ -89,7 +89,7 @@ $gforge_aliases = array();
//
// Set up the forum aliases
//
-if ($sys_use_forum) {
+if (forge_get_config('use_forum')) {
$resforum = db_query_params ('SELECT groups.unix_group_name,lower(fgl.forum_name) AS forum_name
FROM forum_group_list fgl,groups
WHERE fgl.group_id=groups.group_id
@@ -111,7 +111,7 @@ if ($sys_use_forum) {
//
// Set up the tracker aliases
//
-if ($sys_use_tracker) {
+if (forge_get_config('use_tracker')) {
$restracker = db_query_params ('SELECT groups.unix_group_name,lower(agl.name) AS tracker_name,group_artifact_id
FROM artifact_group_list agl, groups
WHERE agl.group_id=groups.group_id
@@ -137,7 +137,7 @@ if ($sys_use_tracker) {
}
}
-if ($sys_use_mail && file_exists($sys_var_path.'/dumps/mailman-aliases')) {
+if (forge_get_config('use_mail') && file_exists($sys_var_path.'/dumps/mailman-aliases')) {
//
// Read in the mailman aliases
//
diff --git a/gforge/cronjobs/mail/mailing_lists_create.php b/gforge/cronjobs/mail/mailing_lists_create.php
index 35dccf9bdc..7829e4fdef 100755
--- a/gforge/cronjobs/mail/mailing_lists_create.php
+++ b/gforge/cronjobs/mail/mailing_lists_create.php
@@ -75,7 +75,7 @@ for ($i=0; $i<$rows; $i++) {
if (! in_array($listname,$mailing_lists)) { // New list?
$err .= "Creating Mailing List: $listname\n";
- //$lcreate_cmd = $sys_path_to_mailman."/bin/newlist -q $listname@$sys_lists_host $email $listpassword &> /dev/null";
+ //$lcreate_cmd = $sys_path_to_mailman."/bin/newlist -q $listname@".forge_get_config('lists_host')." $email $listpassword &> /dev/null";
$lcreate_cmd = $sys_path_to_mailman."/bin/newlist -q $listname $email $listpassword";
$err .= "Command to be executed is $lcreate_cmd\n";
passthru($lcreate_cmd, $failed);
diff --git a/gforge/cronjobs/massmail.php b/gforge/cronjobs/massmail.php
index 869284fe51..ffef692391 100755
--- a/gforge/cronjobs/massmail.php
+++ b/gforge/cronjobs/massmail.php
@@ -85,7 +85,7 @@ if (!$mail_res) {
"$sys_admin_email",
"ATT: Problems with massmail cron script",
"This is automatically generated message from\n
-the mass mailing cron script of $sys_name\n
+the mass mailing cron script of ".forge_get_config ('forge_name')."\n
installation. There was error querying massmail_queue\n
database table. Please take appropriate actions.\n"
);
@@ -190,13 +190,13 @@ page (%2$s), or disable them altogether
by visiting following link:
<%3$s>
'),
- $GLOBALS['sys_name'],
+ forge_get_config ('forge_name'),
util_make_url('/account/'),
util_make_url('/account/unsubscribe.php?ch=_'.$row['confirm_hash'])) ;
} else {
$tail = "" ;
}
- util_send_message($row['email'],$subj, $body."\r\n".$tail,'noreply@'.$sys_default_domain);
+ util_send_message($row['email'],$subj, $body."\r\n".$tail,'noreply@'.forge_get_config('web_host'));
$last_userid = $row['user_id'];
sleep($SLEEP);
diff --git a/gforge/cronjobs/project_weekly_metric.php b/gforge/cronjobs/project_weekly_metric.php
index e638eb0b58..23dd9b8e7e 100755
--- a/gforge/cronjobs/project_weekly_metric.php
+++ b/gforge/cronjobs/project_weekly_metric.php
@@ -57,71 +57,39 @@ if (!$rel) {
#forum messages
-if ($sys_database_type == 'mysql') {
- $sql="INSERT INTO project_counts_weekly_tmp
-SELECT forum_group_list.group_id,'forum',3*log(1+count(forum.msg_id)) AS count FROM forum,forum_group_list
-WHERE forum.group_forum_id=forum_group_list.group_forum_id
-AND post_date > '$last_week'
-AND post_date < '$this_week'
-GROUP BY group_id";
- $rel = db_query_mysql ($sql);
-} else {
- $rel = db_query_params ('INSERT INTO project_counts_weekly_tmp
+$rel = db_query_params ('INSERT INTO project_counts_weekly_tmp
SELECT forum_group_list.group_id,$1,3*log(1+count(forum.msg_id)::float) AS count
FROM forum,forum_group_list
WHERE forum.group_forum_id=forum_group_list.group_forum_id
AND post_date > $2
AND post_date < $3
GROUP BY group_id',
- array('forum',
- $last_week,
- $this_week));
-}
+ array('forum',
+ $last_week,
+ $this_week));
if (!$rel) {
$err .= "\n\n***ERROR:\n\n".db_error();
}
#project manager tasks
-if ($sys_database_type == 'mysql') {
- $sql="INSERT INTO project_counts_weekly_tmp
-SELECT project_group_list.group_id,'tasks',4*log(1+count(project_task.project_task_id)) AS count
-FROM project_task,project_group_list
-WHERE project_task.group_project_id=project_group_list.group_project_id
-AND end_date > '$last_week'
-AND end_date < '$this_week'
-GROUP BY group_id";
- $rel = db_query_mysql ($sql) ;
-} else {
- $rel = db_query_params ('INSERT INTO project_counts_weekly_tmp
+$rel = db_query_params ('INSERT INTO project_counts_weekly_tmp
SELECT project_group_list.group_id,$1,4*log(1+count(project_task.project_task_id)::float) AS count
FROM project_task,project_group_list
WHERE project_task.group_project_id=project_group_list.group_project_id
AND end_date > $2
AND end_date < $3
GROUP BY group_id',
- array('tasks',
- $last_week,
- $this_week));
-}
+ array('tasks',
+ $last_week,
+ $this_week));
if (!$rel) {
$err .= "\n\n***ERROR:\n\n".db_error();
}
#bugs
-if ($sys_database_type == 'mysql') {
- $sql="INSERT INTO project_counts_weekly_tmp
-SELECT agl.group_id,'bugs',3*log(1+count(*)) AS count
-FROM artifact_group_list agl,artifact a
-WHERE a.open_date > '$last_week'
-AND a.open_date < '$this_week'
-AND a.group_artifact_id=agl.group_artifact_id
-AND agl.datatype='1'
-GROUP BY agl.group_id";
- $rel = db_query_mysql($sql);
-} else {
- $rel = db_query_params ('INSERT INTO project_counts_weekly_tmp
+$rel = db_query_params ('INSERT INTO project_counts_weekly_tmp
SELECT agl.group_id,$1,3*log(1+count(*)::float) AS count
FROM artifact_group_list agl,artifact a
WHERE a.open_date > $2
@@ -129,29 +97,17 @@ AND a.open_date < $3
AND a.group_artifact_id=agl.group_artifact_id
AND agl.datatype=$4
GROUP BY agl.group_id',
- array('bugs',
- $last_week,
- $this_week,
- '1'));
-}
+ array('bugs',
+ $last_week,
+ $this_week,
+ '1'));
if (!$rel) {
$err .= "\n\n***ERROR:\n\n".db_error();
}
#patches
-if ($sys_database_type == 'mysql') {
- $sql="INSERT INTO project_counts_weekly_tmp
-SELECT agl.group_id,'patches',10*log(1+count(*)) AS count
-FROM artifact_group_list agl,artifact a
-WHERE a.open_date > '$last_week'
-AND a.open_date < '$this_week'
-AND a.group_artifact_id=agl.group_artifact_id
-AND agl.datatype='3'
-GROUP BY agl.group_id";
- $rel = db_query_mysql($sql);
-} else {
- $rel = db_query_params ('INSERT INTO project_counts_weekly_tmp
+$rel = db_query_params ('INSERT INTO project_counts_weekly_tmp
SELECT agl.group_id,$1,10*log(1+count(*)::float) AS count
FROM artifact_group_list agl,artifact a
WHERE a.open_date > $2
@@ -159,28 +115,16 @@ AND a.open_date < $3
AND a.group_artifact_id=agl.group_artifact_id
AND agl.datatype=$4
GROUP BY agl.group_id',
- array('patches',
- $last_week,
- $this_week,
- '3'));
-}
+ array('patches',
+ $last_week,
+ $this_week,
+ '3'));
if (!$rel) {
$err .= "\n\n***ERROR: \n\n".db_error();
}
#support
-if ($sys_database_type == 'mysql') {
- $sql="INSERT INTO project_counts_weekly_tmp
-SELECT agl.group_id,'support',5*log(1+count(*)) AS count
-FROM artifact_group_list agl,artifact a
-WHERE a.open_date > '$last_week'
-AND a.open_date < '$this_week'
-AND a.group_artifact_id=agl.group_artifact_id
-AND agl.datatype='2'
-GROUP BY agl.group_id";
- $rel = db_query_mysql($sql);
-} else {
- $rel = db_query_params ('INSERT INTO project_counts_weekly_tmp
+$rel = db_query_params ('INSERT INTO project_counts_weekly_tmp
SELECT agl.group_id,$1,5*log(1+count(*)::float) AS count
FROM artifact_group_list agl,artifact a
WHERE a.open_date > $2
@@ -188,63 +132,41 @@ AND a.open_date < $3
AND a.group_artifact_id=agl.group_artifact_id
AND agl.datatype=$4
GROUP BY agl.group_id',
- array('support',
- $last_week,
- $this_week,
- '2'));
-}
+ array('support',
+ $last_week,
+ $this_week,
+ '2'));
if (!$rel) {
$err .= "\n\n***ERROR:\n\n".db_error();
}
#commits
-if ($sys_database_type == 'mysql') {
- $sql="INSERT INTO project_counts_weekly_tmp
-SELECT group_id,'cvs',log(1+sum(commits)) AS count
-FROM stats_cvs_group
-WHERE ((month = '$last_year$last_month' AND day >= '$last_day') OR (month > '$last_year$last_month'))
-AND commits > 0
-GROUP BY group_id";
- $rel = db_query_mysql($sql);
-} else {
- $rel = db_query_params ('INSERT INTO project_counts_weekly_tmp
+$rel = db_query_params ('INSERT INTO project_counts_weekly_tmp
SELECT group_id,$1,log(1+sum(commits)::float) AS count
FROM stats_cvs_group
WHERE ((month = $2 AND day >= $3) OR (month > $4))
AND commits > 0
GROUP BY group_id',
- array('cvs',
- "$last_year$last_month",
- $last_day,
- "$last_year$last_month"));
-}
+ array('cvs',
+ "$last_year$last_month",
+ $last_day,
+ "$last_year$last_month"));
if (!$rel) {
$err .= "\n\n***ERROR:\n\n".db_error();
}
#file releases
-if ($sys_database_type == 'mysql') {
- $sql="INSERT INTO project_counts_weekly_tmp
-SELECT frs_package.group_id,'filereleases',log(5 * count(*))
-FROM frs_release,frs_package
-WHERE frs_package.package_id = frs_release.package_id
-AND frs_release.release_date > '$last_week'
-AND frs_release.release_date < '$this_week'
-GROUP BY frs_package.group_id";
- $rel = db_query_mysql($sql);
-} else {
- $rel = db_query_params ('INSERT INTO project_counts_weekly_tmp
+$rel = db_query_params ('INSERT INTO project_counts_weekly_tmp
SELECT frs_package.group_id,$1,log(5 * count(*)::float)
FROM frs_release,frs_package
WHERE frs_package.package_id = frs_release.package_id
AND frs_release.release_date > $2
AND frs_release.release_date < $3
GROUP BY frs_package.group_id',
- array('filereleases',
- $last_week,
- $this_week));
-}
+ array('filereleases',
+ $last_week,
+ $this_week));
if (!$rel) {
$err .= "\n\n***ERROR:\n\n".db_error();
@@ -253,36 +175,25 @@ if (!$rel) {
db_begin();
#file downloads
-if ($sys_database_type == 'mysql') {
- $sql="INSERT INTO project_counts_weekly_tmp
-SELECT group_id,'downloads', .3*log(1+sum(downloads)) AS downloads
-FROM frs_dlstats_group_vw
-WHERE (month = '$last_year$last_month' AND day >= '$last_day') OR (month > '$last_year$last_month')
-GROUP BY group_id";
- $rel = db_query_mysql($sql);
-} else {
- $rel = db_query_params ('INSERT INTO project_counts_weekly_tmp
+$rel = db_query_params ('INSERT INTO project_counts_weekly_tmp
SELECT group_id,$1, .3*log(1+sum(downloads)::float) AS downloads
FROM frs_dlstats_group_vw
WHERE (month = $2 AND day >= $3) OR (month > $4)
GROUP BY group_id',
- array('downloads',
- "$last_year$last_month",
- $last_day,
- "$last_year$last_month"));
-}
+ array('downloads',
+ "$last_year$last_month",
+ $last_day,
+ "$last_year$last_month"));
if (!$rel) {
$err .= "\n\n***ERROR:\n\n".db_error();
}
db_commit();
-if ($sys_database_type != 'mysql') {
- $rel = db_query_params ('CREATE SEQUENCE project_metric_weekly_seq',
+$rel = db_query_params ('CREATE SEQUENCE project_metric_weekly_seq',
array ());
- if (!$rel) {
- $err .= "\n\n***ERROR: \n\n".db_error();
- }
+if (!$rel) {
+ $err .= "\n\n***ERROR: \n\n".db_error();
}
#create a new table to insert the final records into
@@ -326,19 +237,11 @@ if (!$rel) {
}
db_commit();
-if ($sys_database_type == 'mysql') {
- $sql="INSERT INTO project_weekly_metric (ranking,percentile,group_id)
-SELECT ranking,100-(100*((ranking-1)/$counts)),group_id
-FROM project_metric_weekly_tmp1
-ORDER BY ranking ASC";
- $rel = db_query_mysql($sql);
-} else {
- $rel = db_query_params ('INSERT INTO project_weekly_metric (ranking,percentile,group_id)
+$rel = db_query_params ('INSERT INTO project_weekly_metric (ranking,percentile,group_id)
SELECT ranking,100-(100*((ranking::float-1)/$1)),group_id
FROM project_metric_weekly_tmp1
ORDER BY ranking ASC',
- array($counts));
-}
+ array($counts));
if (!$rel) {
$err .= "\n\n***ERROR:\n\n".db_error();
}
@@ -351,18 +254,11 @@ db_query_params ('DELETE FROM stats_project_metric WHERE month=$1 AND day=$2',
array("$this_year$this_month",
"$this_day"));
-if ($sys_database_type == 'mysql') {
- $sql="INSERT INTO stats_project_metric (month,day,group_id,ranking,percentile)
-SELECT '$this_year$this_month', '$this_day',group_id,ranking,percentile
-FROM project_weekly_metric";
- $rel = db_query_mysql($sql);
-} else {
- $rel = db_query_params ('INSERT INTO stats_project_metric (month,day,group_id,ranking,percentile)
+$rel = db_query_params ('INSERT INTO stats_project_metric (month,day,group_id,ranking,percentile)
SELECT $1::int, $2::int,group_id,ranking,percentile
FROM project_weekly_metric',
- array("$this_year$this_month",
- $this_day));
-}
+ array("$this_year$this_month",
+ $this_day));
if (!$rel) {
$err .= "\n\n***ERROR:\n\n".db_error();
}
diff --git a/gforge/cronjobs/site_stats.php b/gforge/cronjobs/site_stats.php
index 27bf7d068c..e7533c456b 100755
--- a/gforge/cronjobs/site_stats.php
+++ b/gforge/cronjobs/site_stats.php
@@ -62,16 +62,11 @@ $rel = db_query_params ('DELETE FROM stats_agg_logo_by_group WHERE month=$1 AND
array ("$year$month",
$day));
$err .= db_error();
-if ($sys_database_type == 'mysql') {
- $sql = "INSERT INTO stats_agg_logo_by_group SELECT '$year$month' AS month, '$day' AS newday,group_id,count(*) AS count FROM activity_log WHERE type=0 AND day='$yesterday_formatted' GROUP BY month,newday,group_id";
- $rel = db_query_mysql ($sql);
-} else {
- $rel = db_query_params ('INSERT INTO stats_agg_logo_by_group SELECT $1::int AS month, $2::int AS newday,group_id,count(*) AS count
+$rel = db_query_params ('INSERT INTO stats_agg_logo_by_group SELECT $1::int AS month, $2::int AS newday,group_id,count(*) AS count
FROM activity_log WHERE type=0 AND day=$3 GROUP BY month,newday,group_id',
- array ("$year$month",
- $day,
- $yesterday_formatted)) ;
-}
+ array ("$year$month",
+ $day,
+ $yesterday_formatted)) ;
$err .= db_error();
@@ -84,18 +79,10 @@ $rel = db_query_params ('DELETE FROM stats_agg_site_by_group WHERE month=$1 AND
array ("$year$month",
$day));
$err .= db_error();
-if ($sys_database_type == 'mysql') {
- $sql = "INSERT INTO stats_agg_site_by_group ";
- $sql .= "SELECT '$year$month' AS month, '$day' AS newday,group_id,COUNT(*) AS count";
- $sql .= "
- FROM activity_log WHERE type=0 AND day='$yesterday_formatted' GROUP BY month,newday,group_id";
- $rel = db_query_mysql ($sql);
-} else {
- $rel = db_query_params ('INSERT INTO stats_agg_site_by_group SELECT $1::int AS month, $2::int AS newday,group_id,COUNT(*) AS count FROM activity_log WHERE type=0 AND day=$3 GROUP BY month,newday,group_id',
- array ("$year$month",
- $day,
- $yesterday_formatted)) ;
-}
+$rel = db_query_params ('INSERT INTO stats_agg_site_by_group SELECT $1::int AS month, $2::int AS newday,group_id,COUNT(*) AS count FROM activity_log WHERE type=0 AND day=$3 GROUP BY month,newday,group_id',
+ array ("$year$month",
+ $day,
+ $yesterday_formatted)) ;
$err .= db_error();
@@ -107,15 +94,10 @@ $rel = db_query_params ('DELETE FROM stats_site_pages_by_day WHERE month=$1 AND
array ("$year$month",
$day));
$err .= db_error();
-if ($sys_database_type == 'mysql') {
- $sql = "INSERT INTO stats_site_pages_by_day (month,day,site_page_views) SELECT '$year$month' AS month, '$day' AS newday, count(*) AS count FROM activity_log WHERE type=0 AND day='$yesterday_formatted' GROUP BY month,newday";
- $rel = db_query_mysql ($sql);
-} else {
- $rel = db_query_params ('INSERT INTO stats_site_pages_by_day (month,day,site_page_views) SELECT $1::int AS month, $2::int AS newday, count(*) AS count FROM activity_log WHERE type=0 AND day=$3 GROUP BY month,newday',
- array ("$year$month",
- $day,
- $yesterday_formatted)) ;
-}
+$rel = db_query_params ('INSERT INTO stats_site_pages_by_day (month,day,site_page_views) SELECT $1::int AS month, $2::int AS newday, count(*) AS count FROM activity_log WHERE type=0 AND day=$3 GROUP BY month,newday',
+ array ("$year$month",
+ $day,
+ $yesterday_formatted)) ;
$err .= db_error();
@@ -127,14 +109,9 @@ $rel = db_query_params ('DELETE FROM stats_project_developers WHERE month=$1 AND
array ("$year$month",
$day));
$err .= db_error();
-if ($sys_database_type == 'mysql') {
- $sql = "INSERT INTO stats_project_developers (month,day,group_id,developers) SELECT '$year$month' AS month,'$day' AS day,group_id,count(*) AS count FROM user_group GROUP BY month,day,group_id";
- $rel = db_query_mysql ($sql);
-} else {
- $rel = db_query_params ('INSERT INTO stats_project_developers (month,day,group_id,developers) SELECT $1::int AS month,$2::int AS day,group_id,count(*) AS count FROM user_group GROUP BY month,day,group_id',
- array ("$year$month",
- $day));
-}
+$rel = db_query_params ('INSERT INTO stats_project_developers (month,day,group_id,developers) SELECT $1::int AS month,$2::int AS day,group_id,count(*) AS count FROM user_group GROUP BY month,day,group_id',
+ array ("$year$month",
+ $day));
$err .= db_error();
db_commit();
diff --git a/gforge/cronjobs/stats_projects.inc b/gforge/cronjobs/stats_projects.inc
index ff85407f56..cdf12a9707 100755
--- a/gforge/cronjobs/stats_projects.inc
+++ b/gforge/cronjobs/stats_projects.inc
@@ -26,8 +26,6 @@
//
function project_stats_day($year,$month,$day) {
- global $sys_database_type;
-
db_begin();
$day_begin=mktime(0,0,0,$month,$day,$year);
@@ -39,241 +37,7 @@ function project_stats_day($year,$month,$day) {
array ("$year$month",
$day));
- if ($sys_database_type == "mysql") {
- db_query_mysql ("INSERT INTO stats_project
-SELECT
-'$year$month' AS month,
-'$day' AS day,
-mess.* FROM (
-SELECT
- groups.group_id,
- r.count AS release_count,
- fmcount.count AS msg_posted,
- fucount.count AS msg_uniq_auth,
- obug.count AS bugs_opened,
- cbug.count AS bugs_closed,
- osupport.count AS support_opened,
- csupport.count AS support_closed,
- opatches.count AS patches_opened,
- cpatches.count AS patches_closed,
- oartifact.count AS artifacts_opened,
- cartifact.count AS artifacts_closed,
- otask.count AS tasks_opened,
- ctask.count AS tasks_closed,
- helpr.count AS help_requests
-
-FROM groups
-
---
--- Create tmp table of groups that made any releases
---
-LEFT JOIN (
- SELECT group_id,COUNT(release_id) AS count
- FROM frs_release,frs_package
- WHERE
- frs_release.release_date > '$day_begin'
- AND frs_release.release_date < '$day_end'
- AND frs_release.package_id = frs_package.package_id
- GROUP BY group_id
- ) r USING (group_id)
-
---
--- Create tmp table of groups that had any forum posts
---
-LEFT JOIN (
- SELECT forum_group_list.group_id,COUNT(forum.msg_id) AS count
- FROM forum_group_list, forum
- WHERE
- forum_group_list.group_forum_id = forum.group_forum_id
- AND forum.post_date > '$day_begin'
- AND forum.post_date < '$day_end'
- GROUP BY forum_group_list.group_id
- ) fmcount USING (group_id)
-
---
--- Create tmp table of groups and unique posters to forums
---
-LEFT JOIN (
- SELECT forum_group_list.group_id,COUNT( DISTINCT(forum.posted_by) ) AS count
- FROM forum_group_list, forum
- WHERE
- forum_group_list.group_forum_id = forum.group_forum_id
- AND forum.post_date > '$day_begin'
- AND forum.post_date < '$day_end'
- GROUP BY group_id
- ) fucount USING (group_id)
-
---
--- Create tmp table of groups and opened bugs
---
-LEFT JOIN (
- SELECT agl.group_id,count(*) AS count
- FROM artifact_group_list agl,artifact a
- WHERE
- a.open_date > '$day_begin'
- AND a.open_date < '$day_end'
- AND a.group_artifact_id=agl.group_artifact_id
- AND agl.datatype='1'
- GROUP BY agl.group_id
- ) obug USING (group_id)
-
---
--- Create tmp table of groups and closed bugs
---
-LEFT JOIN (
- SELECT agl.group_id,count(*) AS count
- FROM artifact_group_list agl,artifact a
- WHERE
- a.close_date > '$day_begin'
- AND a.close_date < '$day_end'
- AND a.group_artifact_id=agl.group_artifact_id
- AND agl.datatype='1'
- GROUP BY agl.group_id
- ) cbug USING (group_id)
-
---
--- Create tmp table of groups and opened support
---
-LEFT JOIN (
- SELECT agl.group_id,count(*) AS count
- FROM artifact_group_list agl,artifact a
- WHERE
- a.open_date > '$day_begin'
- AND a.open_date < '$day_end'
- AND a.group_artifact_id=agl.group_artifact_id
- AND agl.datatype='2'
- GROUP BY agl.group_id
- ) osupport USING (group_id)
-
---
--- Create tmp table of groups and closed support
---
-LEFT JOIN (
- SELECT agl.group_id,count(*) AS count
- FROM artifact_group_list agl,artifact a
- WHERE
- a.close_date > '$day_begin'
- AND a.close_date < '$day_end'
- AND a.group_artifact_id=agl.group_artifact_id
- AND agl.datatype='2'
- GROUP BY agl.group_id
- ) csupport USING (group_id)
-
---
--- Create tmp table of groups and opened patches
---
-LEFT JOIN (
- SELECT agl.group_id,count(*) AS count
- FROM artifact_group_list agl,artifact a
- WHERE
- a.open_date > '$day_begin'
- AND a.open_date < '$day_end'
- AND a.group_artifact_id=agl.group_artifact_id
- AND agl.datatype='3'
- GROUP BY agl.group_id
- ) opatches USING (group_id)
-
---
--- Create tmp table of groups and closed patches
---
-LEFT JOIN (
- SELECT agl.group_id,count(*) AS count
- FROM artifact_group_list agl,artifact a
- WHERE
- a.close_date > '$day_begin'
- AND a.close_date < '$day_end'
- AND a.group_artifact_id=agl.group_artifact_id
- AND agl.datatype='3'
- GROUP BY agl.group_id
- ) cpatches USING (group_id)
-
---
--- Create tmp table of groups and opened total artifacts
---
-LEFT JOIN (
- SELECT agl.group_id,count(*) AS count
- FROM artifact_group_list agl,artifact a
- WHERE
- a.open_date > '$day_begin'
- AND a.open_date < '$day_end'
- AND a.group_artifact_id=agl.group_artifact_id
- GROUP BY agl.group_id
- ) oartifact USING (group_id)
-
---
--- Create tmp table of groups and closed total artifacts
---
-LEFT JOIN (
- SELECT agl.group_id,count(*) AS count
- FROM artifact_group_list agl,artifact a
- WHERE
- a.close_date > '$day_begin'
- AND a.close_date < '$day_end'
- AND a.group_artifact_id=agl.group_artifact_id
- GROUP BY agl.group_id
- ) cartifact USING (group_id)
-
---
--- Create tmp table of groups that opened tasks
---
-LEFT JOIN (
- SELECT pgl.group_id,count(pt.project_task_id) AS count
- FROM project_group_list pgl, project_task pt
- WHERE
- pgl.group_project_id=pt.group_project_id
- AND pt.start_date > '$day_begin'
- AND pt.start_date < '$day_end'
- GROUP BY pgl.group_id
- ) otask USING (group_id)
-
---
--- Create tmp table of groups that closed tasks
---
-LEFT JOIN (
- SELECT pgl.group_id,count(pt.project_task_id) AS count
- FROM project_group_list pgl, project_task pt
- WHERE
- pgl.group_project_id=pt.group_project_id
- AND pt.end_date > '$day_begin'
- AND pt.end_date < '$day_end'
- GROUP BY pgl.group_id
- ) ctask USING (group_id)
-
---
--- Create tmp table of groups that closed tasks
---
-LEFT JOIN (
- SELECT group_id,COUNT(job_id) AS count
- FROM people_job
- WHERE
- post_date > '$day_begin'
- AND post_date < '$day_end'
- GROUP BY group_id
- ) helpr USING (group_id)
-
-) mess
-
---
--- We really only want the rows that have any content
---
-WHERE
-release_count > 0
-OR msg_posted > 0
-OR msg_uniq_auth > 0
-OR bugs_opened > 0
-OR bugs_closed > 0
-OR support_opened > 0
-OR support_closed > 0
-OR patches_opened > 0
-OR patches_closed > 0
-OR artifacts_opened > 0
-OR artifacts_closed > 0
-OR tasks_opened > 0
-OR tasks_closed > 0
-OR help_requests > 0;");
- } else {
-
- db_query_params ('INSERT INTO stats_project
+ db_query_params ('INSERT INTO stats_project
SELECT
$1::int AS month,
$2::int AS day,
@@ -504,22 +268,21 @@ OR artifacts_closed > 0
OR tasks_opened > 0
OR tasks_closed > 0
OR help_requests > 0;',
- array($year.$month,
- $day,
- $day_begin,
- $day_end,
- '1',
- '1',
- '2',
- '2',
- '3',
- '3'));
-
+ array($year.$month,
+ $day,
+ $day_begin,
+ $day_end,
+ '1',
+ '1',
+ '2',
+ '2',
+ '3',
+ '3'));
+
echo db_error();
-
+
db_commit();
- }
-}
+ }
// Local Variables:
// mode: php
diff --git a/gforge/cronjobs/tracker_gateway.php b/gforge/cronjobs/tracker_gateway.php
index b5d178ee42..bbdc383a2c 100755
--- a/gforge/cronjobs/tracker_gateway.php
+++ b/gforge/cronjobs/tracker_gateway.php
@@ -7,7 +7,7 @@
* Copyright 2009, Roland Mas
*
* @author Tim Perdue tim@gforge.org
- * @author Sung Kim
+ * @author Sung Kim
* @author Francisco Gimeno
*
* This file is part of GForge.
@@ -78,8 +78,7 @@ class TrackerGateway extends Error {
return true;
}
-
-
+
/**
* function - Copy mail(from stdin to tmp and return the tmp file
*
@@ -95,10 +94,10 @@ class TrackerGateway extends Error {
while($buffer = fgets($in, 4096)) {
fputs($out, $buffer);
}
-
+
fclose($in);
fclose($out);
-
+
return $tmpfile;
}
@@ -111,7 +110,7 @@ class TrackerGateway extends Error {
*/
function parseMail($input_file) {
global $argv;
-
+
if (!$mp = new MailParser($input_file)) {
$this->setError('Error In MailParser');
return false;
@@ -142,14 +141,14 @@ class TrackerGateway extends Error {
return false;
}
- $body = addslashes($mp->getBody());
+ $body = $mp->getBody();
// find first occurrence of the marker in the message
$begin = strpos($body, ARTIFACT_MAIL_MARKER);
if ($begin === false) {
$this->setError("Response message wasn't found in your mail. Please verify that ".
- "you entered your message between the correct text markers.".
- "\nYour message was:".
- "\n".$mp->getBody());
+ "you entered your message between the correct text markers.".
+ "\nYour message was:".
+ "\n".$mp->getBody());
return false;
}
// get the part of the message located after the marker
@@ -158,21 +157,21 @@ class TrackerGateway extends Error {
$end = strpos($body, ARTIFACT_MAIL_MARKER);
if ($end === false) {
$this->setError("Response message wasn't found in your mail. Please verify that ".
- "you entered your message between the correct text markers.".
- "\nYour message was:".
- "\n".$mp->getBody());
+ "you entered your message between the correct text markers.".
+ "\nYour message was:".
+ "\n".$mp->getBody());
return false;
}
$message = substr($body, 0, $end);
$message = trim($message);
-
+
// maybe the last line was "> (ARTIFACT_MAIL_MARKER)". In that case, delete the last ">"
$message = preg_replace('/>$/', '', $message);
$this->Message = $message;
-
+
return true;
}
-
+
/**
* Insert data into the tracker db
*
@@ -194,7 +193,7 @@ class TrackerGateway extends Error {
if (!$Artifact || !is_object($Artifact)) {
$this->setError("Could Not Get Artifact");
return false;
- }
+ }
if (!$user_id && !$Artifact->ArtifactType->allowsAnon()) {
$this->setError("Could Not Match Sender Email Address to User and Tracker Does Not Allow Anonymous Posts");
return false;
@@ -213,7 +212,7 @@ class TrackerGateway extends Error {
/*------------------------------------------------------------------------
- * Utility functions
+ * Utility functions
*-----------------------------------------------------------------------*/
/* Find user_id from email */
@@ -229,29 +228,29 @@ class TrackerGateway extends Error {
$user_id = db_result($res,0,'user_id');
}
db_free_result($res);
-
+
return $user_id;
}
function &getArtifact() {
global $argv;
- // $Group not needed, but let the code here to support
- // tracker additions in the Future
- $Group =& group_get_object_by_name($argv[1]);
- if (!$Group || !is_object($Group)) {
- $this->setError('Could Not Get Group Object');
- return false;
- } elseif ($Group->isError()) {
- $this->setError('Getting Group Object: '.$Group->getErrorMessage());
- return false;
- }
- // DBG("Artifact_get_object(".$this->ArtifactId.");");
- $this->Artifact =& artifact_get_object($this->ArtifactId);
-
+ // $Group not needed, but let the code here to support
+ // tracker additions in the Future
+ $Group =& group_get_object_by_name($argv[1]);
+ if (!$Group || !is_object($Group)) {
+ $this->setError('Could Not Get Group Object');
+ return false;
+ } elseif ($Group->isError()) {
+ $this->setError('Getting Group Object: '.$Group->getErrorMessage());
+ return false;
+ }
+ // DBG("Artifact_get_object(".$this->ArtifactId.");");
+ $this->Artifact =& artifact_get_object($this->ArtifactId);
+
return $this->Artifact;
}
-
+
}
@@ -261,19 +260,18 @@ class TrackerGateway extends Error {
* Add this in /etc/syslog.conf and see /var/log/debug file:
* # Debug
* *.=debug /var/log/debug
- *
+ *
*/
function DBG($str) {
global $debug;
if ($debug==1) {
- system("echo \"artifact: ".$str."\n\" >> /tmp/tracker.log");
+ system("echo \"artifact: ".$str."\n\" >> /tmp/tracker-gateway.log");
syslog(LOG_DEBUG, "artifact_gateway: ". $str);
} else if ($debug==2) {
echo $str."\n";
}
}
-
/* Main routine */
$debug = 0;
diff --git a/gforge/cronjobs/update_filesize.php b/gforge/cronjobs/update_filesize.php
index 2132bd911b..36fe6d0dbd 100755
--- a/gforge/cronjobs/update_filesize.php
+++ b/gforge/cronjobs/update_filesize.php
@@ -46,7 +46,7 @@ echo db_error();
while ( $fms_filesize_row = db_fetch_array( $fms_filesize_res ) ) {
- $fms_file_path = $sys_upload_dir . '/' .
+ $fms_file_path = forge_get_config('upload_dir') . '/' .
$fms_filesize_row['unix_group_name'] . '/' .
$fms_filesize_row['filename'];
diff --git a/gforge/cronjobs/vacuum.php b/gforge/cronjobs/vacuum.php
index bd9591718e..9b5101ef1c 100755
--- a/gforge/cronjobs/vacuum.php
+++ b/gforge/cronjobs/vacuum.php
@@ -36,14 +36,12 @@ $err='';
//
// PG 7.2 and 7.3
//
-if ($sys_database_type != 'mysql') {
- $res = db_query_params ('VACUUM FULL ANALYZE;',
+$res = db_query_params ('VACUUM FULL ANALYZE;',
array()) ;
+
-
- if (!$res) {
- $err .= "Error on DB1: " . db_error();
- }
+if (!$res) {
+ $err .= "Error on DB1: " . db_error();
}
cron_entry(12,$err);
diff --git a/gforge/db/20050127-frs-reorg.php b/gforge/db/20050127-frs-reorg.php
index 43b75b046e..1031d07885 100755
--- a/gforge/db/20050127-frs-reorg.php
+++ b/gforge/db/20050127-frs-reorg.php
@@ -58,7 +58,7 @@ $groups =& group_get_objects(util_result_column_to_array($res));
for ($g=0; $ggetUnixName();
+ $newdirlocation = forge_get_config('upload_dir').'/'.$groups[$g]->getUnixName();
$cmd="/bin/mkdir $newdirlocation";
//echo "\n$cmd";
if (!is_dir($newdirlocation)){
@@ -72,7 +72,7 @@ for ($g=0; $gGroup->getUnixName().'/'.$frsps[$p]->getFileName();
+ $newdirlocation = forge_get_config('upload_dir').'/'.$frsps[$p]->Group->getUnixName().'/'.$frsps[$p]->getFileName();
$cmd="/bin/mkdir $newdirlocation";
//echo "\n$cmd";
if (!is_dir($newdirlocation)){
@@ -86,7 +86,7 @@ for ($g=0; $gFRSPackage->Group->getUnixName().'/'.$frsrs[$r]->FRSPackage->getFileName().'/'.$frsrs[$r]->getFileName();
+ $newdirlocation = forge_get_config('upload_dir').'/'.$frsrs[$r]->FRSPackage->Group->getUnixName().'/'.$frsrs[$r]->FRSPackage->getFileName().'/'.$frsrs[$r]->getFileName();
$cmd="/bin/mkdir $newdirlocation";
//echo "\n$cmd";
if (!is_dir($newdirlocation)){
@@ -98,8 +98,8 @@ for ($g=0; $gFRSRelease->FRSPackage->Group->getUnixName().'/'.$frsfs[$f]->getName();
- $newdirlocation = $GLOBALS['sys_upload_dir'].'/'.$frsfs[$f]->FRSRelease->FRSPackage->Group->getUnixName().'/'.$frsfs[$f]->FRSRelease->FRSPackage->getFileName().'/'.$frsfs[$f]->FRSRelease->getFileName().'/';
+ $olddirlocation = forge_get_config('upload_dir').'/'.$frsfs[$f]->FRSRelease->FRSPackage->Group->getUnixName().'/'.$frsfs[$f]->getName();
+ $newdirlocation = forge_get_config('upload_dir').'/'.$frsfs[$f]->FRSRelease->FRSPackage->Group->getUnixName().'/'.$frsfs[$f]->FRSRelease->FRSPackage->getFileName().'/'.$frsfs[$f]->FRSRelease->getFileName().'/';
if (!is_file($newdirlocation.'/'.$frsfs[$f]->getName())) {
$cmd="/bin/mv $olddirlocation $newdirlocation";
//echo "\n$cmd";
@@ -112,7 +112,7 @@ for ($g=0; $gcommit () ;
}
- &update_with_sql("20100308-forum-attachment-types","4.8.99-6");
+ &update_with_sql("20100308-forum-attachment-types","4.8.99-6");
+
+ &update_with_sql("20100330-add-system-event","5.0.0-1");
+ &update_with_sql("20100331-alter-system-event","5.0.0-2");
########################### INSERT HERE #################################
diff --git a/gforge/deb-specific/gforge-config b/gforge/deb-specific/gforge-config
index 88f365a74c..ecd3bf71e7 100644
--- a/gforge/deb-specific/gforge-config
+++ b/gforge/deb-specific/gforge-config
@@ -21,6 +21,12 @@ fi
[ -f /etc/gforge/database.inc ] && chown gforge:gforge /etc/gforge/database.inc
[ -f /etc/gforge/database.inc ] && chmod 640 /etc/gforge/database.inc
+if getent group list
+then
+ [ -f /etc/gforge/database.py ] && chgrp list /etc/gforge/database.py
+fi
+[ -f /etc/gforge/database.py ] && chmod 640 /etc/gforge/database.py
+
[ -f /etc/gforge/local.pl ] && chmod go+rx /etc/gforge
[ -f /etc/gforge/local.pl ] && chown gforge:gforge /etc/gforge/local.pl
[ -f /etc/gforge/local.pl ] && chmod 640 /etc/gforge/local.pl
diff --git a/gforge/debian/README.source b/gforge/debian/README.source
index b27c60be82..97faa88bc3 100644
--- a/gforge/debian/README.source
+++ b/gforge/debian/README.source
@@ -3,5 +3,7 @@ consult /usr/share/doc/dpatch/README.source.gz.
The Debian-specific package sources are managed in upstream's repository.
+Orig tarball is constructed from upstream's sources top-level dir
+using 'make orig'.
- -- Olivier Berger , Tue, 30 Mar 2010 19:02:30 +0200
+ -- Olivier Berger , Sat, 3 Apr 2010 19:38:08 +0200
diff --git a/gforge/debian/changelog b/gforge/debian/changelog
index d7761fc865..74c49f132b 100644
--- a/gforge/debian/changelog
+++ b/gforge/debian/changelog
@@ -1,3 +1,9 @@
+fusionforge (5.0.50-1) unstable; urgency=low
+
+ * Snapshot from upstream SVN.
+
+ -- Roland Mas Tue, 06 Apr 2010 18:30:28 +0200
+
fusionforge (5.0-1) unstable; urgency=low
* New upstream release, woo-hoo!
diff --git a/gforge/debian/control b/gforge/debian/control
index f1839bdbae..f5042e042c 100644
--- a/gforge/debian/control
+++ b/gforge/debian/control
@@ -14,7 +14,7 @@ Architecture: all
Conflicts: sourceforge, gforge-cvs, gforge-common (<< ${source:Version})
Replaces: gforge
Provides: gforge
-Depends: debconf (>= 1.0.32) | debconf-2.0, ucf, gforge-common (=${source:Version}), gforge-web-apache2 | gforge-web, gforge-db-postgresql | gforge-db, gforge-mta-exim4 | gforge-mta, gforge-shell-postgresql | gforge-shell, gforge-lists-mailman | gforge-lists, ${misc:Depends}
+Depends: debconf (>= 1.0.32) | debconf-2.0, ucf, gforge-common (=${source:Version}), gforge-web-apache2 | gforge-web, gforge-db-postgresql | gforge-db, gforge-mta-exim4 | gforge-mta, gforge-shell-postgresql | gforge-shell, fusionforge-plugin-mailman | gforge-lists-mailman | gforge-lists, ${misc:Depends}
Recommends: gforge-plugin-scmsvn | gforge-plugin-scm
Description: FusionForge collaborative development tool - standard metapackage
FusionForge provides many tools to aid collaboration in a
@@ -45,7 +45,7 @@ Architecture: all
Conflicts: sourceforge, gforge-cvs, gforge-common (<< ${source:Version}), gforge
Replaces: gforge
Provides: gforge
-Depends: debconf (>= 1.0.32) | debconf-2.0, ucf, gforge-common (=${source:Version}), gforge-web-apache2 | gforge-web, gforge-db-postgresql | gforge-db, gforge-mta-exim4 | gforge-mta, gforge-shell-postgresql | gforge-shell, gforge-lists-mailman | gforge-lists, gforge-plugin-contribtracker, gforge-plugin-extratabs, gforge-plugin-globalsearch, gforge-plugin-mediawiki, gforge-plugin-projectlabels, gforge-plugin-scmarch, gforge-plugin-scmbzr, gforge-plugin-scmcvs, gforge-plugin-scmdarcs, gforge-plugin-scmgit, gforge-plugin-scmhg, gforge-plugin-scmsvn, ${misc:Depends}
+Depends: debconf (>= 1.0.32) | debconf-2.0, ucf, gforge-common (=${source:Version}), gforge-web-apache2 | gforge-web, gforge-web-apache2-vhosts, gforge-db-postgresql | gforge-db, gforge-mta-exim4 | gforge-mta, gforge-shell-postgresql | gforge-shell, fusionforge-plugin-mailman | gforge-lists-mailman | gforge-lists, gforge-plugin-contribtracker, gforge-plugin-extratabs, gforge-plugin-globalsearch, gforge-plugin-mediawiki, gforge-plugin-projectlabels, gforge-plugin-scmarch, gforge-plugin-scmbzr, gforge-plugin-scmcvs, gforge-plugin-scmdarcs, gforge-plugin-scmgit, gforge-plugin-scmhg, gforge-plugin-scmsvn, ${misc:Depends}
Description: FusionForge collaborative development tool - full metapackage
FusionForge provides many tools to aid collaboration in a
development project, such as bug-tracking, task management,
@@ -289,7 +289,7 @@ Description: collaborative development tool - Bazaar plugin
Package: gforge-plugin-scmgit
Architecture: all
-Depends: gforge-common, gforge-db-postgresql | gforge-db, gforge-web-apache2 | gforge-web, gforge-shell-postgresql | gforge-shell, git-core, gitweb, php5-cli, ${misc:Depends}
+Depends: gforge-common, gforge-db-postgresql | gforge-db, gforge-web-apache2 | gforge-web, gforge-shell-postgresql | gforge-shell, git (>= 1:1.7) | git-core, gitweb, php5-cli, ${misc:Depends}
Provides: gforge-plugin-scm
Description: collaborative development tool - Git plugin
FusionForge provides many tools to aid collaboration in a
@@ -349,7 +349,7 @@ Description: collaborative development tool - GNU Arch plugin
Package: gforge-plugin-mediawiki
Architecture: all
-Depends: gforge-common (>= 4.8), gforge-db-postgresql (>= 4.8) | gforge-db, gforge-web-apache2 (>= 4.8) | gforge-web, mediawiki (>= 1:1.15~), ${misc:Depends}
+Depends: gforge-common (>= 4.8), gforge-db-postgresql (>= 4.8) | gforge-db, gforge-web-apache2 (>= 4.8) | gforge-web, mediawiki (>= 1:1.15~), php5-cli, ${misc:Depends}
Description: Mediawiki plugin for FusionForge
FusionForge provides many tools to aid collaboration in a
development project, such as bug-tracking, task management,
diff --git a/gforge/debian/copyright b/gforge/debian/copyright
index 318003789d..a4481bb0f9 100644
--- a/gforge/debian/copyright
+++ b/gforge/debian/copyright
@@ -243,5 +243,13 @@ are under a BSD-like license:
| OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
`----
+PHPWIKI ??
+
+VIEWVC ??
+
On Debian systems, the complete text of the GNU General Public License
can be found in the /usr/share/common-licenses directory.
+
+# Local Variables:
+# coding: utf-8
+# End:
diff --git a/gforge/debian/dsf-in/plugin-contribtracker.postinst b/gforge/debian/dsf-in/plugin-contribtracker.postinst
new file mode 100644
index 0000000000..08600a8dc7
--- /dev/null
+++ b/gforge/debian/dsf-in/plugin-contribtracker.postinst
@@ -0,0 +1,47 @@
+#! /bin/sh
+# postinst script for gforge-plugin-contribtracker
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * `configure'
+# * `abort-upgrade'
+# * `abort-remove' `in-favour'
+#
+# * `abort-deconfigure' `in-favour'
+# `removing'
+#
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+#
+# quoting from the policy:
+# Any necessary prompting should almost always be confined to the
+# post-installation script, and should be protected with a conditional
+# so that unnecessary prompting doesn't happen if a package's
+# installation fails and the `postinst' is called with `abort-upgrade',
+# `abort-remove' or `abort-deconfigure'.
+
+case "$1" in
+ configure)
+ su -s /bin/sh @OLDPACKAGE@ -c '/usr/share/gforge/plugins/contribtracker/bin/db-upgrade.pl'
+ su -s /bin/sh @OLDPACKAGE@ -c '/usr/share/gforge/bin/register-plugin contribtracker "Contribution Tracker"'
+ ;;
+
+ abort-upgrade|abort-remove|abort-deconfigure)
+
+ ;;
+
+ *)
+ echo "postinst called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/gforge/debian/gforge-plugin-contribtracker.prerm b/gforge/debian/dsf-in/plugin-contribtracker.prerm
similarity index 100%
rename from gforge/debian/gforge-plugin-contribtracker.prerm
rename to gforge/debian/dsf-in/plugin-contribtracker.prerm
diff --git a/gforge/debian/dsf-in/plugin-extratabs.postinst b/gforge/debian/dsf-in/plugin-extratabs.postinst
index 38cafa4a1e..167cdd2aae 100644
--- a/gforge/debian/dsf-in/plugin-extratabs.postinst
+++ b/gforge/debian/dsf-in/plugin-extratabs.postinst
@@ -25,8 +25,8 @@ set -e
case "$1" in
configure)
- /usr/share/@OLDPACKAGE@/plugins/extratabs/bin/db-upgrade.pl
- /usr/share/@OLDPACKAGE@/bin/register-plugin extratabs "Extra Tabs"
+ su -s /bin/sh @OLDPACKAGE@ -c '/usr/share/@OLDPACKAGE@/plugins/extratabs/bin/db-upgrade.pl'
+ su -s /bin/sh @OLDPACKAGE@ -c '/usr/share/@OLDPACKAGE@/bin/register-plugin extratabs "Extra Tabs"'
;;
abort-upgrade|abort-remove|abort-deconfigure)
diff --git a/gforge/debian/dsf-in/plugin-globalsearch.postinst b/gforge/debian/dsf-in/plugin-globalsearch.postinst
index 0257fcd329..f04076ce02 100644
--- a/gforge/debian/dsf-in/plugin-globalsearch.postinst
+++ b/gforge/debian/dsf-in/plugin-globalsearch.postinst
@@ -25,8 +25,8 @@ set -e
case "$1" in
configure)
- /usr/share/@OLDPACKAGE@/plugins/globalsearch/bin/db-upgrade.pl
- /usr/share/@OLDPACKAGE@/bin/register-plugin globalsearch "Global Search"
+ su -s /bin/sh @OLDPACKAGE@ -c '/usr/share/@OLDPACKAGE@/plugins/globalsearch/bin/db-upgrade.pl'
+ su -s /bin/sh @OLDPACKAGE@ -c '/usr/share/@OLDPACKAGE@/bin/register-plugin globalsearch "Global Search"'
;;
abort-upgrade|abort-remove|abort-deconfigure)
diff --git a/gforge/debian/dsf-in/plugin-mediawiki.links b/gforge/debian/dsf-in/plugin-mediawiki.links
deleted file mode 100644
index d75c758833..0000000000
--- a/gforge/debian/dsf-in/plugin-mediawiki.links
+++ /dev/null
@@ -1,45 +0,0 @@
-/usr/share/mediawiki/skins/@PACKAGE@/loader.php /etc/mediawiki-extensions/extensions-available/GforgeAuth.php
-
-/usr/share/mediawiki/StartProfiler.php /usr/share/gforge/www/plugins/mediawiki/StartProfiler.php
-/usr/share/mediawiki/api.php /usr/share/gforge/www/plugins/mediawiki/api.php
-/usr/share/mediawiki/extensions /usr/share/gforge/www/plugins/mediawiki/extensions
-/usr/share/mediawiki/img_auth.php /usr/share/gforge/www/plugins/mediawiki/img_auth.php
-/usr/share/mediawiki/includes /usr/share/gforge/www/plugins/mediawiki/includes
-/usr/share/mediawiki/index.php /usr/share/gforge/www/plugins/mediawiki/index.php
-/usr/share/mediawiki/languages /usr/share/gforge/www/plugins/mediawiki/languages
-/usr/share/mediawiki/maintenance /usr/share/gforge/www/plugins/mediawiki/maintenance
-/usr/share/mediawiki/opensearch_desc.php /usr/share/gforge/www/plugins/mediawiki/opensearch_desc.php
-/usr/share/mediawiki/profileinfo.php /usr/share/gforge/www/plugins/mediawiki/profileinfo.php
-/usr/share/mediawiki/redirect.php /usr/share/gforge/www/plugins/mediawiki/redirect.php
-/usr/share/mediawiki/thumb.php /usr/share/gforge/www/plugins/mediawiki/thumb.php
-/usr/share/mediawiki/trackback.php /usr/share/gforge/www/plugins/mediawiki/trackback.php
-
-/usr/share/mediawiki/skins/monobook/FF2Fixes.css /usr/share/mediawiki/skins/fusionforge/FF2Fixes.css
-/usr/share/mediawiki/skins/monobook/IE50Fixes.css /usr/share/mediawiki/skins/fusionforge/IE50Fixes.css
-/usr/share/mediawiki/skins/monobook/IE55Fixes.css /usr/share/mediawiki/skins/fusionforge/IE55Fixes.css
-/usr/share/mediawiki/skins/monobook/IE60Fixes.css /usr/share/mediawiki/skins/fusionforge/IE60Fixes.css
-/usr/share/mediawiki/skins/monobook/IE70Fixes.css /usr/share/mediawiki/skins/fusionforge/IE70Fixes.css
-/usr/share/mediawiki/skins/monobook/IEMacFixes.css /usr/share/mediawiki/skins/fusionforge/IEMacFixes.css
-/usr/share/mediawiki/skins/monobook/KHTMLFixes.css /usr/share/mediawiki/skins/fusionforge/KHTMLFixes.css
-/usr/share/mediawiki/skins/monobook/Opera6Fixes.css /usr/share/mediawiki/skins/fusionforge/Opera6Fixes.css
-/usr/share/mediawiki/skins/monobook/Opera7Fixes.css /usr/share/mediawiki/skins/fusionforge/Opera7Fixes.css
-/usr/share/mediawiki/skins/monobook/Opera9Fixes.css /usr/share/mediawiki/skins/fusionforge/Opera9Fixes.css
-/usr/share/mediawiki/skins/monobook/audio.png /usr/share/mediawiki/skins/fusionforge/audio.png
-/usr/share/mediawiki/skins/monobook/bullet.gif /usr/share/mediawiki/skins/fusionforge/bullet.gif
-/usr/share/mediawiki/skins/monobook/discussionitem_icon.gif /usr/share/mediawiki/skins/fusionforge/discussionitem_icon.gif
-/usr/share/mediawiki/skins/monobook/document.png /usr/share/mediawiki/skins/fusionforge/document.png
-/usr/share/mediawiki/skins/monobook/external-rtl.png /usr/share/mediawiki/skins/fusionforge/external-rtl.png
-/usr/share/mediawiki/skins/monobook/external.png /usr/share/mediawiki/skins/fusionforge/external.png
-/usr/share/mediawiki/skins/monobook/file_icon.gif /usr/share/mediawiki/skins/fusionforge/file_icon.gif
-/usr/share/mediawiki/skins/monobook/headbg.jpg /usr/share/mediawiki/skins/fusionforge/headbg.jpg
-/usr/share/mediawiki/skins/monobook/link_icon.gif /usr/share/mediawiki/skins/fusionforge/link_icon.gif
-/usr/share/mediawiki/skins/monobook/lock_icon.gif /usr/share/mediawiki/skins/fusionforge/lock_icon.gif
-/usr/share/mediawiki/skins/monobook/magnify-clip.png /usr/share/mediawiki/skins/fusionforge/magnify-clip.png
-/usr/share/mediawiki/skins/monobook/mail_icon.gif /usr/share/mediawiki/skins/fusionforge/mail_icon.gif
-/usr/share/mediawiki/skins/monobook/news_icon.png /usr/share/mediawiki/skins/fusionforge/news_icon.png
-/usr/share/mediawiki/skins/monobook/required.gif /usr/share/mediawiki/skins/fusionforge/required.gif
-/usr/share/mediawiki/skins/monobook/rtl.css /usr/share/mediawiki/skins/fusionforge/rtl.css
-/usr/share/mediawiki/skins/monobook/user.gif /usr/share/mediawiki/skins/fusionforge/user.gif
-/usr/share/mediawiki/skins/monobook/video.png /usr/share/mediawiki/skins/fusionforge/video.png
-/usr/share/mediawiki/skins/monobook/wiki-indexed.png /usr/share/mediawiki/skins/fusionforge/wiki-indexed.png
-/usr/share/mediawiki/skins/monobook/wiki.png /usr/share/mediawiki/skins/fusionforge/wiki.png
diff --git a/gforge/debian/dsf-in/plugin-mediawiki.postinst b/gforge/debian/dsf-in/plugin-mediawiki.postinst
index c646aded39..d5f060aaef 100644
--- a/gforge/debian/dsf-in/plugin-mediawiki.postinst
+++ b/gforge/debian/dsf-in/plugin-mediawiki.postinst
@@ -25,7 +25,7 @@ set -e
case "$1" in
configure)
- /usr/share/@OLDPACKAGE@/bin/register-plugin mediawiki "Mediawiki"
+ su -s /bin/sh @OLDPACKAGE@ -c '/usr/share/@OLDPACKAGE@/bin/register-plugin mediawiki "Mediawiki"'
@OLDPACKAGE@-config
for flavour in apache apache-perl apache-ssl apache2 ; do
if [ -x /usr/sbin/$flavour ]; then
diff --git a/gforge/debian/dsf-in/plugin-projectlabels.postinst b/gforge/debian/dsf-in/plugin-projectlabels.postinst
index d2c1d6428e..b0137e21dc 100644
--- a/gforge/debian/dsf-in/plugin-projectlabels.postinst
+++ b/gforge/debian/dsf-in/plugin-projectlabels.postinst
@@ -25,8 +25,8 @@ set -e
case "$1" in
configure)
- /usr/share/@OLDPACKAGE@/plugins/projectlabels/bin/db-upgrade.pl
- /usr/share/@OLDPACKAGE@/bin/register-plugin projectlabels "Project Labels"
+ su -s /bin/sh @OLDPACKAGE@ -c '/usr/share/@OLDPACKAGE@/plugins/projectlabels/bin/db-upgrade.pl'
+ su -s /bin/sh @OLDPACKAGE@ -c '/usr/share/@OLDPACKAGE@/bin/register-plugin projectlabels "Project Labels"'
;;
abort-upgrade|abort-remove|abort-deconfigure)
diff --git a/gforge/debian/dsf-in/plugin-scmgit.postinst b/gforge/debian/dsf-in/plugin-scmgit.postinst
index d356d3698b..8e68daea7c 100644
--- a/gforge/debian/dsf-in/plugin-scmgit.postinst
+++ b/gforge/debian/dsf-in/plugin-scmgit.postinst
@@ -29,6 +29,7 @@ case "$1" in
# Prepare database
su -s /bin/sh @OLDPACKAGE@ -c '/usr/share/gforge/bin/register-plugin scmgit "Git"'
+ su -s /bin/sh @OLDPACKAGE@ -c '/usr/share/gforge/plugins/scmgit/bin/db-upgrade.pl'
;;
abort-upgrade|abort-remove|abort-deconfigure)
diff --git a/gforge/debian/dsf-in/plugin-scmgit.prerm b/gforge/debian/dsf-in/plugin-scmgit.prerm
index d8151e85bb..80a7759fcd 100644
--- a/gforge/debian/dsf-in/plugin-scmgit.prerm
+++ b/gforge/debian/dsf-in/plugin-scmgit.prerm
@@ -23,6 +23,7 @@ case "$1" in
if [ -f /var/run/postgresql/.s.PGSQL.5432 ]
then
/usr/share/@OLDPACKAGE@/bin/unregister-plugin scmgit
+ su -s /bin/sh @OLDPACKAGE@ -c '/usr/share/gforge/plugins/scmgit/bin/db-delete.pl'
else
echo "WARNING: database not available to unregister scmgit plugin"
fi
diff --git a/gforge/debian/patches/disable-dav.dpatch b/gforge/debian/patches/disable-dav.dpatch
index 78db719056..82f2c84933 100755
--- a/gforge/debian/patches/disable-dav.dpatch
+++ b/gforge/debian/patches/disable-dav.dpatch
@@ -5,17 +5,39 @@
## DP: Disable SVN-over-WebDAV
@DPATCH@
-diff -urNad gforge~/plugins/scmsvn/etc/plugins/scmsvn/config.php gforge/plugins/scmsvn/etc/plugins/scmsvn/config.php
---- gforge~/plugins/scmsvn/etc/plugins/scmsvn/config.php 2009-08-19 20:55:48.000000000 +0200
-+++ gforge/plugins/scmsvn/etc/plugins/scmsvn/config.php 2009-08-19 21:12:57.000000000 +0200
-@@ -7,8 +7,8 @@
- } else {
- $default_svn_server = 'scm';
- }
+diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' gforge~/plugins/scmsvn/etc/plugins/scmsvn/config.php gforge/plugins/scmsvn/etc/plugins/scmsvn/config.php
+--- gforge~/plugins/scmsvn/etc/plugins/scmsvn/config.php 2010-04-21 19:45:44.000000000 +0200
++++ gforge/plugins/scmsvn/etc/plugins/scmsvn/config.php 2010-04-21 20:44:14.000000000 +0200
+@@ -3,8 +3,8 @@
+ //$default_svn_server = forge_get_config('web_host') ;
+ //$default_svn_server = "svn." . forge_get_config('web_host') ;
+ $default_svn_server = forge_get_config('scm_host');
-$use_ssh = false;
-$use_dav = true;
+$use_ssh = true;
+$use_dav = false;
$use_ssl = true;
- // $svn_root = $GLOBALS['sys_chroot'].'/scmrepos/svn' ;
+ // $svn_root = forge_get_config('chroot').'/scmrepos/svn' ;
+diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' gforge~/plugins/scmsvn/etc/plugins/scmsvn/config.php.~1~ gforge/plugins/scmsvn/etc/plugins/scmsvn/config.php.~1~
+--- gforge~/plugins/scmsvn/etc/plugins/scmsvn/config.php.~1~ 1970-01-01 01:00:00.000000000 +0100
++++ gforge/plugins/scmsvn/etc/plugins/scmsvn/config.php.~1~ 2010-04-21 19:45:44.000000000 +0200
+@@ -0,0 +1,18 @@
++
diff --git a/gforge/debian/rules b/gforge/debian/rules
index ee969fbd6e..c7fb80438b 100755
--- a/gforge/debian/rules
+++ b/gforge/debian/rules
@@ -19,6 +19,7 @@ include /usr/share/dpatch/dpatch.make
CRONDFILES=$(patsubst packaging/cron.d/%,debian/$(OLDPACKAGE)-%.cron.d,$(wildcard packaging/cron.d/[a-z]*))
DIRSFILES=$(patsubst packaging/dirs/%,debian/$(OLDPACKAGE)-%.dirs,$(wildcard packaging/dirs/[a-z]*))
+LINKSFILES=$(patsubst packaging/links/%,debian/$(OLDPACKAGE)-%.links,$(wildcard packaging/links/[a-z]*))
INSTALLFILES=$(patsubst packaging/install/%,debian/$(OLDPACKAGE)-%.install,$(wildcard packaging/install/[a-z]*))
DOCSFILES=$(patsubst packaging/docs/oldpkgname%,debian/$(OLDPACKAGE)%.docs,$(wildcard packaging/docs/oldpkgname*)) $(patsubst packaging/docs/pkgname%,debian/$(PACKAGE)%.docs,$(wildcard packaging/docs/pkgname*))
POFILES=$(patsubst debian/dsf-po/%,debian/po/%,$(wildcard debian/dsf-po/*) debian/po/POTFILES.in)
@@ -27,7 +28,7 @@ remove-binary-files:
sh $(CURDIR)/deb-specific/manage-uufiles.sh clean
.PHONY: conffiles
-conffiles: $(CRONDFILES) $(DIRSFILES) $(INSTALLFILES) $(DOCSFILES) debian/control
+conffiles: $(CRONDFILES) $(DIRSFILES) $(LINKSFILES) $(INSTALLFILES) $(DOCSFILES) debian/control
debian/$(OLDPACKAGE)-%.cron.d:
(cat $(CURDIR)/packaging/cron.d/00phpcron ; sed -e 's/\$$FFUSER/$(OLDPACKAGE)/g' $(CURDIR)/packaging/cron.d/$*) > $@
@@ -35,6 +36,9 @@ debian/$(OLDPACKAGE)-%.cron.d:
debian/$(OLDPACKAGE)-%.dirs:
cp $(CURDIR)/packaging/dirs/$* $@
+debian/$(OLDPACKAGE)-%.links:
+ cp $(CURDIR)/packaging/links/$* $@
+
debian/$(OLDPACKAGE)-%.install:
cp $(CURDIR)/packaging/install/$* $@
@@ -80,6 +84,7 @@ clean: remove-binary-files unpatch
rm -f $(CURDIR)/debian/*.cron.d
rm -f $(CURDIR)/debian/*.dirs
+ rm -f $(CURDIR)/debian/*.links
rm -f $(CURDIR)/debian/*.install
rm -f $(CURDIR)/debian/*.docs
rm -f $(CURDIR)/debian/$(OLDPACKAGE)-config.sgml
diff --git a/gforge/docs/docbook/docbook/user_guide/introduction/introduction.xml b/gforge/docs/docbook/docbook/user_guide/introduction/introduction.xml
index d9ae253418..a4aaf59724 100644
--- a/gforge/docs/docbook/docbook/user_guide/introduction/introduction.xml
+++ b/gforge/docs/docbook/docbook/user_guide/introduction/introduction.xml
@@ -81,6 +81,18 @@
This section describes how to publish new releases of your project.
+
+
+ Blocks
+
+
+
+ This section describes how to use HTML
+ blocks to customize the appearance of
+ project pages.
+
+
+
diff --git a/gforge/docs/docbook/docbook/user_guide/project_functions/blocks.xml b/gforge/docs/docbook/docbook/user_guide/project_functions/blocks.xml
new file mode 100644
index 0000000000..abdfca7ff5
--- /dev/null
+++ b/gforge/docs/docbook/docbook/user_guide/project_functions/blocks.xml
@@ -0,0 +1,123 @@
+
+ Blocks
+
+
+ Introduction
+
+
+ The Blocks plugin allows the project manager to customize the appearance
+ of the project pages.
+
+
+ A block is a piece of HTML that will be displayed (if active) on a predefined location.
+ Predefined location includes: project description and a user blocks (right side)
+ at summary page, and headers on top of each tool (trackers, forums, etc.).
+
+
+ In case the HTML project description block is activated, it overwrites the short
+ project description provided in text mode (the short project description is still
+ used in the project tree).
+
+
+
+ It is not possible to create a new block.
+
+
+
+
+
+ Activating and modifying blocks
+
+
+ The project administrator logs in
+ and enters his project.
+ He clicks on the 'Admin '
+ link to enter the administration area.
+ He clicks on the 'Blocks admin '
+ link.
+ He can then edit a block to change its content and
+ also activate or deactivate a block.
+ Once submitted, the block is changed.
+
+
+ To edit the block, the HTML editor or a simple text area (showing the
+ HTML code) will be used, depending whether the HTML editor is activated or not.
+
+
+ You might include images in the block as well as text.
+
+
+ It is a good idea to first activate the blocks you want to include, and
+ have a look at the corresponding page before modifying them. This allows you
+ check their placement in the page.
+
+
+
+
+ Macros
+
+
+ When you activate a block, a predefined content is provided. The content will
+ use macros.
+
+
+ For example, you might have :
+
+
+ {boxHeader}Enter your text here{boxFooter}
+
+
+ We recommend that you use these macros. Use of the macros will guarantee a
+ consistent look and feel.
+
+
+
+ You can create boxes like the ones on the right site of summary page,
+ by inserting the following sentences in the content:
+
+
+
+ {boxTop Hello} :
+ will create the top part of the box using Hello
+ as title.
+
+ {boxMiddle Here} :
+ will create a middle part of a box using Here
+ as title (optional).
+
+ {boxBottom} :
+ will create the end part of a box.
+
+
+
+
+ {boxHeader} :
+ will create a header before a text.
+
+ {boxFooter} :
+ will create a footer after a text.
+
+
+
+
+ You can create as many boxes as you want, but a boxTop
+ has to be closed by a boxBottom
+ and a boxHeader has to be closed by
+ a boxFooter .
+
+
+
+ Examples
+
+ You can, for example, use the summary_right block to display your project logo.
+
+
+ You can use the summary_description block to provide a more complete description
+ of your project and also links to major project resources.
+
+
+ HTML blocks for tools can be used to explain purpose and usage of the different
+ tools (ex: trackers).
+
+
+
diff --git a/gforge/docs/fusionforge.doxygen b/gforge/docs/fusionforge.doxygen
new file mode 100644
index 0000000000..9677d0911c
--- /dev/null
+++ b/gforge/docs/fusionforge.doxygen
@@ -0,0 +1,1551 @@
+# Doxyfile 1.6.3
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME =
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY =
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak,
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it parses.
+# With this tag you can assign which parser to use for a given extension.
+# Doxygen has a built-in mapping, but you can override or extend it using this tag.
+# The format is ext=language, where ext is a file extension, and language is one of
+# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP,
+# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat
+# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran),
+# use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen to replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penality.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will rougly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
+# will list include files with double quotes in the documentation
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command , where is the value of
+# the FILE_VERSION_FILTER tag, and is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by
+# doxygen. The layout file controls the global structure of the generated output files
+# in an output format independent way. The create the layout file that represents
+# doxygen's defaults, run doxygen with the -l option. You can optionally specify a
+# file name after the option, if omitted DoxygenLayout.xml will be used as the name
+# of the layout file.
+
+LAYOUT_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE = ../apidocs/fusionforge/output.log
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = gforge/common
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS =
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command , where
+# is the value of the INPUT_FILTER tag, and is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.
+# Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = ../apidocs/fusionforge
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP = YES
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER
+# are set, an additional index file will be generated that can be used as input for
+# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated
+# HTML documentation.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add.
+# For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see
+# Qt Help Project / Custom Filters .
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's
+# filter section matches.
+# Qt Help Project / Filter Attributes .
+
+QHP_SECT_FILTER_ATTRS =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
+# will be generated, which together with the HTML files, form an Eclipse help
+# plugin. To install this plugin and make it available under the help contents
+# menu in Eclipse, the contents of the directory containing the HTML and XML
+# files needs to be copied into the plugins directory of eclipse. The name of
+# the directory within the plugins directory should be the same as
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before the help appears.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have
+# this name.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NONE
+
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
+# and Class Hierarchy pages using a tree view instead of an ordered list.
+
+USE_INLINE_TREES = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) there is already a search function so this one should
+# typically be disabled. For large projects the javascript based search engine
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE = NO
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be implemented using a PHP enabled web server instead of at the web client using Javascript. Doxygen will generate the search PHP script and index
+# file to put on the web server. The advantage of the server based approach is that it scales better to large projects and allows full text search. The disadvances is that it is more difficult to setup
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+# Note that when enabling USE_PDFLATEX this option is only used for
+# generating bitmaps for formulas in the HTML output, but not in the
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# By default doxygen will write a font called FreeSans.ttf to the output
+# directory and reference it in all dot files that doxygen generates. This
+# font does not include all possible unicode characters however, so when you need
+# these (or just want a differently looking font) you can specify the font name
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
+# which can be done by putting it in a standard location or by setting the
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
+# containing the font.
+
+DOT_FONTNAME = FreeSans
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the output directory to look for the
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a
+# different font using DOT_FONTNAME you can set the path where dot
+# can find it using this tag.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT = YES
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
diff --git a/gforge/docs/phpdoc/makedoc.sh b/gforge/docs/phpdoc/makedoc.sh
index 4f79f571c7..6784a66c87 100755
--- a/gforge/docs/phpdoc/makedoc.sh
+++ b/gforge/docs/phpdoc/makedoc.sh
@@ -26,14 +26,14 @@
# *
# * @var string TITLE
# */
-TITLE="GForge PHP Documentation"
+TITLE="FusionForge PHP Documentation"
#/**
# * name to use for the default package. If not specified, uses 'default'
# *
# * @var string PACKAGES
# */
-PACKAGES="GForge"
+PACKAGES="FusionForge"
#/**
# * name of a directory(s) to parse directory1,directory2
@@ -48,7 +48,7 @@ PATH_PROJECT=$PWD/../..
# *
# * @var string PATH_PHPDOC
# */
-PATH_PHPDOC=/tmp/phpdocumentor-1.3.0rc3/phpdoc
+PATH_PHPDOC=/tmp/PhpDocumentor-1.4.3/phpdoc
#/**
# * where documentation will be put
diff --git a/gforge/docs/phpdoc/manageclass.patch b/gforge/docs/phpdoc/manageclass.patch
deleted file mode 100644
index df514b8f72..0000000000
--- a/gforge/docs/phpdoc/manageclass.patch
+++ /dev/null
@@ -1,11 +0,0 @@
-diff -ruN /tmp/phpdocumentor-1.3.0rc3/phpDocumentor.ini /home/bayle/tmp/phpdocumentor-1.3.0rc3/phpDocumentor.ini
---- /tmp/phpdocumentor-1.3.0rc3/phpDocumentor.ini 2004-01-11 04:25:39.000000000 +0100
-+++ /home/bayle/tmp/phpdocumentor-1.3.0rc3/phpDocumentor.ini 2005-01-04 22:24:30.000000000 +0100
-@@ -26,6 +26,7 @@
- php5
- phtml
- inc
-+class
-
- ;; deprecated in 1.2
- ;; this list is informational only - the following tags will be parsed as
diff --git a/gforge/docs/phpdoc/phpDocumentor.ini.patch b/gforge/docs/phpdoc/phpDocumentor.ini.patch
new file mode 100644
index 0000000000..3bcedbb9de
--- /dev/null
+++ b/gforge/docs/phpdoc/phpDocumentor.ini.patch
@@ -0,0 +1,19 @@
+--- phpDocumentor.ini.orig 2010-02-25 11:48:58.918048044 +0100
++++ phpDocumentor.ini 2010-02-25 11:49:19.668076615 +0100
+@@ -22,7 +22,7 @@
+
+ ;; set max memory usage size to be very high, to avoid it crashing it the middle of its run
+ ;; due to using a boatload of memory
+-;;memory_limit = 512M
++memory_limit = 1536M
+
+ [_phpDocumentor_phpfile_exts]
+ php
+@@ -30,6 +30,7 @@
+ php4
+ phtml
+ inc
++class
+
+ ;; deprecated in 1.2
+ ;; this list is informational only - the following tags will be parsed as
diff --git a/gforge/etc/config.ini b/gforge/etc/config.ini
new file mode 100644
index 0000000000..74f80f35af
--- /dev/null
+++ b/gforge/etc/config.ini
@@ -0,0 +1,3 @@
+[core]
+forge_name = FusionForge
+user_registration_restricted = false
diff --git a/gforge/etc/database.py.example b/gforge/etc/database.py.example
new file mode 100644
index 0000000000..833a14f540
--- /dev/null
+++ b/gforge/etc/database.py.example
@@ -0,0 +1,6 @@
+# PLEASE DO NOT REMOVE THIS LINE
+sys_dbhost="";
+sys_dbname="alexandria";
+sys_dbuser="www";
+sys_dbpasswd="";
+sys_ldap_passwd="";
diff --git a/gforge/etc/gforge.conf.example b/gforge/etc/gforge.conf.example
index df8ceca78f..5f1d769d70 100644
--- a/gforge/etc/gforge.conf.example
+++ b/gforge/etc/gforge.conf.example
@@ -16,8 +16,8 @@ upload_host=upload.gforge.company.com
download_host=download.gforge.company.com
ftpuploadhost=upload.gforge.company.com
ftpuploaddir=/path/to/frs/upload
-statsadmin_groupid=2
-newsadmin_groupid=3
+newsadmin_groupid=2
+statsadmin_groupid=3
peerrating_groupid=4
template_project=5
admin_login=admin
@@ -34,7 +34,7 @@ sys_sendmail_path=/usr/sbin/sendmail
sys_path_to_jpgraph=/path/to/jpgraph
sys_path_to_scmweb=/usr/share/gforge/bin/
gforge_chroot=
-gforge_etc=/etc
+gforge_etc=/etc/gforge
sys_custom_path=/path/to/gforge/etc/custom
groupdir=/home/groups
homedir=/home
@@ -43,9 +43,9 @@ svndir=/svnroot
uploaddir=/path/to/uploads/
sys_urlroot=/path/to/gforge/www/
sys_jabber_pass=
-usr_share_gforge=/path/to/gforge
+usr_share_gforge=/opt/gforge
usr_lib_gforge=/path/to/usr/share/gforge
-var_lib_gforge=/path/to/var/lib/gforge
+var_lib_gforge=/var/lib/gforge
var_log_gforge=/path/to/var/log/gforge
sys_show_source=0
sys_force_login=0
@@ -75,27 +75,37 @@ sys_use_mail=true
sys_use_survey=true
sys_use_frs=true
sys_use_fti=false
-sys_use_ftp=true
+sys_use_ftp=false
sys_use_trove=true
-sys_use_snippet=true
+sys_use_snippet=false
sys_use_shell=true
sys_use_ratings=true
sys_use_ssl=false
-sys_use_people=true
+sys_use_people=false
sys_use_ftpuploads=false
+sys_use_diary=true
+sys_use_bookmarks=true
+sys_use_project_tags=true
+sys_use_project_full_list=true
sys_use_gateways=true
-sys_use_project_vhost=true
+sys_use_project_vhost=false
sys_use_project_database=false
sys_use_project_multimedia=false
+sys_use_private_project=true
sys_project_reg_restricted=true
sys_user_reg_restricted=false
+sys_require_accept_conditions=false
+sys_require_unique_email=false
sys_localinc=/path/to/local.inc
sys_jabber_pass=
sys_plugins_path=/usr/share/gforge/plugins/
-sys_sslcrt=/etc/apache2/ssl/apache.pem
-sys_sslkey=/etc/apache2/ssl/apache.pem
+sys_sslcrt=
+sys_sslkey=
noreply_to_bitbucket=true
sys_simple_dns=true
sys_apache_user=www-gforge
sys_apache_group=www-gforge
sys_forum_return_domain=gforge.company.com
+sys_block_anonymous_downloads=false
+sys_urlprefix=/
+dovhost=true
diff --git a/gforge/etc/httpd.conf.example b/gforge/etc/httpd.conf.example
index b3359136ab..aa8e17d5fa 100644
--- a/gforge/etc/httpd.conf.example
+++ b/gforge/etc/httpd.conf.example
@@ -1,14 +1,10 @@
-
- Listen 443
-
-NameVirtualHost 10.GF.OR.GE:443
-Listen 80
+# 01common begin
order allow,deny
deny from all
-NameVirtualHost 10.GF.OR.GE:80
+#NameVirtualHost *:80
# This is magic for virtual hosting!
UseCanonicalName Off
@@ -16,17 +12,16 @@ UseCanonicalName Off
## block web access to CVS directories.
deny from all
-#
-# Main host
-#
-
+# 01common end
+# 05maindirauth begin
+
Options Indexes FollowSymlinks
AllowOverride All
order allow,deny
allow from all
- php_admin_value include_path "/path/to/gforge/etc/custom:/etc/gforge:/path/to/gforge:/path/to/gforge/www/include:."
+ php_admin_value include_path "/path/to/gforge/etc/custom:/etc/gforge:/opt/gforge:/opt/gforge/www/include:/opt/gforge/plugins:/usr/share/php:."
php_admin_value default_charset "UTF-8"
- php_flag register_globals "Off"
+ # php_flag register_globals "Off"
###
### safe PHP settings
##
@@ -43,22 +38,26 @@ UseCanonicalName Off
# apache's error_log. So make sure error_log isn't defined in php.ini (/etc/php5/apache/php.ini)
##php_admin_value error_log ''
-# HTTP
-
+# 05maindirauth end
+# 060maindirhttp.vhost begin
+
ServerName gforge.company.com
ServerAlias www.gforge.company.com
ServerAdmin webmaster@gforge.company.com
- DocumentRoot /path/to/gforge/www
+ DocumentRoot /opt/gforge/www
+ #
# Apache 1.3
- #User www-gforge
- #Group www-gforge
+ # User www-gforge
+ # Group www-gforge
+ #
# Apache 2 apache2-mpm-perchild
- #AssignUserID www-gforge www-gforge
- # Apache 2 but this is not the same
- #
+ # AssignUserID www-gforge www-gforge
+ # Apache 2
+ #
# SuexecUserGroup www-gforge www-gforge
- #
- Alias /images/ /path/to/gforge/www/images/
+ #
+# 060maindirhttp.vhost end
+# 06maindirhttp begin
DirectoryIndex index.html index.php
UserDir disabled
@@ -66,11 +65,11 @@ UseCanonicalName Off
php_admin_value default_charset "UTF-8"
-
- Include /etc/httpd.secrets
+
+ Include /etc/gforge/httpd.secrets
- ScriptAliasMatch ^/plugins/([^/]*)/cgi-bin/(.*) /usr/share/gforge/plugins/$1/cgi-bin/$2
+ ScriptAliasMatch ^/plugins/([^/]*)/cgi-bin/(.*) /opt/gforge/plugins/$1/cgi-bin/$2
# Projects and Users script
@@ -79,258 +78,146 @@ UseCanonicalName Off
ForceType application/x-httpd-php
-
- ForceType application/x-httpd-php
-
# 404 Error document
ErrorDocument 404 /404.php
- LogFormat "%h %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" gforge
- CustomLog "|/usr/bin/cronolog /path/to/var/log/gforge/%Y/%m/%d/gforge.log" gforge
- # GForge without the DNS delegation
+ # FusionForge without the DNS delegation
# Project home pages are in a virtual /www/ location
-# AliasMatch ^/www/([^/]*)/(.*) /home/groups/$1/htdocs/$2
-# ScriptAliasMatch ^/([^/]*)/cgi-bin/(.*) /home/groups/$1/cgi-bin/$2
-#
-# Options Indexes FollowSymlinks
-# AllowOverride All
-# order allow,deny
-# allow from all
-#
+ # AliasMatch ^/www/([^/]*)/(.*) /home/groups/$1/htdocs/$2
+ # ScriptAliasMatch ^/([^/]*)/cgi-bin/(.*) /home/groups/$1/cgi-bin/$2
+ #
+ # Options Indexes FollowSymlinks
+ # AllowOverride All
+ # order allow,deny
+ # allow from all
+ #
+
+ Alias /fckeditor/ /usr/share/fckeditor/
+
+ Options Indexes MultiViews FollowSymLinks
+ AllowOverride None
+ Order allow,deny
+ allow from all
+
+
+ RedirectMatch 301 ^(/plugins/mediawiki/wiki/[-a-zA-Z0-9_]*)/*$ $1/index.php
+ AliasMatch ^/plugins/mediawiki/wiki/[-a-zA-Z0-9_]*/index.php /opt/gforge/www/plugins/mediawiki/index.php
+ AliasMatch ^/plugins/mediawiki/wiki/([-a-zA-Z0-9_]*)/images/(.*) /var/lib/gforge/plugins/mediawiki/projects/$1/images/$2
+
+ Alias /anonscm/ /var/lib/gforge/chroot/scmrepos/
+
+
+ Options -Indexes
+
+
+ Options +Indexes
+
+
+
+ Allow from all
+
+
+
+ ProxyPass http://127.0.0.1:8081/
+ ProxyPassReverse http://127.0.0.1:8081/
+
+# 06maindirhttp end
+# 06zmaindirhttp.vhost begin
+ Alias / /opt/gforge/www/
+ LogFormat "%h %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" fusionforge
+ CustomLog "|/usr/bin/cronolog /path/to/var/log/gforge/%Y/%m/%d/fusionforge.log" fusionforge
# Ensure that we don't try to use SSL on SSL Servers
SSLDisable
-
-
-# HTTPS
-
- ServerName gforge.company.com
- ServerAlias www.gforge.company.com
- ServerAdmin webmaster@gforge.company.com
- # Apache 1.3
- #User www-gforge
- #Group www-gforge
- # Apache 2 apache2-mpm-perchild
- #AssignUserID www-gforge www-gforge
- # Apache 2
-
- SuexecUserGroup www-gforge www-gforge
-
- DocumentRoot /path/to/gforge/www
- Alias /images/ /path/to/gforge/www/images/
- DirectoryIndex index.html index.php
-
- UserDir disabled
-
-
- php_admin_value default_charset "UTF-8"
-
- Include /etc/httpd.secrets
+ RewriteEngine on
+ RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
+ RewriteRule .* - [F]
+
+# 06zmaindirhttp.vhost end
+# 200list.vhost begin
+
+ ServerName lists.gforge.company.com
+# 200list.vhost end
+# 20list begin
+ AddHandler cgi-script .cgi
+
+ ScriptAlias /cgi-bin/mailman/ /var/lib/mailman/cgi-bin/
+ ScriptAlias /mailman/ /var/lib/mailman/cgi-bin/
+
+ Alias /pipermail /var/lib/mailman/archives/public
+
+ AllowOverride Options
+ Options FollowSymLinks
- ScriptAliasMatch ^/plugins/([^/]*)/cgi-bin/(.*) /usr/share/gforge/plugins/$1/cgi-bin/$2
-
- # Projects and Users script
-
- ForceType application/x-httpd-php
+ Alias /images/mailman /usr/share/images/mailman
+
+ order allow,deny
+ allow from all
-
- ForceType application/x-httpd-php
-
-
- ForceType application/x-httpd-php
-
-
- # 404 Error document
- ErrorDocument 404 /404.php
- LogFormat "%h %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" gforge
- CustomLog "|/usr/bin/cronolog /path/to/var/log/gforge/%Y/%m/%d/gforge.log" gforge
-
-
- SSLEngine on
- SSLCertificateFile /etc/apache2/ssl/apache.pem
- SSLCertificateKeyFile /etc/apache2/ssl/apache.pem
-
- SSLOptions +StdEnvVars
-
-
- SSLOptions +StdEnvVars
-
- SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
-
-
+# 20list end
+# 20zlist.vhost begin
+ RedirectMatch permanent ^/$ http://lists.gforge.company.com/mailman/listinfo
+ LogFormat "%h %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" fusionforge
+ CustomLog "|/usr/bin/cronolog /path/to/var/log/gforge/%Y/%m/%d/fusionforge-lists.log" fusionforge
+ # Ensure that we don't try to use SSL on SSL Servers
- SSLEnable
- SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
+ SSLDisable
-
-#
-# SCM host
-#
-
- Options Indexes FollowSymlinks
- AllowOverride All
- order allow,deny
- allow from all
- php_admin_value include_path "/path/to/gforge/etc/custom:/etc/gforge:/path/to/gforge:/path/to/gforge/www/include:."
- php_admin_value default_charset "UTF-8"
-
-
-# SCM HTTP vhost
-
- ServerName cvs.gforge.company.com
- DocumentRoot /path/to/gforge/scm
- Alias /images/ /path/to/gforge/www/images/
- LogFormat "%h %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" gforge
- CustomLog "|/usr/bin/cronolog /path/to/var/log/gforge/%Y/%m/%d/gforge.log" gforge
- # Ensure that we don't try to use SSL on SSL Servers
-
- SSLDisable
-
-
-
-# SCM HTTP SSL vhost
-
- ServerName cvs.gforge.company.com
- DocumentRoot /path/to/gforge/scm
- LogFormat "%h %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" gforge
- CustomLog "|/usr/bin/cronolog /path/to/var/log/gforge/%Y/%m/%d/gforge.log" gforge
-
-
- SSLEngine on
- SSLCertificateFile /etc/apache2/ssl/apache.pem
- SSLCertificateKeyFile /etc/apache2/ssl/apache.pem
-
- SSLOptions +StdEnvVars
-
-
- SSLOptions +StdEnvVars
-
- SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
-
-
-
- SSLEnable
-
-
-
-
-#
-# Download host
-#
-
- ServerName download.gforge.company.com
- DocumentRoot /path/to/var/lib/gforge/download
- LogFormat "%h %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" gforge
- CustomLog "|/usr/bin/cronolog /path/to/var/log/gforge/%Y/%m/%d/gforge.log" gforge
- # Ensure that we don't try to use SSL on SSL Servers
-
- SSLDisable
-
-
-
-#
-# List host
-#
-# HTTP
-
- ServerName lists.gforge.company.com
- AddHandler cgi-script .cgi
-
- ScriptAlias /mailman/ /var/lib/mailman/cgi-bin/
-
- Alias /pipermail /var/lib/mailman/archives/public
-
- AllowOverride Options
- Options FollowSymLinks
-
-
- Alias /images/mailman /usr/share/images/mailman
-
- order allow,deny
- allow from all
-
-
- RedirectMatch permanent ^/$ http://lists.gforge.company.com/mailman/listinfo
- LogFormat "%h %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" gforge
- CustomLog "|/usr/bin/cronolog /path/to/var/log/gforge/%Y/%m/%d/gforge.log" gforge
- # Ensure that we don't try to use SSL on SSL Servers
-
- SSLDisable
-
+ RewriteEngine on
+ RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
+ RewriteRule .* - [F]
-#
-# List host
-#
-# HTTPS
-
- ServerName lists.gforge.company.com
- AddHandler cgi-script .cgi
-
-
- SSLEngine on
- SSLCertificateFile /etc/apache2/ssl/apache.pem
- SSLCertificateKeyFile /etc/apache2/ssl/apache.pem
-
- SSLOptions +StdEnvVars
-
-
- SSLOptions +StdEnvVars
-
- SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
-
-
-
- SSLEnable
-
-
- ScriptAlias /mailman/ /var/lib/mailman/cgi-bin/
-
- Alias /pipermail /var/lib/mailman/archives/public
-
- AllowOverride Options
- Options FollowSymLinks
-
-
- Alias /images/mailman /usr/share/images/mailman
-
- order allow,deny
- allow from all
-
-
- RedirectMatch permanent ^/$ https://lists.gforge.company.com/mailman/listinfo
- LogFormat "%h %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" gforge
- CustomLog "|/usr/bin/cronolog /path/to/var/log/gforge/%Y/%m/%d/gforge.log" gforge
-
-
-#
-# * hosts
-#
-
+# 20zlist.vhost end
+# 40project.vhost begin
+
ServerName gforge.company.com
ServerAlias *.gforge.company.com
VirtualDocumentRoot /home/groups/%1/htdocs
VirtualScriptAlias /home/groups/%1/cgi-bin
DirectoryIndex index.html index.php
php_admin_value default_charset "UTF-8"
- php_admin_value include_path "/path/to/gforge/etc/custom:/etc/gforge:/path/to/gforge:/path/to/gforge/www/include:."
+ php_admin_value include_path "/path/to/gforge/etc/custom:/etc/gforge:/opt/gforge:/opt/gforge/www/include:."
Alias /themes-gforge/ /usr/share/gforge/www/themes/
- Options Indexes FollowSymlinks
- AllowOverride All
- order allow,deny
- allow from all
-
- LogFormat "%h %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" gforge
- CustomLog "|/usr/bin/cronolog /path/to/var/log/gforge/%Y/%m/%d/gforge.log" gforge
- # Ensure that we don't try to use SSL on SSL Servers
-
- SSLDisable
-
+ Options Indexes FollowSymlinks
+ AllowOverride All
+ order allow,deny
+ allow from all
+
+ LogFormat "%h %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" fusionforge
+ CustomLog "|/usr/bin/cronolog /path/to/var/log/gforge/%Y/%m/%d/fusionforge-project-vhost.log" fusionforge
+ # Ensure that we don't try to use SSL on SSL Servers
+
+ SSLDisable
+
-
+# 40project.vhost end
+# 55dnsalias.vhost begin
+#This may be used
+#ServerPath /sub1/
+#RewriteEngine On
+#RewriteRule ^(/sub1/.*) /www/subdomain$1
+
+# Other virtual hosts, as requested by users
+Include /var/lib/gforge/etc/httpd.vhosts
+# 55dnsalias.vhost end
+# 61plugin-scmdarcs begin
+
+ SetEnv DARCSWEB_CONFPATH /etc/gforge/plugins/scmdarcs/
+
+# 61plugin-scmdarcs end
+# 61plugin-scmgit begin
+
+ SetEnv GITWEB_CONFIG /etc/gforge/plugins/scmgit/gitweb.conf
+
+# 61plugin-scmgit end
+# 99maindirhttp begin
+#Alias / /opt/gforge/www/
+DocumentRoot /opt/gforge/www
+# 99maindirhttp end
diff --git a/gforge/etc/httpd.d/05maindirauth b/gforge/etc/httpd.d/05maindirauth
index 6faee6b58f..9f37f72578 100644
--- a/gforge/etc/httpd.d/05maindirauth
+++ b/gforge/etc/httpd.d/05maindirauth
@@ -4,7 +4,7 @@
AllowOverride All
order allow,deny
allow from all
- php_admin_value include_path "{sys_custom_path}:/etc/gforge:{usr_share_gforge}:{usr_share_gforge}/www/include:/usr/share/php:."
+ php_admin_value include_path "{sys_custom_path}:/etc/gforge:{usr_share_gforge}:{usr_share_gforge}/www/include:{usr_share_gforge}/plugins:/usr/share/php:."
php_admin_value default_charset "UTF-8"
# php_flag register_globals "Off"
###
diff --git a/gforge/etc/httpd.d/06maindirhttp b/gforge/etc/httpd.d/06maindirhttp
index dd5fc211c6..54f311fea1 100644
--- a/gforge/etc/httpd.d/06maindirhttp
+++ b/gforge/etc/httpd.d/06maindirhttp
@@ -42,9 +42,9 @@
allow from all
+ RedirectMatch 301 ^({sys_urlprefix}plugins/mediawiki/wiki/[-a-zA-Z0-9_]*)/*$ $1/index.php
AliasMatch ^{sys_urlprefix}plugins/mediawiki/wiki/[-a-zA-Z0-9_]*/index.php {usr_share_gforge}/www/plugins/mediawiki/index.php
- AliasMatch ^{sys_urlprefix}plugins/mediawiki/wiki/([-a-zA-Z0-9_]*)/images/(.*) {var_lib_gforge}/plugins/mediawiki/wikidata/$1/images/$2
- AliasMatch ^{sys_urlprefix}plugins/mediawiki/wiki/([-a-zA-Z0-9_]*)/skins/(.*) /usr/share/mediawiki/skins/$2
+ AliasMatch ^{sys_urlprefix}plugins/mediawiki/wiki/([-a-zA-Z0-9_]*)/images/(.*) {var_lib_gforge}/plugins/mediawiki/projects/$1/images/$2
Alias {sys_urlprefix}anonscm/ {var_lib_gforge}/chroot/scmrepos/
diff --git a/gforge/etc/httpd.d/07maindirhttp.vhost.ssl b/gforge/etc/httpd.d/07maindirhttp.vhost.ssl
index f917e2ed3a..598f15ffda 100644
--- a/gforge/etc/httpd.d/07maindirhttp.vhost.ssl
+++ b/gforge/etc/httpd.d/07maindirhttp.vhost.ssl
@@ -58,10 +58,27 @@
Order allow,deny
allow from all
+ ##### COPY 20list begin #####
+ AddHandler cgi-script .cgi
- AliasMatch ^{sys_urlprefix}plugins/mediawiki/wiki/[-a-zA-Z0-9_]*/index.php /usr/share/gforge/www/plugins/mediawiki/index.php
- AliasMatch ^{sys_urlprefix}plugins/mediawiki/wiki/([-a-zA-Z0-9_]*)/images/(.*) /var/lib/gforge/plugins/mediawiki/wikidata/$1/images/$2
- AliasMatch ^{sys_urlprefix}plugins/mediawiki/wiki/([-a-zA-Z0-9_]*)/skins/(.*) /usr/share/mediawiki/skins/$2
+ ScriptAlias /cgi-bin/mailman/ /var/lib/mailman/cgi-bin/
+ ScriptAlias /mailman/ /var/lib/mailman/cgi-bin/
+
+ Alias /pipermail /var/lib/mailman/archives/public
+
+ AllowOverride Options
+ Options FollowSymLinks
+
+
+ Alias /images/mailman /usr/share/images/mailman
+
+ order allow,deny
+ allow from all
+
+ ##### COPY 20list end #####
+ RedirectMatch 301 ^({sys_urlprefix}plugins/mediawiki/wiki/[-a-zA-Z0-9_]*)/*$ $1/index.php
+ AliasMatch ^{sys_urlprefix}plugins/mediawiki/wiki/[-a-zA-Z0-9_]*/index.php {usr_share_gforge}/www/plugins/mediawiki/index.php
+ AliasMatch ^{sys_urlprefix}plugins/mediawiki/wiki/([-a-zA-Z0-9_]*)/images/(.*) {var_lib_gforge}/plugins/mediawiki/projects/$1/images/$2
Alias {sys_urlprefix}anonscm/ {var_lib_gforge}/chroot/scmrepos/
Alias {sys_urlprefix} {usr_share_gforge}/www/
diff --git a/gforge/etc/httpd.d/httpd.secrets b/gforge/etc/httpd.d/httpd.secrets
index 53f8d74a8d..74e949e477 100644
--- a/gforge/etc/httpd.d/httpd.secrets
+++ b/gforge/etc/httpd.d/httpd.secrets
@@ -5,8 +5,8 @@ SetEnv sys_localinc {sys_localinc}
#RequestHeader unset GForgeDbhost
#RequestHeader append GForgeDbhost {db_host}
-RequestHeader unset GForgeDbport
-RequestHeader append GForgeDbport {db_port}
+#RequestHeader unset GForgeDbport
+#RequestHeader append GForgeDbport {db_port}
RequestHeader unset GForgeDbname
RequestHeader append GForgeDbname {db_name}
diff --git a/gforge/etc/httpd.secrets.example b/gforge/etc/httpd.secrets.example
index d38b5cb500..f83fc95975 100644
--- a/gforge/etc/httpd.secrets.example
+++ b/gforge/etc/httpd.secrets.example
@@ -1,10 +1,24 @@
# PLEASE DO NOT REMOVE THIS LINE
SetEnv sys_localinc /path/to/local.inc
-SetEnv sys_gfdbhost
-SetEnv sys_gfdbport 5432
-SetEnv sys_gfdbname alexandria
-SetEnv sys_gfdbuser www
-SetEnv sys_gfdbpasswd
-SetEnv sys_gfldap_passwd
-SetEnv sys_jabber_pass
+
+#RequestHeader unset GForgeDbhost
+#RequestHeader append GForgeDbhost
+
+#RequestHeader unset GForgeDbport
+#RequestHeader append GForgeDbport 5432
+
+RequestHeader unset GForgeDbname
+RequestHeader append GForgeDbname alexandria
+
+RequestHeader unset GForgeDbuser
+RequestHeader append GForgeDbuser www
+
+RequestHeader unset GForgeDbpasswd
+RequestHeader append GForgeDbpasswd
+
+RequestHeader unset GForgeLdapPasswd
+RequestHeader append GForgeLdapPasswd
+
+RequestHeader unset GForgeJabberPasswd
+RequestHeader append GForgeJabberPasswd
diff --git a/gforge/etc/local.d/01begin b/gforge/etc/local.d/01begin
index 919a4f1c41..c61eaa5df0 100644
--- a/gforge/etc/local.d/01begin
+++ b/gforge/etc/local.d/01begin
@@ -1,33 +1,29 @@
//
-// Really Important Safety Tip: --> DO NOT LEAVE ANY WHITE
-// SPACE AFTER THE CLOSING PHP TAG AT THE END OF THIS FILE!
-//
-// Doing so will really confuse the software and cause
-// 1) cookies to fail and 2) HTML page headers to fail
-// which will give you some preally hard-to-debug problems.
-// Why? PHP is a *pre-processor* -- anything that's not PHP gets
-// emitted as part of the HTML stream and processed by the browser,
-// so white space is meaningful!
+// FusionForge global paths
//
+$sys_etc_path='{gforge_etc}';
+$sys_share_path='{usr_share_gforge}';
+$sys_var_path='{var_lib_gforge}';
+
//
-// GForge hostnames
+// FusionForge hostnames
//
// Hostnames should be fully qualified domain names (FQDNs); using short names
-// would be prettier but would stop you from distributing your SourceForge
-// implementation across multiple domains.
+// would be prettier but would stop you from distributing your implementation
+// across multiple domains.
//
// Of course, if you have a lot of machines serving a particular purpose
// such as FTP or for shell accounts, the "hostname" here might be in
// reality an addr_list of machines that is serviced by a round-robin
// mechanism or something fancy like a local-director.
//
-// The default GForge domain
-// this is used where ever the "naked" form of the GForge domain
+// The default FusionForge domain
+// this is used where ever the "naked" form of the FusionForge domain
// might be used. E.g., "mailto:admin@gforge.net"
$sys_default_domain = '{domain_name}';
$sys_forum_return_domain = "{sys_forum_return_domain}";
@@ -43,7 +39,7 @@ $sys_download_host = '{download_host}';
$sys_shell_host = '{shell_host}';
$sys_users_host = '{users_host}';
-// Machine that hosts the GForge mailing lists (This could also be
+// Machine that hosts the FusionForge mailing lists (This could also be
// the mail host if you have enough horsepower & bandwidth)
$sys_lists_host = '{lists_host}';
diff --git a/gforge/etc/local.d/02scm b/gforge/etc/local.d/02scm
index 88906cc1a8..14c4ec9dec 100644
--- a/gforge/etc/local.d/02scm
+++ b/gforge/etc/local.d/02scm
@@ -4,7 +4,7 @@
// Machine that hosts SCM
$sys_scm_host = '{scm_host}';
-$sys_cvs_host= '{scm_host}';
+$sys_cvs_host=$sys_scm_host;
// Force the use of a single scm host instead of scm.project.domain.com
// Set to 1 to use scm.domain.com for all projects
@@ -12,11 +12,11 @@ $sys_cvs_host= '{scm_host}';
$sys_scm_single_host = 1;
// Path to tarballs directory
-$sys_scm_tarballs_path='{sys_scm_tarballs_path}';
+$sys_scm_tarballs_path="$sys_var_path/scmtarballs";
// Path to snapshots directory
-$sys_scm_snapshots_path='{sys_scm_snapshots_path}';
+$sys_scm_snapshots_path="$sys_var_path/scmsnapshots";
// Path to SCMWEB
-$sys_path_to_scmweb='{sys_path_to_scmweb}';
+$sys_path_to_scmweb="$sys_share_path/bin/";
diff --git a/gforge/etc/local.d/10database.env b/gforge/etc/local.d/10database.env
index d702f27e89..368ee62818 100644
--- a/gforge/etc/local.d/10database.env
+++ b/gforge/etc/local.d/10database.env
@@ -1,5 +1,3 @@
-$sys_database_type='pgsql';
-
if (function_exists ('apache_request_headers')) {
$headers = apache_request_headers() ;
}
@@ -7,7 +5,7 @@ if (function_exists ('apache_request_headers')) {
// Databases, html/php/other paths, passwords
if (getenv ('SERVER_SOFTWARE')) { // We're on the web
$sys_dbhost = @$headers['GForgeDbhost'] or getenv('sys_gfdbhost');
- $sys_dbport = $headers['GForgeDbport'] or getenv('sys_gfdbport');
+ $sys_dbport = @$headers['GForgeDbport'] or getenv('sys_gfdbport');
$sys_dbname = $headers['GForgeDbname'] or getenv('sys_gfdbname');
$sys_dbuser = $headers['GForgeDbuser'] or getenv('sys_gfdbuser');
$sys_dbpasswd = $headers['GForgeDbpasswd'] or getenv('sys_gfdbpasswd');
diff --git a/gforge/etc/local.d/25features b/gforge/etc/local.d/25features
index 8e363acde1..e173acad6b 100644
--- a/gforge/etc/local.d/25features
+++ b/gforge/etc/local.d/25features
@@ -46,6 +46,13 @@ $sys_use_project_multimedia={sys_use_project_multimedia};
// If set to true, only a site admin can register projects
//
$sys_project_reg_restricted={sys_project_reg_restricted};
+
+//
+// Auto approve project registration.
+//
+$sys_project_reg_autoapprove=false;
+$sys_project_reg_autoapprove_user='admin';
+
//
// Restricted user registration
// If set to true, only a site admin can register users
diff --git a/gforge/etc/local.d/30homegroupother b/gforge/etc/local.d/30homegroupother
index f846c759a8..0b3cf05327 100644
--- a/gforge/etc/local.d/30homegroupother
+++ b/gforge/etc/local.d/30homegroupother
@@ -22,9 +22,9 @@ $sys_ftp_upload_host='{ftpuploadhost}';
$sys_apache_user='{sys_apache_user}';
$sys_apache_group='{sys_apache_group}';
-// Where the GForge files are placed
+// Where the FusionForge files are placed
// *** IMPORTANT: sys_urlroot *MUST* be an ABSOLUTE FILEYSTEM PATH NAME
-// that points to the www directory of the GForge
+// that points to the www directory of the FusionForge
// installation. If you use ANY form of relative path
// you will break the html_image function in include/html.php
//
@@ -53,7 +53,7 @@ $sys_bcc_all_email_address='';
// GUI modifications (menu colors, etc.)
// See the top of the file include/html.php, this is where the menu colors
-// and colors used throughout GForge are defined.
+// and colors used throughout FusionForge are defined.
// Themeing related vars... Some of this needs to change in the session stuff
// The theme base directory, everything else is handled by theme_sysinit()
@@ -70,7 +70,7 @@ $sys_images_url='';
$sys_images_secure_url='';
// Groups
-// The GForge permission model is based on groups
+// The FusionForge permission model is based on groups
// certain parts of the site, like news, stats, etc
// are based on special group_id numbers
// group_id #1 is the super-user group of sitewide admins
@@ -99,5 +99,15 @@ $sys_force_login={sys_force_login};
//$gantt_task_font_size=12;
// Place for customized files
-$sys_custom_path='{sys_custom_path}';
+$sys_custom_path=$sys_etc_path.'/custom';
+
+// Gettext files (default: /usr/share/locale).
+$sys_gettext_path=$sys_share_path.'/locales';
+
+// Define the type of installation
+// * development:
+// * integration:
+// * staging:
+// * production: normal mode.
+$sys_install_type = 'production';
diff --git a/gforge/etc/local.d/50plugins b/gforge/etc/local.d/50plugins
index cb8fdab203..2ce54dc3bc 100644
--- a/gforge/etc/local.d/50plugins
+++ b/gforge/etc/local.d/50plugins
@@ -2,5 +2,14 @@
// Plugins configuration
//
// Path to plugins directory
-$sys_plugins_path='{sys_plugins_path}';
+$sys_plugins_path="$sys_share_path/plugins/";
+
+// You can overwrite FusionForge's default role settings here
+//$default_roles=array(
+// 'Admin'=>array( 'projectadmin'=>'A', 'frs'=>'1', 'scm'=>'1', 'docman'=>'1', 'forumadmin'=>'2', 'forum'=>'2', 'trackeradmin'=>'2', 'tracker'=>'2', 'pmadmin'=>'2', 'pm'=>'2', 'webcal'=>'1' ),
+// 'Senior Developer'=>array( 'projectadmin'=>'0', 'frs'=>'1', 'scm'=>'1', 'docman'=>'1', 'forumadmin'=>'2', 'forum'=>'2', 'trackeradmin'=>'2', 'tracker'=>'2', 'pmadmin'=>'2', 'pm'=>'2', 'webcal'=>'2' ),
+// 'Junior Developer'=>array( 'projectadmin'=>'0', 'frs'=>'0', 'scm'=>'1', 'docman'=>'0', 'forumadmin'=>'0', 'forum'=>'1', 'trackeradmin'=>'0', 'tracker'=>'1', 'pmadmin'=>'0', 'pm'=>'1', 'webcal'=>'2' ),
+// 'Doc Writer'=>array( 'projectadmin'=>'0', 'frs'=>'0', 'scm'=>'0', 'docman'=>'1', 'forumadmin'=>'0', 'forum'=>'1', 'trackeradmin'=>'0', 'tracker'=>'0', 'pmadmin'=>'0', 'pm'=>'0' , 'webcal'=>'2'),
+// 'Support Tech'=>array( 'projectadmin'=>'0', 'frs'=>'0', 'scm'=>'0', 'docman'=>'1', 'forumadmin'=>'0', 'forum'=>'1', 'trackeradmin'=>'0', 'tracker'=>'2', 'pmadmin'=>'0', 'pm'=>'0' , 'webcal'=>'2')
+//);
diff --git a/gforge/etc/local.inc.example b/gforge/etc/local.inc.example
index cc6ff27e1f..9757cfd915 100644
--- a/gforge/etc/local.inc.example
+++ b/gforge/etc/local.inc.example
@@ -7,15 +7,9 @@
// FusionForge global paths
//
$sys_etc_path='/etc/gforge';
-$sys_opt_path='/opt/gforge';
+$sys_share_path='/opt/gforge';
$sys_var_path='/var/lib/gforge';
-//
-// FusionForge database type
-//
-//$sys_database_type='mysql';
-$sys_database_type='pgsql';
-
//
// FusionForge hostnames
//
@@ -33,6 +27,7 @@ $sys_database_type='pgsql';
// might be used. E.g., "mailto:admin@gforge.net"
$sys_default_domain = 'gforge.company.com';
$sys_forum_return_domain = "gforge.company.com";
+//$sys_fallback_domain = 'gforge2.company.com';
// Machine used for downloading sources/packages
$sys_download_host = 'download.gforge.company.com';
@@ -44,9 +39,9 @@ $sys_download_host = 'download.gforge.company.com';
$sys_shell_host = 'shell.gforge.company.com';
$sys_users_host = 'users.gforge.company.com';
-// Machine that hosts the GForge mailing lists (This could also be
+// Machine that hosts the FusionForge mailing lists (This could also be
// the mail host if you have enough horsepower & bandwidth)
-$sys_lists_host = 'gforge.company.com';
+$sys_lists_host = 'lists.gforge.company.com';
//
// SCM configuration
@@ -68,7 +63,7 @@ $sys_scm_tarballs_path="$sys_var_path/scmtarballs";
$sys_scm_snapshots_path="$sys_var_path/scmsnapshots";
// Path to SCMWEB
-$sys_path_to_scmweb="$sys_opt_path/bin/";
+$sys_path_to_scmweb="$sys_share_path/bin/";
//Databases, html/php/other paths
//server to use for updates and reads
@@ -164,6 +159,9 @@ $sys_use_bookmarks=true;
$sys_use_project_tags=true;
$sys_use_project_full_list=true;
+// This one exists purely for hysteric raisins
+$sys_use_mwframe=false;
+
// Enable/Disable user ratings
$sys_use_ratings=true;
// Enable/Disable the ability to upload files using FTP in FRS
@@ -183,26 +181,30 @@ $sys_use_project_multimedia=false;
// If set to true, only a site admin can register projects
//
$sys_project_reg_restricted=true;
+
+//
+// Auto approve project registration.
+//
+$sys_project_reg_autoapprove=false;
+$sys_project_reg_autoapprove_user='admin';
+
//
// Restricted user registration
// If set to true, only a site admin can register users
//
$sys_user_reg_restricted=false;
+// Require acceptance of terms and conditions
+$sys_require_accept_conditions=false;
+// Block anonymous downloads?
+$sys_block_anonymous_downloads=false;
//
// Groups and Homes dir prefix
//
$homedir_prefix='/home';
$groupdir_prefix='/home/groups';
-
-//
-// SCM directory prefixes
-//
-//$cvsdir_prefix='$sys_var_path/cvsroot';
-//$svndir_prefix="$sys_var_path/svnroot";
$cvsdir_prefix='/cvsroot';
$svndir_prefix='/svnroot';
-
$sys_chroot='';
//
@@ -213,20 +215,21 @@ $sys_chroot='';
// Your php.ini file may have to be modified to allow writing outside
// the webserver's directory
//
-$sys_upload_dir="$sys_var_path/uploads/";
+$sys_upload_dir='/path/to/uploads/';
$sys_ftp_upload_dir='/path/to/frs/upload';
$sys_ftp_upload_host='upload.gforge.company.com';
-$sys_apache_user='apacheuser';
-$sys_apache_group='apachegroup';
+//$sys_ftp_upload_chowner='{ftpuploadchowner}';
+$sys_apache_user='www-gforge';
+$sys_apache_group='www-gforge';
-// Where the GForge files are placed
+// Where the FusionForge files are placed
// *** IMPORTANT: sys_urlroot *MUST* be an ABSOLUTE FILEYSTEM PATH NAME
-// that points to the www directory of the GForge
+// that points to the www directory of the FusionForge
// installation. If you use ANY form of relative path
// you will break the html_image function in include/html.php
//
-$sys_urlroot="$sys_opt_path/www/";
-$sys_urlprefix="";
+$sys_urlroot='/path/to/gforge/www/';
+$sys_urlprefix='/';
// Name of the system as a whole (needed by various utils and titles)
$sys_name='MyForge';
@@ -243,18 +246,18 @@ $sys_session_expire = 60 * 60 * 24 * 7;
// Require that user give unique (not yet existent in db) email upon
// registration
-$sys_require_unique_email=0;
+$sys_require_unique_email=false;
//
// Require that all email be copied to this address if present
$sys_bcc_all_email_address='';
// GUI modifications (menu colors, etc.)
// See the top of the file include/html.php, this is where the menu colors
-// and colors used throughout GForge are defined.
+// and colors used throughout FusionForge are defined.
// Themeing related vars... Some of this needs to change in the session stuff
// The theme base directory, everything else is handled by theme_sysinit()
-$sys_themeroot="$sys_opt_path/www/themes/";
+$sys_themeroot='/path/to/gforge/www/themes/';
// If you want an other default theme or language
$sys_theme='gforge';
$sys_lang='English';
@@ -267,18 +270,18 @@ $sys_images_url='';
$sys_images_secure_url='';
// Groups
-// The GForge permission model is based on groups
+// The FusionForge permission model is based on groups
// certain parts of the site, like news, stats, etc
// are based on special group_id numbers
// group_id #1 is the super-user group of sitewide admins
-$sys_stats_group=2;
-$sys_news_group=3;
+$sys_news_group=2;
+$sys_stats_group=3;
$sys_peer_rating_group=4;
$sys_template_group=5;
$default_trove_cat=18;
// JPGRAPH Package
-$sys_path_to_jpgraph=$sys_opt_path.'/jpgraph';
+$sys_path_to_jpgraph='/path/to/jpgraph';
// Show Source
// Setting this to 1 will add a "Show Source" link to the bottom of each page
@@ -299,7 +302,7 @@ $sys_force_login=0;
$sys_custom_path=$sys_etc_path.'/custom';
// Gettext files (default: /usr/share/locale).
-$sys_gettext_path=$sys_opt_path.'/locales';
+$sys_gettext_path=$sys_share_path.'/locales';
// Define the type of installation
// * development:
@@ -312,7 +315,7 @@ $sys_install_type = 'production';
// Plugins configuration
//
// Path to plugins directory
-$sys_plugins_path="$sys_opt_path/plugins/";
+$sys_plugins_path="$sys_share_path/plugins/";
// You can overwrite FusionForge's default role settings here
//$default_roles=array(
@@ -323,4 +326,11 @@ $sys_plugins_path="$sys_opt_path/plugins/";
// 'Support Tech'=>array( 'projectadmin'=>'0', 'frs'=>'0', 'scm'=>'0', 'docman'=>'1', 'forumadmin'=>'0', 'forum'=>'1', 'trackeradmin'=>'0', 'tracker'=>'2', 'pmadmin'=>'0', 'pm'=>'0' , 'webcal'=>'2')
//);
-// End of customizations -- place nothing after this line
+//bbcode customizations
+$sys_bbcode_make_clickable=1;
+$sys_bbcode_smilie_on=1;
+$sys_bbcode_bbcode_on=1;
+$sys_bbcode_strip_html=1;
+
+// End of customizations -- place nothing after the closing PHP tag!
+?>
diff --git a/gforge/etc/local.pl.example b/gforge/etc/local.pl.example
index f0ae1d66d2..67341efc72 100644
--- a/gforge/etc/local.pl.example
+++ b/gforge/etc/local.pl.example
@@ -15,7 +15,7 @@ $sys_urlroot='/usr/share/gforge/www/' ;
$sf_cache_dir = '/var/cache/gforge' ;
$sys_name = 'MyForge' ;
$sys_themeroot = $sys_urlroot.'themes/' ;
-$sys_news_group = '3' ;
+$sys_news_group = '2' ;
$sys_dbhost = '' ;
$sys_dbname = 'alexandria' ;
$sys_dbuser = 'www' ;
@@ -27,8 +27,8 @@ $admin_login = 'admin' ;
$admin_password = '' ;
$server_admin = 'webmaster@gforge.company.com' ;
$domain_name = 'gforge.company.com' ;
-$newsadmin_groupid = '3' ;
-$statsadmin_groupid = '2' ;
+$newsadmin_groupid = '2' ;
+$statsadmin_groupid = '3' ;
$peerrating_groupid = '4' ;
$noreply_to_bitbucket = 'true' ;
$sys_simple_dns = 'true';
@@ -36,6 +36,6 @@ $sys_ip_address = '10.GF.OR.GE';
$chroot_prefix = '';
$homedir_prefix = '/home';
$grpdir_prefix = '/home/groups';
-$file_dir = '/path/to/var/lib/gforge';
+$file_dir = '/var/lib/gforge';
$cvs_root = '/cvsroot';
$svn_root = '/svnroot';
diff --git a/gforge/etc/templates/database.py b/gforge/etc/templates/database.py
new file mode 100644
index 0000000000..ee5e09bd27
--- /dev/null
+++ b/gforge/etc/templates/database.py
@@ -0,0 +1,6 @@
+# PLEASE DO NOT REMOVE THIS LINE
+sys_dbhost="{db_host}";
+sys_dbname="{db_name}";
+sys_dbuser="{db_user}";
+sys_dbpasswd="{db_password}";
+sys_ldap_passwd="{ldap_web_add_password}";
diff --git a/gforge/fusionforge-install-1-deps.php b/gforge/fusionforge-install-1-deps.php
index ed99d5bc2d..a29fe7804e 100755
--- a/gforge/fusionforge-install-1-deps.php
+++ b/gforge/fusionforge-install-1-deps.php
@@ -48,7 +48,7 @@ function installRedhat() {
addFusionForgeYumRepo();
addDagRPMForgeYumRepo();
INFO("Installing packages: Executing YUM. Please wait...\n\n\n");
- passthru("yum -y install httpd php mailman cvs postgresql postgresql-libs postgresql-server postgresql-contrib perl-URI php-pgsql subversion mod_dav_svn postfix rcs php-gd mod_ssl wget openssh which liberation-fonts htmlpurifier php-mbstring poppler-utils php-pecl-zip antiword");
+ passthru("yum -y install httpd php mailman cvs postgresql postgresql-libs postgresql-server postgresql-contrib perl-URI php-pgsql subversion mod_dav_svn postfix rcs php-gd mod_ssl wget openssh which liberation-fonts htmlpurifier php-mbstring php-jpgraph-1.5.2 poppler-utils php-pecl-zip antiword");
}
function installRHEL4() {
@@ -117,7 +117,7 @@ function addFusionForgeYumRepo() {
if (getenv('FFORGE_RPM_REPO')) {
$rpm_repo = getenv('FFORGE_RPM_REPO');
} else {
- $rpm_repo = 'http://fusionforge.fusionforge.org/rpm/5.0';
+ $rpm_repo = 'http://fusionforge.fusionforge.org/rpm/5.1';
}
$repo = '
diff --git a/gforge/fusionforge-install-2.php b/gforge/fusionforge-install-2.php
index fe2ded0037..068753575a 100755
--- a/gforge/fusionforge-install-2.php
+++ b/gforge/fusionforge-install-2.php
@@ -212,6 +212,10 @@
{
symlink ("../../plugins/fckeditor/www", "fckeditor");
}
+ if (!is_dir("blocks"))
+ {
+ symlink ("../../plugins/blocks/www", "blocks");
+ }
//cd /opt/gforge
chdir("/opt/gforge");
@@ -239,8 +243,9 @@
$hash = md5(microtime());
system("perl -spi -e \"s/sys_session_key = 'foobar'/sys_session_key = '$hash'/\" /etc/gforge/local.inc");
- # Use liberation fonts if jpgraph provided in the archive.
- if (is_dir("/opt/gforge/jpgraph")) {
+ # Set jpgraph path.
+ if (is_dir("/usr/share/jpgraph")) {
+ system("perl -spi -e \"s!^(.sys_path_to_jpgraph)=.*!\\$1='/usr/share/jpgraph';!\" /etc/gforge/local.inc");
system("perl -spi -e \"s!//(.gantt_title_font_family)='FF_ARIAL';!\\$1='FF_LIBERATION_SANS';!\" /etc/gforge/local.inc");
system("perl -spi -e \"s!//(.gantt_title_font_style=.*)!\\$1!\" /etc/gforge/local.inc");
system("perl -spi -e \"s!//(.gantt_title_font_size=.*)!\\$1!\" /etc/gforge/local.inc");
diff --git a/gforge/mkadmin-mysql.sh b/gforge/mkadmin-mysql.sh
deleted file mode 100755
index fa042d7dbc..0000000000
--- a/gforge/mkadmin-mysql.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-USER_NAME=$1
-shift
-mysql $* <>$config{'logfile'}") || die "Couldn't Open Logfile: $!\n";
- select (Log);
- $| = 1;
- }
-
- setsid || die "Can't get a new session: $!\n";
- umask 0;
-}
-
-##############################
-# log message to the logfile #
-##############################
-sub logme {
- my $msg = shift (@_);
- my $time = strftime "%Y-%m-%d - %T", localtime;
- print "$time\t$msg\n";
-}
-
-###################
-# exit the server #
-###################
-sub exit_nicely {
- &logme ("----- SystemDaemon.pl Ended -----\n");
- close (Server);
- close (Log);
- exit 0;
-}
-
-##################
-# socket control #
-##################
-sub listen_for_request {
- BEGIN { $ENV{PATH} = '/usr/bin:/usr/games:/bin' }
-
- my ($port, $proto, $EOL, $iaddr, $paddr, $name, $user);
-
- $user = getpwnam($config{'username'});
-
- $SIG{'CHLD'} = \&child_handler;
- $EOL = "\015\012";
-
- $port = $config{'port'};
- $proto = getprotobyname('tcp');
- $port = $1 if $port =~ /(\d+)/; # untaint port number
-
- socket (Server, PF_INET, SOCK_STREAM, $proto) || die "socket(): $!";
- setsockopt (Server, SOL_SOCKET, SO_REUSEADDR, pack ("l", 1)) || die "setsockopt(): $!";
- bind (Server, sockaddr_in ($port, inet_aton("$config{'ipaddr'}"))) || die "bind(): $!";
-
- $> = $user;
-
- listen (Server, SOMAXCONN) || die "listen(): $!";
-
- &logme("----- SystemDaemon.pl Started on Port: $port -----");
-
- $waitedpid = 0;
-
- for ($waitedpid = 0; ($paddr = accept (Client,Server)) || $waitedpid; $waitedpid = 0, close Client) {
- if ($waitedpid && !$paddr) { next; }
- ($port,$iaddr) = sockaddr_in ($paddr);
- $name = gethostbyaddr ($iaddr, AF_INET);
-
- &logme ("Connection From $name [". inet_ntoa($iaddr) ."] at Port $port");
-
- &spawn_new_child;
- }
-
- #################
- # child handler #
- #################
- sub child_handler {
- $waitedpid = wait;
- }
-
- #########################
- # spawn a child process #
- #########################
- sub spawn_new_child {
- my ($pid, $cmd);
- my $tmp;
-
- if (!defined($pid = fork)) {
- &logme("Cannot fork(): $!");
- return;
- } elsif ($pid) {
- return; # I'm the parent
- }
-
- # else I'm the child -- go spawn
- eval {
- local $SIG{'ALRM'} = sub { select (Log); close(Data); die "Timeout\n"; };
- alarm 15;
- open (Data, ">>&Client") || die "Can't read/write to Client: $!\n";
- select (Data);
-
- &check_network;
-
- select (Log);
- close (Data);
- alarm 0;
- };
-
- close (Client);
- exit;
- }
-}
-
-
-
-############################
-# Main Connection Function #
-############################
-sub check_service {
- my ($host, $port, $label_str, $send_str, $search_str) = @_;
-
- my ($bigbuf, $buf, $time);
-
- printf("%-40s", $label_str);
-
- my $sock = IO::Socket::INET->new( PeerAddr => "$host.sourceforge.net",
- PeerPort => $port,
- Proto => 'tcp',
- Timeout => 5,
- Type => SOCK_STREAM() );
-
- if (!$sock) {
- print "[ FAILED ] Could Not Open Socket\n";
- return;
- }
-
- fcntl($sock, F_SETFL(), fcntl($sock, F_GETFL(), 0) | O_NONBLOCK()) || die "Unable to make socket non-blocking: $!";
-
- if ($sock->send($send_str, 0)) {
- $time = time();
-
- while ($time+5 > time()) {
- $sock->recv($buf, 2048, 0);
- $bigbuf .= $buf;
-
- if ($bigbuf =~ $search_str) {
- print "[ OK ]\n";
- $sock->close();
- return;
- }
- }
-
- $sock->close();
- }
- print "[ FAILED ] Could Not Send to Socket\n";
-
- return;
-}
-
-
-####################################
-# check all the different machines #
-####################################
-sub check_network {
- my $output;
-
- print "\n SourceForge Network Checker\n";
-
- # Webservers
- print "\n";
- foreach (@webservers) {
- &check_service($_, 80, "Checking HTTPD on $_ ", "HEAD HTTP/1.1 200 OK\n\n", "Server");
- }
-
- # Project WebServers
- print "\n";
- foreach (@pwebservers) {
- &check_service($_, 80, "Checking HTTPD on $_ ", "GET / HTTP/1.1\nHost: phpsysinfo.sourceforge.net\n\n", "script that displays information");
- }
-
- # CVS
- print "\n";
- foreach $_ (@cvsservers) {
- &check_service($_, 2401, "Checking CVS on $_ ", "hello\n", "cvs");
- }
-
- # Mail
- print "\n";
- foreach (@mailservers) {
- &check_service($_, 25, "Checking Mail on $_ ", "\n", "ESMTP");
- }
-
- # mysql
- print "\n";
- foreach (@mysqlservers) {
- if ($_ eq 'moby.p') {
- &check_service("vhost2.p", 80, "Checking MySQL on moby.p ", "GET /pager.php3\n", "mysql-good");
- } elsif ($_ eq 'underworld.i') {
- &check_service("bush.i", 80, "Checking MySQL on underworld.i ", "GET /pager.php3\n", "mysql-good");
- }
- }
-
- # pgsql
- print "\n";
- foreach (@pgsqlservers) {
- &check_service($_, 80, "Checking PGSQL on $_ ", "GET /testdb.php3\n", "postgres-good");
- }
-
- # Ping Hosts
- print "\n";
- foreach (@pingservers) {
- printf("%-40s", "Checking PING on $_ ");
- $output = `/bin/ping -c 1 $_.sourceforge.net`;
-
- if($output =~ /time=/){
- print "[ OK ]\n";
- } else {
- print "[ FAILED ]\n";
- }
- }
-}
-
-
-################
-# Main Control #
-################
-&daemon;
-&listen_for_request;
diff --git a/gforge/packaging/control/010meta-standard b/gforge/packaging/control/010meta-standard
index 3841695a7a..918d274b5c 100644
--- a/gforge/packaging/control/010meta-standard
+++ b/gforge/packaging/control/010meta-standard
@@ -1,8 +1,8 @@
Package: @PACKAGE@-standard
Architecture: all
-Conflicts: sourceforge, gforge-cvs, @OLDPACKAGE@-common (<< ${source:Version})
+Conflicts: sourceforge, @OLDPACKAGE@-cvs, @OLDPACKAGE@-common (<< ${source:Version})
Replaces: @OLDPACKAGE@
Provides: @OLDPACKAGE@
-Depends: debconf (>= 1.0.32) | debconf-2.0, ucf, @OLDPACKAGE@-common (=${source:Version}), @OLDPACKAGE@-web-apache2 | @OLDPACKAGE@-web, @OLDPACKAGE@-db-postgresql | @OLDPACKAGE@-db, @OLDPACKAGE@-mta-exim4 | @OLDPACKAGE@-mta, @OLDPACKAGE@-shell-postgresql | @OLDPACKAGE@-shell, @OLDPACKAGE@-lists-mailman | @OLDPACKAGE@-lists, ${misc:Depends}
+Depends: debconf (>= 1.0.32) | debconf-2.0, ucf, @OLDPACKAGE@-common (=${source:Version}), @OLDPACKAGE@-web-apache2 | @OLDPACKAGE@-web, @OLDPACKAGE@-db-postgresql | @OLDPACKAGE@-db, @OLDPACKAGE@-mta-exim4 | @OLDPACKAGE@-mta, @OLDPACKAGE@-shell-postgresql | @OLDPACKAGE@-shell, @PACKAGE@-plugin-mailman | @OLDPACKAGE@-lists-mailman | @OLDPACKAGE@-lists, ${misc:Depends}
Recommends: @OLDPACKAGE@-plugin-scmsvn | @OLDPACKAGE@-plugin-scm
Description: FusionForge collaborative development tool - standard metapackage
diff --git a/gforge/packaging/control/011meta-minimal b/gforge/packaging/control/011meta-minimal
index 098405cac2..294951e66e 100644
--- a/gforge/packaging/control/011meta-minimal
+++ b/gforge/packaging/control/011meta-minimal
@@ -1,6 +1,6 @@
Package: @PACKAGE@-minimal
Architecture: all
-Conflicts: sourceforge, gforge-cvs, @OLDPACKAGE@-common (<< ${source:Version}), @OLDPACKAGE@
+Conflicts: sourceforge, @OLDPACKAGE@-cvs, @OLDPACKAGE@-common (<< ${source:Version}), @OLDPACKAGE@
Replaces: @OLDPACKAGE@
Provides: @OLDPACKAGE@
Depends: debconf (>= 1.0.32) | debconf-2.0, ucf, @OLDPACKAGE@-common (=${source:Version}), @OLDPACKAGE@-web-apache2 | @OLDPACKAGE@-web, @OLDPACKAGE@-db-postgresql | @OLDPACKAGE@-db, ${misc:Depends}
diff --git a/gforge/packaging/control/012meta-full b/gforge/packaging/control/012meta-full
index 886ecf5708..da4596f43e 100644
--- a/gforge/packaging/control/012meta-full
+++ b/gforge/packaging/control/012meta-full
@@ -1,7 +1,7 @@
Package: @PACKAGE@-full
Architecture: all
-Conflicts: sourceforge, gforge-cvs, @OLDPACKAGE@-common (<< ${source:Version}), @OLDPACKAGE@
+Conflicts: sourceforge, @OLDPACKAGE@-cvs, @OLDPACKAGE@-common (<< ${source:Version}), @OLDPACKAGE@
Replaces: @OLDPACKAGE@
Provides: @OLDPACKAGE@
-Depends: debconf (>= 1.0.32) | debconf-2.0, ucf, @OLDPACKAGE@-common (=${source:Version}), @OLDPACKAGE@-web-apache2 | @OLDPACKAGE@-web, @OLDPACKAGE@-web-apache2-vhosts, @OLDPACKAGE@-db-postgresql | @OLDPACKAGE@-db, @OLDPACKAGE@-mta-exim4 | @OLDPACKAGE@-mta, @OLDPACKAGE@-shell-postgresql | @OLDPACKAGE@-shell, @OLDPACKAGE@-lists-mailman | @OLDPACKAGE@-lists, @OLDPACKAGE@-plugin-contribtracker, @OLDPACKAGE@-plugin-extratabs, @OLDPACKAGE@-plugin-globalsearch, @OLDPACKAGE@-plugin-mediawiki, @OLDPACKAGE@-plugin-projectlabels, @OLDPACKAGE@-plugin-scmarch, @OLDPACKAGE@-plugin-scmbzr, @OLDPACKAGE@-plugin-scmcvs, @OLDPACKAGE@-plugin-scmdarcs, @OLDPACKAGE@-plugin-scmgit, @OLDPACKAGE@-plugin-scmhg, @OLDPACKAGE@-plugin-scmsvn, ${misc:Depends}
+Depends: debconf (>= 1.0.32) | debconf-2.0, ucf, @OLDPACKAGE@-common (=${source:Version}), @OLDPACKAGE@-web-apache2 | @OLDPACKAGE@-web, @OLDPACKAGE@-web-apache2-vhosts, @OLDPACKAGE@-db-postgresql | @OLDPACKAGE@-db, @OLDPACKAGE@-mta-exim4 | @OLDPACKAGE@-mta, @OLDPACKAGE@-shell-postgresql | @OLDPACKAGE@-shell, @PACKAGE@-plugin-mailman | @OLDPACKAGE@-lists-mailman | @OLDPACKAGE@-lists, @OLDPACKAGE@-plugin-contribtracker, @OLDPACKAGE@-plugin-extratabs, @OLDPACKAGE@-plugin-globalsearch, @OLDPACKAGE@-plugin-mediawiki, @OLDPACKAGE@-plugin-projectlabels, @OLDPACKAGE@-plugin-scmarch, @OLDPACKAGE@-plugin-scmbzr, @OLDPACKAGE@-plugin-scmcvs, @OLDPACKAGE@-plugin-scmdarcs, @OLDPACKAGE@-plugin-scmgit, @OLDPACKAGE@-plugin-scmhg, @OLDPACKAGE@-plugin-scmsvn, ${misc:Depends}
Description: FusionForge collaborative development tool - full metapackage
diff --git a/gforge/packaging/control/132plugin-scmbzr b/gforge/packaging/control/132plugin-scmbzr
index 3ca70baff8..71d6d96f45 100644
--- a/gforge/packaging/control/132plugin-scmbzr
+++ b/gforge/packaging/control/132plugin-scmbzr
@@ -1,5 +1,5 @@
Package: @OLDPACKAGE@-plugin-scmbzr
Architecture: all
-Depends: @OLDPACKAGE@-common, gforge-db-postgresql | gforge-db, gforge-web-apache2 | gforge-web, gforge-shell-postgresql | gforge-shell, bzr, php5-cli, ${misc:Depends}
+Depends: @OLDPACKAGE@-common, @OLDPACKAGE@-db-postgresql | @OLDPACKAGE@-db, @OLDPACKAGE@-web-apache2 | @OLDPACKAGE@-web, @OLDPACKAGE@-shell-postgresql | @OLDPACKAGE@-shell, bzr, php5-cli, ${misc:Depends}
Provides: @OLDPACKAGE@-plugin-scm
Description: collaborative development tool - Bazaar plugin
diff --git a/gforge/packaging/control/133plugin-scmgit b/gforge/packaging/control/133plugin-scmgit
index 9876191b1f..a8b8ed1493 100644
--- a/gforge/packaging/control/133plugin-scmgit
+++ b/gforge/packaging/control/133plugin-scmgit
@@ -1,5 +1,5 @@
Package: @OLDPACKAGE@-plugin-scmgit
Architecture: all
-Depends: @OLDPACKAGE@-common, gforge-db-postgresql | gforge-db, gforge-web-apache2 | gforge-web, gforge-shell-postgresql | gforge-shell, git-core, gitweb, php5-cli, ${misc:Depends}
+Depends: @OLDPACKAGE@-common, @OLDPACKAGE@-db-postgresql | @OLDPACKAGE@-db, @OLDPACKAGE@-web-apache2 | @OLDPACKAGE@-web, @OLDPACKAGE@-shell-postgresql | @OLDPACKAGE@-shell, git (>= 1:1.7) | git-core, gitweb, php5-cli, ${misc:Depends}
Provides: @OLDPACKAGE@-plugin-scm
Description: collaborative development tool - Git plugin
diff --git a/gforge/packaging/control/134plugin-scmhg b/gforge/packaging/control/134plugin-scmhg
index 6ea630b326..a273a7ddfe 100644
--- a/gforge/packaging/control/134plugin-scmhg
+++ b/gforge/packaging/control/134plugin-scmhg
@@ -1,5 +1,5 @@
Package: @OLDPACKAGE@-plugin-scmhg
Architecture: all
-Depends: @OLDPACKAGE@-common, gforge-db-postgresql | gforge-db, gforge-web-apache2 | gforge-web, gforge-shell-postgresql | gforge-shell, mercurial, php5-cli, ${misc:Depends}
+Depends: @OLDPACKAGE@-common, @OLDPACKAGE@-db-postgresql | @OLDPACKAGE@-db, @OLDPACKAGE@-web-apache2 | @OLDPACKAGE@-web, @OLDPACKAGE@-shell-postgresql | @OLDPACKAGE@-shell, mercurial, php5-cli, ${misc:Depends}
Provides: @OLDPACKAGE@-plugin-scm
Description: collaborative development tool - Mercurial (Hg) plugin
diff --git a/gforge/packaging/control/135plugin-scmdarcs b/gforge/packaging/control/135plugin-scmdarcs
index 41939ed16b..5d952ae735 100644
--- a/gforge/packaging/control/135plugin-scmdarcs
+++ b/gforge/packaging/control/135plugin-scmdarcs
@@ -1,5 +1,5 @@
Package: @OLDPACKAGE@-plugin-scmdarcs
Architecture: all
-Depends: @OLDPACKAGE@-common, gforge-db-postgresql | gforge-db, gforge-web-apache2 | gforge-web, gforge-shell-postgresql | gforge-shell, darcs, darcsweb, php5-cli, ${misc:Depends}
+Depends: @OLDPACKAGE@-common, @OLDPACKAGE@-db-postgresql | @OLDPACKAGE@-db, @OLDPACKAGE@-web-apache2 | @OLDPACKAGE@-web, @OLDPACKAGE@-shell-postgresql | @OLDPACKAGE@-shell, darcs, darcsweb, php5-cli, ${misc:Depends}
Provides: @OLDPACKAGE@-plugin-scm
Description: collaborative development tool - Darcs plugin
diff --git a/gforge/packaging/control/136plugin-scmarch b/gforge/packaging/control/136plugin-scmarch
index c508279bb2..33ea4885f6 100644
--- a/gforge/packaging/control/136plugin-scmarch
+++ b/gforge/packaging/control/136plugin-scmarch
@@ -1,5 +1,5 @@
Package: @OLDPACKAGE@-plugin-scmarch
Architecture: all
-Depends: @OLDPACKAGE@-common, gforge-db-postgresql | gforge-db, gforge-web-apache2 | gforge-web, gforge-shell-postgresql | gforge-shell, php5-cli, tla, ${misc:Depends}
+Depends: @OLDPACKAGE@-common, @OLDPACKAGE@-db-postgresql | @OLDPACKAGE@-db, @OLDPACKAGE@-web-apache2 | @OLDPACKAGE@-web, @OLDPACKAGE@-shell-postgresql | @OLDPACKAGE@-shell, php5-cli, tla, ${misc:Depends}
Provides: @OLDPACKAGE@-plugin-scm
Description: collaborative development tool - GNU Arch plugin
diff --git a/gforge/packaging/control/160plugin-mediawiki b/gforge/packaging/control/160plugin-mediawiki
index 3190fdade7..bfc8469030 100644
--- a/gforge/packaging/control/160plugin-mediawiki
+++ b/gforge/packaging/control/160plugin-mediawiki
@@ -1,4 +1,4 @@
Package: @OLDPACKAGE@-plugin-mediawiki
Architecture: all
-Depends: @OLDPACKAGE@-common (>= 4.8), @OLDPACKAGE@-db-postgresql (>= 4.8) | @OLDPACKAGE@-db, @OLDPACKAGE@-web-apache2 (>= 4.8) | @OLDPACKAGE@-web, mediawiki (>= 1:1.15~), ${misc:Depends}
+Depends: @OLDPACKAGE@-common (>= 4.8), @OLDPACKAGE@-db-postgresql (>= 4.8) | @OLDPACKAGE@-db, @OLDPACKAGE@-web-apache2 (>= 4.8) | @OLDPACKAGE@-web, mediawiki (>= 1:1.15~), php5-cli, ${misc:Depends}
Description: Mediawiki plugin for FusionForge
diff --git a/gforge/packaging/control/Makefile b/gforge/packaging/control/Makefile
index ca76363208..edac5db72d 100644
--- a/gforge/packaging/control/Makefile
+++ b/gforge/packaging/control/Makefile
@@ -1,2 +1,9 @@
-../../debian/control: $(wildcard [0-9][0-9][0-9]*)
- ls [0-9][0-9][0-9]* | grep -v shortdesc | while read file ; do cat $${file}; if [ -f $${file}.shortdesc ] ; then cat AAAdesc; echo ' .'; cat $${file}.shortdesc; fi; echo ''; done | sed 's/@PACKAGE@/gforge/g' > ../../debian/control
+OLDPACKAGE=gforge
+PACKAGE=fusionforge
+SRCPACKAGE=fusionforge
+FORGENAME=FusionForge
+
+SED_REPLACE=sed -e 's/@PACKAGE@/$(PACKAGE)/g' -e 's/@SRCPACKAGE@/$(SRCPACKAGE)/g' -e 's/@OLDPACKAGE@/$(OLDPACKAGE)/g' -e 's/@FORGENAME@/$(FORGENAME)/g'
+
+../../debian/control: $(wildcard *)
+ ls [0-9][0-9][0-9]* | grep -v shortdesc | grep -v scmcpold | while read file ; do cat $${file}; if [ -f $${file}.shortdesc ] ; then cat AAAdesc; echo ' .'; cat $${file}.shortdesc; fi; echo ''; done | $(SED_REPLACE) > $@
diff --git a/gforge/packaging/cron.d/00phpcron b/gforge/packaging/cron.d/00phpcron
index 5faae2829c..61b6cc54b5 100644
--- a/gforge/packaging/cron.d/00phpcron
+++ b/gforge/packaging/cron.d/00phpcron
@@ -1,4 +1,5 @@
-FFCRON="/usr/share/gforge/cronjobs"
+FFDIR=/usr/share/gforge
+FFCRON=$FFDIR/cronjobs
FFUSER=gforge
# You may need to change the pathname to php CLI (command line interface)
diff --git a/gforge/packaging/cron.d/cron.fusionforge b/gforge/packaging/cron.d/cron.fusionforge
index c13bb3970a..e38bf8c036 100644
--- a/gforge/packaging/cron.d/cron.fusionforge
+++ b/gforge/packaging/cron.d/cron.fusionforge
@@ -102,6 +102,3 @@ MAILTO=""
# Create SVN tarballs
5 3 * * * root $PHP $GFORGE/plugins/scmsvn/cronjobs/tarballs.php
-
-# Docman parse word engine
-56 * * * * $FFUSER $PHP $FFCRON/update_docdata_dataword.php
diff --git a/gforge/packaging/cron.d/plugin-mediawiki b/gforge/packaging/cron.d/plugin-mediawiki
index 555636b616..6aad9229ff 100644
--- a/gforge/packaging/cron.d/plugin-mediawiki
+++ b/gforge/packaging/cron.d/plugin-mediawiki
@@ -3,4 +3,4 @@
#
# Create new wikis four times an hour
-*/15 * * * * root [ -x /usr/share/gforge/plugins/mediawiki/cronjobs/create-wikis.sh ] && /usr/share/gforge/plugins/mediawiki/cronjobs/create-wikis.sh
+*/15 * * * * root [ -x $FFDIR/plugins/mediawiki/cronjobs/create-wikis.php ] && $FFDIR/plugins/mediawiki/cronjobs/create-wikis.php
diff --git a/gforge/packaging/dirs/plugin-mediawiki b/gforge/packaging/dirs/plugin-mediawiki
index 92b32fbced..fb0ebab027 100644
--- a/gforge/packaging/dirs/plugin-mediawiki
+++ b/gforge/packaging/dirs/plugin-mediawiki
@@ -3,7 +3,6 @@ etc/mediawiki-extensions/extensions-available
usr/share/gforge/plugins/mediawiki/bin
usr/share/gforge/plugins/mediawiki/common
usr/share/gforge/plugins/mediawiki/cronjobs
-usr/share/gforge/www/plugins/mediawiki
usr/share/gforge/etc/httpd.d
usr/share/mediawiki/skins
usr/share/mediawiki/skins/fusionforge
diff --git a/gforge/packaging/install/common b/gforge/packaging/install/common
index ddc3180523..30aeab5124 100644
--- a/gforge/packaging/install/common
+++ b/gforge/packaging/install/common
@@ -1,3 +1,4 @@
+etc/config.ini etc/fusionforge/
etc/httpd.d/[0-1,6-9][0-9]* usr/share/gforge/etc/httpd.d/
etc/httpd.d/httpd* usr/share/gforge/etc/httpd.d/
etc/local.d/[0-9][0-9]* usr/share/gforge/etc/local.d/
diff --git a/gforge/packaging/install/db-postgresql b/gforge/packaging/install/db-postgresql
index 93bfb70591..f2153b081e 100644
--- a/gforge/packaging/install/db-postgresql
+++ b/gforge/packaging/install/db-postgresql
@@ -60,7 +60,11 @@ db/20090507-add_element_pos.sql usr/share/gforge/db/
db/20090507-add_project_query.sql usr/share/gforge/db/
db/20090507-browse_list.sql usr/share/gforge/db/
db/20100308-forum-attachment-types.sql usr/share/gforge/db/
+db/20100330-add-system-event.sql usr/share/gforge/db/
+db/20100331-alter-system-event.sql usr/share/gforge/db/
#
utils/inject-users.php usr/share/gforge/bin/
utils/inject-groups.php usr/share/gforge/bin/
utils/inject-files.php usr/share/gforge/bin/
+#
+utils/fixscripts/normalize_roles.php usr/share/gforge/bin/
diff --git a/gforge/packaging/install/plugin-mediawiki b/gforge/packaging/install/plugin-mediawiki
index e53f65dd27..39f1aae0b6 100644
--- a/gforge/packaging/install/plugin-mediawiki
+++ b/gforge/packaging/install/plugin-mediawiki
@@ -1,6 +1,6 @@
plugins/mediawiki/bin/* usr/share/gforge/plugins/mediawiki/bin/
plugins/mediawiki/common/* usr/share/gforge/plugins/mediawiki/common/
plugins/mediawiki/cronjobs/* usr/share/gforge/plugins/mediawiki/cronjobs/
-plugins/mediawiki/www/* usr/share/gforge/www/plugins/mediawiki/
+plugins/mediawiki/www/* usr/share/gforge/plugins/mediawiki/www/
plugins/mediawiki/mediawiki-skin/* usr/share/mediawiki/skins/
plugins/mediawiki/etc/httpd.d/* usr/share/gforge/etc/httpd.d/
diff --git a/gforge/packaging/install/plugin-scmgit b/gforge/packaging/install/plugin-scmgit
index e0b6876d82..a27706204d 100644
--- a/gforge/packaging/install/plugin-scmgit
+++ b/gforge/packaging/install/plugin-scmgit
@@ -1,2 +1,7 @@
-plugins/scmgit/common/* usr/share/gforge/plugins/scmgit/common/
-plugins/scmgit/etc/plugins/scmgit/* etc/gforge/plugins/scmgit/
+plugins/scmgit/bin/* usr/share/gforge/plugins/scmgit/bin/
+plugins/scmgit/common/* usr/share/gforge/plugins/scmgit/common/
+plugins/scmgit/www/* usr/share/gforge/plugins/scmgit/www/
+plugins/scmgit/db/* usr/share/gforge/plugins/scmgit/lib/
+plugins/scmgit/etc/plugins/scmgit/* etc/gforge/plugins/scmgit/
+
+
diff --git a/gforge/debian/dsf-in/common.links b/gforge/packaging/links/common
similarity index 100%
rename from gforge/debian/dsf-in/common.links
rename to gforge/packaging/links/common
diff --git a/gforge/debian/dsf-in/plugin-scmdarcs.links b/gforge/packaging/links/plugin-scmdarcs
similarity index 100%
rename from gforge/debian/dsf-in/plugin-scmdarcs.links
rename to gforge/packaging/links/plugin-scmdarcs
diff --git a/gforge/debian/dsf-in/plugin-scmgit.links b/gforge/packaging/links/plugin-scmgit
similarity index 100%
rename from gforge/debian/dsf-in/plugin-scmgit.links
rename to gforge/packaging/links/plugin-scmgit
diff --git a/gforge/packaging/links/web-apache2 b/gforge/packaging/links/web-apache2
new file mode 100644
index 0000000000..7239274219
--- /dev/null
+++ b/gforge/packaging/links/web-apache2
@@ -0,0 +1 @@
+/usr/share/gforge/www/env.inc.php usr/share/gforge/plugins/env.inc.php
diff --git a/tests/func/Tasks/AllTests.php b/gforge/plugins/blocks/common/blocks-init.php
similarity index 71%
rename from tests/func/Tasks/AllTests.php
rename to gforge/plugins/blocks/common/blocks-init.php
index e2e856d908..e7caefa72c 100644
--- a/tests/func/Tasks/AllTests.php
+++ b/gforge/plugins/blocks/common/blocks-init.php
@@ -1,7 +1,7 @@
- * Copyright (C) 2009 Alain Peyrat, Alcatel-Lucent
+ * Copyright (C) 2006 Alain Peyrat, Alcatel-Lucent
*
* This file is part of FusionForge.
*
@@ -9,7 +9,7 @@
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
- *
+ *
* FusionForge is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
@@ -24,7 +24,7 @@
/*
* Standard Alcatel-Lucent disclaimer for contributing to open source
*
- * "The test suite ("Contribution") has not been tested and/or
+ * "The provided file ("Contribution") has not been tested and/or
* validated for release as or in products, combinations with products or
* other commercial use. Any use of the Contribution is entirely made at
* the user's own responsibility and the user can not rely on any features,
@@ -43,33 +43,16 @@
* ALONE BASIS."
*/
-if (!defined('PHPUnit_MAIN_METHOD')) {
- define('PHPUnit_MAIN_METHOD', 'Tasks_AllTests::main');
-}
-
-require_once 'PHPUnit/Framework.php';
-require_once 'PHPUnit/TextUI/TestRunner.php';
-
-require_once dirname(__FILE__).'/createTask.php';
-
-class Tasks_AllTests
-{
- public static function main()
- {
- PHPUnit_TextUI_TestRunner::run(self::suite());
- }
+global $gfplugins;
+require_once $gfplugins.'blocks/common/blocksPlugin.class.php';
- public static function suite()
- {
- $suite = new PHPUnit_Framework_TestSuite('PHPUnit Framework');
+$blocksPluginObject = new blocksPlugin ;
- $suite->addTestSuite('CreateTask');
+register_plugin ($blocksPluginObject) ;
- return $suite;
- }
-}
+// Local Variables:
+// mode: php
+// c-file-style: "bsd"
+// End:
-if (PHPUnit_MAIN_METHOD == 'Tasks_AllTests::main') {
- Framework_AllTests::main();
-}
?>
diff --git a/gforge/plugins/blocks/common/blocksPlugin.class.php b/gforge/plugins/blocks/common/blocksPlugin.class.php
new file mode 100644
index 0000000000..a1bb987ed7
--- /dev/null
+++ b/gforge/plugins/blocks/common/blocksPlugin.class.php
@@ -0,0 +1,156 @@
+
+ *
+ * This file is part of FusionForge.
+ *
+ * FusionForge is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * FusionForge is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FusionForge; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+/*
+ * Standard Alcatel-Lucent disclaimer for contributing to open source
+ *
+ * "The provided file ("Contribution") has not been tested and/or
+ * validated for release as or in products, combinations with products or
+ * other commercial use. Any use of the Contribution is entirely made at
+ * the user's own responsibility and the user can not rely on any features,
+ * functionalities or performances Alcatel-Lucent has attributed to the
+ * Contribution.
+ *
+ * THE CONTRIBUTION BY ALCATEL-LUCENT IS PROVIDED AS IS, WITHOUT WARRANTY
+ * OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, COMPLIANCE,
+ * NON-INTERFERENCE AND/OR INTERWORKING WITH THE SOFTWARE TO WHICH THE
+ * CONTRIBUTION HAS BEEN MADE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * ALCATEL-LUCENT BE LIABLE FOR ANY DAMAGES OR OTHER LIABLITY, WHETHER IN
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * CONTRIBUTION OR THE USE OR OTHER DEALINGS IN THE CONTRIBUTION, WHETHER
+ * TOGETHER WITH THE SOFTWARE TO WHICH THE CONTRIBUTION RELATES OR ON A STAND
+ * ALONE BASIS."
+ */
+
+class blocksPlugin extends Plugin {
+ function blocksPlugin () {
+ $this->Plugin() ;
+ $this->name = "blocks" ;
+ $this->text = "Blocks" ; // To show in the tabs, use...
+ $this->hooks[] = "groupisactivecheckbox" ; // The "use ..." checkbox in editgroupinfo
+ $this->hooks[] = "groupisactivecheckboxpost" ; //
+ $this->hooks[] = "project_admin_plugins"; // to show up in the admin page fro group
+ $this->hooks[] = "blocks"; // to show up in the admin page fro group
+ }
+
+ function CallHook ($hookname, $params) {
+ global $use_blocksplugin,$G_SESSION,$HTML;
+ $group_id=$params['group'];
+ if ($hookname == "groupisactivecheckbox") {
+ //Check if the group is active
+ // this code creates the checkbox in the project edit public info page to activate/deactivate the plugin
+ $group = &group_get_object($group_id);
+ echo "";
+ echo "";
+ echo ' usesPlugin ( $this->name ) ) {
+ echo "checked=\"checked\"";
+ }
+ echo " /> ";
+ echo " ";
+ echo "";
+ echo "Use ".$this->text." Plugin ";
+ echo " ";
+ echo " ";
+ } elseif ($hookname == "groupisactivecheckboxpost") {
+ // this code actually activates/deactivates the plugin after the form was submitted in the project edit public info page
+ $group = &group_get_object($group_id);
+ $use_blocksplugin = getStringFromRequest('use_blocksplugin');
+ if ( $use_blocksplugin == 1 ) {
+ $group->setPluginUse ( $this->name );
+ } else {
+ $group->setPluginUse ( $this->name, false );
+ }
+ } elseif ($hookname == "project_admin_plugins") {
+ // this displays the link in the project admin options page to it's blocks administration
+ $group_id = $params['group_id'];
+ $group = &group_get_object($group_id);
+ if ( $group->usesPlugin ( $this->name ) ) {
+ echo '' . _("Blocks Admin") . '
';
+ }
+ }
+ elseif ($hookname == "blocks") {
+ // Check if block is active and if yes, display the block.
+ // Return true if plugin is active, false otherwise.
+ $group = &group_get_object($GLOBALS['group_id']);
+ if ( $group && $group->usesPlugin ( $this->name ) ) {
+
+ $c =& $this->renderBlock($params);
+ if ($c !== false) {
+ echo $c;
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ function renderBlock($name) {
+ $group_id = $GLOBALS['group_id'];
+ $res = db_query_params('SELECT content
+ FROM plugin_blocks
+ WHERE group_id=$1
+ AND name=$2
+ AND status=1',
+ array($group_id, $name)); // 1 is for active
+ if (db_numrows($res)== 0) {
+ return false;
+ } else {
+ $content = db_result($res,0,"content");
+ if ($content) {
+ return $this->parseContent($content).' ';
+ } else {
+ return " ";
+ }
+ }
+ }
+
+ function parseContent($t) {
+ global $HTML;
+
+ $t =& preg_replace('/{boxTop (.*?)}<\/p>/ie', '$HTML->boxTop("$1")', $t);
+ $t =& preg_replace('/{boxTop (.*?)}/ie', '$HTML->boxTop("$1")', $t);
+ $t =& preg_replace('/
{boxMiddle (.*?)}<\/p>/ie', '$HTML->boxMiddle("$1")', $t);
+ $t =& preg_replace('/{boxMiddle (.*?)}/ie', '$HTML->boxMiddle("$1")', $t);
+ $t =& preg_replace('/
{boxBottom}<\/p>/i', $HTML->boxBottom(), $t);
+ $t =& preg_replace('/{boxBottom}/i', $HTML->boxBottom(), $t);
+
+ $t =& preg_replace('/
{boxHeader}/i', '
', $t);
+ $t =& preg_replace('/{boxHeader}/i', ' ', $t);
+ $t =& preg_replace('/{boxFooter}<\/p>/i', ' ', $t);
+ $t =& preg_replace('/{boxFooter}/i', ' ', $t);
+
+ return $t;
+ }
+}
+
+// Local Variables:
+// mode: php
+// c-file-style: "bsd"
+// End:
+
+?>
diff --git a/gforge/plugins/blocks/db/blocks-init.sql b/gforge/plugins/blocks/db/blocks-init.sql
new file mode 100755
index 0000000000..fb08b8e830
--- /dev/null
+++ b/gforge/plugins/blocks/db/blocks-init.sql
@@ -0,0 +1,14 @@
+CREATE SEQUENCE plugin_blocks_pk_seq
+ START WITH 1
+ INCREMENT BY 1
+ MAXVALUE 2147483647
+ NO MINVALUE
+ CACHE 1;
+
+CREATE TABLE plugin_blocks (
+ id integer DEFAULT nextval('plugin_blocks_pk_seq'::text) NOT NULL,
+ group_id integer,
+ name text,
+ content text,
+ status integer
+) ;
diff --git a/tests/func/News/AllTests.php b/gforge/plugins/blocks/etc/plugins/blocks/config.php
similarity index 69%
rename from tests/func/News/AllTests.php
rename to gforge/plugins/blocks/etc/plugins/blocks/config.php
index 1b4db269cf..ba95a554ab 100644
--- a/tests/func/News/AllTests.php
+++ b/gforge/plugins/blocks/etc/plugins/blocks/config.php
@@ -1,7 +1,7 @@
- * Copyright (C) 2009 Alain Peyrat, Alcatel-Lucent
+ * Copyright (C) 2006 Alain Peyrat, Alcatel-Lucent
*
* This file is part of FusionForge.
*
@@ -9,7 +9,7 @@
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
- *
+ *
* FusionForge is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
@@ -24,7 +24,7 @@
/*
* Standard Alcatel-Lucent disclaimer for contributing to open source
*
- * "The test suite ("Contribution") has not been tested and/or
+ * "The provided file ("Contribution") has not been tested and/or
* validated for release as or in products, combinations with products or
* other commercial use. Any use of the Contribution is entirely made at
* the user's own responsibility and the user can not rely on any features,
@@ -42,34 +42,10 @@
* TOGETHER WITH THE SOFTWARE TO WHICH THE CONTRIBUTION RELATES OR ON A STAND
* ALONE BASIS."
*/
-
-if (!defined('PHPUnit_MAIN_METHOD')) {
- define('PHPUnit_MAIN_METHOD', 'News_AllTests::main');
-}
-
-require_once 'PHPUnit/Framework.php';
-require_once 'PHPUnit/TextUI/TestRunner.php';
-
-require_once dirname(__FILE__).'/news.php';
-
-class News_AllTests
-{
- public static function main()
- {
- PHPUnit_TextUI_TestRunner::run(self::suite());
- }
-
- public static function suite()
- {
- $suite = new PHPUnit_Framework_TestSuite('PHPUnit Framework');
-
- $suite->addTestSuite('CreateNews');
-
- return $suite;
- }
-}
-if (PHPUnit_MAIN_METHOD == 'News_AllTests::main') {
- Framework_AllTests::main();
-}
+$plugins_blocks_templates = array(
+ 'summary_right' => "{boxTop Project}\nEnter your text here\n{boxBottom}",
+ 'summary_description' => "Enter your description here",
+ '*' => "{boxHeader}Enter your text here{boxFooter}");
+
?>
diff --git a/gforge/plugins/blocks/www/index.php b/gforge/plugins/blocks/www/index.php
new file mode 100644
index 0000000000..3d39586fd0
--- /dev/null
+++ b/gforge/plugins/blocks/www/index.php
@@ -0,0 +1,418 @@
+
+ *
+ * This file is part of FusionForge.
+ *
+ * FusionForge is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * FusionForge is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FusionForge; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+/*
+ * Standard Alcatel-Lucent disclaimer for contributing to open source
+ *
+ * "The provided file ("Contribution") has not been tested and/or
+ * validated for release as or in products, combinations with products or
+ * other commercial use. Any use of the Contribution is entirely made at
+ * the user's own responsibility and the user can not rely on any features,
+ * functionalities or performances Alcatel-Lucent has attributed to the
+ * Contribution.
+ *
+ * THE CONTRIBUTION BY ALCATEL-LUCENT IS PROVIDED AS IS, WITHOUT WARRANTY
+ * OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, COMPLIANCE,
+ * NON-INTERFERENCE AND/OR INTERWORKING WITH THE SOFTWARE TO WHICH THE
+ * CONTRIBUTION HAS BEEN MADE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * ALCATEL-LUCENT BE LIABLE FOR ANY DAMAGES OR OTHER LIABLITY, WHETHER IN
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * CONTRIBUTION OR THE USE OR OTHER DEALINGS IN THE CONTRIBUTION, WHETHER
+ * TOGETHER WITH THE SOFTWARE TO WHICH THE CONTRIBUTION RELATES OR ON A STAND
+ * ALONE BASIS."
+ */
+
+require_once dirname(__FILE__)."/../../env.inc.php";
+require_once $gfwww.'include/pre.php';
+require_once $gfconfig.'plugins/blocks/config.php' ;
+
+require_once $gfcommon.'forum/ForumFactory.class.php';
+require_once $gfcommon.'tracker/ArtifactFactory.class.php';
+require_once $gfcommon.'mail/MailingListFactory.class.php';
+require_once $gfcommon.'pm/ProjectGroupFactory.class.php';
+require_once $gfcommon.'survey/SurveyFactory.class.php';
+
+function getAvailableBlocks($group) {
+ $blocks = array(
+ 'summary_description' =>
+ _("Block to replace the default project description with an enhanced one."),
+ 'summary_right' =>
+ _("Block in the summary page (right)"),
+ 'request_join' =>
+ _("Block to list informations requested to ask to join a project"),
+ );
+
+ if ($group->usesForum()) {
+ // Get the blocks in the forums.
+ $blocks['forum index'] = _("Display block at the top of the listing");
+ $ff = new ForumFactory($group);
+ foreach ( $ff->getForums() as $f) {
+ $blocks['forum_'.$f->getName()] = _("Display block at the top");
+ }
+ }
+
+ if ($group->usesTracker()) {
+ // Get the blocks in the trackers.
+ $blocks['tracker index'] = _("Display block at the top of the listing");
+ $ff = new ArtifactTypeFactory($group);
+ foreach ( $ff->getArtifactTypes() as $f) {
+ $blocks['tracker_'.$f->getName()] = _("Display block at the top");
+ }
+ }
+
+ if ($group->usesMail()) {
+ // Get the blocks in the mailing lists.
+ $blocks['mail index'] = _("Display block at the top of the listing");
+ $ff = new MailingListFactory($group);
+ foreach ( $ff->getMailingLists() as $f) {
+ $blocks['mail_'.$f->getName()] = _("Display block at the top");
+ }
+ }
+
+ if ($group->usesPM()) {
+ // Get the blocks in the tasks.
+ $blocks['tasks index'] = _("Display block at the top of the listing");
+ $ff = new ProjectGroupFactory($group);
+ foreach ( $ff->getProjectGroups() as $f) {
+ $blocks['tasks_'.$f->getName()] = _("Display block at the top");
+ }
+ }
+
+ if ($group->usesDocman()) {
+ // Get the blocks in the doc.
+ $blocks['doc index'] = _("Display block at the top of the listing");
+ }
+
+ if ($group->usesSurvey()) {
+ // Get the blocks in the survey.
+ $blocks['survey index'] = _("Display block at the top of the listing");
+ $ff = new SurveyFactory($group);
+ foreach ( $ff->getSurveys() as $f) {
+ $blocks['survey_'.$f->getTitle()] = _("Display block at the top");
+ }
+ }
+
+ if ($group->usesNews()) {
+ // Get the blocks in the news.
+ $blocks['news index'] = _("Display block at the top of the listing");
+ }
+
+ if ($group->usesSCM()) {
+ // Get the blocks in the scm.
+ $blocks['scm index'] = _("Display block at the top of the listing");
+ }
+
+ if ($group->usesFRS()) {
+ // Get the blocks in the files.
+ $blocks['files index'] = _("Display block at the top of the listing");
+ }
+
+ return $blocks;
+}
+
+// the header that displays for the user portion of the plugin
+function blocks_Project_Header($params) {
+ global $DOCUMENT_ROOT,$HTML,$id;
+ $params['toptab']='blocks';
+ $params['group']=$id;
+ /*
+ Show horizontal links
+ */
+ site_project_header($params);
+}
+
+$user = session_get_user(); // get the session user
+
+if (!$user || !is_object($user) || $user->isError() || !$user->isActive()) {
+ exit_error("Invalid User", "Cannot Process your request for this user.");
+}
+
+$type = getStringFromRequest('type');
+$id = getStringFromRequest('id');
+$pluginname = getStringFromRequest('pluginname');
+$name = getStringFromRequest('name');
+$body = getStringFromRequest('body');
+$activate = getArrayFromRequest('activate');
+
+$blocks_text = array(
+ 'forum' => _('Forums'),
+ 'tracker' => _('Trackers'),
+ 'mail' => _('Lists'),
+ 'tasks' => _('Tasks'),
+ 'doc' => _('Docs'),
+ 'survey' => _('Surveys'),
+ 'news' => _('News'),
+ 'scm' => _('SCM'),
+ 'files' => _('Files')
+);
+
+if (!$type) {
+ exit_error("Cannot Process your request","No TYPE specified"); // you can create items in Base.tab and customize this messages
+} elseif (!$id) {
+ exit_error("Cannot Process your request","No ID specified");
+} else {
+ if ($type == 'group') {
+ $group = group_get_object($id);
+ if ( !$group) {
+ exit_error("Invalid Project", "Inexistent Project");
+ }
+ if ( ! ($group->usesPlugin ( $pluginname )) ) {//check if the group has the blocks plugin active
+ exit_error("Error", "First activate the $pluginname plugin through the Project's Admin Interface");
+ }
+ $userperm = $group->getPermission($user);//we'll check if the user belongs to the group (optional)
+ if ( !$userperm->IsMember()) {
+ exit_error("Access Denied", "You are not a member of this project");
+ }
+ // other perms checks here...
+ blocks_Project_Header(array('title'=>$pluginname . ' Project Plugin!','pagename'=>"$pluginname",'sectionvals'=>array(group_getname($id))));
+ // DO THE STUFF FOR THE PROJECT PART HERE
+ echo "We are in the Project blocks plugin ";
+ echo "Greetings from planet " . $world; // $world comes from the config file in /etc
+ } elseif ($type == 'admin') {
+ $group = group_get_object($id);
+ if ( !$group) {
+ exit_error("Invalid Project", "Inexistent Project");
+ }
+ if ( ! ($group->usesPlugin ( $pluginname )) ) {//check if the group has the blocks plugin active
+ exit_error("Error", "First activate the $pluginname plugin through the Project's Admin Interface");
+ }
+ $userperm = $group->getPermission($user);//we'll check if the user belongs to the group
+ if ( !$userperm->IsMember()) {
+ exit_error("Access Denied", "You are not a member of this project");
+ }
+ //only project admin can access here
+ if ( $userperm->isAdmin() ) {
+ blocks_Project_Header(array('title'=>$pluginname . ' Project Plugin!','pagename'=>"$pluginname",'sectionvals'=>array(group_getname($id))));
+ // DO THE STUFF FOR THE PROJECT ADMINISTRATION PART HERE
+
+ $res = db_query_params('SELECT name, status FROM plugin_blocks WHERE group_id=$1',
+ array($id));
+ while ($row = db_fetch_array($res)) {
+ $status[ $row['name'] ] = $row['status'];
+ }
+
+ print _("Blocks are customizable HTML boxes in the left or right side of the pages the web site. They are created manually.");
+
+ print "
";
+ } else {
+ exit_error("Access Denied", "You are not a project Admin");
+ }
+ } elseif ($type == 'admin_post') {
+ $group = group_get_object($id);
+ if ( !$group) {
+ exit_error("Invalid Project", "Inexistent Project");
+ }
+ if ( ! ($group->usesPlugin ( $pluginname )) ) {//check if the group has the blocks plugin active
+ exit_error("Error", "First activate the $pluginname plugin through the Project's Admin Interface");
+ }
+ $userperm = $group->getPermission($user);//we'll check if the user belongs to the group
+ if ( !$userperm->IsMember()) {
+ exit_error("Access Denied", "You are not a member of this project");
+ }
+ //only project admin can access here
+ if ( $userperm->isAdmin() ) {
+ $res = db_query_params('SELECT name, status FROM plugin_blocks WHERE group_id=$1',
+ array($id));
+ while ($row = db_fetch_array($res)) {
+ $present[ $row['name'] ] = true;
+ $status[ $row['name'] ] = $row['status'];
+ }
+ $blocks = getAvailableBlocks($group);
+
+ // Workaround when a block has a name with a & inside.
+ // It seems sadly converted by the form (or php?).
+ foreach ($activate as $k => $v) {
+ $nk = str_replace("&","&", $k);
+ if ($nk !== $k) {
+ $activate[$nk] = $v;
+ unset($activate[$k]);
+ }
+ }
+
+ foreach ($blocks as $b => $help) {
+
+ if (!$activate[$b])
+ $activate[$b] = 0;
+
+ if ((!isset($status[$b]) && $activate[$b]) ||
+ (isset($status[$b]) && $activate[$b] !== $status[$b]))
+ // Must be updated.
+ if (!isset($present[$b])) {
+ db_query_params('INSERT INTO plugin_blocks (group_id, name, status)
+ VALUES ($1, $2, $3)',
+ array($id, $b, $activate[$b]));
+ } else {
+ db_query_params('UPDATE plugin_blocks SET status=$1
+ WHERE group_id=$2 AND name=$3',
+ array($activate[$b], $id, $b));
+ }
+ }
+ header("Location: /plugins/blocks/index.php?id=$id&type=admin&pluginname=blocks");
+ exit;
+ } else {
+ exit_error("Access Denied", "You are not a project Admin");
+ }
+ } elseif ($type == 'configure') {
+ $group = group_get_object($id);
+ if ( !$group) {
+ exit_error("Invalid Project", "Inexistent Project");
+ }
+ if ( ! ($group->usesPlugin ( $pluginname )) ) {//check if the group has the blocks plugin active
+ exit_error("Error", "First activate the $pluginname plugin through the Project's Admin Interface");
+ }
+ $userperm = $group->getPermission($user);//we'll check if the user belongs to the group
+ if ( !$userperm->IsMember()) {
+ exit_error("Access Denied", "You are not a member of this project");
+ }
+ //only project admin can access here
+ if ( $userperm->isAdmin() ) {
+ blocks_Project_Header(array('title'=>$pluginname . ' Project Plugin!','pagename'=>"$pluginname",'sectionvals'=>array(group_getname($id))));
+ // DO THE STUFF FOR THE PROJECT ADMINISTRATION PART HERE
+
+ $res = db_query_params('SELECT content FROM plugin_blocks WHERE group_id=$1 AND name=$2',
+ array($id, $name));
+ $body = db_result($res,0,"content");
+
+ print _("Edit the block as you want. If you activate the HTML editor, you will be able to use WYSIWYG formatting (bold, colors...)");
+
+ print "";
+ print "$blocks[$name] ($name)";
+ print "";
+ print " ";
+
+ print "".
+ _("Tips").
+ " " .
+ _("You can create boxes like the ones on the right site of summary page, by inserting the following sentences in the content:
{boxTop Hello}: will create the top part of the box using Hello as title. {boxMiddle Here}: will create a middle part of a box using Here as title (optional). {boxBottom}: will create the end part of a box.
{boxHeader}: will create a header before a text. {boxFooter}: will create a footer after a text. You can create as many boxes as you want, but a boxTop has to be closed by a boxBottom and a boxHeader has to be closed by a boxFooter.
").
+ " ";
+ } else {
+ exit_error("Access Denied", "You are not a project Admin");
+ }
+ } elseif ($type == 'configure_post') {
+ $group = group_get_object($id);
+ if ( !$group) {
+ exit_error("Invalid Project", "Inexistent Project");
+ }
+ if ( ! ($group->usesPlugin ( $pluginname )) ) {//check if the group has the blocks plugin active
+ exit_error("Error", "First activate the $pluginname plugin through the Project's Admin Interface");
+ }
+ $userperm = $group->getPermission($user);//we'll check if the user belongs to the group
+ if ( !$userperm->IsMember()) {
+ exit_error("Access Denied", "You are not a member of this project");
+ }
+ //only project admin can access here
+ if ( $userperm->isAdmin() ) {
+ $res = db_query_params('SELECT id FROM plugin_blocks WHERE group_id=$1 AND name=$2',
+ array($id,$name));
+ if (db_numrows($res)== 0) {
+ db_query_params('INSERT INTO plugin_blocks (group_id, name, content)
+ VALUES ($1, $2, $3)',
+ array($id, $name, $body));
+ } else {
+ db_query_params('UPDATE plugin_blocks SET content=$1
+ WHERE group_id=$2 AND name=$3',
+ array($body, $id, $name));
+ }
+ header("Location: /plugins/blocks/index.php?id=$id&type=admin&pluginname=blocks");
+ exit;
+ } else {
+ exit_error("Access Denied", "You are not a project Admin");
+ }
+ }
+}
+
+site_project_footer(array());
+
+?>
diff --git a/gforge/plugins/createplugin.sh b/gforge/plugins/createplugin.sh
deleted file mode 100755
index a3823d48ae..0000000000
--- a/gforge/plugins/createplugin.sh
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/bin/sh
-
-modelfullname=HelloWorld
-modelminus=`echo $modelfullname | tr '[A-Z]' '[a-z]'`
-modelplugdir=$modelminus
-
-usage() {
- echo Usage: $0 PluginName
-}
-
-echo "Plugin template creator"
-if [ "$#" != "1" ]
-then
- usage
-else
- fullname=$1
- minus=`echo $1 | tr '[A-Z]' '[a-z]'`
- plugdir=$minus
- echo "Creating $1 plugin"
- echo "Creating directory $plugdir"
- [ ! -d $plugdir ] && mkdir $plugdir
- [ ! -d $plugdir/bin ] && mkdir $plugdir/bin
- [ ! -d $plugdir/etc/plugins/$minus ] && mkdir -p $plugdir/etc/plugins/$minus
- [ ! -d $plugdir/common/languages ] && mkdir -p $plugdir/common/languages
- [ ! -d $plugdir/www ] && mkdir $plugdir/www
-
- if [ ! -f $plugdir/common/${fullname}Plugin.class.php ]
- then
- echo Creating $plugdir/common/${fullname}Plugin.class.php
- cat $modelplugdir/common/${modelfullname}Plugin.class.php | \
- sed "s/$modelminus/$minus/g" | \
- sed "s/$modelfullname/$fullname/g" > \
- $plugdir/common/${fullname}Plugin.class.php
- fi
- if [ ! -f $plugdir/common/$minus-init.php ]
- then
- echo Creating $plugdir/common/$minus-init.php
- cat $modelplugdir/common/$modelminus-init.php | \
- sed "s/$modelminus/$minus/g" | \
- sed "s/$modelfullname/$fullname/g" > \
- $plugdir/common/$minus-init.php
- fi
- if [ ! -f $plugdir/www/index.php ]
- then
- echo Creating $plugdir/www/index.php
- cat $modelplugdir/www/index.php | \
- sed "s/$modelminus/$minus/g" | \
- sed "s/$modelfullname/$fullname/g" > \
- $plugdir/www/index.php
- fi
-# if [ ! -f $plugdir/common/languages/Base.tab ]
-# then
-# echo Creating $plugdir/common/languages/Base.tab
-# cat $modelplugdir/common/languages/Base.tab | \
-# sed "s/$modelminus/$minus/g" | \
-# sed "s/$modelfullname/$fullname/g" > \
-# $plugdir/common/languages/Base.tab
-# fi
-fi
diff --git a/gforge/plugins/cvssyncmail/db/cvssyncmail-init.sql b/gforge/plugins/cvssyncmail/db/cvssyncmail-init.sql
deleted file mode 100644
index 60a2a131a0..0000000000
--- a/gforge/plugins/cvssyncmail/db/cvssyncmail-init.sql
+++ /dev/null
@@ -1 +0,0 @@
-INSERT INTO plugins (plugin_name,plugin_desc) VALUES ('cvssyncmail','CVS Syncmail Plugin');
diff --git a/gforge/plugins/cvstracker/common/cvstrackerPlugin.class.php b/gforge/plugins/cvstracker/common/cvstrackerPlugin.class.php
index 81a43aef25..a98f0b2807 100644
--- a/gforge/plugins/cvstracker/common/cvstrackerPlugin.class.php
+++ b/gforge/plugins/cvstracker/common/cvstrackerPlugin.class.php
@@ -165,19 +165,19 @@ class cvstrackerPlugin extends Plugin {
*
*/
function addCvsTrackerToFile($group, $path) {
- global $sys_plugins_path, $sys_users_host, $cvs_binary_version;
+ global $cvs_binary_version;
$FOut = fopen($path, "a");
if($FOut) {
fwrite($FOut, "# BEGIN added by gforge-plugin-cvstracker\n");
if ( $cvs_binary_version == "1.12" ) {
$Line = "ALL ( php -q -d include_path=".ini_get('include_path').
- " ".$sys_plugins_path."/cvstracker/bin/post.php
+ " ".forge_get_config('plugins_path')."/cvstracker/bin/post.php
%r %p %{sVv} )\n";
}
if ( $cvs_binary_version == "1.11") {
$Line = "ALL ( php -q -d include_path=".ini_get('include_path').
- " ".$sys_plugins_path."/cvstracker/bin/post.php
+ " ".forge_get_config('plugins_path')."/cvstracker/bin/post.php
".$group->getUnixName()." %{sVv} )\n";
}
fwrite($FOut,$Line);
@@ -193,16 +193,16 @@ class cvstrackerPlugin extends Plugin {
* return array with the loginfo lines.
*/
function getCvsTrackerLogInfoLines() {
- global $sys_plugins_path, $sys_users_host, $cvs_binary_version;
+ global $cvs_binary_version;
$array=array();
$array[]="# BEGIN added by gforge-plugin-cvstracker\n";
if ( $cvs_binary_version == "1.11" ) {
$array[] = "ALL ( php -q -d include_path=".ini_get('include_path').
- " ".$sys_plugins_path."/cvstracker/bin/post.php
+ " ".forge_get_config('plugins_path')."/cvstracker/bin/post.php
".$group->getUnixName()." %{sVv} )\n";
}else { //it's version 1.12
$array[] = "ALL ( php -q -d include_path=".ini_get('include_path').
- " ".$sys_plugins_path."/cvstracker/bin/post.php
+ " ".forge_get_config('plugins_path')."/cvstracker/bin/post.php
%r %p %{sVv} )\n";
}
$array[]= "# END added by gforge-plugin-cvstracker\n";
diff --git a/gforge/plugins/externalsearch/etc/plugins/externalsearch/config.php b/gforge/plugins/externalsearch/etc/plugins/externalsearch/config.php
index e90097c5f3..dea190f391 100644
--- a/gforge/plugins/externalsearch/etc/plugins/externalsearch/config.php
+++ b/gforge/plugins/externalsearch/etc/plugins/externalsearch/config.php
@@ -1,8 +1,8 @@
'http://www.google.com/search?as_sitesearch='.$GLOBALS['sys_default_domain'].'&as_q=',
- 'AllTheWeb' => 'http://alltheweb.com/search?advanced=1&dincl='.$GLOBALS['sys_default_domain'].'&q='
+ 'Google' => 'http://www.google.com/search?as_sitesearch='.forge_get_config('web_host').'&as_q=',
+ 'AllTheWeb' => 'http://alltheweb.com/search?advanced=1&dincl='.forge_get_config('web_host').'&q='
);
// Local Variables:
diff --git a/gforge/plugins/extratabs/common/ExtraTabsPlugin.class.php b/gforge/plugins/extratabs/common/ExtraTabsPlugin.class.php
index 544958e76c..4f4866dc72 100644
--- a/gforge/plugins/extratabs/common/ExtraTabsPlugin.class.php
+++ b/gforge/plugins/extratabs/common/ExtraTabsPlugin.class.php
@@ -37,8 +37,8 @@ class ExtraTabsPlugin extends Plugin {
if ($hookname == "project_admin_plugins") {
$group_id=$params['group_id'];
- echo util_make_link ('/plugins/extratabs/index.php?group_id='.$group_id,
- _('Extra tabs')).' ';
+ echo ''.util_make_link ('/plugins/extratabs/index.php?group_id='.$group_id,
+ _('Extra tabs')).'
';
} elseif ($hookname == "groupmenu") {
$group_id=$params['group'];
$project = &group_get_object($group_id);
diff --git a/gforge/plugins/extratabs/common/extratabs-init.php b/gforge/plugins/extratabs/common/extratabs-init.php
index 8e8d08a073..ca0969a18c 100644
--- a/gforge/plugins/extratabs/common/extratabs-init.php
+++ b/gforge/plugins/extratabs/common/extratabs-init.php
@@ -1,6 +1,6 @@
$group_id,'admin_flags'=>'A'));
// get current information
@@ -36,30 +39,46 @@ $selected = 0; // No item selected by default
// Do work before displaying so that the result is immediately visible
if (getStringFromRequest ('addtab') != '') {
- $tab_name = htmlspecialchars(trim(getStringFromRequest ('tab_name')));
- $tab_url = htmlspecialchars(trim(getStringFromRequest ('tab_url')));
- $res = db_query_params ('INSERT INTO plugin_extratabs_main (group_id, index, tab_name, tab_url) VALUES ($1,$2,$3,$4)',
- array ($group_id,
- $newid,
- $tab_name,
- $tab_url)) ;
- if (!$res || db_affected_rows($res) < 1) {
- $feedback = sprintf (_('Cannot insert new tab entry: %s'),
- db_error());
+ if ($tab_name == '' || $tab_url == '' || $tab_url == 'http://') {
+ $error_msg = _('ERROR: Missing Name or URL for the new tab');
+ } else if (!util_check_url($tab_url)) {
+ $error_msg = _('ERROR: Malformed URL (only http, https and ftp allowed)');
} else {
- $feedback = _('Tab added');
+ $res = db_query_params('SELECT * FROM plugin_extratabs_main WHERE group_id=$1 AND tab_name=$2',
+ array($group_id, $tab_name));
+ if ($res && db_numrows($res) > 0) {
+ $error_msg = _('ERROR: Name for tab is already used.');
+ } else {
+ $res = db_query_params ('INSERT INTO plugin_extratabs_main (group_id, index, tab_name, tab_url) VALUES ($1,$2,$3,$4)',
+ array ($group_id,
+ $newid,
+ $tab_name,
+ $tab_url)) ;
+ if (!$res || db_affected_rows($res) < 1) {
+ $feedback = sprintf (_('Cannot insert new tab entry: %s'),
+ db_error());
+ } else {
+ $tab_name = '';
+ $tab_url = 'http://';
+ $feedback = _('Tab successfully added');
+ }
+ }
}
} elseif (getStringFromRequest ('delete') != '') {
$res = db_query_params ('DELETE FROM plugin_extratabs_main WHERE group_id=$1 AND index=$2',
array ($group_id,
$index)) ;
if (!$res || db_affected_rows($res) < 1) {
- $feedback = sprintf (_('Cannot delete tab entry: %s'),
- db_error());
+ $error_msg = sprintf (_('Cannot delete tab entry: %s'), db_error());
} else {
$res = db_query_params ('UPDATE plugin_extratabs_main SET index=index-1 WHERE group_id=$1 AND index > $2',
array ($group_id,
$index)) ;
+ if ($res) {
+ $feedback = _('Tab successfully deleted');
+ } else {
+ $error_msg = sprintf (_('Cannot delete tab entry: %s'), db_error());
+ }
}
} elseif (getStringFromRequest ('up') != '') {
if ($index > 1) {
@@ -75,8 +94,10 @@ if (getStringFromRequest ('addtab') != '') {
array ($previous,
$group_id)) ;
$selected = $previous;
+ $feedback = _('Tab successfully moved');
} else {
- $selected = $index;
+ $warning_msg = _('Tab not moved, already at first position');
+ $selected = $index;
}
} elseif (getStringFromRequest ('down') != '') {
if ($index < $newid - 1) {
@@ -91,9 +112,11 @@ if (getStringFromRequest ('addtab') != '') {
$res = db_query_params('UPDATE plugin_extratabs_main SET index=$1 WHERE group_id=$2 AND index=0',
array ($next,
$group_id)) ;
+ $feedback = _('Tab successfully moved');
$selected = $next;
} else {
- $selected = $index;
+ $warning_msg = _('Tab not moved, already at last position');
+ $selected = $index;
}
}
if (!$res) {
@@ -107,24 +130,30 @@ project_admin_header(array('title'=>$adminheadertitle, 'group'=>$group->getID())
?>
-
+
+
+
-
-
+
+Add new tab
+
-
+
-
+
+
+
+
+
-
0) {
?>
-
-
+
-
+
-?>
-
+
+Move or delete tab
+
-
" . $row['tab_name'] . "";
+ echo "" . $row['tab_name'] . " ";
} else {
echo "" . $row['tab_name'] . " ";
}
} ?>
-
+
+
+
1) { ?>
-
-
+
+
+
+
-
'1','admin_flags'=>'A'));
-include_once($GLOBALS['sys_plugins_path'].'/globalsearch/common/globalsearch_edit_utils.php');
+include_once(forge_get_config('plugins_path').'/globalsearch/common/globalsearch_edit_utils.php');
$HTML->header(array('title'=>_('Edit associated forges for global search')));
diff --git a/gforge/plugins/helloworld/db/helloworld-init.sql b/gforge/plugins/helloworld/db/helloworld-init.sql
deleted file mode 100644
index 65738c2e6d..0000000000
--- a/gforge/plugins/helloworld/db/helloworld-init.sql
+++ /dev/null
@@ -1,6 +0,0 @@
-CREATE TABLE plugin_helloworld_sample_data (
- domain text,
- ip_address text
-) ;
-
-INSERT INTO plugins (plugin_name,plugin_desc) VALUES ('helloworld','HelloWorld GForge Plugin');
\ No newline at end of file
diff --git a/gforge/plugins/ldapextauth/etc/plugins/ldapextauth/mapping.php b/gforge/plugins/ldapextauth/etc/plugins/ldapextauth/mapping.php
index 07f56236dd..d44b088518 100644
--- a/gforge/plugins/ldapextauth/etc/plugins/ldapextauth/mapping.php
+++ b/gforge/plugins/ldapextauth/etc/plugins/ldapextauth/mapping.php
@@ -14,7 +14,7 @@ function plugin_ldapextauth_mapping ($entry) {
// Defines new user email address, from LDAP or based on forge domain.
$result['email'] = $entry['mail'][0] ;
- //$result['email'] = $entry['uid'][0] . '@' . $GLOBALS['sys_default_domain'] ;
+ //$result['email'] = $entry['uid'][0] . '@' . forge_get_config('web_host') ;
// Defines new user theme, causes error if left blank.
$result['themeid']=$GLOBALS['sys_default_theme_id'];
@@ -26,9 +26,9 @@ function plugin_ldapextauth_mapping ($entry) {
//$result['phone'] = $entry['telephonenumber'][0]; //AD
//$result['fax'] = '' ;
//$result['title'] = '' ;
- //$result['ccode']=$GLOBALS['sys_default_country_code'];
+ //$result['ccode']=forge_get_config('default_country_code');
//$result['language_id'] = '' ;
- //$result['timezone']=$GLOBALS['sys_default_timezone'];
+ //$result['timezone']=forge_get_config('default_timezone');
return $result ;
}
diff --git a/gforge/plugins/mantis/lib/mantis-init.sql b/gforge/plugins/mantis/lib/mantis-init.sql
deleted file mode 100644
index 288111ea1e..0000000000
--- a/gforge/plugins/mantis/lib/mantis-init.sql
+++ /dev/null
@@ -1 +0,0 @@
-INSERT INTO plugins (plugin_name,plugin_desc) VALUES ('mantis','Mantis GForge Plugin');
\ No newline at end of file
diff --git a/gforge/plugins/mediawiki/bin/drop-wiki.php b/gforge/plugins/mediawiki/bin/drop-wiki.php
new file mode 100644
index 0000000000..770095cf37
--- /dev/null
+++ b/gforge/plugins/mediawiki/bin/drop-wiki.php
@@ -0,0 +1,64 @@
+#! /usr/bin/php5
+\n";
+ exit (0);
+}
+
+array_shift($argv);
+foreach ($argv as $project) {
+ echo "Removing project wiki of $project.\n";
+
+ $project_dir = "$mediawiki_projects_path/$project";
+ echo " Deleting project subdir $project_dir.\n";
+ if (!is_dir($project_dir)) {
+ echo "$project_dir does not exist!\n";
+ } else {
+ system("rm -rf $project_dir");
+ }
+
+ $schema = "plugin_mediawiki_$project";
+ strtr($schema, "-", "_");
+ echo " Dropping database schema $schema.\n";
+ $res = db_query_params("DROP SCHEMA $schema CASCADE", array());
+ if (!$res) {
+ echo db_error();
+ }
+}
+
+ // Local Variables:
+ // mode: php
+ // c-file-style: "bsd"
+ // End:
+
+?>
+
diff --git a/gforge/plugins/mediawiki/bin/drop-wiki.sh b/gforge/plugins/mediawiki/bin/drop-wiki.sh
deleted file mode 100755
index 4b181b1f75..0000000000
--- a/gforge/plugins/mediawiki/bin/drop-wiki.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#! /bin/sh
-
-# Usage: drop-wiki.sh
-
-project=$1
-
-wdprefix=/var/lib/gforge/plugins/mediawiki/wikidata
-
-# Minimal sanitisation of project name
-project=$(echo $project | sed s/[^-a-zA-Z0-9_]//g)
-if [ -d $wdprefix/$project ] ; then
- rm -r $wdprefix/$project
-fi
-
-schema=$(echo plugin_mediawiki_$project | sed s/-/_/g)
-su -s /bin/sh postgres -c "/usr/bin/psql gforge" <<-EOF
-DROP SCHEMA $schema CASCADE;
-EOF
diff --git a/gforge/plugins/mediawiki/bin/mw-wrapper.php b/gforge/plugins/mediawiki/bin/mw-wrapper.php
new file mode 100644
index 0000000000..5b8d381376
--- /dev/null
+++ b/gforge/plugins/mediawiki/bin/mw-wrapper.php
@@ -0,0 +1,69 @@
+#! /usr/bin/php5 -f
+
-
+
@@ -344,7 +344,7 @@ class ForumAdmin extends Error {
//$moderated_forums["A"] = "All Forums for this group"; // to show all
echo html_build_select_box_from_assoc($moderated_forums,forum_id,$forum_id);
- echo ' ';
+ echo ' ';
$title = array();
$title[] = _('Forum Name');
@@ -375,16 +375,15 @@ class ForumAdmin extends Error {
echo "
boxGetAltRowStyle($i++). ">
$onemsg[forum_name]
- $onemsg[subject]
+ $onemsg[subject]
" . html_build_select_box_from_assoc($options,"doaction[]",1) . "
";
}
echo $HTML->listTableBottom();
echo '
-
-
-
+
+
';
}
diff --git a/gforge/www/forum/admin/index.php b/gforge/www/forum/admin/index.php
index 0ed18837f4..dfeb6428f8 100644
--- a/gforge/www/forum/admin/index.php
+++ b/gforge/www/forum/admin/index.php
@@ -212,7 +212,7 @@ if ($group_id) {
//actually delete the message
$feedback .= $fa->ExecuteAction("delete");
forum_header(array('title'=>_('Delete a Message')));
- echo ''.util_make_link ('/forum/forum.php?forum_id=' . $forum_id, _("Return to the forum")) ;
+ echo '
'.util_make_link ('/forum/forum.php?forum_id=' . $forum_id, _("Return to the forum")) . '
';
forum_footer(array());
} elseif (getStringFromRequest("cancel")) {
// the user cancelled the request, go back to forum
@@ -480,6 +480,10 @@ if ($group_id) {
$fa = new ForumAdmin();
$fa->PrintAdminOptions();
}
+
+ if ($f)
+ plugin_hook ("blocks", "forum index");
+
//
// Get existing forums
//
diff --git a/gforge/www/forum/forum.php b/gforge/www/forum/forum.php
index c9e8aea6a9..038bbf739d 100644
--- a/gforge/www/forum/forum.php
+++ b/gforge/www/forum/forum.php
@@ -33,6 +33,7 @@ $thread_id = getIntFromRequest('thread_id');
$offset = getIntFromRequest('offset');
$max_rows = getIntFromRequest('max_rows');
$set = getStringFromRequest('set');
+$feedback = htmlspecialchars(getStringFromRequest('feedback'));
if ($forum_id) {
@@ -85,14 +86,14 @@ if ($forum_id) {
$sanitizer = new TextSanitizer();
$body = $sanitizer->SanitizeHtml($body);
-
+
$attach = getUploadedFile("attachment1");
if ($attach['size']) {
$has_attach = true;
} else {
$has_attach = false;
}
-
+
if (!$fm->create($subject, $body, $thread_id, $is_followup_to,$has_attach) || $fm->isError()) {
form_release_key(getStringFromRequest("form_key"));
exit_error(_('Error'),_('Error creating ForumMessage: ').$fm->getErrorMessage());
@@ -312,42 +313,44 @@ ORDER BY f.most_recent_date DESC',
echo db_error();
- $title_arr=array();
- $title_arr[]=_('Topic');
- $title_arr[]=_('Topic Starter');
- $title_arr[]=_('Replies');
- $title_arr[]=_('Last Post');
-
- $ret_val .= $GLOBALS['HTML']->listTableTop ($title_arr);
- $i=0;
- while (($row=db_fetch_array($result)) && ($i < $max_rows)) {
- $ret_val .= '
- boxGetAltRowStyle($i) .'>'.
- html_image('ic/cfolder15.png',"15","13",array("border"=>"0")) . ' ';
- /*
- See if this message is new or not
- If so, highlite it in bold
- */
- if ($f->getSavedDate() < $row['recent']) {
- $bold_begin='';
- $bold_end=' ';
- } else {
- $bold_begin='';
- $bold_end='';
+ if ($avail_rows > 0) {
+ $title_arr=array();
+ $title_arr[]=_('Topic');
+ $title_arr[]=_('Topic Starter');
+ $title_arr[]=_('Replies');
+ $title_arr[]=_('Last Post');
+
+ $ret_val .= $GLOBALS['HTML']->listTableTop ($title_arr);
+ $i=0;
+ while (($row=db_fetch_array($result)) && ($i < $max_rows)) {
+ $ret_val .= '
+ boxGetAltRowStyle($i) .'>'.
+ html_image('ic/cfolder15.png',"15","13",array("border"=>"0")) . ' ';
+ /*
+ See if this message is new or not
+ If so, highlite it in bold
+ */
+ if ($f->getSavedDate() < $row['recent']) {
+ $bold_begin='';
+ $bold_end=' ';
+ } else {
+ $bold_begin='';
+ $bold_end='';
+ }
+ /*
+ show the subject and poster
+ */
+ $ret_val .= $bold_begin.$row['subject'] .$bold_end.' '.
+ ''.$row['realname'].' '.
+ ''. $row['followups'] .' '.
+ ''.date(_('Y-m-d H:i'),$row['recent']).' ';
+ $i++;
}
- /*
- show the subject and poster
- */
- $ret_val .= $bold_begin.$row['subject'] .$bold_end.' '.
- ''.$row['realname'].' '.
- ''. $row['followups'] .' '.
- ''.date(_('Y-m-d H:i'),$row['recent']).' ';
- $i++;
- }
- $ret_val .= $GLOBALS['HTML']->listTableBottom();
+ $ret_val .= $GLOBALS['HTML']->listTableBottom();
+ }
}
/*
diff --git a/gforge/www/forum/include/ForumHTML.class.php b/gforge/www/forum/include/ForumHTML.class.php
index e8260b41ad..4e2493d22f 100644
--- a/gforge/www/forum/include/ForumHTML.class.php
+++ b/gforge/www/forum/include/ForumHTML.class.php
@@ -25,12 +25,12 @@ require_once $gfwww.'forum/admin/ForumAdmin.class.php';
require_once $gfwww.'forum/include/AttachManager.class.php';
function forum_header($params) {
- global $HTML,$group_id,$forum_name,$forum_id,$sys_news_group,$f,$sys_use_forum,$sys_use_trove,$group_forum_id;
+ global $HTML,$group_id,$forum_name,$forum_id,$sys_news_group,$f,$group_forum_id;
if ($group_forum_id) {
$forum_id=$group_forum_id;
}
- if (!$sys_use_forum) {
+ if (!forge_get_config('use_forum')) {
exit_disabled();
}
@@ -56,7 +56,7 @@ function forum_header($params) {
echo '';
if (!$result || db_numrows($result) < 1) {
- echo ''._('Error - this news item was not found').' ';
+ echo ''._('Error - this news item was not found').'
';
} else {
$user = user_get_object(db_result($result,0,'submitted_by'));
$group =& group_get_object($params['group']);
@@ -88,7 +88,7 @@ function forum_header($params) {
// display classification
if ($params['group'] == $sys_news_group) {
print stripslashes(trove_news_getcatlisting(db_result($result,0,'forum_id'),0,1));
- } elseif ($sys_use_trove) {
+ } elseif (forge_get_config('use_trove')) {
print stripslashes(trove_getcatlisting($params['group'],0,1));
}
}
@@ -130,6 +130,10 @@ function forum_header($params) {
$menu_links
);
}
+
+ $pluginManager = plugin_manager_get_object();
+ if ($f && $pluginManager->PluginIsInstalled('blocks') && plugin_hook ("blocks", "forum_".$f->getName()))
+ echo ' ';
if (session_loggedin() ) {
if ($f) {
diff --git a/gforge/www/forum/index.php b/gforge/www/forum/index.php
index 5f3fd1251a..f1a21c84ba 100644
--- a/gforge/www/forum/index.php
+++ b/gforge/www/forum/index.php
@@ -43,9 +43,10 @@ if ($group_id) {
}
forum_header(array('title'=>sprintf(_('Forums for %1$s'), $g->getPublicName()) ));
+ echo ''.sprintf(_('Forums for %1$s'), $g->getPublicName()) .' ';
if ($ff->isError() || count($farr) < 1) {
- echo ''.sprintf(_('No Forums Found For %1$s'), $g->getPublicName()) .' ';
+ echo ''.sprintf(_('No Forums Found for %1$s'), $g->getPublicName()) .'
';
if($ff->isError()) {
echo $ff->getErrorMessage();
}
@@ -57,6 +58,9 @@ if ($group_id) {
// echo _('Choose a forum and you can browse, search, and post messages.
');
echo $HTML->subMenu(array(_("My Monitored Forums")),array("/forum/myforums.php?group_id=$group_id"));
+
+ plugin_hook ("blocks", "forum index");
+
$tablearr=array(_('Forum'),_('Description'),_('Threads'),_('Posts'), _('Last Post'),_('Moderation Level'));
echo $HTML->listTableTop($tablearr);
diff --git a/gforge/www/frs/admin/deletepackage.php b/gforge/www/frs/admin/deletepackage.php
index a48f22811a..04de17ec17 100644
--- a/gforge/www/frs/admin/deletepackage.php
+++ b/gforge/www/frs/admin/deletepackage.php
@@ -52,14 +52,11 @@ if (!$frsp || !is_object($frsp)) {
}
/*
-
Relatively simple form to delete packages of releases
-
*/
-frs_admin_header(array('title'=>_('Release Edit/File Releases'),'group'=>$group_id));
+frs_admin_header(array('title'=>sprintf(_('Delete Package: %1$s'), $frsp->getName()),'group'=>$group_id));
- echo '
'.$frsp->getName().'
';
echo '
@@ -68,9 +65,10 @@ frs_admin_header(array('title'=>_('Release Edit/File Releases'),'group'=>$group_
'._('You are about to permanently and irretrievably delete this package and all its releases and files!').'
- '._('I\'m Sure').'
-
- '._('I\'m Really Sure').'
+ '._('I\'m Sure').'
+
+
+ '._('I\'m Really Sure').'
diff --git a/gforge/www/frs/admin/editrelease.php b/gforge/www/frs/admin/editrelease.php
index 63689a0afc..70b04780ee 100644
--- a/gforge/www/frs/admin/editrelease.php
+++ b/gforge/www/frs/admin/editrelease.php
@@ -71,12 +71,7 @@ if (!$frsr || !is_object($frsr)) {
exit_error('Error',$frsr->getErrorMessage());
}
-//we make sure we are not receiving $sys_ftp_upload_dir by POST or GET, to prevent security problems
-global $sys_ftp_upload_dir;
-if (!$sys_ftp_upload_dir) {
- exit_error('Error','External sys_ftp_upload_dir detected');
-}
-$upload_dir = $sys_ftp_upload_dir . "/" . $g->getUnixName();
+$upload_dir = forge_get_config('ftp_upload_dir') . "/" . $g->getUnixName();
/*
@@ -158,8 +153,8 @@ if (getStringFromRequest('step2')) {
$group_unix_name=group_getunixname($group_id);
$ftp_filename = getStringFromRequest('ftp_filename');
- if (($userfile && is_uploaded_file($userfile['tmp_name'])) || ($sys_use_ftpuploads && $ftp_filename)){
- if ($sys_use_ftpuploads && $ftp_filename && util_is_valid_filename($ftp_filename) && is_file($upload_dir.'/'.$ftp_filename)) {
+ if (($userfile && is_uploaded_file($userfile['tmp_name'])) || (forge_get_config('use_ftpuploads') && $ftp_filename)){
+ if (forge_get_config('use_ftpuploads') && $ftp_filename && util_is_valid_filename($ftp_filename) && is_file($upload_dir.'/'.$ftp_filename)) {
//file was uploaded already via ftp
//use setuid prog to chown it
//$cmd = escapeshellcmd("$sys_ftp_upload_chowner $ftp_filename");
@@ -302,27 +297,33 @@ frs_admin_header(array('title'=>_('Edit Releases'),'group'=>$group_id));
-
-Now, choose a file to upload into the system. The maximum file size is determined by the site administrator, but defaults to 2MB. If you need to upload large files, contact your site administrator.
') ?>
+
+
+
">
-
-
-
-
-:
-
+:
+';
- printf(_('Alternatively, you can use FTP to upload a new file at %1$s'), $sys_ftp_upload_host).' ';
+ printf(_('Alternatively, you can use FTP to upload a new file at %1$s'), forge_get_config('ftp_upload_host')).' ';
echo _('Choose an FTP file instead of uploading:').' ';
$arr[]='';
$ftp_files_arr=array_merge($arr,ls($upload_dir,true));
echo html_build_select_box_from_arrays($ftp_files_arr,$ftp_files_arr,'ftp_filename','',false); ?>
+
+
+)
+
+
+
+:
+
+
diff --git a/gforge/www/frs/admin/qrs.php b/gforge/www/frs/admin/qrs.php
index 3949273d61..308a8f0fcb 100644
--- a/gforge/www/frs/admin/qrs.php
+++ b/gforge/www/frs/admin/qrs.php
@@ -45,7 +45,7 @@ if (!$can_post) {
exit_permission_denied();
}
-$upload_dir = $sys_ftp_upload_dir . "/" . $g->getUnixName();
+$upload_dir = forge_get_config('ftp_upload_dir') . "/" . $g->getUnixName();
/*
Quick file release system , Darrell Brogdon, SourceForge, Aug, 2000
@@ -65,7 +65,7 @@ if (getStringFromRequest('submit')) {
$preformatted = getStringFromRequest('preformatted');
$ftp_filename = getStringFromRequest('ftp_filename');
$feedback = '' ;
- if ($sys_use_ftpuploads && $ftp_filename && util_is_valid_filename($ftp_filename) && is_file($upload_dir.'/'.$ftp_filename)) {
+ if (forge_get_config('use_ftpuploads') && $ftp_filename && util_is_valid_filename($ftp_filename) && is_file($upload_dir.'/'.$ftp_filename)) {
//file was uploaded already via ftp
//use setuid prog to chown it
//$cmd = escapeshellcmd("$sys_ftp_upload_chowner $ftp_filename");
@@ -110,7 +110,7 @@ if (getStringFromRequest('submit')) {
} elseif ($frsp->isError()) {
exit_error('Error',$frsp->getErrorMessage());
} else {
- if ($userfile && (is_uploaded_file($userfile['tmp_name']) || ($sys_use_ftpuploads && $ftp_filename))) {
+ if ($userfile && (is_uploaded_file($userfile['tmp_name']) || (forge_get_config('use_ftpuploads') && $ftp_filename))) {
//
// Create a new FRSRelease in the db
//
@@ -242,10 +242,10 @@ frs_admin_header(array('title'=>_('Quick Release System'),'group'=>$group_id));
:
- ';
- printf(_('Alternatively, you can use FTP to upload a new file at %1$s'), $sys_ftp_upload_host).' ';
+ printf(_('Alternatively, you can use FTP to upload a new file at %1$s'), forge_get_config('ftp_upload_host')).' ';
echo _('Choose an FTP file instead of uploading:').' ';
$arr[]='';
$ftp_files_arr=array_merge($arr,ls($upload_dir,true));
diff --git a/gforge/www/frs/download.php b/gforge/www/frs/download.php
index 29880aeb59..e447a2a3e3 100644
--- a/gforge/www/frs/download.php
+++ b/gforge/www/frs/download.php
@@ -90,7 +90,7 @@ if ($GLOBALS['sys_block_anonymous_downloads']) {
}
}
-$filepath=$sys_upload_dir.'/'.$Group->getUnixName().'/'.$Package->getFileName().'/'.$Release->getFileName().'/'.$File->getName();
+$filepath=forge_get_config('upload_dir').'/'.$Group->getUnixName().'/'.$Package->getFileName().'/'.$Release->getFileName().'/'.$File->getName();
if (file_exists($filepath)) {
Header('Content-disposition: attachment; filename="'.str_replace('"', '', $filename).'"');
Header("Content-type: application/binary");
diff --git a/gforge/www/frs/include/frs_utils.php b/gforge/www/frs/include/frs_utils.php
index 3dfbbbd61e..ebb8bc7320 100644
--- a/gforge/www/frs/include/frs_utils.php
+++ b/gforge/www/frs/include/frs_utils.php
@@ -64,12 +64,12 @@ function frs_admin_footer() {
}
function frs_header($params) {
- global $group_id,$HTML,$sys_use_frs;
+ global $group_id,$HTML;
/*
Does this site use FRS?
*/
- if (!$sys_use_frs) {
+ if (!forge_get_config('use_frs')) {
exit_disabled();
}
@@ -180,23 +180,16 @@ function frs_show_release_popup ($group_id, $name='release_id', $checked_val="xz
/*
return a pop-up select box of releases for the project
*/
- global $FRS_RELEASE_RES, $sys_database_type;
+ global $FRS_RELEASE_RES;
if (!$group_id) {
return 'ERROR - GROUP ID REQUIRED';
} else {
if (!isset($FRS_RELEASE_RES)) {
- if ($sys_database_type == "mysql") {
- $sql = "SELECT frs_release.release_id,concat(frs_package.name,' : ',frs_release.name) ";
- } else {
- $sql = "SELECT frs_release.release_id,(frs_package.name || ' : ' || frs_release.name) ";
- }
- $sql .=
- "FROM frs_release,frs_package
+ $FRS_RELEASE_RES = db_query_params("SELECT frs_release.release_id,(frs_package.name || ' : ' || frs_release.name) FROM frs_release,frs_package
WHERE frs_package.group_id=$1
-AND frs_release.package_id=frs_package.package_id";
-
- $FRS_RELEASE_RES = db_query_params($sql,array($group_id));
+AND frs_release.package_id=frs_package.package_id",
+ array($group_id));
echo db_error();
}
return html_build_select_box($FRS_RELEASE_RES,$name,$checked_val,false);
diff --git a/gforge/www/frs/index.php b/gforge/www/frs/index.php
index a1e03a6deb..c5900f020a 100644
--- a/gforge/www/frs/index.php
+++ b/gforge/www/frs/index.php
@@ -62,6 +62,9 @@ $num_packages = db_numrows( $res_package );
frs_header(array('title'=>_('Project Filelist'),'group'=>$group_id));
+plugin_hook("blocks", "files index");
+
+
if ( $num_packages < 1) {
echo ""._('No File Packages')." ";
echo ""._('There are no file packages defined for this project.')." ";
diff --git a/gforge/www/frs/reporting/downloads.php b/gforge/www/frs/reporting/downloads.php
index 4ab0dfdebc..a391b0acb9 100644
--- a/gforge/www/frs/reporting/downloads.php
+++ b/gforge/www/frs/reporting/downloads.php
@@ -92,6 +92,8 @@ frs_header(array('title'=>_('File Release Reporting'),
?>
+
+
diff --git a/gforge/www/help/index.php b/gforge/www/help/index.php
index afe86c8a0d..cb0cb3d2a9 100644
--- a/gforge/www/help/index.php
+++ b/gforge/www/help/index.php
@@ -26,7 +26,7 @@
require_once('../env.inc.php');
require_once $gfwww.'include/pre.php';
-$HTML->header(array('title'=>sprintf(_('Welcome to %1$s'), $GLOBALS['sys_name'])));
+$HTML->header(array('title'=>sprintf(_('Welcome to %1$s'), forge_get_config ('forge_name'))));
print "" ._('Page Information')."
";
/**
diff --git a/gforge/www/help/tracker.php b/gforge/www/help/tracker.php
index 1cff2a8ac5..b9d99e3d18 100644
--- a/gforge/www/help/tracker.php
+++ b/gforge/www/help/tracker.php
@@ -68,6 +68,10 @@ help_header('Tracker Help - ' . htmlspecialchars(ucwords(str_replace('_',' ',$he
case 'comment':
print( _('Comment'));
break;
+ case 'description':
+ print( _('Enter the complete description.'));
+ print( _("Editing tips: http,https or ftp : will be changed in hyperlinks.[#NNN] : to reference id NNN in the trackers.[TNNN] : to reference id NNN in the tasks.[wiki:<pagename>] : to reference page 'pagename' in the project's wiki.[forum:<msg_id>] : to reference post msg_id in the project's forums. "));
+ break;
case 'attach_file':
print( _('When you wish to attach a file to a tracker item you must check this checkbox before submitting changes.'));
break;
diff --git a/gforge/www/help/trove_cat.php b/gforge/www/help/trove_cat.php
index c4dc0c394b..fb7fdb6d41 100644
--- a/gforge/www/help/trove_cat.php
+++ b/gforge/www/help/trove_cat.php
@@ -44,8 +44,8 @@ $row_cat = db_fetch_array($res_cat);
help_header("Trove Category - ".$row_cat['fullname']);
print ''."\n";
-print ''._('Full Category Name').': '.$row_cat['fullname']." \n";
-print ''._('Short Name').': '.$row_cat['shortname']." \n";
+print ''._('Full Category Name').': '.$row_cat['fullname']." \n";
+print ''._('Short Name').': '.$row_cat['shortname']." \n";
print "
\n";
print ''._('Description').':'.$row_cat['description'].' '."
\n";
diff --git a/gforge/www/include/Layout.class.php b/gforge/www/include/Layout.class.php
index 3570281b2d..c5f835560c 100644
--- a/gforge/www/include/Layout.class.php
+++ b/gforge/www/include/Layout.class.php
@@ -1,294 +1,459 @@
Error();
+
+ $this->navigation = new Navigation();
+
// determine rootindex
- if ( file_exists($GLOBALS['sys_custom_path'] . '/index_std.php') )
- $this->rootindex = $GLOBALS['sys_custom_path'] . '/index_std.php';
- else
+ if ( file_exists(forge_get_config('custom_path') . '/index_std.php') ) {
+ $this->rootindex = forge_get_config('custom_path') . '/index_std.php';
+ } else {
$this->rootindex = $GLOBALS['gfwww'].'index_std.php';
+ }
- // determine themeroot
- $this->themeroot = $GLOBALS['sys_themeroot'].$GLOBALS['sys_theme'];
- /* if images directory exists in theme, then use it as imgroot */
- if (file_exists ($this->themeroot.'/images')){
- $this->imgroot = util_make_uri ('/themes/'.$GLOBALS['sys_theme'].'/images/');
+ // determine theme{dir,url}
+ $this->themedir = forge_get_config('themes_root') . forge_get_config('default_theme') . '/';
+ if (!file_exists ($this->themedir)) {
+ html_error_top(_("Can't find theme directory!"));
+ return;
}
-
- $this->Error();
+ $this->themeurl = util_make_url('themes/' . forge_get_config('default_theme') . '/');
+
+ // determine {css,img,js}{url,dir}
+ if (file_exists ($this->themedir . 'css/')) {
+ $this->cssdir = $this->themedir . 'css/';
+ $this->cssbaseurl = $this->themeurl . 'css/';
+ } else {
+ $this->cssdir = $this->themedir;
+ $this->cssbaseurl = $this->themeurl;
+ }
+
+ if (file_exists ($this->themedir . 'images/')) {
+ $this->imgdir = $this->themedir . 'images/';
+ $this->imgbaseurl = $this->themeurl . 'images/';
+ } else {
+ $this->imgdir = $this->themedir;
+ $this->imgbaseurl = $this->themeurl;
+ }
+
+ if (file_exists ($this->themedir . 'js/')) {
+ $this->jsdir = $this->themedir . 'js/';
+ $this->jsbaseurl = $this->themeurl . 'js/';
+ } else {
+ $this->jsdir = $this->themedir;
+ $this->jsbaseurl = $this->themeurl;
+ }
+
+ // determine CSS stylesheets
+ $this->cssurls[] = util_make_url ('/themes/css/fusionforge.css');
+
+ /* check if a personalized css stylesheet exist, if yes include only
+ this stylesheet. New stylesheets should use the .css file.
+ */
+ $theme_cssfile = forge_get_config('default_theme') . '.css';
+ if (file_exists($this->cssdir . $theme_cssfile)) {
+ $this->cssurls[] = $this->cssbaseurl . $theme_cssfile;
+ } else {
+ /* if this is not the case, then include the compatibility stylesheet
+ that contains all removed styles from the code and check if a
+ custom stylesheet exists.
+ Used for compatibility with existing stylesheets
+ */
+ $this->cssurls[] = util_make_url('/themes/css/gforge-compat.css');
+ if (file_exists($this->cssdir . 'theme.css')) {
+ $this->cssurls[] = $this->cssbaseurl . 'theme.css';
+ }
+ }
+
+ // for backward compatibility
+ $this->themeroot = $this->themedir;
+ $this->imgroot = $this->imgbaseurl;
}
- /**
- * headerLink() - common code for all themes
- *
+ /**
+ * header() - generates the complete header of page by calling
+ * headerStart() and bodyHeader().
*/
- function headerLink() {
- echo ' ';
- echo ' ';
- echo ' ';
- echo ' ';
+ function header($params) {
+ $this->headerStart($params); ?>
+
+ bodyHeader($params);
}
+
/**
- * headerStart() - common code for all themes
+ * headerStart() - generates the header code for all themes up to the
+ * closing .
+ * Override any of the methods headerHTMLDeclaration(), headerTitle(),
+ * headerFavIcon(), headerRSS(), headerSearch(), headerCSS(), or
+ * headerJS() to adapt your theme.
*
* @param array Header parameters array
*/
function headerStart($params) {
- if (!$params['title']) {
- $params['title'] = $GLOBALS['sys_name'];
- } else {
- $params['title'] = $GLOBALS['sys_name'] . ': ' . $params['title'];
- }
- print 'headerHTMLDeclaration();
+ ?>
+
+
+ headerTitle($params);
+ $this->headerFavIcon();
+ $this->headerRSS();
+ $this->headerSearch();
+ $this->headerCSS();
+ $this->headerJS();
?>
+
+ headerFavIcon();
+ $this->headerRSS();
+ $this->headerSearch();
+ }
-
+ /**
+ * headerHTMLDeclaration() - generates the HTML declaration, i.e. the
+ * XML declaration, the doctype definition, and the opening .
+ *
+ */
+ function headerHTMLDeclaration() {
+ print '';
+ if ($this->doctype=='strict') {
+ echo '';
+ } else {
+ echo '';
+ }
+ echo '';
+ }
-
-
-
-
- headerLink();
-
- if (isset($GLOBALS['group_id'])) {
- $activity = ' ';
- echo $activity;
- }
+ /**
+ * headerTitle() - creates the header
+ *
+ * @param array Header parameters array
+ */
+ function headerTitle($params) {
+ echo $this->navigation->getTitle($params);
+ }
+
+
+ /**
+ * headerFavIcon() - creates the favicon headers
+ *
+ */
+ function headerFavIcon() {
+ echo $this->navigation->getFavIcon();
+ }
- $this->headerCSS();
+ /**
+ * headerRSS() - creates the RSS headers
+ *
+ */
+ function headerRSS() {
+ echo $this->navigation->getRSS();
+ }
- echo '
-
- ';
+ /**
+ * headerSearch() - creates the search header
+ *
+ */
+ function headerSearch() {
+ echo ' ';
+ }
- echo "\n".''."\n";
- }
-
+ /**
+ * Create the CSS headers for all cssfiles in $cssfiles and
+ * calls the plugin cssfile hook.
+ */
function headerCSS() {
- /* check if a personalized css stylesheet exist, if yes include only
- this stylesheet
- new stylesheets should use the .css file
- */
- $theme_cssfile = $this->themeroot . '/css/'.$GLOBALS['sys_theme'].'.css';
- if (file_exists($theme_cssfile)){
- echo '
- ';
- } else {
- /* if this is not our case, then include the compatibility stylesheet
- that contains all removed styles from the code and check if a
- custom stylesheet exists.
- Used for compatibility with existing stylesheets
- */
- echo '
- ';
- $theme_cssfile = $this->themeroot . '/css/theme.css';
- if (file_exists($theme_cssfile)){
- echo '
- ';
- }
+ // include the common css
+ foreach ($this->cssurls as $cssurl) {
+ echo ' ';
}
+
plugin_hook ('cssfile',$this);
}
- function header($params) {
- $this->headerStart($params); ?>
-
- bodyHeader($params);
+ /**
+ * headerJS() - creates the JS headers and calls the plugin javascript hook
+ * @todo generalize this
+ */
+ function headerJS() {
+ echo '
+
+ ';
}
-
- function bodyHeader($params){
+
+ function bodyHeader($params){
?>
-
-
-
+
+
+ rootindex;
@@ -305,11 +470,11 @@ if (isset($params['group']) && $params['group']) {
return '
-
+
-
- '.$title.'
-
+
+ '.$title.'
+
@@ -332,7 +497,7 @@ if (isset($params['group']) && $params['group']) {
- '.$title.'
+ '.$title.'
@@ -379,8 +544,8 @@ if (isset($params['group']) && $params['group']) {
$return = '
-
-
+
+
';
$count=count($title_arr);
@@ -399,116 +564,24 @@ if (isset($params['group']) && $params['group']) {
function listTableBottom() {
return '
-
+
';
}
function outerTabs($params) {
- global $sys_use_trove,$sys_use_snippet,$sys_use_people,$sys_use_project_tags, $sys_use_project_full_list;
+ $menu =& $this->navigation->getSiteMenu();
- $TABS_DIRS[]=util_make_url ('/');
- $TABS_DIRS[]=util_make_url ('/my/');
- if ($sys_use_trove || $sys_use_project_tags || $sys_use_project_full_list) {
- $TABS_DIRS[]=util_make_url ('/softwaremap/') ;
- }
- if ($sys_use_snippet) {
- $TABS_DIRS[]=util_make_url ('/snippet/') ;
- }
- if ($sys_use_people) {
- $TABS_DIRS[]=util_make_url ('/people/') ;
- }
- $TABS_TITLES[]=_('Home');
- $TABS_TITLES[]=_('My Page');
- if ($sys_use_trove || $sys_use_project_tags || $sys_use_project_full_list) {
- $TABS_TITLES[]=_('Projects');
- }
- if ($sys_use_snippet) {
- $TABS_TITLES[]=_('Code Snippets');
- }
- if ($sys_use_people) {
- $TABS_TITLES[]=_('Project Openings');
- }
-
- // outermenu hook
- $PLUGIN_TABS_DIRS = Array();
- $hookParams['DIRS'] = &$PLUGIN_TABS_DIRS;
- $hookParams['TITLES'] = &$TABS_TITLES;
- plugin_hook ("outermenu", $hookParams) ;
- $TABS_DIRS = array_merge($TABS_DIRS, $PLUGIN_TABS_DIRS);
-
- $user_is_super=false;
- if (session_loggedin()) {
- $projectmaster =& group_get_object(GROUP_IS_MASTER);
- $projectstats =& group_get_object(GROUP_IS_STATS);
- $permmaster =& $projectmaster->getPermission( session_get_user() );
- $permstats =& $projectstats->getPermission( session_get_user() );
-
- if ($permmaster->isAdmin()) {
- $user_is_super=true;
- $TABS_DIRS[]=util_make_url ('/admin/') ;
- $TABS_TITLES[]=_('Admin');
- }
- if ($permstats->isMember()) {
- $TABS_DIRS[]=util_make_url ('/reporting/') ;
- $TABS_TITLES[]=_('Reporting');
- }
- }
- if(isset($params['group']) && $params['group']) {
- // get group info using the common result set
- $project =& group_get_object($params['group']);
- if ($project && is_object($project)) {
- if ($project->isError()) {
-
- } elseif (!$project->isProject()) {
-
- } else {
- if (isset ($GLOBALS['sys_noforcetype']) && $GLOBALS['sys_noforcetype']) {
- $TABS_DIRS[]=util_make_url ('/project/?group_id') .$project->getId();
- } else {
- $TABS_DIRS[]=util_make_url ('/projects/') .$project->getUnixName().'/';
- }
- $TABS_TITLES[]=$project->getPublicName();
- $selected=count($TABS_DIRS)-1;
- }
- }
- } elseif (strstr(getStringFromServer('REQUEST_URI'),util_make_uri ('/my/') ) ||
- strstr(getStringFromServer('REQUEST_URI'),util_make_uri ('/account/') ) ||
- strstr(getStringFromServer('REQUEST_URI'),util_make_uri ('/register/') ) ||
- strstr(getStringFromServer('REQUEST_URI'),util_make_uri ('/themes/') ) ) {
- $selected=array_search(util_make_url ('/my/'), $TABS_DIRS);
- } elseif (strstr(getStringFromServer('REQUEST_URI'),util_make_uri ('softwaremap') )) {
- $selected=array_search(util_make_url ('/softwaremap/'), $TABS_DIRS);
- } elseif (strstr(getStringFromServer('REQUEST_URI'),util_make_uri ('/snippet/') )) {
- $selected=array_search(util_make_url ('/snippet/'), $TABS_DIRS);
- } elseif (strstr(getStringFromServer('REQUEST_URI'),util_make_uri ('/people/') )) {
- $selected=array_search(util_make_url ('/people/'), $TABS_DIRS);
- } elseif (strstr(getStringFromServer('REQUEST_URI'),util_make_uri ('/reporting/') )) {
- $selected=array_search(util_make_url ('/reporting/'),$TABS_DIRS);
- } elseif (strstr(getStringFromServer('REQUEST_URI'),util_make_uri ('/admin/') ) && $user_is_super) {
- $selected=array_search(util_make_url ('/admin/'),$TABS_DIRS);
- } elseif (count($PLUGIN_TABS_DIRS)>0) {
- foreach ($PLUGIN_TABS_DIRS as $PLUGIN_TABS_DIRS_VALUE) {
- if (strstr(getStringFromServer('REQUEST_URI'), parse_url ($PLUGIN_TABS_DIRS_VALUE, PHP_URL_PATH))) {
- $selected=array_search($PLUGIN_TABS_DIRS_VALUE, $TABS_DIRS);
- break;
- }
- }
- } else {
- $selected=0;
- }
- echo $this->tabGenerator($TABS_DIRS, $TABS_TITLES, false, $selected, '');
+ echo $this->tabGenerator($menu['urls'], $menu['titles'], false, $menu['selected'], '');
}
/**
- * quicknav() - Prints out the quicknav menu, contained
- * here in case we want to allow it to be
- * overridden.
- *
+ * Prints out the quicknav menu, contained here in case we
+ * want to allow it to be overridden.
*/
function quickNav() {
if (!session_loggedin()) {
- return '';
+ return;
} else {
// get all projects that the user belongs to
$res = db_query_params ('SELECT group_id FROM groups JOIN user_group USING (group_id) WHERE user_group.user_id=$1 AND groups.status=$2 ORDER BY group_name',
@@ -516,50 +589,38 @@ if (isset($params['group']) && $params['group']) {
'A'));
echo db_error();
if (!$res || db_numrows($res) < 1) {
- return '';
+ return;
} else {
- $ret = '
+ echo '
'._('Quick Jump To...').' ';
for ($i = 0; $i < db_numrows($res); $i++) {
$group_id = db_result($res, $i, 'group_id');
- $project =& group_get_object($group_id);
- if (!$project || !is_object($project)) {
- return;
- }
- if ($project->isError()) {
- //wasn't found or some other problem
- return;
- }
- if (!$project->isProject()) {
- return;
- }
-
- $menu = $project->getMenu();
- $ret .= '
- '
- . $project->getPublicName() .' ';
-
- for ($j = 0; $j < count($menu['dirs']); $j++) {
- $ret .= '
- '
+ $menu =& $this->navigation->getProjectMenu($group_id);
+
+ echo '
+ '
+ . $menu['name'] .' ';
+
+ for ($j = 0; $j < count($menu['urls']); $j++) {
+ echo '
+ '
. $menu['titles'][$j] . ' ';
- if ($menu['admindirs'][$j]) {
- $ret .= '
- '
- . _('Admin') . ' ';
+ if ($menu['adminurls'][$j]) {
+ echo '
+ '
+ . _('Admin') . ' ';
}
}
}
- $ret .= '
+ echo '
';
}
}
- return $ret;
}
/**
@@ -569,23 +630,11 @@ if (isset($params['group']) && $params['group']) {
* @param string Is the tab currently selected
* @param string Is the group we should look up get title info
*/
- function projectTabs($toptab, $group) {
+ function projectTabs($toptab, $group_id) {
// get group info using the common result set
- $project =& group_get_object($group);
- if (!$project || !is_object($project)) {
- return;
- }
- if ($project->isError()) {
- //wasn't found or some other problem
- return;
- }
- if (!$project->isProject()) {
- return;
- }
+ $menu =& $this->navigation->getProjectMenu($group_id, $toptab);
- $menu = $project->getMenu($toptab);
-
- echo $this->tabGenerator($menu['dirs'], $menu['titles'], true, $menu['selected'], 'white');
+ echo $this->tabGenerator($menu['urls'], $menu['titles'], true, $menu['selected'], 'white');
}
function tabGenerator($TABS_DIRS,$TABS_TITLES,$nested=false,$selected=false,$sel_tab_bgcolor='white',$total_width='100%') {
@@ -617,12 +666,12 @@ if (isset($params['group']) && $params['group']) {
$wassel=false;
$issel=($selected==$i);
$bgimg=(($issel)?'theme-'.$inner.'-selected-bg.png':'theme-'.$inner.'-notselected-bg.png');
- // $rowspan=(($issel)?'rowspan="2" ' : '');
+ // $rowspan=(($issel)?'rowspan="2" ' : '');
$return .= '
- '.
- ' '.
- 'imgroot . $bgimg.')" width="'.$width.'%" align="center">'.util_make_link ($TABS_DIRS[$i],$TABS_TITLES[$i],array('class'=>(($issel)?'tabsellink':'tablink')),true).' ';
+ '.
+ ' '.
+ 'imgbaseurl . $bgimg.')" width="'.$width.'%" align="center">'.util_make_link ($TABS_DIRS[$i],$TABS_TITLES[$i],array('class'=>(($issel)?'tabsellink':'tablink')),true).' ';
} elseif ($i==$count-1) {
//
// this is the last tab, choose an image with name-end
@@ -630,20 +679,20 @@ if (isset($params['group']) && $params['group']) {
$wassel=($selected==$i-1);
$issel=($selected==$i);
$bgimg=(($issel)?'theme-'.$inner.'-selected-bg.png':'theme-'.$inner.'-notselected-bg.png');
- // $rowspan=(($issel)?'rowspan="2" ' : '');
+ // $rowspan=(($issel)?'rowspan="2" ' : '');
//
// Build image between current and prior tab
//
$return .= '
- '.
- ' '.
- 'imgroot . $bgimg.')" width="'.$width.'%" align="center">'.util_make_link ($TABS_DIRS[$i],$TABS_TITLES[$i],array('class'=>(($issel)?'tabsellink':'tablink')),true).' ';
+ '.
+ ' '.
+ 'imgbaseurl . $bgimg.')" width="'.$width.'%" align="center">'.util_make_link ($TABS_DIRS[$i],$TABS_TITLES[$i],array('class'=>(($issel)?'tabsellink':'tablink')),true).' ';
//
// Last graphic on right-side
//
$return .= '
- '.
- ' ';
+ '.
+ ' ';
} else {
//
@@ -652,14 +701,14 @@ if (isset($params['group']) && $params['group']) {
$wassel=($selected==$i-1);
$issel=($selected==$i);
$bgimg=(($issel)?'theme-'.$inner.'-selected-bg.png':'theme-'.$inner.'-notselected-bg.png');
- // $rowspan=(($issel)?'rowspan="2" ' : '');
+ // $rowspan=(($issel)?'rowspan="2" ' : '');
//
// Build image between current and prior tab
//
$return .= '
- '.
- ' '.
- 'imgroot . $bgimg.')" width="'.$width.'%" align="center">'.util_make_link ($TABS_DIRS[$i],$TABS_TITLES[$i],array('class'=>(($issel)?'tabsellink':'tablink')),true).' ';
+ '.
+ ' '.
+ 'imgbaseurl . $bgimg.')" width="'.$width.'%" align="center">'.util_make_link ($TABS_DIRS[$i],$TABS_TITLES[$i],array('class'=>(($issel)?'tabsellink':'tablink')),true).' ';
}
}
@@ -680,11 +729,11 @@ if (isset($params['group']) && $params['group']) {
}
$return .= ' ';
if ($beg_cols > 0) {
- $return .= ' ';
+ $return .= ' ';
}
- $return .= ' ';
+ $return .= ' ';
if ($end_cols > 0) {
- $return .= ' ';
+ $return .= ' ';
}
$return .= ' ';
@@ -697,199 +746,7 @@ if (isset($params['group']) && $params['group']) {
}
function searchBox() {
- global $words,$forum_id,$group_id,$group_project_id,$atid,$exact,$type_of_search;
-
- if(get_magic_quotes_gpc()) {
- $defaultWords = stripslashes($words);
- } else {
- $defaultWords = $words;
- }
-
- //Fix CVE-2007-0176
- $defaultWords = htmlspecialchars($defaultWords);
-
- // if there is no search currently, set the default
- if ( ! isset($type_of_search) ) {
- $exact = 1;
- }
-
- print '';
- print '';
- $parameters = array(
- SEARCH__PARAMETER_GROUP_ID => $group_id,
- SEARCH__PARAMETER_ARTIFACT_ID => $atid,
- SEARCH__PARAMETER_FORUM_ID => $forum_id,
- SEARCH__PARAMETER_GROUP_PROJECT_ID => $group_project_id
- );
-
- $searchManager =& getSearchManager();
- $searchManager->setParametersValues($parameters);
- $searchEngines =& $searchManager->getAvailableSearchEngines();
-
- echo '';
- for($i = 0, $max = count($searchEngines); $i < $max; $i++) {
- $searchEngine =& $searchEngines[$i];
- echo 'getType() ? ' selected="selected"' : '' ).'>'.$searchEngine->getLabel($parameters).' '."\n";
- }
- echo ' ';
-
- $parameters = $searchManager->getParameters();
- foreach($parameters AS $name => $value) {
- print ' ';
- }
- print '' . html_image('pixel-transparent.gif', 1, 1, array('alt' => "")) . ' ';
- print ' ';
-
- print '' . html_image('pixel-transparent.gif', 1, 1, array('alt' => "")) . ' ';
- print ' ';
-
- if (isset($group_id) && $group_id) {
- $link_content = html_image('notes.png','21','21',array('alt'=>_('Advanced search'), 'title'=>_('Advanced search')));
- print ' '.util_make_link ('/search/advanced_search.php?group_id='.$group_id, $link_content, array('class'=>'lnkutility', 'id'=>'advanced-search'));
- }
- print '
';
- print ' ';
- }
-
- function advancedSearchBox($sectionsArray, $group_id, $words, $isExact) {
- // display the searchmask
- print '
-
-
-
- '
- .$this->createUnderSections($sectionsArray).'
- ';
-
-
- //create javascript methods for select none/all
- print '
-
- ';
-
- }
-
- function createUnderSections($sectionsArray) {
- global $group_subsection_names;
-
- $countLines = 0;
- foreach ($sectionsArray as $section) {
- if(is_array($section)) {
- $countLines += (3 + count ($section));
- } else {
- //2 lines one for section name and one for checkbox
- $countLines += 3;
- }
- }
-
- $maxCol = 3;
- $breakLimit = ceil($countLines/$maxCol);
- $break = $breakLimit;
- $countLines = 0;
- $countCol = 1;
-
- $return = '
- ';
+ echo $this->navigation->getSearchBox();
}
/**
@@ -958,7 +815,7 @@ if (isset($params['group']) && $params['group']) {
* @param boolean is this row part of the title ?
*
*/
- function multiTableRow($row_attr, $cell_data, $istitle) {
+ function multiTableRow($row_attr, $cell_data, $istitle) {
$return= '
$img_extra_params_value) {
$return .= $key . '="' . $img_extra_params_value . '" ';
diff --git a/gforge/www/include/features_boxes.php b/gforge/www/include/features_boxes.php
index ebffad5148..41ad707185 100644
--- a/gforge/www/include/features_boxes.php
+++ b/gforge/www/include/features_boxes.php
@@ -12,7 +12,7 @@ require_once $gfcommon.'include/tag_cloud.php';
require_once $gfcommon.'include/Stats.class.php';
function show_features_boxes() {
- GLOBAL $HTML,$sys_use_ratings,$sys_use_frs,$sys_use_project_tags;
+ GLOBAL $HTML, $sys_use_project_tags;
plugin_hook ("features_boxes_top", array());
$return = '' . _('Features Boxes') . ' ';
@@ -20,16 +20,16 @@ function show_features_boxes() {
if ($sys_use_project_tags) {
$return .= $HTML->boxTop(_('Tag Cloud'), 'Tag_Cloud');
$return .= tag_cloud();
- $return .= $HTML->boxMiddle(sprintf(_('%1$s Statistics'), $GLOBALS['sys_name']), 'Forge_Statistics');
+ $return .= $HTML->boxMiddle(sprintf(_('%1$s Statistics'), forge_get_config ('forge_name')), 'Forge_Statistics');
} else {
- $return .= $HTML->boxTop(sprintf(_('%1$s Statistics'), $GLOBALS['sys_name']), 'Forge_Statistics');
+ $return .= $HTML->boxTop(sprintf(_('%1$s Statistics'), forge_get_config ('forge_name')), 'Forge_Statistics');
}
$return .= show_sitestats();
- if ($sys_use_frs) {
+ if (forge_get_config('use_frs')) {
$return .= $HTML->boxMiddle(_('Top Project Downloads'), 'Top_Projects_Downloads');
$return .= show_top_downloads();
}
- if ($sys_use_ratings) {
+ if (forge_get_config('use_ratings')) {
$return .= $HTML->boxMiddle(_('Highest Ranked Users'), 'Highest_Ranked_Users');
$return .= show_highest_ranked_users();
}
@@ -139,15 +139,15 @@ function stats_downloads_total() {
}
function show_sitestats() {
- global $sys_use_trove;
+
$gforge = new FusionForge();
$return = '';
$return .= _('Hosted Projects').': ';
- if ($sys_use_trove) {
+ if (forge_get_config('use_trove')) {
$return .= '';
}
$return .= ''.number_format($gforge->getNumberOfPublicHostedProjects()).' ';
- if ($sys_use_trove) {
+ if (forge_get_config('use_trove')) {
$return .= ' ';
}
$return .= "
";
diff --git a/gforge/www/include/help.php b/gforge/www/include/help.php
index a4158b641f..8c874e1770 100644
--- a/gforge/www/include/help.php
+++ b/gforge/www/include/help.php
@@ -37,7 +37,7 @@ function help_header($title) {
- Site Help System:
+ Site Help System:
header($params);
- echo html_feedback_top($GLOBALS['feedback']);
+
+ if(isset($GLOBALS['error_msg']) && $GLOBALS['error_msg']) {
+ echo html_error_top($GLOBALS['error_msg']);
+ }
+ if(isset($GLOBALS['warning_msg']) && $GLOBALS['warning_msg']) {
+ echo html_warning_top($GLOBALS['warning_msg']);
+ }
+ if(isset($GLOBALS['feedback']) && $GLOBALS['feedback']) {
+ echo html_feedback_top($GLOBALS['feedback']);
+ }
}
/**
diff --git a/gforge/www/include/plugins_utils.php b/gforge/www/include/plugins_utils.php
new file mode 100644
index 0000000000..3fac40cdac
--- /dev/null
+++ b/gforge/www/include/plugins_utils.php
@@ -0,0 +1,41 @@
+');
+}
+
+
+function helpButton($help) {
+
+}
+function getIcon($url,$w=16,$h=16,$args=array()) {
+ echo html_image($url,$w,$h,$args);
+}
+function getImage($img) {
+ echo util_make_url($html->imgroot.$img);
+
+}
+?>
+
diff --git a/gforge/www/include/pre.php b/gforge/www/include/pre.php
index 92ef7fd2b7..6879c311ea 100644
--- a/gforge/www/include/pre.php
+++ b/gforge/www/include/pre.php
@@ -32,6 +32,10 @@ if (!isset($no_gz_buffer) || !$no_gz_buffer) {
}
require $gfcgfile;
+require $gfcommon.'include/config.php';
+require $gfcommon.'include/config-vars.php';
+
+forge_read_config_file ($gfconfig.'/config.ini') ;
// get constants used for flags or status
require $gfcommon.'include/constants.php';
@@ -56,7 +60,7 @@ require_once $gfwww.'include/Layout.class.php';
require_once $gfcommon.'include/utils.php';
//database abstraction
-require_once $gfcommon.'include/database-'.$sys_database_type.'.php';
+require_once $gfcommon.'include/database-pgsql.php';
//security library
require_once $gfcommon.'include/session.php';
@@ -95,7 +99,7 @@ require_once $gfcommon.'include/forms.php';
db_connect();
if (!$GLOBALS['gfconn']) {
- print "$sys_name Could Not Connect to Database: ".db_error();
+ print forge_get_config ('forge_name')." Could Not Connect to Database: ".db_error();
exit;
}
@@ -115,7 +119,7 @@ session_set();
plugin_hook('after_session_set');
//mandatory login
-if (!session_loggedin() && $sys_force_login == 1 ) {
+if (!session_loggedin() && forge_get_config ('force_login') == 1 ) {
$expl_pathinfo = explode('/',getStringFromServer('REQUEST_URI'));
if (getStringFromServer('REQUEST_URI')!='/' && $expl_pathinfo[1]!='account' && $expl_pathinfo[1]!='export' ) exit_not_logged_in();
// Show proj* export even if not logged in when force login
@@ -140,7 +144,7 @@ if (session_loggedin()) {
//
// Include user Theme
//
-require_once $sys_themeroot.$sys_theme.'/Theme.class.php';
+require_once forge_get_config('themes_root').forge_get_config('default_theme').'/Theme.class.php';
$HTML=new Theme();
diff --git a/gforge/www/include/preplugins.php b/gforge/www/include/preplugins.php
new file mode 100644
index 0000000000..d4d9dc4b32
--- /dev/null
+++ b/gforge/www/include/preplugins.php
@@ -0,0 +1,13 @@
+
+
diff --git a/gforge/www/include/project_home.php b/gforge/www/include/project_home.php
index 1876b18fc0..d3eb254885 100644
--- a/gforge/www/include/project_home.php
+++ b/gforge/www/include/project_home.php
@@ -22,12 +22,18 @@ site_project_header(array('title'=>$title,'group'=>$group_id,'toptab'=>'home'));
// ########################################### end top area
// two column deal
+// Embedd some RDFa to describe the project using DOAP and SIOC
echo '
+
+
+
+
+
- '.$project->getPublicName().'
+ '.$project->getPublicName().'
'._('Project summary').' ';
@@ -43,17 +49,31 @@ $res_admin = db_query_params ('SELECT users.user_id,users.user_name,users.realna
'A'));
if ($project->getStatus() == 'H') {
- print "".sprintf(_('NOTE: This project entry is maintained by the %1$s staff. We are not the official site for this product. Additional copyright information may be found on this project\'s homepage.'), $GLOBALS['sys_name'])."
\n";
+ print "".sprintf(_('NOTE: This project entry is maintained by the %1$s staff. We are not the official site for this product. Additional copyright information may be found on this project\'s homepage.'), forge_get_config ('forge_name'))."
\n";
}
$hook_params = array () ;
$hook_params['group_id'] = $group_id ;
plugin_hook ("project_before_description",$hook_params) ;
-if ($project->getDescription()) {
- print "" . nl2br($project->getDescription()) . '
';
-} else {
- print "" . _('This project has not yet submitted a description.') . '
';
+// insert an empty which seems to be better if not compacted
+print ' '."\n";
+// print '' ...
+//print '';
+
+// Try to display the blocks description first if active.
+$pluginManager = plugin_manager_get_object();
+if (! $pluginManager->PluginIsInstalled('blocks') || !plugin_hook ("blocks", "summary_description")) {
+ $project_description = $project->getDescription();
+ if ($project_description) {
+ // need to use a litteral version for content attribute since nl2br is for HTML
+ print "
"
+ .''
+ . nl2br($project_description)
+ .'
';
+ } else {
+ print "
" . _('This project has not yet submitted a description.') . '
';
+ }
}
print "
\n";
@@ -76,13 +96,17 @@ if ($GLOBALS['sys_use_project_tags']) {
}
}
-if($GLOBALS['sys_use_trove']) {
+if(forge_get_config('use_trove')) {
print "
\n";
print stripslashes(trove_getcatlisting($group_id,0,1,1));
}
// registration date
-print(_('Registered: ') . date(_('Y-m-d H:i'), $project->getStartDate()));
+$project_start_date = $project->getStartDate();
+print(_('Registered: ') .
+ '
'.
+ date(_('Y-m-d H:i'), $project_start_date).
+ ' ');
// Get the activity percentile
// CB hide stats if desired
@@ -95,13 +119,13 @@ if ($project->usesStats()) {
}
print '
'.sprintf (_('Activity Ranking: %d'), $actv_res) ;
print '
'.sprintf(_('View project
Statistics '),util_make_url ('/project/stats/?group_id='.$group_id));
- if ( ($project->usesTracker() && $GLOBALS['sys_use_tracker']) || ($project->usesPm() && $GLOBALS['sys_use_pm']) ) {
+ if ( ($project->usesTracker() && forge_get_config('use_tracker')) || ($project->usesPm() && forge_get_config('use_pm')) ) {
print sprintf(_(' or
Activity '),util_make_url ('/project/report/?group_id='.$group_id));
}
print '
'.sprintf(_('View list of
RSS feeds available for this project.'), util_make_url ('/export/rss_project.php?group_id='.$group_id)). ' ' . html_image('ic/rss.png',16,16,array());
}
-if($GLOBALS['sys_use_people']) {
+if(forge_get_config('use_people')) {
$jobs_res = db_query_params ('SELECT name
FROM people_job,people_job_category
WHERE people_job.category_id=people_job_category.category_id
@@ -120,9 +144,16 @@ if($GLOBALS['sys_use_people']) {
$num),
util_make_url ('/people/?group_id='.$group_id),
db_result($jobs_res,0,"name"));
+//print '
';
+//print '';
+//print ' ';
+//echo '
';
+//end of job description part
}
}
}
+
+
$hook_params = array () ;
$hook_params['group_id'] = $group_id ;
plugin_hook ("project_after_description",$hook_params) ;
@@ -132,6 +163,9 @@ echo '
' ;
// ########################### Developers on this project
echo '' ;
+
+plugin_hook ("blocks", "summary_right") ;
+
echo $HTML->boxTop(_('Project Members'), 'Project_Members');
$iam_member = false ;
@@ -145,7 +179,24 @@ if (db_numrows($res_admin) > 0) {
$started_developers=true;
echo ''. _('Developers').': ';
}
- echo util_make_link_u ($row_admin['user_name'],$row_admin['user_id'],$row_admin['realname']).' ';
+ if (!$started_developers) {
+ echo ''."\n";
+ } else {
+ echo '
'."\n";
+ }
+ # a foaf:Person that holds an account on the forge
+ $developer_url = util_make_url_u ($row_admin['user_name'],$row_admin['user_id']);
+ echo '
'."\n";
+ echo '
'."\n";
+ echo '
'."\n";
+ echo util_make_link_u ($row_admin['user_name'],$row_admin['user_id'],$row_admin['realname']) ." \n";
+ echo "
\n"; // /sioc:UserAccount
+ echo "
\n"; // /foaf:holdsAccount
+ echo "
\n"; // /foaf:Person
+ echo "
\n"; // /doap:maintainer|developer
if ($row_admin['user_id'] == user_getid())
$iam_member = true ;
}
@@ -153,9 +204,14 @@ if (db_numrows($res_admin) > 0) {
}
$members = $project->getUsers();
-echo '
';
+echo '
';
+echo '';
+echo '';
echo util_make_link ('/project/memberlist.php?group_id='.$group_id,sprintf(_('View the %1$d Member(s)'),count($members)));
-echo '';
+echo ' ';
+echo '
';
+echo '
';
+// end of project usergroup description
if (!$iam_member) {
echo '
'.util_make_link ('/project/request.php?group_id='.$group_id,_('Request to join')).'
';
@@ -241,6 +297,7 @@ if ($project->usesFRS()) {
' . $package_name . '
';
// Releases to display
+//print '';
echo '
'
.$package_release.'
@@ -249,6 +306,7 @@ if ($project->usesFRS()) {
. $rel_date["month"] . ' ' . $rel_date["mday"] . ', ' . $rel_date["year"] .
'
';
+//echo '';
// -> notes
// accessibility: image is a link, so alt must be unique in page => construct a unique alt
@@ -300,7 +358,7 @@ echo $HTML->boxTop(_('Public Areas'), 'Public_Areas');
// ################# Homepage Link
-echo '';
+echo '
';
echo util_make_link ('http://' . $project->getHomePage(), $HTML->getHomePic(_('Home Page')) . ' ' . _('Project Home Page'), false, true);
echo '
';
@@ -325,12 +383,20 @@ if ($project->usesTracker()) {
if (!$result || $rows < 1) {
echo '
'._('There are no public trackers available').' ';
} else {
- echo '
';
+ echo '';
for ($j = 0; $j < $rows; $j++) {
- echo '';
- echo util_make_link ('/tracker/?atid='. db_result($result, $j, 'group_artifact_id') . '&group_id='.$group_id.'&func=browse',db_result($result, $j, 'name')) . ' ' ;
- printf(ngettext('(%1$s open / %2$s total)', '(%1$s open / %2$s total)', (int) db_result($result, $j, 'open_count')), (int) db_result($result, $j, 'open_count'), (int) db_result($result, $j, 'count'));
- echo ' '.db_result($result, $j, 'description').' ';
+ // tracker REST paths are something like : /tracker/cm/project/A_PROJECT/atid/NUMBER to plan compatibility
+ // with OSLC-CM server API
+ $group_artifact_id = db_result($result, $j, 'group_artifact_id');
+ $tracker_stdzd_uri = util_make_url('/tracker/cm/project/'. $project->getUnixName() .'/atid/'. $group_artifact_id);
+ echo ''."\n";
+ print ''."\n";
+ echo util_make_link ('/tracker/?atid='. $group_artifact_id . '&group_id='.$group_id.'&func=browse',db_result($result, $j, 'name')) . ' ' ;
+ echo " \n"; // /owl:sameAs
+ printf(ngettext('(%1$s open / %2$s total)', '(%1$s open / %2$s total)', (int) db_result($result, $j, 'open_count')), (int) db_result($result, $j, 'open_count'), (int) db_result($result, $j, 'count'));
+ echo ' '.db_result($result, $j, 'description');
+ print ' '."\n";
+ echo " \n";
}
echo ' ';
}
@@ -341,6 +407,7 @@ if ($project->usesTracker()) {
if ($project->usesForum()) {
echo '
+
';
diff --git a/gforge/www/include/project_summary.php b/gforge/www/include/project_summary.php
index 716539251c..182389e6c1 100644
--- a/gforge/www/include/project_summary.php
+++ b/gforge/www/include/project_summary.php
@@ -185,7 +185,7 @@ function project_summary($group_id,$mode,$no_table) {
}
}
- // ##################### Task Manager
+ // ##################### Tasks
if ($project->usesPm()) {
$return .= '
diff --git a/gforge/www/include/squal_pre.php b/gforge/www/include/squal_pre.php
index fea690f9b2..20d32b2819 100644
--- a/gforge/www/include/squal_pre.php
+++ b/gforge/www/include/squal_pre.php
@@ -20,14 +20,21 @@ if (!isset($no_gz_buffer) || !$no_gz_buffer) {
}
require $gfcgfile;
+require $gfcommon.'include/config.php';
+require $gfcommon.'include/config-vars.php';
+
+forge_read_config_file ($gfconfig.'/config.ini') ;
+
require $gfcommon.'include/constants.php';
-require_once $gfcommon.'include/database-'.$sys_database_type.'.php';
+require_once $gfcommon.'include/database-pgsql.php';
require_once $gfcommon.'include/session.php';
require_once $gfcommon.'include/Error.class.php';
require_once $gfcommon.'include/User.class.php';
+require_once $gfcommon.'include/UserManager.class.php';
require_once $gfcommon.'include/Permission.class.php';
require_once $gfcommon.'include/utils.php';
require_once $gfcommon.'include/Group.class.php';
+require_once $gfcommon.'include/ProjectManager.class.php';
require_once $gfcommon.'include/escapingUtils.php';
require_once $gfcommon.'include/gettext.php';
diff --git a/gforge/www/include/user_home.php b/gforge/www/include/user_home.php
index c2225142ed..acebcb67b6 100644
--- a/gforge/www/include/user_home.php
+++ b/gforge/www/include/user_home.php
@@ -17,6 +17,8 @@ $HTML->header(array('title'=>_('Developer Profile')));
echo $HTML->boxTop(_('Personal Information'), _('Personal Information')); ?>
+
+
@@ -25,31 +27,56 @@ echo $HTML->boxTop(_('Personal Information'), _('Personal Information')); ?>
';
+//echo '';
+// description as a FusionForge Community member
+//print '';
+
if (session_loggedin() && user_ismember(1)) {
echo util_make_link ('/admin/useredit.php?user_id='.$user_id,$user_id);
} else {
echo $user_id;
+//echo '
';
}
?>
- ( '._('Skills Profile').''); ?> )
+ ( '._('Skills Profile').''); ?> )
- getUnixName(); ?>
+ getUnixName();
+ ?>
- getTitle() .' '. $user->getRealName(); ?>
+
+
+
+ getTitle();
+ print ($user_title ? $user_title .' ' :''). $user->getRealName();
+ ?>
+
+
+
:
- getEmail())); ?>
+ getEmail();
+ $user_mailsha1=$user->getSha1Email();
+ // Removed for privacy reasons
+ //print '';
+ print '';
+ echo util_make_link ('/sendmessage.php?touser='.$user_id, str_replace('@',' @nospam@ ',$user_mail));
+ echo ' ';
+ ?>
getJabberAddress()) { ?>
@@ -71,7 +98,11 @@ echo $HTML->boxTop(_('Personal Information'), _('Personal Information')); ?>
getPhone()) { ?>
- getPhone(); ?>
+ getPhone().'">';
+echo $user->getPhone();
+//echo '';
+?>
@@ -93,7 +124,7 @@ echo $HTML->boxTop(_('Personal Information'), _('Personal Information')); ?>
boxMiddle(_('Peer Rating'), _('Peer Rating'));
echo '
';
if ($user->usesRatings()) {
@@ -118,7 +149,11 @@ echo $HTML->boxTop(_('Personal Information'), _('Personal Information')); ?>
$res = db_query_params ('SELECT count(*) from user_diary WHERE user_id=$1 AND is_public=1',
array ($user_id));
echo _('Diary/Note entries:').' '.db_result($res,0,0).'
- '.util_make_link ('/developer/diary.php?diary_user='.$user_id,_('View Diary & Notes')).'
+ ';
+ //.''
+ echo util_make_link ('/developer/diary.php?diary_user='.$user_id,_('View Diary & Notes'));
+ //.' '.
+ echo '
';
echo util_make_link ('/developer/monitor.php?diary_user='.$user_id,
html_image("ic/check.png",'15','13',array(),0) ._('Monitor this Diary')
@@ -148,26 +183,53 @@ echo $HTML->boxTop(_('Personal Information'), _('Personal Information')); ?>
'A'));
// see if there were any groups
+echo '
'."\n";
if (db_numrows($res_cat) < 1) {
?>
"._('This developer is a member of the following projects:')."
";
+
while ($row_cat = db_fetch_array($res_cat)) {
- print ('
' . util_make_link_g ($row_cat['unix_group_name'],$row_cat['group_id'],$row_cat['group_name']).' ('.$row_cat['role_name'].')');
+
+ $project_link = util_make_link_g ($row_cat['unix_group_name'],$row_cat['group_id'],$row_cat['group_name']);
+ $project_uri = util_make_url_g ($row_cat['unix_group_name'],$row_cat['group_id']);
+ // sioc:UserGroups for all members of a project are named after /projects/A_PROJECT/members/
+ $usergroup_uri = $project_uri .'members/';
+
+
+ print '
'."\n"
+ .''."\n"
+ .'
'."\n"
+ .'';
+ //print '
';
+
+ print (' ' . $project_link .' ('.$row_cat['role_name'].')');
print "\n";
+
+ if (trim($row_cat['admin_flags']) == 'A') {
+ print ' ';
+ }
+ else {
+ print ' ';
+ }
+
+ echo "
\n"; // sioc:Space .../projects/A_PROJECT/
+ echo "\n"; // sioc:usergroup_of
+ echo "
\n"; // sioc:UserGroup .../projects/A_PROJECT/members
+ echo " \n"; // sioc:member_of
}
print '';
} // end if groups
+echo "
\n"; // prefixes
+echo " \n"; // end of about=""
$me = session_get_user();
-if ($sys_use_ratings) {
+if (forge_get_config('use_ratings')) {
if ($user->usesRatings() && (!$me || $me->usesRatings())) {
- echo 'If you are familiar with this user, please take a moment to rate him/her on the following criteria. Keep in mind, that your rating will be visible to the user and others.
';
- echo 'The '. $GLOBALS['sys_name'] .' Peer Rating system is based on concepts from Advogato . The system has been re-implemented and expanded in a few ways.
';
-
+ printf(_('If you are familiar with this user, please take a moment to rate him/her on the following criteria. Keep in mind, that your rating will be visible to the user and others.
The %1$s Peer Rating system is based on concepts from Advogato. The system has been re-implemented and expanded in a few ways.
'), forge_get_config ('forge_name'));
?>
@@ -175,7 +237,7 @@ if ($user->usesRatings() && (!$me || $me->usesRatings())) {
The Peer rating box shows all rating averages (and response levels) for each individual criteria. Due to the math and processing required to do otherwise, these numbers incoporate responses from both "trusted" and "non-trusted" users.The "Sitewide Rank" field shows the user\'s rank compared to all ranked %1$s users. The "Aggregate Score" shows an average, weighted overall score, based on trusted-responses only. The "Personal Importance" field shows the weight that users ratings of other developers will be given (between 1 and 1.5) -- higher rated user\'s responses are given more weight. If you would like to opt-out from peer rating system (this will affect your ability to both rate and be rated), refer to your account maintenance page . If you choose not to participate, your ratings of other users will be permanently deleted and the \'Peer Rating\' box will disappear from your user page.
'),
- $GLOBALS['sys_name'],
+ forge_get_config ('forge_name'),
util_make_url ("/account/"));
} else if ($me && !$me->usesRatings()) { ?>
diff --git a/gforge/www/index_std.php b/gforge/www/index_std.php
index 9b812b7ab1..dd6cf53f4d 100644
--- a/gforge/www/index_std.php
+++ b/gforge/www/index_std.php
@@ -76,5 +76,15 @@ echo $HTML->boxBottom();
printf (_('This site is running %1$s version %2$s'),
$forge->software_name,
$forge->software_version) ;
+ printf(''."\n"
+ .'
'."\n"
+ .'
'."\n"
+ .' '."\n"
+ .' '."\n"
+ ."
\n"
+ ."
\n"
+ ."
\n",
+ $forge->software_name,
+ $forge->software_version);
?>
\ No newline at end of file
diff --git a/gforge/www/mail/admin/index.php b/gforge/www/mail/admin/index.php
index f6844de8aa..07ab86cc26 100644
--- a/gforge/www/mail/admin/index.php
+++ b/gforge/www/mail/admin/index.php
@@ -122,7 +122,7 @@ if ($group_id) {
if(getIntFromGet('add_list')) {
mail_header(array(
'title' => _('Add a Mailing List')));
- printf(_('Lists are named in this manner:projectname-listname@%1$s
It will take 6-24 Hours for your list to be created.
'), $GLOBALS['sys_lists_host']);
+ printf(_('Lists are named in this manner:projectname-listname@%1$s
It will take 6-24 Hours for your list to be created.
'), forge_get_config('lists_host'));
$mlFactory = new MailingListFactory($Group);
if (!$mlFactory || !is_object($mlFactory) || $mlFactory->isError()) {
@@ -168,7 +168,7 @@ if ($group_id) {
- getUnixName(); ?>- @
+ getUnixName(); ?>- @
@@ -234,7 +234,7 @@ if ($group_id) {
mail_footer(array());
exit;
}
- echo '
'.sprintf(_('You can administrate lists from here. Please note that private lists can still be viewed by members of your project, but are not listed on %1$s.'), $GLOBALS['sys_name']).'
';
+ echo ''.sprintf(_('You can administrate lists from here. Please note that private lists can still be viewed by members of your project, but are not listed on %1$s.'), forge_get_config ('forge_name')).'
';
echo '
'._('Add Mailing List').'
diff --git a/gforge/www/mail/index.php b/gforge/www/mail/index.php
index 01b4e28ca3..21f99d1741 100644
--- a/gforge/www/mail/index.php
+++ b/gforge/www/mail/index.php
@@ -35,6 +35,7 @@ if ($group_id) {
'title' => sprintf(_('Mailing Lists for %1$s'), $Group->getPublicName())
));
+ plugin_hook ("blocks", "mail index");
$mlArray =& $mlFactory->getMailingLists();
diff --git a/gforge/www/my/diary.php b/gforge/www/my/diary.php
index 64f73ce901..bf2545f3c7 100644
--- a/gforge/www/my/diary.php
+++ b/gforge/www/my/diary.php
@@ -100,7 +100,7 @@ AND user_diary_monitor.monitored_user=$1',
$to = ''; // send to noreply@
$subject = sprintf (_("[%s User Notes: %s] %s"),
- $GLOBALS['sys_name'],
+ forge_get_config ('forge_name'),
$u->getRealName(),
stripslashes($summary)) ;
$body = util_line_wrap(stripslashes($details)) ;
@@ -112,7 +112,7 @@ To stop monitoring this user, login to %s and visit the following link:
%s
",
- $GLOBALS['sys_name'],
+ forge_get_config ('forge_name'),
util_make_url ("/developer/monitor.php?diary_user=". user_getid())) ;
util_send_message($to, $subject, $body, $to, $tolist);
@@ -169,11 +169,11 @@ To stop monitoring this user, login to %s and visit the following link:
}
echo site_user_header(array('title'=>_('My Diary And Notes')));
+ echo '' . _('My Diary And Notes') . ' ';
echo '
-
- '. $info_str .'
-
+ '. $info_str .'
+
diff --git a/gforge/www/my/index.php b/gforge/www/my/index.php
index f4089c8eaf..de89b8b539 100644
--- a/gforge/www/my/index.php
+++ b/gforge/www/my/index.php
@@ -41,7 +41,7 @@ if (!session_loggedin()) { // || $sf_user_hash) {
>
-
+
">
?>
-
+
">
?>
-
+
">
?>
-
+
1,
@@ -266,7 +266,7 @@ title="">
/*
Forums that are actively monitored
*/
- if ($GLOBALS['sys_use_forum']) {
+ if (forge_get_config('use_forum')) {
$last_group=0;
$order_name_arr=array();
$order_name_arr[]=_('Remove');
@@ -297,7 +297,7 @@ title="">
/*
Filemodules that are actively monitored
*/
- if ($GLOBALS['sys_use_frs']) {
+ if (forge_get_config('use_frs')) {
$last_group=0;
$order_name_arr=array();
$order_name_arr[]=_('Remove');
diff --git a/gforge/www/news/admin/index.php b/gforge/www/news/admin/index.php
index 6a1cd0f211..752c5e0f30 100644
--- a/gforge/www/news/admin/index.php
+++ b/gforge/www/news/admin/index.php
@@ -81,7 +81,7 @@ if ($group_id && $group_id != $sys_news_group && user_ismember($group_id,'A')) {
$sanitizer = new TextSanitizer();
$details = $sanitizer->SanitizeHtml($details);
$result = db_query_params("UPDATE news_bytes SET is_approved=$1, summary=$2,
-details=$3 WHERE id=$4 AND group_id=$5", array($status, htmlspecialchars($summary), addslashes($details), $id, $group_id));
+details=$3 WHERE id=$4 AND group_id=$5", array($status, htmlspecialchars($summary), $details, $id, $group_id));
if (!$result || db_affected_rows($result) < 1) {
$feedback .= _('Error On Update:');
@@ -115,7 +115,7 @@ details=$3 WHERE id=$4 AND group_id=$5", array($status, htmlspecialchars($summar
echo notepad_func();
echo '
-
'.sprintf(_('Approve a NewsByte For Project: %1$s'), $group->getPublicName()).'
+
'.sprintf(_('Approve a NewsByte For Project: %1$s'), $group->getPublicName()).'
@@ -151,7 +151,7 @@ details=$3 WHERE id=$4 AND group_id=$5", array($status, htmlspecialchars($summar
unset($GLOBALS['editor_was_set_up']);
echo '
- '.sprintf(_('If this item is on the %1$s home page and you edit it, it will be removed from the home page.'), $GLOBALS['sys_name']).'
+ '.sprintf(_('If this item is on the %1$s home page and you edit it, it will be removed from the home page.'), forge_get_config ('forge_name')).'
';
@@ -164,12 +164,12 @@ details=$3 WHERE id=$4 AND group_id=$5", array($status, htmlspecialchars($summar
$rows=db_numrows($result);
$group =& group_get_object($group_id);
+ echo '
'._('List of News Submitted for Project').': '.$group->getPublicName().' ';
if ($rows < 1) {
echo '
-
'._('No Queued Items Found').': '.$group->getPublicName().' ';
+
'._('No Queued Items Found').'
';
} else {
echo '
-
'._('List of News Submitted for Project').': '.$group->getPublicName().'
';
for ($i=0; $i<$rows; $i++) {
echo '
@@ -200,7 +200,7 @@ details=$3 WHERE id=$4 AND group_id=$5", array($status, htmlspecialchars($summar
$sanitizer = new TextSanitizer();
$details = $sanitizer->SanitizeHtml($details);
$result=db_query_params("UPDATE news_bytes SET is_approved='1', post_date=$1,
-summary=$2, details=$3 WHERE id=$4", array(time(), htmlspecialchars($summary), addslashes($details), $id));
+summary=$2, details=$3 WHERE id=$4", array(time(), htmlspecialchars($summary), $details, $id));
if (!$result || db_affected_rows($result) < 1) {
$feedback .= _('Error On Update:');
} else {
@@ -262,7 +262,7 @@ AND news_bytes.group_id=groups.group_id ", array($id));
$user =& user_get_object(db_result($result,0,'submitted_by'));
echo '
- '.sprintf(_('Approve a NewsByte For Project: %1$s'), $group->getPublicName()).'
+ '.sprintf(_('Approve a NewsByte For Project: %1$s'), $group->getPublicName()).'
@@ -342,7 +342,7 @@ AND news_bytes.group_id=groups.group_id ", array($id));
} else {
- exit_error(_('Permission denied.'),sprintf(_('You have to be an admin on the project you are editing or a member of the %s News team.'), $GLOBALS['sys_name']));
+ exit_error(_('Permission denied.'),sprintf(_('You have to be an admin on the project you are editing or a member of the %s News team.'), forge_get_config ('forge_name')));
}
diff --git a/gforge/www/news/admin/news_admin_utils.php b/gforge/www/news/admin/news_admin_utils.php
index 0f89867621..2be76a5804 100644
--- a/gforge/www/news/admin/news_admin_utils.php
+++ b/gforge/www/news/admin/news_admin_utils.php
@@ -87,9 +87,9 @@ function show_news_approve_form($qpa_pending, $qpa_rejected, $qpa_approved) {
$rows=db_numrows($result);
if ($rows < 1) {
echo '
- '._('No rejected items found for this week').' ';
+ '._('No rejected items found for this week').' ';
} else {
- echo ''.sprintf(_('These items were rejected this past week (total: %1$s)'), $rows).' ';
+ echo ''.sprintf(_('These items were rejected this past week (total: %1$s)'), $rows).' ';
echo $GLOBALS['HTML']->listTableTop($title_arr);
for ($i=0; $i<$rows; $i++) {
show_news_item($result,$i,false,false);
@@ -105,9 +105,9 @@ function show_news_approve_form($qpa_pending, $qpa_rejected, $qpa_approved) {
$rows=db_numrows($result);
if ($rows < 1) {
echo '
- '._('No approved items found for this week').' ';
+ '._('No approved items found for this week').' ';
} else {
- echo ''.sprintf(_('These items were approved this past week (total: %1$s)'), $rows).' ';
+ echo ''.sprintf(_('These items were approved this past week (total: %1$s)'), $rows).' ';
echo $GLOBALS['HTML']->listTableTop($title_arr);
for ($i=0; $i<$rows; $i++) {
show_news_item($result,$i,true,false);
diff --git a/gforge/www/news/index.php b/gforge/www/news/index.php
index b3201c8fd1..3146b2a91c 100644
--- a/gforge/www/news/index.php
+++ b/gforge/www/news/index.php
@@ -36,6 +36,8 @@ $feedback = htmlspecialchars(getStringFromRequest('feedback'));
news_header(array('title'=>_('News')));
echo '' . _('News') . ' ';
+plugin_hook ("blocks", "news index");
+
echo _('Choose a News item and you can browse, search, and post messages.
');
/*
diff --git a/gforge/www/news/news_utils.php b/gforge/www/news/news_utils.php
index 706de8b809..f878a112db 100644
--- a/gforge/www/news/news_utils.php
+++ b/gforge/www/news/news_utils.php
@@ -29,9 +29,9 @@
*/
function news_header($params) {
- global $HTML,$group_id,$news_name,$news_id,$sys_news_group,$sys_use_news;
+ global $HTML,$group_id,$news_name,$news_id,$sys_news_group;
- if (!$sys_use_news) {
+ if (!forge_get_config('use_news')) {
exit_disabled();
}
diff --git a/gforge/www/news/submit.php b/gforge/www/news/submit.php
index 906b35d6d7..2c6de55341 100644
--- a/gforge/www/news/submit.php
+++ b/gforge/www/news/submit.php
@@ -97,7 +97,6 @@ if (session_loggedin()) {
exit_error('Error',$f->getErrorMessage());
}
$new_id=$f->getID();
-
$sql='INSERT INTO news_bytes (group_id,submitted_by,is_approved,post_date,forum_id,summary,details)
VALUES ($1, $2, $3, $4, $5, $6, $7)';
$result=db_query_params($sql,
@@ -124,13 +123,14 @@ if (session_loggedin()) {
/*
Show the submit form
*/
- news_header(array('title'=>_('News')));
+ news_header(array('title'=>_('Submit News')));
+ echo '' . _('Submit News') . ' ';
$jsfunc = notepad_func();
$group = group_get_object($group_id);
echo '
- '. sprintf(_('You can post news about your project if you are an admin on your project. You may also post "help wanted" notes if your project needs help.
All posts for your project will appear instantly on your project summary page. Posts that are of special interest to the community will have to be approved by a member of the %1$s news team before they will appear on the %1$s home page.
You may include URLs, but not HTML in your submissions.
URLs that start with http:// are made clickable.'), $GLOBALS['sys_name']) .'
' . $jsfunc .
+ '. sprintf(_('You can post news about your project if you are an admin on your project. You may also post "help wanted" notes if your project needs help.All posts for your project will appear instantly on your project summary page. Posts that are of special interest to the community will have to be approved by a member of the %1$s news team before they will appear on the %1$s home page.
You may include URLs, but not HTML in your submissions.
URLs that start with http:// are made clickable.'), forge_get_config ('forge_name')) .'
' . $jsfunc .
'
diff --git a/gforge/www/people/admin/index.php b/gforge/www/people/admin/index.php
index b357d4e3a2..0ed8600bcb 100644
--- a/gforge/www/people/admin/index.php
+++ b/gforge/www/people/admin/index.php
@@ -27,7 +27,7 @@ require_once('../../env.inc.php');
require_once $gfwww.'include/pre.php';
require_once $gfwww.'people/people_utils.php';
-if (!$sys_use_people) {
+if (!forge_get_config('use_people')) {
exit_disabled();
}
diff --git a/gforge/www/people/createjob.php b/gforge/www/people/createjob.php
index c000fb552c..ba57e3f9c3 100644
--- a/gforge/www/people/createjob.php
+++ b/gforge/www/people/createjob.php
@@ -28,7 +28,7 @@ require_once $gfwww.'include/pre.php';
require_once $gfwww.'people/people_utils.php';
require_once $gfwww.'project/admin/project_admin_utils.php';
-if (!$sys_use_people) {
+if (!forge_get_config('use_people')) {
exit_disabled();
}
diff --git a/gforge/www/people/editjob.php b/gforge/www/people/editjob.php
index cd9211b5aa..be696c13ed 100644
--- a/gforge/www/people/editjob.php
+++ b/gforge/www/people/editjob.php
@@ -27,7 +27,7 @@ require_once('../env.inc.php');
require_once $gfwww.'include/pre.php';
require_once $gfwww.'people/people_utils.php';
-if (!$sys_use_people) {
+if (!forge_get_config('use_people')) {
exit_disabled();
}
diff --git a/gforge/www/people/editprofile.php b/gforge/www/people/editprofile.php
index 138e339363..93c0024104 100644
--- a/gforge/www/people/editprofile.php
+++ b/gforge/www/people/editprofile.php
@@ -13,7 +13,7 @@ require_once $gfwww.'include/pre.php';
require_once $gfwww.'people/people_utils.php';
require_once $gfwww.'people/skills_utils.php';
-if (!$sys_use_people) {
+if (!forge_get_config('use_people')) {
exit_disabled();
}
diff --git a/gforge/www/people/helpwanted-latest.php b/gforge/www/people/helpwanted-latest.php
index 435abbd5f9..d8d21c75af 100644
--- a/gforge/www/people/helpwanted-latest.php
+++ b/gforge/www/people/helpwanted-latest.php
@@ -27,7 +27,7 @@ require_once('../env.inc.php');
require_once $gfwww.'include/pre.php';
require_once $gfwww.'people/people_utils.php';
-if (!$sys_use_people) {
+if (!forge_get_config('use_people')) {
exit_disabled();
}
diff --git a/gforge/www/people/index.php b/gforge/www/people/index.php
index f45eee3a2a..520d625688 100644
--- a/gforge/www/people/index.php
+++ b/gforge/www/people/index.php
@@ -28,7 +28,7 @@ require_once $gfwww.'include/pre.php';
require_once $gfwww.'people/people_utils.php';
require_once $gfwww.'project/admin/project_admin_utils.php';
-if (!$sys_use_people) {
+if (!forge_get_config('use_people')) {
exit_disabled();
}
@@ -58,7 +58,7 @@ if ($group_id) {
people_header(array('title'=>_('Help Wanted System')));
- printf(_('The %1$s Project Help Wanted board is for non-commercial, project volunteer openings. Commercial use is prohibited.
Project listings remain live for two weeks, or until closed by the poster, whichever comes first. (Project administrators may always re-post expired openings.)
Browse through the category menu to find projects looking for your help.
If you\'re a project admin, log in and submit help wanted requests through your project administration page.
To suggest new job categories, submit a request via the support manager.
'), $GLOBALS['sys_name']);
+ printf(_('The %1$s Project Help Wanted board is for non-commercial, project volunteer openings. Commercial use is prohibited.
Project listings remain live for two weeks, or until closed by the poster, whichever comes first. (Project administrators may always re-post expired openings.)
Browse through the category menu to find projects looking for your help.
If you\'re a project admin, log in and submit help wanted requests through your project administration page.
To suggest new job categories, submit a request via the support manager.
'), forge_get_config ('forge_name'));
echo people_show_category_table();
diff --git a/gforge/www/people/people_utils.php b/gforge/www/people/people_utils.php
index 082e316b20..f6b5bd36a9 100644
--- a/gforge/www/people/people_utils.php
+++ b/gforge/www/people/people_utils.php
@@ -400,7 +400,7 @@ function people_show_job_list($result) {
$title_arr[]=_('Title');
$title_arr[]=_('Category');
$title_arr[]=_('Date Opened');
- $title_arr[]= sprintf(_('%1$s project'), $GLOBALS['sys_name']);
+ $title_arr[]= sprintf(_('%1$s project'), forge_get_config ('forge_name'));
$return = $GLOBALS['HTML']->listTableTop ($title_arr);
diff --git a/gforge/www/people/viewjob.php b/gforge/www/people/viewjob.php
index ffcd5d0496..0c61e3912c 100644
--- a/gforge/www/people/viewjob.php
+++ b/gforge/www/people/viewjob.php
@@ -27,7 +27,7 @@ require_once('../env.inc.php');
require_once $gfwww.'include/pre.php';
require_once $gfwww.'people/people_utils.php';
-if (!$sys_use_people) {
+if (!forge_get_config('use_people')) {
exit_disabled();
}
diff --git a/gforge/www/people/viewprofile.php b/gforge/www/people/viewprofile.php
index 207785485b..6a2f7e1145 100644
--- a/gforge/www/people/viewprofile.php
+++ b/gforge/www/people/viewprofile.php
@@ -13,7 +13,7 @@ require_once $gfwww.'include/pre.php';
require_once $gfwww.'people/people_utils.php';
require_once $gfwww.'people/skills_utils.php';
-if (!$sys_use_people) {
+if (!forge_get_config('use_people')) {
exit_disabled();
}
diff --git a/gforge/www/plugins/mediawiki b/gforge/www/plugins/mediawiki
new file mode 120000
index 0000000000..838d4a5a41
--- /dev/null
+++ b/gforge/www/plugins/mediawiki
@@ -0,0 +1 @@
+../../plugins/mediawiki/www
\ No newline at end of file
diff --git a/gforge/www/pm/add_task.php b/gforge/www/pm/add_task.php
index c0178cbb56..e75b53c497 100644
--- a/gforge/www/pm/add_task.php
+++ b/gforge/www/pm/add_task.php
@@ -8,7 +8,7 @@
*/
/*
- Project/Task Manager
+ Tasks
By Tim Perdue, Sourceforge, 11/99
Heavy rewrite by Tim Perdue April 2000
diff --git a/gforge/www/pm/admin/index.php b/gforge/www/pm/admin/index.php
index 1e696153a1..9f9df94c7f 100644
--- a/gforge/www/pm/admin/index.php
+++ b/gforge/www/pm/admin/index.php
@@ -8,7 +8,7 @@
*/
/*
- Project/Task Manager
+ Tasks
By Tim Perdue, Sourceforge, 11/99
Heavy rewrite by Tim Perdue April 2000
@@ -72,7 +72,9 @@ if (getStringFromRequest('post_changes')) {
if (!$pg->create($project_name,$description,$is_public,$send_all_posts_to)) {
exit_error('Error',$pg->getErrorMessage());
} else {
- $feedback .= _('Project Inserted');
+ $feedback .= _('Subproject Inserted');
+ $feedback .= ' ';
+ $feedback .= _("Please configure also the roles (by default, it's 'No Access')");
}
} else if ($add_cat) {
@@ -178,8 +180,9 @@ if ($add_cat && $group_project_id) {
if (!$pg->userIsAdmin()) {
exit_permission_denied();
}
- pm_header(array ('title'=>_('Add Categories')));
- echo ""._('Add Categories To').": ". $pg->getName() ." ";
+
+ $title = sprintf(_('Add Categories to: %s'), $pg->getName());
+ pm_header(array ('title'=>$title));
/*
List of possible categories for this ArtifactType
@@ -242,9 +245,8 @@ if ($add_cat && $group_project_id) {
if (!$pg->userIsAdmin()) {
exit_permission_denied();
}
- pm_header(array ('title'=>_('Add Categories')));
-
- echo ''._('Modify an Category in').': '. $pg->getName() .' ';
+ $title = sprintf(_('Modify a Category in: %s'), $pg->getName());
+ pm_header(array ('title'=>$title));
$ac = new ProjectCategory($pg,$id);
if (!$ac || !is_object($ac)) {
@@ -279,10 +281,10 @@ if ($add_cat && $group_project_id) {
exit_permission_denied();
}
- pm_header(array ('title'=>_('Add a new project')));
+ pm_header(array ('title'=>_('Add a new subproject')));
?>
- This is different than adding a task to a project.') ?>
+ This is different than adding a task to a subproject.') ?>
" method="post">
@@ -293,7 +295,7 @@ if ($add_cat && $group_project_id) {
-
+
@@ -320,10 +322,10 @@ if ($add_cat && $group_project_id) {
exit_permission_denied();
}
- pm_header(array('title'=>_('Change Project/Task Manager Status')));
+ pm_header(array('title'=>_('Change Tasks Status')));
?>
-
+
@@ -340,7 +342,7 @@ if ($add_cat && $group_project_id) {
-->
- :
+ :
@@ -409,7 +411,7 @@ if ($add_cat && $group_project_id) {
/*
Show main page
*/
- pm_header(array('title'=>_('Project/Task Manager Administration')));
+ pm_header(array('title'=>_('Tasks Administration')));
//
// Show link to create new subproject
@@ -417,8 +419,8 @@ if ($add_cat && $group_project_id) {
if ($perm->isPMAdmin()) {
?>
-
-
+
+
getProjectGroups();
if (count($pg_arr) < 1 || $pg_arr == false) {
- echo _('No Projects Found None found for this group. You may add new Projects using the "Add A Project" link above.
');
+ echo _('No Subprojects Found in this Project You may add new Subprojects using the "Add a Subproject" link above.
');
echo db_error();
} else {
for ($i=0; $i'._('Edit/Update Project').': '.$pg_arr[$i]->getName().'
';
+ echo ''._('Edit/Update Subproject').': '.$pg_arr[$i]->getName().'
';
}
}
diff --git a/gforge/www/pm/browse_task.php b/gforge/www/pm/browse_task.php
index 90d33c0115..e87cb273fd 100644
--- a/gforge/www/pm/browse_task.php
+++ b/gforge/www/pm/browse_task.php
@@ -8,7 +8,7 @@
*/
/*
- Project/Task Manager
+ Tasks
By Tim Perdue, Sourceforge, 11/99
Heavy rewrite by Tim Perdue April 2000
diff --git a/gforge/www/pm/csv.php b/gforge/www/pm/csv.php
index ad42f2c497..528aaaa30b 100644
--- a/gforge/www/pm/csv.php
+++ b/gforge/www/pm/csv.php
@@ -48,7 +48,7 @@
//
-pm_header(array('title'=>_('Upload data into the task manager.'),'group_project_id'=>$group_project_id));
+pm_header(array('title'=>_('Upload data into the tasks.'),'group_project_id'=>$group_project_id));
$headers = getIntFromRequest('headers', 1);
$full = getIntFromRequest('full', 1);
diff --git a/gforge/www/pm/deletetask.php b/gforge/www/pm/deletetask.php
index 70c6f89c67..3dfd434485 100644
--- a/gforge/www/pm/deletetask.php
+++ b/gforge/www/pm/deletetask.php
@@ -8,7 +8,7 @@
*/
/*
- Project/Task Manager
+ Tasks
By Tim Perdue, Sourceforge, 11/99
Heavy rewrite by Tim Perdue April 2000
diff --git a/gforge/www/pm/detail_task.php b/gforge/www/pm/detail_task.php
index b89c8627c8..651870908a 100644
--- a/gforge/www/pm/detail_task.php
+++ b/gforge/www/pm/detail_task.php
@@ -8,7 +8,7 @@
*/
/*
- Project/Task Manager
+ Tasks
By Tim Perdue, Sourceforge, 11/99
Heavy rewrite by Tim Perdue April 2000
diff --git a/gforge/www/pm/format_csv.php b/gforge/www/pm/format_csv.php
index c313717e41..9b1ad659c8 100644
--- a/gforge/www/pm/format_csv.php
+++ b/gforge/www/pm/format_csv.php
@@ -48,7 +48,7 @@
//
-pm_header(array('title'=>_('Upload data into the task manager.'),'group_project_id'=>$group_project_id));
+pm_header(array('title'=>_('Upload data into the tasks.'),'group_project_id'=>$group_project_id));
$headers = getIntFromRequest('headers', 1);
$full = getIntFromRequest('full', 1);
diff --git a/gforge/www/pm/ganttpage.php b/gforge/www/pm/ganttpage.php
index 0bec5c58b9..a88ca1bde8 100644
--- a/gforge/www/pm/ganttpage.php
+++ b/gforge/www/pm/ganttpage.php
@@ -8,7 +8,7 @@
*/
/*
- Project/Task Manager
+ Tasks
By Tim Perdue, Sourceforge, 11/99
Heavy rewrite by Tim Perdue April 2000
diff --git a/gforge/www/pm/include/ProjectGroupHTML.class.php b/gforge/www/pm/include/ProjectGroupHTML.class.php
index 6fba1ba6a0..71b6125ea8 100644
--- a/gforge/www/pm/include/ProjectGroupHTML.class.php
+++ b/gforge/www/pm/include/ProjectGroupHTML.class.php
@@ -8,7 +8,7 @@
*/
/*
- Project/Task Manager
+ Tasks
By Tim Perdue, Sourceforge, 11/99
Heavy rewrite by Tim Perdue April 2000
@@ -19,9 +19,9 @@ require_once $gfcommon.'pm/ProjectGroup.class.php';
function pm_header($params) {
// XXX ogi: What to do with these?
- global $group_id,$is_pm_page,$words,$group_project_id,$HTML,$order,$pg,$sys_use_pm;
+ global $group_id,$is_pm_page,$words,$group_project_id,$HTML,$order,$pg;
- if (!$sys_use_pm) {
+ if (!forge_get_config('use_pm')) {
exit_disabled();
}
@@ -36,10 +36,11 @@ function pm_header($params) {
}
if (!$project->usesPm()) {
- exit_error(_('Error'),_('This Project Has Turned Off The Task Manager'));
+ exit_error(_('Error'),_('This Project Has Turned Off The Tasks'));
}
site_project_header($params);
+ echo '' . $params['title']. ' ';
$labels = array();
$links = array();
@@ -81,6 +82,8 @@ function pm_header($params) {
echo ($HTML->subMenu($labels,$links));
}
+ if ($pg)
+ plugin_hook ("blocks", "tasks_".$pg->getName());
}
function pm_footer($params) {
diff --git a/gforge/www/pm/include/ProjectTaskHTML.class.php b/gforge/www/pm/include/ProjectTaskHTML.class.php
index 0ecd2c95c5..be6da04858 100644
--- a/gforge/www/pm/include/ProjectTaskHTML.class.php
+++ b/gforge/www/pm/include/ProjectTaskHTML.class.php
@@ -8,7 +8,7 @@
*/
/*
- Project/Task Manager
+ Tasks
By Tim Perdue, Sourceforge, 11/99
Heavy rewrite by Tim Perdue April 2000
diff --git a/gforge/www/pm/index.php b/gforge/www/pm/index.php
index 9fcbbd3923..d4d7980a8e 100644
--- a/gforge/www/pm/index.php
+++ b/gforge/www/pm/index.php
@@ -8,7 +8,7 @@
*/
/*
- Project/Task Manager
+ Tasks
By Tim Perdue, Sourceforge, 11/99
Heavy rewrite by Tim Perdue April 2000
@@ -44,7 +44,9 @@ if ($pg_arr && $pgf->isError()) {
exit_error('Error',$pgf->getErrorMessage());
}
-pm_header(array('title'=>_('Project/Task Manager: Subprojects And Tasks')));
+pm_header(array('title'=>_('Subprojects and Tasks')));
+
+plugin_hook("blocks", "tasks index");
$perm =& $g->getPermission( session_get_user() );
if ($perm->isPMAdmin()) {
@@ -56,7 +58,9 @@ if ($perm->isPMAdmin()) {
}
if (count($pg_arr) < 1 || $pg_arr == false) {
- echo ''._('
No Subprojects Found No subprojects have been set up, or you cannot view them.
The Admin for this project will have to set up projects using the admin page ').'
';
+ echo ''._('No Subprojects Found').'
';
+ echo ''._('No subprojects have been set up, or you cannot view them.').'
';
+ echo ''._('The Admin for this project will have to set up subprojects using the admin page.').'
';
} else {
echo '
'._('Choose a Subproject and you can browse/edit/add tasks to it.').'
';
@@ -66,8 +70,8 @@ if (count($pg_arr) < 1 || $pg_arr == false) {
*/
$tablearr=array(_('Subproject Name'),
_('Description'),
- _('Open'),
- _('Total'));
+ _('Open Tasks'),
+ _('Total Number of Tasks'));
echo $HTML->listTableTop($tablearr);
for ($j = 0; $j < count($pg_arr); $j++) {
@@ -79,11 +83,11 @@ if (count($pg_arr) < 1 || $pg_arr == false) {
echo '
boxGetAltRowStyle($j) . '>
' .
- html_image("ic/taskman20w.png","20","20",array("border"=>"0")) . ' '.
+ html_image("ic/taskman20w.png","20","20",array("border"=>"0", "align"=>"middle")) . ' '.
$pg_arr[$j]->getName() .'
'.$pg_arr[$j]->getDescription() .'
- '. (int) $pg_arr[$j]->getOpenCount().'
- '. (int) $pg_arr[$j]->getTotalCount().'
+ '. (int) $pg_arr[$j]->getOpenCount().'
+ '. (int) $pg_arr[$j]->getTotalCount().'
';
}
}
diff --git a/gforge/www/pm/mod_task.php b/gforge/www/pm/mod_task.php
index 7a92041baa..59518ca5a8 100644
--- a/gforge/www/pm/mod_task.php
+++ b/gforge/www/pm/mod_task.php
@@ -8,7 +8,7 @@
*/
/*
- Project/Task Manager
+ Tasks
By Tim Perdue, Sourceforge, 11/99
Heavy rewrite by Tim Perdue April 2000
diff --git a/gforge/www/pm/msproject/msp.php b/gforge/www/pm/msproject/msp.php
index 1707863a43..6ffb4e323c 100644
--- a/gforge/www/pm/msproject/msp.php
+++ b/gforge/www/pm/msproject/msp.php
@@ -31,24 +31,13 @@ return data:
$array[errormessage]='Bad Password';
*/
function &MSPLogin($username,$password) {
- global $feedback,$session_ser,$sys_database_type;
+ global $feedback,$session_ser;
$success=session_login_valid(strtolower($username),$password);
if ($success) {
$array['success']=true;
$array['session_hash']=$session_ser;
- if ( $sys_database_type == "mysql" ) {
- $sql="SELECT pgl.group_project_id, CONCAT(g.group_name, ': ', pgl.project_name) AS name
- FROM groups g, project_group_list pgl, role_setting rs, user_group ug
- WHERE ug.user_id='".user_getid()."'
- AND g.group_id=pgl.group_id
- AND rs.value::integer > 0
- AND rs.group_project_id = pgl.group_project_id
- AND ug.role_id = rs.role_id
- AND rs.section_name='pm'";
- $res=db_query_mysql($sql);
- } else {
- $res=db_query_params ('SELECT pgl.group_project_id, g.group_name || $1 || pgl.project_name AS name
+ $res=db_query_params ('SELECT pgl.group_project_id, g.group_name || $1 || pgl.project_name AS name
FROM groups g, project_group_list pgl, role_setting rs, user_group ug
WHERE ug.user_id=$2
AND g.group_id=pgl.group_id
@@ -56,10 +45,9 @@ function &MSPLogin($username,$password) {
AND rs.group_project_id = pgl.group_project_id
AND ug.role_id = rs.role_id
AND rs.section_name=$3',
- array(': ',
- user_getid(),
- 'pm'));
- }
+ array(': ',
+ user_getid(),
+ 'pm'));
$rows=db_numrows($res);
if (!$res || $rows<1) {
$array['success']=false;
diff --git a/gforge/www/pm/reporting/index.php b/gforge/www/pm/reporting/index.php
index 1ba563f82c..1a53a9ed5d 100644
--- a/gforge/www/pm/reporting/index.php
+++ b/gforge/www/pm/reporting/index.php
@@ -8,7 +8,7 @@
*/
/*
- Project/Task Manager
+ Tasks
By Tim Perdue, Sourceforge, 11/99
Heavy rewrite by Tim Perdue April 2000
diff --git a/gforge/www/pm/task.php b/gforge/www/pm/task.php
index 6cc69ae146..a6d74e2bc8 100644
--- a/gforge/www/pm/task.php
+++ b/gforge/www/pm/task.php
@@ -8,7 +8,7 @@
*/
/*
- Project/Task Manager
+ Tasks
By Tim Perdue, Sourceforge, 11/99
Heavy rewrite by Tim Perdue April 2000
@@ -280,7 +280,10 @@ switch (getStringFromRequest('func')) {
unset($pt);
}
}
- if (!$was_error) {
+ if ($count == 0) {
+ $warning_msg = _('No task selected');
+ }
+ elseif (!$was_error) {
$feedback = _('Task Updated Successfully');
}
include $gfwww.'pm/browse_task.php';
diff --git a/gforge/www/pm/uploadcsv.php b/gforge/www/pm/uploadcsv.php
index eea15d8fa7..f7df9d8bf3 100644
--- a/gforge/www/pm/uploadcsv.php
+++ b/gforge/www/pm/uploadcsv.php
@@ -6,7 +6,7 @@
//
-pm_header(array('title'=>_('Upload data into the task manager.'),'group_project_id'=>$group_project_id));
+pm_header(array('title'=>_('Upload data into the tasks.'),'group_project_id'=>$group_project_id));
?>
diff --git a/gforge/www/project/admin/database.php b/gforge/www/project/admin/database.php
index fbb05a7652..baa10dcb2a 100644
--- a/gforge/www/project/admin/database.php
+++ b/gforge/www/project/admin/database.php
@@ -33,7 +33,7 @@ require_once('../../env.inc.php');
require_once $gfwww.'include/pre.php';
require_once $gfwww.'project/admin/project_admin_utils.php';
-if (!$sys_use_project_database) {
+if (!forge_get_config('use_project_database')) {
exit_disabled();
}
diff --git a/gforge/www/project/admin/editgroupinfo.php b/gforge/www/project/admin/editgroupinfo.php
index adf32985d1..702673c2b1 100644
--- a/gforge/www/project/admin/editgroupinfo.php
+++ b/gforge/www/project/admin/editgroupinfo.php
@@ -191,7 +191,7 @@ function c($v) {
@@ -204,7 +204,7 @@ if($sys_use_mail) {
@@ -217,7 +217,7 @@ if($sys_use_survey) {
@@ -230,7 +230,7 @@ if($sys_use_forum) {
@@ -243,7 +243,7 @@ if($sys_use_pm) {
@@ -256,7 +256,7 @@ if($sys_use_scm) {
@@ -269,7 +269,7 @@ if($sys_use_news) {
@@ -282,7 +282,7 @@ if($sys_use_docman) {
@@ -295,7 +295,7 @@ if($sys_use_ftp) {
@@ -308,7 +308,7 @@ if($sys_use_tracker) {
@@ -335,7 +335,7 @@ plugin_hook("groupisactivecheckbox",$hookParams);
.
diff --git a/gforge/www/project/admin/editimages.php b/gforge/www/project/admin/editimages.php
index e35dfdfb4a..fda79f213c 100644
--- a/gforge/www/project/admin/editimages.php
+++ b/gforge/www/project/admin/editimages.php
@@ -31,7 +31,7 @@ require_once('../../env.inc.php');
require_once $gfwww.'include/pre.php';
require_once $gfwww.'project/admin/project_admin_utils.php';
-if (!$sys_use_project_multimedia) {
+if (!forge_get_config('use_project_multimedia')) {
exit_disabled();
}
diff --git a/gforge/www/project/admin/group_trove.php b/gforge/www/project/admin/group_trove.php
index 3402c9eec2..58596c65c5 100644
--- a/gforge/www/project/admin/group_trove.php
+++ b/gforge/www/project/admin/group_trove.php
@@ -69,10 +69,12 @@ if (getStringFromRequest('submit') && getStringFromRequest('root1')) {
session_redirect('/project/admin/?group_id='.$group_id);
}
-project_admin_header(array('title'=>_('Group Trove Information'),'group'=>$group_id));
+project_admin_header(array('title'=>_('Edit Trove Categorization'),'group'=>$group_id));
?>
-Edit Trove Categorization
Select up to three locations for this project in each of the Trove root categories. If the project does not require any or all of these locations, simply select "None Selected".
IMPORTANT: Projects should be categorized in the most specific locations available in the map. Simultaneous categorization in a specific category AND a parent category will result in only the more specific categorization being accepted
.') ?>
+
+
+
diff --git a/gforge/www/project/admin/index.php b/gforge/www/project/admin/index.php
index 6e3509b4fe..eda9a5a7d4 100644
--- a/gforge/www/project/admin/index.php
+++ b/gforge/www/project/admin/index.php
@@ -69,10 +69,10 @@ project_admin_header(array('title'=>$adminheadertitle, 'group'=>$group->getID())
-getUnixName().'.'.$GLOBALS['sys_default_domain']; ?>
+getUnixName().'.'.forge_get_config('web_host'); ?>
getUnixName()); ?>
getUnixName()).'/htdocs'; ?>
diff --git a/gforge/www/project/admin/project_admin_utils.php b/gforge/www/project/admin/project_admin_utils.php
index f977a0f5ef..208e84870b 100644
--- a/gforge/www/project/admin/project_admin_utils.php
+++ b/gforge/www/project/admin/project_admin_utils.php
@@ -62,17 +62,17 @@ function project_admin_header($params) {
$labels[] = _('Users');
$labels[] = _('Tools');
$labels[] = _('Project History');
- if($GLOBALS['sys_use_people']) {
+ if(forge_get_config('use_people')) {
$labels[] = _('Post Jobs');
$labels[] = _('Edit Jobs');
}
- if($GLOBALS['sys_use_project_multimedia']) {
+ if(forge_get_config('use_project_multimedia')) {
$labels[] = _('Edit Multimedia Data');
}
- if($GLOBALS['sys_use_project_vhost']) {
+ if(forge_get_config('use_project_vhost')) {
$labels[] = _('VHOSTs');
}
- if($GLOBALS['sys_use_project_database']) {
+ if(forge_get_config('use_project_database')) {
$labels[] = _('Database Admin');
}
if ($project->usesStats()) {
@@ -84,17 +84,17 @@ function project_admin_header($params) {
$links[] = '/project/admin/users.php?group_id='.$group_id;
$links[] = '/project/admin/tools.php?group_id='.$group_id;
$links[] = '/project/admin/history.php?group_id='.$group_id;
- if($GLOBALS['sys_use_people']) {
+ if(forge_get_config('use_people')) {
$links[] = '/people/createjob.php?group_id='.$group_id;
$links[] = '/people/?group_id='.$group_id;
}
- if($GLOBALS['sys_use_project_multimedia']) {
+ if(forge_get_config('use_project_multimedia')) {
$links[] = '/project/admin/editimages.php?group_id='.$group_id;
}
- if($GLOBALS['sys_use_project_vhost']) {
+ if(forge_get_config('use_project_vhost')) {
$links[] = '/project/admin/vhost.php?group_id='.$group_id;
}
- if($GLOBALS['sys_use_project_database']) {
+ if(forge_get_config('use_project_database')) {
$links[] = '/project/admin/database.php?group_id='.$group_id;
}
$links[] = '/project/stats/?group_id='.$group_id;
diff --git a/gforge/www/project/admin/tools.php b/gforge/www/project/admin/tools.php
index 051fd02f3f..57567f4985 100644
--- a/gforge/www/project/admin/tools.php
+++ b/gforge/www/project/admin/tools.php
@@ -131,7 +131,7 @@ function c($v) {
@@ -144,7 +144,7 @@ if($sys_use_forum) {
@@ -157,7 +157,7 @@ if($sys_use_tracker) {
@@ -170,20 +170,20 @@ if($sys_use_mail) {
usesPM()); ?> />
-
+
@@ -196,7 +196,7 @@ if($sys_use_docman) {
@@ -209,7 +209,7 @@ if($sys_use_survey) {
@@ -222,7 +222,7 @@ if($sys_use_news) {
@@ -235,7 +235,7 @@ if($sys_use_scm) {
@@ -248,7 +248,7 @@ if($sys_use_frs) {
@@ -300,7 +300,7 @@ if($group->usesMail()) { ?>
usesPM()) { ?>
-
+
usesDocman()) { ?>
diff --git a/gforge/www/project/admin/vhost.php b/gforge/www/project/admin/vhost.php
index 7237a7c471..c401cc29f1 100644
--- a/gforge/www/project/admin/vhost.php
+++ b/gforge/www/project/admin/vhost.php
@@ -28,7 +28,7 @@ require_once('../../env.inc.php');
require_once $gfwww.'include/pre.php';
require_once $gfwww.'project/admin/project_admin_utils.php';
-if (!$sys_use_project_vhost) {
+if (!forge_get_config('use_project_vhost')) {
exit_disabled();
}
@@ -108,7 +108,7 @@ project_admin_header(array('title'=>_('Virtual Host Management'),'group'=>$group
-Add New Virtual Host To add a new virtual host - simply point a CNAME for yourhost.org at %1$s.%2$s . %3$s does not currently host mail (i.e. cannot be an MX) or DNS.
Clicking on "create" will schedule the creation of the Virtual Host. This will be synced to the project webservers - such that yourhost.org will display the material at %4$s.%5$s .'), $group->getUnixName(), $GLOBALS['sys_default_domain'], $GLOBALS['sys_name'], $group->getUnixName(), $GLOBALS['sys_default_domain']) ?>
+Add New Virtual Host
To add a new virtual host - simply point a CNAME for yourhost.org at %1$s.%2$s . %3$s does not currently host mail (i.e. cannot be an MX) or DNS.
Clicking on "create" will schedule the creation of the Virtual Host. This will be synced to the project webservers - such that yourhost.org will display the material at %4$s.%5$s .'), $group->getUnixName(), forge_get_config('web_host'), forge_get_config ('forge_name'), $group->getUnixName(), forge_get_config('web_host')) ?>
diff --git a/gforge/www/project/memberlist.php b/gforge/www/project/memberlist.php
index 3f59408aa6..afb45977c5 100644
--- a/gforge/www/project/memberlist.php
+++ b/gforge/www/project/memberlist.php
@@ -23,7 +23,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-
require_once('../env.inc.php');
require_once $gfwww.'include/pre.php';
@@ -36,13 +35,23 @@ if (!$group_id && $form_grp) {
site_project_header(array('title'=>_('Project Member List'),'group'=>$group_id,'toptab'=>'memberlist'));
-echo _('If you would like to contribute to this project by becoming a developer, contact one of the project admins, designated in bold text below.
');
+echo '' . _('Project Member List') . ' ';
+
+echo '' . _('If you would like to contribute to this project by becoming a developer, contact one of the project admins, designated in bold text below.') . '
';
+// beginning of the user descripion block
+$project =& group_get_object($group_id);
+$project_stdzd_uri = util_make_url_g ($project->getUnixName(), $group_id);
+$usergroup_stdzd_uri = $project_stdzd_uri.'members/';
+print '';
+print ' ';
+print ' ';
+print '
';
$title_arr=array();
$title_arr[]=_('Member');
$title_arr[]=_('Username');
$title_arr[]=_('Role/Position');
-if($GLOBALS['sys_use_people']) {
+if(forge_get_config('use_people')) {
$title_arr[]=_('Skills');
}
@@ -56,23 +65,41 @@ $res_memb = db_query_params("SELECT users.*,user_group.admin_flags,role.role_nam
AND user_group.group_id=$1
AND users.status='A'
ORDER BY users.user_name ", array($group_id));
+
$i=0;
while ( $row_memb=db_fetch_array($res_memb) ) {
- echo 'boxGetAltRowStyle($i++).'>';
+ echo ' boxGetAltRowStyle($i++).'>'."\n";
+ // RDFa
+ $member_uri = util_make_url_u ($row_memb['user_name'],$row_memb['user_id']);
+ print '';
+ print '
';
+ print '
';
if ( trim($row_memb['admin_flags'])=='A' ) {
+// echo '
';
echo '
'.$row_memb['realname'].' ';
+// echo '';
} else {
+// echo '
';
echo '
'.$row_memb['realname'].' ';
+// echo '';
}
-
+
+ /*
+ print '
';
+ echo ' ';
+ print '
';
+ echo ' ';
+ print '
';
+ echo ' ';*/
echo '
'.util_make_link_u ($row_memb['user_name'],$row_memb['user_id'],$row_memb['user_name']).'
'.$row_memb['role'].' ';
- if($GLOBALS['sys_use_people']) {
+ if(forge_get_config('use_people')) {
echo '
'.util_make_link ('/people/viewprofile.php?user_id='.$row_memb['user_id'],_('View')).' ';
}
- echo '
';
+ print '';
+ echo ' ';
}
-
+// end of community member description block
echo $GLOBALS['HTML']->listTableBottom();
site_project_footer(array());
diff --git a/gforge/www/project/report/index.php b/gforge/www/project/report/index.php
index 9ffba0a9b2..4f60f3aee0 100644
--- a/gforge/www/project/report/index.php
+++ b/gforge/www/project/report/index.php
@@ -126,10 +126,11 @@ if (!$group_id && $form_grp) {
$group_id = $form_grp;
}
-site_project_header(array('title'=>_('Project Member List'),'group'=>$group_id,'toptab'
-=>'memberlist'));
+site_project_header(array('title'=>_('Project Member List'),'group'=>$group_id,'toptab'=>'memberlist'));
-echo _('If you would like to contribute to this project by becoming a developer, contact one of the project admins, designated in bold text below.
');
+echo '';
+echo _('If you would like to contribute to this project by becoming a developer, contact one of the project admins, designated in bold text below.');
+echo '
';
$title_arr=array();
$title_arr[]=_('Developer');
@@ -165,7 +166,7 @@ while ( $row_memb=db_fetch_array($res_memb) ) {
'.$row_memb['role'].'
';
- if($GLOBALS['sys_use_people']) {
+ if(forge_get_config('use_people')) {
echo '
'.util_make_link('/people/viewprofile.php?user_id='.$row_memb['user_id'],_('View')).'
';
diff --git a/gforge/www/project/request.php b/gforge/www/project/request.php
index 4d76aac7dd..6e90e4e765 100644
--- a/gforge/www/project/request.php
+++ b/gforge/www/project/request.php
@@ -22,7 +22,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-
require_once('../env.inc.php');
require_once $gfwww.'include/pre.php';
require_once $gfcommon.'include/GroupJoinRequest.class.php';
@@ -54,6 +53,10 @@ if ($submit) {
site_project_header(array('title'=>_('Request to join project'),'group'=>$group_id,'toptab'=>'summary'));
+echo '' . _('Request to join project') . ' ';
+
+plugin_hook ("blocks", "request_join");
+
?>
getAdmins());
@@ -61,8 +64,8 @@ echo ngettext('You can request to join a project by clicking the submit button.
" method="post">
-
+
diff --git a/gforge/www/project/stats/index.php b/gforge/www/project/stats/index.php
index 86fd419513..3b7e0a19b6 100644
--- a/gforge/www/project/stats/index.php
+++ b/gforge/www/project/stats/index.php
@@ -42,6 +42,14 @@ if (!$end || $end <= $start) {
$end = $z[count($z)-1];
}
+// Find a default SPAN value depending on the number of days.
+$delta=($end - $start)/24/60/60;
+if (!$SPAN) {
+ $SPAN = 1;
+ if ($delta > 60) $SPAN=2;
+ if ($delta > 365) $SPAN=3;
+}
+
site_project_header(array('title'=>_('Project Activity').' '.$group->getPublicName(),'group'=>$group_id,'toptab'=>'home'));
$area = util_ensure_value_in_set ($area, array ('tracker','forum','docman','taskman','downloads')) ;
diff --git a/gforge/www/register/projectinfo.php b/gforge/www/register/projectinfo.php
index e8ed6fae9c..50ef7fd475 100644
--- a/gforge/www/register/projectinfo.php
+++ b/gforge/www/register/projectinfo.php
@@ -46,7 +46,7 @@ require_once $gfcommon.'scm/SCMFactory.class.php';
if ($sys_project_reg_restricted) {
session_require(array('group'=>'1','admin_flags'=>'A'),
sprintf (_('Project registration is restricted on %s, and only administrators can create new projects.'),
- $sys_name));
+ forge_get_config ('forge_name')));
} elseif (!session_loggedin()) {
exit_not_logged_in();
}
@@ -64,19 +64,23 @@ if (getStringFromRequest('submit')) {
$is_public = getIntFromRequest('is_public');
$feedback = "";
- if ($sys_use_scm && !$scm) {
+ if (forge_get_config('use_scm') && !$scm) {
form_release_key(getStringFromRequest("form_key"));
// $feedback .= _('Site has SCM enabled, but no SCM was chosen.');
} else {
$scm_host = '';
$plugin = false ;
- if ($sys_use_scm && $scm && $scm != 'noscm') {
+ if (forge_get_config('use_scm') && $scm && $scm != 'noscm') {
$plugin = plugin_get_object($scm);
if ($plugin) {
$scm_host = $plugin->getDefaultServer();
}
}
+ if ( !$purpose && ($sys_project_reg_autoapprove == true) ) {
+ $purpose = 'No purpose given, autoapprove was on';
+ }
+
$group = new Group();
$u =& session_get_user();
$res = $group->create(
@@ -89,7 +93,7 @@ if (getStringFromRequest('submit')) {
$scm_host,
$is_public
);
- if ($res && $sys_use_scm && $plugin) {
+ if ($res && forge_get_config('use_scm') && $plugin) {
$group->setUsesSCM (true) ;
$res = $group->setPluginUse ($scm, true);
} else {
@@ -101,14 +105,27 @@ if (getStringFromRequest('submit')) {
$feedback .= $group->getErrorMessage();
} else {
$HTML->header(array('title'=>_('Registration complete')));
-
- ?>
-
- Thank you for choosing %1$s'), $GLOBALS['sys_name'])?>
-
-
- Your project has been submitted to the %1$s administrators. Within 72 hours, you will receive notification of their decision and further instructions.
Thank you for choosing %1$s'), forge_get_config ('forge_name'));
+ } else if ($group->isError()) {
+ printf(_('ERROR: %1$s
'), $group->getErrorMessage() );
+ } else {
+ printf(_('Approving Project: %1$s'), $group->getUnixName()).' ';
+
+ if (!$group->approve( user_get_object_by_name ( $sys_project_reg_autoapprove_user ) ) ) {
+ printf(_('Approval ERROR: %1$s
'), $group->getErrorMessage() );
+ } else {
+ $hook_params = array () ;
+ $hook_params['group_id'] = $group_id ;
+ plugin_hook ("group_approved", $hook_params) ;
+
+ plugin_hook('add_cal_group',$group_id);
+
+ printf(_('Your project has been automatically approved. You should receive an email containing further information shortly.
Thank you for choosing %1$s'), forge_get_config ('forge_name'));
+ }
+ }
+
$HTML->footer(array());
exit();
}
@@ -124,7 +141,8 @@ if (getStringFromRequest('submit')) {
$feedback = '';
}
-site_header(array('title'=>_('Project Information')));
+site_header(array('title'=>_('Register Project')));
+echo '' . _('Register Project') . ' ';
?>
@@ -132,32 +150,52 @@ site_header(array('title'=>_('Project Information')));
-1. Project full nameYou should start with specifying the name of your project. The "Full Name" is descriptive, and has no arbitrary restrictions (except a 40 character limit).
Full Name: ') ?>
+'.$index.'. '._('Project full name').'';
+ echo _('You should start with specifying the name of your project. The "Full Name" is descriptive, and has no arbitrary restrictions (except a 40 character limit).
Full Name: '); ?>
-
+
-2. Project Purpose And Summarization Please provide detailed, accurate description of your project and what %1$s resources and in which way you plan to use. This description will be the basis for the approval or rejection of your project\'s hosting on %1$s, and later, to ensure that you are using the services in the intended way. This description will not be used as a public description of your project. It must be written in English. '), $GLOBALS['sys_name'])?>
-
-
-
-
+'.$index.'. '._('Project Purpose And Summarization').'';
+ echo '';
+ printf(_('Please provide detailed, accurate description of your project and what %1$s resources and in which way you plan to use. This description will be the basis for the approval or rejection of your project\'s hosting on %1$s, and later, to ensure that you are using the services in the intended way. This description will not be used as a public description of your project. It must be written in English.'), forge_get_config ('forge_name'));
+ echo '
';
+ echo '';
+ echo htmlspecialchars($purpose);
+ echo ' ';
+}
+?>
-3. Project Public DescriptionThis is the description of your project which will be shown on the Project Summary page, in search results, etc. It should not be as comprehensive and formal as Project Purpose description (step 2), so feel free to use concise and catchy wording. Maximum length is 255 chars.
')?>
-
-
+'.$index.'. '. _('Project Public Description').'';
+ echo '';
+ echo _('This is the description of your project which will be shown on the Project Summary page, in search results, etc. Maximum length is 255 chars.');
+ echo '
';
+ ?>
-
+
-4. Project Unix NameIn addition to full project name, you will need to choose short,"Unix" name for your project.
The "Unix Name" has several restrictions because it is used in so many places around the site. They are:Cannot match the unix name of any other project Must be between 3 and 15 characters in length Must be in lower case Can only contain characters, numbers, and dashes Must be a valid unix username Cannot match one of our reserved domains Unix name will never change for this project
Your unix name is important, however, because it will be used for many things, including:A web site at unixname.%1$s A CVS Repository root of /cvsroot/unixname at cvs.unixname.%1$s Shell access to unixname.%1$s Search engines throughout the site
Unix Name: '), $GLOBALS['sys_default_domain']) ?>
+'.$index.'. '._('Project Unix Name').'';
+ printf(_('In addition to full project name, you will need to choose short,"Unix" name for your project.
The "Unix Name" has several restrictions because it is used in so many places around the site. They are:Cannot match the unix name of any other project Must be between 3 and 15 characters in length Must be in lower case Can only contain characters, numbers, and dashes Must be a valid unix username Cannot match one of our reserved domains Unix name will never change for this project
Your unix name is important, however, because it will be used for many things, including:A web site at unixname.%1$s A CVS Repository root of /cvsroot/unixname at cvs.unixname.%1$s Shell access to unixname.%1$s Search engines throughout the site
Unix Name: '), forge_get_config('web_host')) ?>
-
+
getSCMs() ;
-if ($sys_use_scm && count($scm_plugins) > 0) {
- echo _('5. SCM You can choose among different SCM for your project, but just one (or none at all). Please select the SCM system you want to use.
')."\n";
+if (forge_get_config('use_scm') && count($scm_plugins) > 0) {
+ $index++;
+ echo ''.$index.'. '._('Source Code').' ';
+ echo _('You can choose among different SCM for your project, but just one (or none at all). Please select the SCM system you want to use.
')."\n";
echo ''."\n";
}
-?>
- ". _('Public')."";
+if ($sys_use_private_project) {
+ $index++;
+ echo ''.$index.'. '._('Visibility'). ' ';
+ echo " ". _('Public')."
";
- echo " ". _('Private')."
";
- } else {
- echo " ";
+ echo " ". _('Private')."
";
+} else {
+ echo " ";
+}
?>
-
+
+
diff --git a/gforge/www/reporting/groupadded_graph.php b/gforge/www/reporting/groupadded_graph.php
index 35d55cc80e..1779528ecc 100644
--- a/gforge/www/reporting/groupadded_graph.php
+++ b/gforge/www/reporting/groupadded_graph.php
@@ -68,7 +68,7 @@ $graph->Add( $lineplot);
//$graph->SetMargin(10,10,25,10);
$graph->title->Set("Projects Added ".$report->getSpanName()
." (".date('m/d/Y',$report->getStartDate()) ."-". date('m/d/Y',$report->getEndDate()) .")");
-$graph->subtitle->Set($sys_name);
+$graph->subtitle->Set(forge_get_config ('forge_name'));
//$graph->xaxis-> title->Set("Date" );
//$graph->yaxis-> title->Set("Number" );
diff --git a/gforge/www/reporting/groupcum_graph.php b/gforge/www/reporting/groupcum_graph.php
index 8641a06a72..0457c46378 100644
--- a/gforge/www/reporting/groupcum_graph.php
+++ b/gforge/www/reporting/groupcum_graph.php
@@ -68,7 +68,7 @@ $graph->Add( $lineplot);
//$graph->SetMargin(10,10,25,10);
$graph->title->Set("Cumulative Projects ".$report->getSpanName()
." (".date('m/d/Y',$report->getStartDate()) ."-". date('m/d/Y',$report->getEndDate()) .")");
-$graph->subtitle->Set($sys_name);
+$graph->subtitle->Set(forge_get_config ('forge_name'));
//$graph->xaxis-> title->Set("Date" );
//$graph->yaxis-> title->Set("Number" );
diff --git a/gforge/www/reporting/index.php b/gforge/www/reporting/index.php
index c4cdf81f8e..ca7594deb4 100644
--- a/gforge/www/reporting/index.php
+++ b/gforge/www/reporting/index.php
@@ -32,6 +32,8 @@ require_once $gfcommon.'reporting/ReportSetup.class.php';
session_require( array('group'=>$sys_stats_group) );
+$feedback = htmlspecialchars(getStringFromRequest('feedback'));
+
echo report_header('Main Page');
?>
diff --git a/gforge/www/reporting/projectact_graph.php b/gforge/www/reporting/projectact_graph.php
index f555216193..b09f8267ea 100644
--- a/gforge/www/reporting/projectact_graph.php
+++ b/gforge/www/reporting/projectact_graph.php
@@ -105,7 +105,7 @@ if ($area=='tracker') {
$graph->Add( $lineplot4 );
// Legends
- $lineplot4 ->SetLegend("Docs");
+ $lineplot4 ->SetLegend(convert_unicode(_('Docs')));
} elseif ($area=='downloads') {
@@ -116,7 +116,7 @@ if ($area=='tracker') {
$graph->Add( $lineplot4 );
// Legends
- $lineplot4 ->SetLegend("Downloads");
+ $lineplot4 ->SetLegend(convert_unicode(_('Downloads')));
} elseif ($area=='taskman') {
@@ -133,8 +133,80 @@ if ($area=='tracker') {
$graph->Add( $lineplot6 );
// Legends
- $lineplot5 ->SetLegend("Task Open");
- $lineplot6 ->SetLegend("Task Close");
+ $lineplot5 ->SetLegend(convert_unicode(_('Task Open')));
+ $lineplot6 ->SetLegend(convert_unicode(_('Task Close')));
+
+} elseif ($area=='pageviews') {
+
+ // Create the PageViews plot
+ $ydata4 =& $report->getPageViews();
+ $lineplot4 =new LinePlot($ydata4);
+ $lineplot4 ->SetColor("blue");
+ $graph->Add( $lineplot4 );
+
+ // Legends
+ $lineplot4 ->SetLegend(convert_unicode(_('Page Views')));
+
+} else {
+ /*
+ * The goal of this code is to get values from the activity hook to compute stats without the
+ * need of another specific hook or another dedicated tables.
+ *
+ * So, values are requested to the hook and stored in $results array.
+ * After, the sum is made according to the chosen interval
+ * And then, the sum is stored in the ydata array.
+ */
+
+ $results = array();
+ $ids = array();
+ $texts = array();
+
+ $hookParams['group'] = $g_id ;
+ $hookParams['results'] = &$results;
+ $hookParams['show'] = array();
+ $hookParams['begin'] = $start;
+ $hookParams['end'] = $end;
+ $hookParams['ids'] = &$ids;
+ $hookParams['texts'] = &$texts;
+ plugin_hook ("activity", $hookParams) ;
+
+ if ($SPAN == REPORT_TYPE_DAILY) {
+ $interval = REPORT_DAY_SPAN;
+ } elseif ($SPAN == REPORT_TYPE_WEEKLY) {
+ $interval = REPORT_WEEK_SPAN;
+ } elseif ($SPAN == REPORT_TYPE_MONTHLY) {
+ $interval = REPORT_MONTH_SPAN;
+ }
+
+ print "start: $start ".date('r',$start)." ";
+ print " end: $end ".date('r', $end)." ";
+
+ $sum = array();
+ $starting_date = $start;
+ foreach ($results as $arr) {
+ $d = $arr['activity_date'];
+ $col = intval(($d - $starting_date)/$interval);
+ $col_date = $starting_date+$col*$interval;
+ $sum[$col_date]++;
+ }
+
+ // Now, stores the values in the ydata array for the graph.
+ $ydata = array();
+ $i = 0;
+ foreach ($report->getDates() as $d) {
+ $ydata[$i++] = isset($sum[strtotime($d)]) ? $sum[strtotime($d)] : 0;
+ }
+
+ $lineplot =new LinePlot($ydata);
+ $lineplot->SetColor("violet");
+ $graph->Add( $lineplot );
+
+ // Legends
+ $lineplot->SetLegend($area);
+
+// var_dump($report->getDates());
+// var_dump($ydata);
+// exit;
}
@@ -143,7 +215,7 @@ if ($area=='tracker') {
//
$graph->title->Set("Project Activity For: ".util_unconvert_htmlspecialchars($g->getPublicName()).
" (".date('Y-m-d',$report->getStartDate()) ." to ". date('Y-m-d',$report->getEndDate()) .")");
-$graph->subtitle->Set($sys_name);
+$graph->subtitle->Set(forge_get_config ('forge_name'));
//$graph->xaxis-> title->Set("Date" );
//$graph->yaxis-> title->Set("Number" );
diff --git a/gforge/www/reporting/projecttime_graph.php b/gforge/www/reporting/projecttime_graph.php
index 3846e48d5e..fe2f01aa28 100644
--- a/gforge/www/reporting/projecttime_graph.php
+++ b/gforge/www/reporting/projecttime_graph.php
@@ -76,7 +76,7 @@ $arr['subproject']='By Subproject';
$arr['user']='By User';
$graph->title->Set("Time Report ".$arr[$type]." (".date('m/d/Y',$start) ."-". date('m/d/Y',$end) .")");
-$graph->subtitle->Set($sys_name);
+$graph->subtitle->Set(forge_get_config ('forge_name'));
report_pie_arr($report->labels,$report->getData());
diff --git a/gforge/www/reporting/rebuild.php b/gforge/www/reporting/rebuild.php
index 8d3b19c4df..5db71e1e8b 100644
--- a/gforge/www/reporting/rebuild.php
+++ b/gforge/www/reporting/rebuild.php
@@ -47,7 +47,7 @@ if (getStringFromRequest('submit') && getStringFromRequest('im_sure')) {
}
}
-
+
echo '';
echo _('Reporting System Initialization');
echo ' ';
diff --git a/gforge/www/reporting/siteact_graph.php b/gforge/www/reporting/siteact_graph.php
index 4a56c0e642..c4b1c49e87 100644
--- a/gforge/www/reporting/siteact_graph.php
+++ b/gforge/www/reporting/siteact_graph.php
@@ -73,8 +73,8 @@ if ($area=='tracker') {
$graph->Add( $lineplot2 );
// Legends
- $lineplot->SetLegend (convert_unicode(_('Tracker Items Opened')));
- $lineplot2 ->SetLegend(convert_unicode(_('Tracker Items Closed')));
+ $lineplot->SetLegend (convert_unicode(_('Tracker Items Opened')));
+ $lineplot2 ->SetLegend(convert_unicode(_('Tracker Items Closed')));
} elseif ($area=='forum') {
@@ -134,7 +134,7 @@ if ($area=='tracker') {
// Titles
//
$graph->title->Set("Site-Wide Activity (".date('m/d/Y',$report->getStartDate()) ."-". date('m/d/Y',$report->getEndDate()) .")");
-$graph->subtitle->Set($sys_name);
+$graph->subtitle->Set(forge_get_config ('forge_name'));
//$graph->xaxis-> title->Set("Date" );
//$graph->yaxis-> title->Set("Number" );
diff --git a/gforge/www/reporting/sitetime_graph.php b/gforge/www/reporting/sitetime_graph.php
index 3f794ba9a6..82b1149470 100644
--- a/gforge/www/reporting/sitetime_graph.php
+++ b/gforge/www/reporting/sitetime_graph.php
@@ -75,7 +75,7 @@ $arr['subproject']='By Subproject';
$arr['user']='By User';
$graph->title->Set("Time Report ".$arr[$type]." (".date('m/d/Y',$start) ."-". date('m/d/Y',$end) .")");
-$graph->subtitle->Set($sys_name);
+$graph->subtitle->Set(forge_get_config ('forge_name'));
report_pie_arr($report->labels,$report->getData());
diff --git a/gforge/www/reporting/sitetimebar_graph.php b/gforge/www/reporting/sitetimebar_graph.php
index 0ee7e35857..ac2927055f 100644
--- a/gforge/www/reporting/sitetimebar_graph.php
+++ b/gforge/www/reporting/sitetimebar_graph.php
@@ -92,7 +92,7 @@ $graph->Add($bplot);
// Setup the titles
$graph->title->Set("Hours Recorded (".date('m/d/Y',$start) ."-". date('m/d/Y',$end) .")");
-$graph->subtitle->Set($sys_name);
+$graph->subtitle->Set(forge_get_config ('forge_name'));
$graph->xaxis->title->Set("Date");
$graph->yaxis->title->Set("Hours");
diff --git a/gforge/www/reporting/timeadd.php b/gforge/www/reporting/timeadd.php
index c134e1e1e5..ca47345091 100644
--- a/gforge/www/reporting/timeadd.php
+++ b/gforge/www/reporting/timeadd.php
@@ -103,43 +103,18 @@ if ($week) {
report_header(_('Time tracking'));
if (!$group_project_id) {
- if ( $sys_database_type == "mysql" ) {
- $sql = "SELECT pgl.group_project_id,CONCAT(g.group_name, '**', pgl.project_name)
- FROM groups g, project_group_list pgl, user_group ug
- WHERE ug.user_id='".user_getid()."'
- AND ug.group_id=g.group_id
- AND g.group_id=pgl.group_id
- ORDER BY group_name,project_name";
- $respm = db_query_mysql($sql);
- } else {
- $respm = db_query_params ('SELECT pgl.group_project_id,g.group_name || $1 || pgl.project_name
+ $respm = db_query_params ('SELECT pgl.group_project_id,g.group_name || $1 || pgl.project_name
FROM groups g, project_group_list pgl, user_group ug
WHERE ug.user_id=$2
AND ug.group_id=g.group_id
AND g.group_id=pgl.group_id
ORDER BY group_name,project_name',
- array ('**',
- user_getid()));
- }
+ array ('**',
+ user_getid()));
}
?>
$sys_stats_group,'A') );
-$time_code = getStringFromRequest('time_code');
-$category_name = getStringFromRequest('category_name');
+$time_code = getIntFromRequest('time_code');
+$category_name = trim(getStringFromRequest('category_name'));
if (getStringFromRequest('submit')) {
if (getStringFromRequest('add')) {
diff --git a/gforge/www/reporting/toolspie_graph.php b/gforge/www/reporting/toolspie_graph.php
index 02faadc14a..2509b191b0 100644
--- a/gforge/www/reporting/toolspie_graph.php
+++ b/gforge/www/reporting/toolspie_graph.php
@@ -135,7 +135,7 @@ $arr[5]='Forum Messages';
$arr[6]='Tasks';
$arr[7]='Downloads';
$graph->title->Set($arr[$datatype]." By Project (".date('m/d/Y',$start) ."-". date('m/d/Y',$end) .")");
-$graph->subtitle->Set($sys_name);
+$graph->subtitle->Set(forge_get_config ('forge_name'));
// Create the tracker open plot
report_pie_arr(util_result_column_to_array($res,0), util_result_column_to_array($res,1));
diff --git a/gforge/www/reporting/trackerpie_graph.php b/gforge/www/reporting/trackerpie_graph.php
index bae6402c42..169aabc413 100644
--- a/gforge/www/reporting/trackerpie_graph.php
+++ b/gforge/www/reporting/trackerpie_graph.php
@@ -123,7 +123,7 @@ $arr['group']='By Group';
$arr['resolution']='By Resolution';
$arr['assignee']='By Assignee';
$graph->title->Set($arr[$area]." (".date('m/d/Y',$start) ."-". date('m/d/Y',$end) .")");
-$graph->subtitle->Set($sys_name);
+$graph->subtitle->Set(forge_get_config ('forge_name'));
// Create the tracker open plot
report_pie_arr(util_result_column_to_array($res,0), util_result_column_to_array($res,1));
diff --git a/gforge/www/reporting/useract.php b/gforge/www/reporting/useract.php
index ff9d97cc7b..e89bb833e8 100644
--- a/gforge/www/reporting/useract.php
+++ b/gforge/www/reporting/useract.php
@@ -55,7 +55,9 @@ if (!$end || $end <= $start) {
echo report_header(_('User Activity'));
$abc_array = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');
-echo _('Choose the First Letter of the name of the person you wish to report on.
');
+echo '
';
+echo _('Choose the First Letter of the name of the person you wish to report on.');
+echo '
';
for ($i=0; $i'.$abc_array[$i].' ';
@@ -80,8 +82,9 @@ if ($sw) {
- " width="640" height="480">
+ " width="640" height="480">
+
title->Set("User Activity For: ".$u->getRealName()
." (".date('m/d/Y',$report->getStartDate()) ."-". date('m/d/Y',$report->getEndDate()) .")");
-$graph->subtitle->Set($sys_name);
+$graph->subtitle->Set(forge_get_config ('forge_name'));
//$graph->xaxis-> title->Set("Date" );
//$graph->yaxis-> title->Set("Number" );
diff --git a/gforge/www/reporting/useradded_graph.php b/gforge/www/reporting/useradded_graph.php
index 7fc694a30e..70328ab578 100644
--- a/gforge/www/reporting/useradded_graph.php
+++ b/gforge/www/reporting/useradded_graph.php
@@ -68,7 +68,7 @@ $graph->Add( $lineplot);
//$graph->SetMargin(10,10,25,10);
$graph->title->Set("Users Added ".$report->getSpanName()
." (".date('m/d/Y',$report->getStartDate()) ."-". date('m/d/Y',$report->getEndDate()) .")");
-$graph->subtitle->Set($sys_name);
+$graph->subtitle->Set(forge_get_config ('forge_name'));
//$graph->xaxis-> title->Set("Date" );
//$graph->yaxis-> title->Set("Number" );
diff --git a/gforge/www/reporting/usercum_graph.php b/gforge/www/reporting/usercum_graph.php
index 1597c3cf25..8e8174d1f7 100644
--- a/gforge/www/reporting/usercum_graph.php
+++ b/gforge/www/reporting/usercum_graph.php
@@ -68,7 +68,7 @@ $graph->Add( $lineplot);
//$graph->SetMargin(10,10,25,10);
$graph->title->Set("Cumulative Users ".$report->getSpanName()
." (".date('m/d/Y',$report->getStartDate()) ."-". date('m/d/Y',$report->getEndDate()) .")");
-$graph->subtitle->Set($sys_name);
+$graph->subtitle->Set(forge_get_config ('forge_name'));
//$graph->xaxis-> title->Set("Date" );
//$graph->yaxis-> title->Set("Number" );
diff --git a/gforge/www/reporting/usersummary.php b/gforge/www/reporting/usersummary.php
index ded4c8de60..1efbcb300e 100644
--- a/gforge/www/reporting/usersummary.php
+++ b/gforge/www/reporting/usersummary.php
@@ -53,7 +53,7 @@ if (!$tstat) {
$n[]=_('Any');
$n[]=_('Open');
-$n[]=_('closed');
+$n[]=_('Closed');
$l[]='1,2';
$l[]='1';
@@ -98,7 +98,7 @@ GROUP BY realname, users.user_id, user_name, status_name, pgl.group_id, pt.group
$end,
db_int_array_to_any_clause ($tstat)));
if (!$res || db_numrows($res) < 1) {
- echo _('No matches found').db_error();
+ echo '' . _('No matches found').db_error() . '
';
} else {
$tableHeaders = array(
_('Name'),
@@ -157,7 +157,7 @@ if (!$res || db_numrows($res) < 1) {
}
echo '
- '.util_make_link ('/tracker/?func=detail&atid='.db_result($res2,$j,'group_artifact_id'). '&group_id='.db_result($res2,$j,'group_id'). '&aid='.db_result($res2,$j,'artifact_id'), db_result($res2,$j,'summary')).'
+ '.util_make_link ('/tracker/?func=detail&atid='.db_result($res2,$j,'group_artifact_id'). '&group_id='.db_result($res2,$j,'group_id'). '&aid='.db_result($res2,$j,'artifact_id'), db_result($res2,$j,'summary')).'
';
}
diff --git a/gforge/www/reporting/usertime.php b/gforge/www/reporting/usertime.php
index 4fc22e4bac..0aa2ebbf18 100644
--- a/gforge/www/reporting/usertime.php
+++ b/gforge/www/reporting/usertime.php
@@ -106,8 +106,9 @@ if ($sw) {
echo $HTML->listTableBottom ();
} elseif ($dev_id) { ?>
- " width="640" height="480">
+ " width="640" height="480" alt="" />
+
title->Set("Time Report ".$arr[$type]." (".date('m/d/Y',$start) ."-". date('m/d/Y',$end) .")");
-$graph->subtitle->Set($sys_name);
+$graph->subtitle->Set(forge_get_config ('forge_name'));
// Create the tracker open plot
//$data =& $report->getData();
diff --git a/gforge/www/scm/admin/index.php b/gforge/www/scm/admin/index.php
index 06cdd13711..c4e97d39de 100644
--- a/gforge/www/scm/admin/index.php
+++ b/gforge/www/scm/admin/index.php
@@ -29,7 +29,7 @@ require_once $gfwww.'include/pre.php';
require_once $gfwww.'scm/include/scm_utils.php';
require_once $gfcommon.'scm/SCMFactory.class.php';
-global $sys_use_scm;
+
$group_id = getIntFromRequest('group_id');
diff --git a/gforge/www/scm/include/scm_utils.php b/gforge/www/scm/include/scm_utils.php
index 6ca7e1a02a..c16ba02eea 100644
--- a/gforge/www/scm/include/scm_utils.php
+++ b/gforge/www/scm/include/scm_utils.php
@@ -25,8 +25,8 @@
*/
function scm_header($params) {
- global $HTML, $sys_use_scm;
- if (!$sys_use_scm) {
+ global $HTML;
+ if (!forge_get_config('use_scm')) {
exit_disabled();
}
diff --git a/gforge/www/scm/include/viewvc_utils.php b/gforge/www/scm/include/viewvc_utils.php
index 7c45fe766d..7467b10641 100644
--- a/gforge/www/scm/include/viewvc_utils.php
+++ b/gforge/www/scm/include/viewvc_utils.php
@@ -100,7 +100,7 @@ function viewcvs_execute($repos_name, $repos_type) {
'REPOSITORY_TYPE="'.$repos_type.'" '.
'REPOSITORY_NAME="'.make_arg_cmd_safe($repos_name).'" '.
'HTTP_HOST="'.make_arg_cmd_safe(getStringFromServer('HTTP_HOST')).'" '.
- 'DOCROOT="/themes/'.$GLOBALS['sys_theme'].'/viewvc" '.
+ 'DOCROOT="/themes/'.forge_get_config('default_theme').'/viewvc" '.
$viewcvs_path.'/bin/cgi/viewvc.cgi 2>&1';
ob_start();
diff --git a/gforge/www/scm/index.php b/gforge/www/scm/index.php
index c56ecec253..9de794781c 100644
--- a/gforge/www/scm/index.php
+++ b/gforge/www/scm/index.php
@@ -31,6 +31,8 @@ require_once $gfwww.'scm/include/scm_utils.php';
$group_id = getIntFromRequest("group_id");
scm_header(array('title'=>_('SCM Repository'),'group'=>$group_id));
+plugin_hook ("blocks", "scm index");
+
$hook_params = array () ;
$hook_params['group_id'] = $group_id ;
plugin_hook ("scm_page", $hook_params) ;
diff --git a/gforge/www/scm/reporting/commits_graph.php b/gforge/www/scm/reporting/commits_graph.php
index d293843cef..4de21798a5 100644
--- a/gforge/www/scm/reporting/commits_graph.php
+++ b/gforge/www/scm/reporting/commits_graph.php
@@ -89,7 +89,7 @@ $graph = new PieGraph(640, 480,"auto");
//$graph->title->Set("Commits By User (".date('m/d/Y',$start) ."-". date('m/d/Y',$end) .")");
$graph->title->Set(utf8_decode(_("Commits By User")." (".strftime('%x',$start) ." - ". strftime('%x',$end) .")"));
-$graph->subtitle->Set($sys_name);
+$graph->subtitle->Set(forge_get_config ('forge_name'));
// Create the tracker open plot
report_pie_arr(util_result_column_to_array($res,0), util_result_column_to_array($res,1), 0);
diff --git a/gforge/www/scm/reporting/commitstime_graph.php b/gforge/www/scm/reporting/commitstime_graph.php
index 06da09b8e9..f896c7d011 100644
--- a/gforge/www/scm/reporting/commitstime_graph.php
+++ b/gforge/www/scm/reporting/commitstime_graph.php
@@ -79,7 +79,7 @@ $graph->Add( $lineplot);
//$graph->SetMargin(10,10,25,10);
$graph->title->Set($g->getPublicName()." Commits Over Time: ".$report->start_date." - ".$report->end_date);
-$graph->subtitle->Set($sys_name);
+$graph->subtitle->Set(forge_get_config ('forge_name'));
//$graph->xaxis-> title->Set("Date" );
//$graph->yaxis-> title->Set("Number" );
diff --git a/gforge/www/scm/reporting/index.php b/gforge/www/scm/reporting/index.php
index 88833df741..794b246020 100644
--- a/gforge/www/scm/reporting/index.php
+++ b/gforge/www/scm/reporting/index.php
@@ -29,31 +29,29 @@ require_once $gfwww.'include/pre.php';
require_once $gfwww.'scm/include/scm_utils.php';
$group_id = getIntFromRequest("group_id");
-scm_header(array('title'=>_('SCM Repository'),'group'=>$group_id));
+scm_header(array('title'=>_('SCM Repository Reporting'),'group'=>$group_id));
?>
-Reporting
-
-Commits Over Time
+Commits Over Time
-Commits Last 30 Days
+Commits Last 30 Days
-Commits Last 90 Days
+Commits Last 90 Days
-Commits Last 365 Days
+Commits Last 365 Days
diff --git a/gforge/www/scm/viewvc.php b/gforge/www/scm/viewvc.php
index 28f03293d3..9246d31315 100644
--- a/gforge/www/scm/viewvc.php
+++ b/gforge/www/scm/viewvc.php
@@ -20,7 +20,7 @@ require_once $gfwww.'include/pre.php';
require_once $gfwww.'scm/include/scm_utils.php';
require_once $gfwww.'scm/include/viewvc_utils.php';
-if (!$sys_use_scm) {
+if (!forge_get_config('use_scm')) {
exit_disabled();
}
@@ -53,7 +53,7 @@ if (!$Group->usesSCM()) {
// check if the scm_box is located in another server
$scm_box = $Group->getSCMBox();
-//$external_scm = (gethostbyname($sys_default_domain) != gethostbyname($scm_box));
+//$external_scm = (gethostbyname(forge_get_config('web_host')) != gethostbyname($scm_box));
$external_scm = !$sys_scm_single_host;
if (session_loggedin()) {
diff --git a/gforge/www/search/include/SearchManager.class.php b/gforge/www/search/include/SearchManager.class.php
index 1d2d7cbf9a..44147093b8 100644
--- a/gforge/www/search/include/SearchManager.class.php
+++ b/gforge/www/search/include/SearchManager.class.php
@@ -134,7 +134,7 @@ class SearchManager {
SEARCH__TYPE_IS_PEOPLE,
new GFSearchEngine(SEARCH__TYPE_IS_PEOPLE, 'PeopleHtmlSearchRenderer', _('People'))
);
- if ($GLOBALS['sys_use_people']) {
+ if (forge_get_config('use_people')) {
$this->addSearchEngine(
SEARCH__TYPE_IS_SKILL,
new GFSearchEngine(SEARCH__TYPE_IS_SKILL, 'SkillHtmlSearchRenderer', _('Skill'))
diff --git a/gforge/www/search/include/renderers/AdvancedSearchHtmlSearchRenderer.class.php b/gforge/www/search/include/renderers/AdvancedSearchHtmlSearchRenderer.class.php
index bfc2d6319a..4eb05f7008 100644
--- a/gforge/www/search/include/renderers/AdvancedSearchHtmlSearchRenderer.class.php
+++ b/gforge/www/search/include/renderers/AdvancedSearchHtmlSearchRenderer.class.php
@@ -77,7 +77,7 @@ class AdvancedSearchHtmlSearchRenderer extends HtmlGroupSearchRenderer {
$sectionarray = $this->getSectionArray();
$this->handleTransferInformation($sectionarray);
- $GLOBALS['HTML']->advancedSearchBox($sectionarray, $this->groupId, $this->words, $this->isExact);
+ echo $this->getAdvancedSearchBox($sectionarray, $this->groupId, $this->words, $this->isExact);
}
/**
@@ -302,6 +302,150 @@ class AdvancedSearchHtmlSearchRenderer extends HtmlGroupSearchRenderer {
}
return $sections;
}
+
+ function getAdvancedSearchBox($sectionsArray, $group_id, $words, $isExact) {
+ $res = '';
+ // display the searchmask
+ $res .= '
+
+
+
+ '
+ . $this->createSubSections($sectionsArray) .'
+ ';
+
+
+ //create javascript methods for select none/all
+ $res .= '
+
+ ';
+ return $res;
+ }
+
+ function createSubSections($sectionsArray) {
+ global $group_subsection_names;
+
+ $countLines = 0;
+ foreach ($sectionsArray as $section) {
+ if(is_array($section)) {
+ $countLines += (3 + count ($section));
+ } else {
+ //2 lines one for section name and one for checkbox
+ $countLines += 3;
+ }
+ }
+
+ $maxCol = 3;
+ $breakLimit = ceil($countLines/$maxCol);
+ $break = $breakLimit;
+ $countLines = 0;
+ $countCol = 1;
+
+ $return = '
+ ';
+
+ }
+
}
// Local Variables:
diff --git a/gforge/www/search/include/renderers/ProjectHtmlSearchRenderer.class.php b/gforge/www/search/include/renderers/ProjectHtmlSearchRenderer.class.php
index 2537dec980..26de48b5f3 100644
--- a/gforge/www/search/include/renderers/ProjectHtmlSearchRenderer.class.php
+++ b/gforge/www/search/include/renderers/ProjectHtmlSearchRenderer.class.php
@@ -73,12 +73,12 @@ class ProjectHtmlSearchRenderer extends HtmlSearchRenderer {
* redirectToResult - redirect the user directly to the result when there is only one matching result
*/
function redirectToResult() {
- global $sys_use_fti;
+
$project_name = $this->getResultId('unix_group_name');
$project_id = $this->getResultId('group_id');
- if ($sys_use_fti) {
+ if (forge_get_config('use_fti')) {
// If FTI is being used, the project name returned by the query will be "projectname ", so
// we remove the HTML code (otherwise we'd get an error)
$project_name = str_replace('', '', $project_name);
diff --git a/gforge/www/search/index.php b/gforge/www/search/index.php
index cda13b54a6..54e39d29b7 100644
--- a/gforge/www/search/index.php
+++ b/gforge/www/search/index.php
@@ -67,8 +67,7 @@ if ($renderer) {
$renderer->flush();
} else {
$HTML->header(array('title'=>_('Search')));
-
- echo ''._('Error - Invalid search').' ';
+ echo ' '._('Error - Invalid search').'
';
$HTML->footer(array());
exit();
diff --git a/gforge/www/sendmessage.php b/gforge/www/sendmessage.php
index 7a29b4f5c1..be8810b67d 100644
--- a/gforge/www/sendmessage.php
+++ b/gforge/www/sendmessage.php
@@ -46,8 +46,8 @@ if ($touser) {
}
}
-if ($toaddress && !eregi($GLOBALS['sys_default_domain'],$toaddress)) {
- exit_error(_('Error'),sprintf(_('You can only send to addresses @%1$s .'),$GLOBALS['sys_default_domain']));
+if ($toaddress && !eregi(forge_get_config('web_host'),$toaddress)) {
+ exit_error(_('Error'),sprintf(_('You can only send to addresses @%1$s .'),forge_get_config('web_host')));
}
@@ -81,8 +81,8 @@ if (getStringFromRequest('send_mail')) {
*/
$to=eregi_replace('_maillink_','@',$toaddress);
$to = util_remove_CRLF($to);
- util_send_message($to,stripslashes($subject),stripslashes($body),$email,'',$name);
- $HTML->header(array('title'=>$GLOBALS['sys_name'].' ' ._('Contact') ));
+ util_send_message($to,$subject,$body,$email,'',$name);
+ $HTML->header(array('title'=>forge_get_config ('forge_name').' ' ._('Contact') ));
echo ''._('Message has been sent').'.
';
$HTML->footer(array());
exit;
@@ -92,8 +92,8 @@ if (getStringFromRequest('send_mail')) {
*/
$to=db_result($result,0,'email');
$to = util_remove_CRLF($to);
- util_send_message($to,stripslashes($subject),stripslashes($body),$email,'',$name);
- $HTML->header(array('title'=>$GLOBALS['sys_name'].' '._('Contact')));
+ util_send_message($to,$subject,$body,$email,'',$name);
+ $HTML->header(array('title'=>forge_get_config ('forge_name').' '._('Contact')));
echo ''._('Message has been sent').'
';
$HTML->footer(array());
exit;
@@ -116,7 +116,7 @@ if (session_loggedin()) {
}
$subject = getStringFromRequest('subject');
-$HTML->header(array('title'=>$GLOBALS['sys_name'].' Staff'));
+$HTML->header(array('title'=>forge_get_config ('forge_name').' Staff'));
?>
diff --git a/gforge/www/snapshots.php b/gforge/www/snapshots.php
index 94a049b046..fb9714d48b 100644
--- a/gforge/www/snapshots.php
+++ b/gforge/www/snapshots.php
@@ -45,13 +45,13 @@ $group_name=$group->getUnixName();
$filename=$group_name.'-scm-latest.tar.gz';
-if (file_exists($sys_scm_snapshots_path.'/'.$filename)) {
+if (file_exists(forge_get_config('scm_snapshots_path').'/'.$filename)) {
Header('Content-disposition: filename="'.str_replace('"', '', $filename).'"');
Header('Content-type: application/x-gzip');
- $length = filesize($sys_scm_snapshots_path.'/'.$filename);
+ $length = filesize(forge_get_config('scm_snapshots_path').'/'.$filename);
Header('Content-length: '.$length);
- readfile_chunked($sys_scm_snapshots_path.'/'.$filename);
+ readfile_chunked(forge_get_config('scm_snapshots_path').'/'.$filename);
} else {
session_redirect(util_make_url('/404.php'));
}
diff --git a/gforge/www/snippet/snippet_utils.php b/gforge/www/snippet/snippet_utils.php
index 3e9644acf0..4ae554b6f2 100644
--- a/gforge/www/snippet/snippet_utils.php
+++ b/gforge/www/snippet/snippet_utils.php
@@ -94,9 +94,9 @@ $SCRIPT_EXTENSION[15] = '.sql';
$SCRIPT_EXTENSION[16] = '.cs';
function snippet_header($params) {
- global $HTML, $sys_use_snippet;
+ global $HTML;
- if (!$sys_use_snippet) {
+ if (!forge_get_config('use_snippet')) {
exit_disabled();
}
diff --git a/gforge/www/soap/docman/docman.php b/gforge/www/soap/docman/docman.php
index 74b6f3e51f..e2d1e9ea62 100644
--- a/gforge/www/soap/docman/docman.php
+++ b/gforge/www/soap/docman/docman.php
@@ -320,8 +320,7 @@ function &addDocument($session_ser,$group_id,$doc_group,$title,$description,$lan
}
if ($base64_contents) {
- $bin_data = base64_decode($base64_contents);
- $data = addslashes($bin_data);
+ $data = base64_decode($base64_contents);
$file_url='';
$uploaded_data_name=$filename;
} elseif ($file_url) {
@@ -408,8 +407,7 @@ function &updateDocument($session_ser,$group_id,$doc_group,$doc_id,$title,$descr
if((!$base64_contents) && (!$file_url)){
if((!$base64_contents) && (!$d->isURL())){
- $bin_data=$d->getFileData();
- $data = addslashes($bin_data);
+ $data = $d->getFileData();
$uploaded_data_name=$d->getFileName();
$file_url='';
}else{
@@ -425,8 +423,7 @@ function &updateDocument($session_ser,$group_id,$doc_group,$doc_id,$title,$descr
$uploaded_data_name=$file_url;
$uploaded_data_type='URL';
}elseif($base64_contents){
- $bin_data = base64_decode($base64_contents);
- $data = addslashes($bin_data);
+ $data = base64_decode($base64_contents);
$file_url='';
$uploaded_data_name=$filename;
}
diff --git a/gforge/www/soap/frs/frs.php b/gforge/www/soap/frs/frs.php
index b7c93db7b5..5657bcc3fa 100644
--- a/gforge/www/soap/frs/frs.php
+++ b/gforge/www/soap/frs/frs.php
@@ -504,7 +504,7 @@ function getFile($session_ser,$group_id,$package_id,$release_id,$file_id) {
return new soap_fault ('','getFile',$frsf->getErrorMessage(),$frsf->getErrorMessage());
}
- $file_location = $GLOBALS['sys_upload_dir'].'/'.
+ $file_location = forge_get_config('upload_dir').'/'.
$frsf->FRSRelease->FRSPackage->Group->getUnixName().'/'.
$frsf->FRSRelease->FRSPackage->getFileName().'/'.
$frsf->FRSRelease->getFileName().'/'.
diff --git a/gforge/www/soap/index.php b/gforge/www/soap/index.php
index de80f67aa1..52693e758c 100644
--- a/gforge/www/soap/index.php
+++ b/gforge/www/soap/index.php
@@ -9,7 +9,7 @@ require_once $gfcommon.'include/FusionForge.class.php';
ini_set('memory_limit','32M');
-$uri = 'http://'.$sys_default_domain;
+$uri = 'http://'.forge_get_config('web_host');
// 1. include client and server
require_once $gfwww.'soap/nusoap.php';
//$debug = true;
diff --git a/gforge/www/soap/nusoap.php b/gforge/www/soap/nusoap.php
index bab2c7a898..cd27ebc644 100644
--- a/gforge/www/soap/nusoap.php
+++ b/gforge/www/soap/nusoap.php
@@ -4018,7 +4018,7 @@ class nusoap_server extends nusoap_base {
function serialize_return() {
$this->debug('Entering serialize_return methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI);
// if fault
- if (isset($this->methodreturn) && ((get_class($this->methodreturn) == 'soap_fault') || (get_class($this->methodreturn) == 'nusoap_fault'))) {
+ if (isset($this->methodreturn) && ((@get_class($this->methodreturn) == 'soap_fault') || (@get_class($this->methodreturn) == 'nusoap_fault'))) {
$this->debug('got a fault object from method');
$this->fault = $this->methodreturn;
return;
diff --git a/gforge/www/softwaremap/full_list.php b/gforge/www/softwaremap/full_list.php
index 2353503074..113d304fd9 100644
--- a/gforge/www/softwaremap/full_list.php
+++ b/gforge/www/softwaremap/full_list.php
@@ -55,7 +55,7 @@ if ($GLOBALS['sys_use_project_tags']) {
$subMenuUrl[] = '/softwaremap/tag_cloud.php';
}
-if ($GLOBALS['sys_use_trove']) {
+if (forge_get_config('use_trove')) {
$subMenuTitle[] = _('Project Tree');
$subMenuUrl[] = '/softwaremap/trove_list.php';
}
@@ -131,13 +131,25 @@ for ($i_proj=1;$i_proj<=$querytotalcount;$i_proj++) {
}
if ($row_grp && $viewthisrow) {
+
+ // Embed RDFa description for /projects/PROJ_NAME
+ $proj_uri = util_make_url_g(strtolower($row_grp['unix_group_name']),$row_grp['group_id']);
+ print ''."\n";
+ print '
'."\n";
+
print '
';
print '';
- print ""
- .$row_grp['group_name']." ";
+ print util_make_link_g(strtolower($row_grp['unix_group_name']),$row_grp['group_id'],''
+ .''
+ .$row_grp['group_name']
+ .' '
+ .' ').' ';
if ($row_grp['short_description']) {
- print "- " . $row_grp['short_description'];
+ print "- "
+ . ''
+ . $row_grp['short_description']
+ . ' ';
}
// extra description
@@ -153,9 +165,10 @@ for ($i_proj=1;$i_proj<=$querytotalcount;$i_proj++) {
.'[This project needs help] ';
}
*/
- print '
';
+ print '
';
+ print '
'; // /doap:Project
print ' ';
- } // end if for row and range chacking
+ } // end if for row and range chacking
}
// print bottom navigation if there are more projects to display
diff --git a/gforge/www/softwaremap/index.php b/gforge/www/softwaremap/index.php
index 1e1ad4d23c..e29c2c2a09 100644
--- a/gforge/www/softwaremap/index.php
+++ b/gforge/www/softwaremap/index.php
@@ -13,7 +13,7 @@ require_once('../env.inc.php');
require_once $gfwww.'include/pre.php';
if ($GLOBALS['sys_use_project_tags']) {
header('Location: '.util_make_url('softwaremap/tag_cloud.php'));
-}elseif ($GLOBALS['sys_use_trove']){
+}elseif (forge_get_config('use_trove')){
header('Location: '.util_make_url('softwaremap/trove_list.php'));
}else{
header('Location: '.util_make_url('softwaremap/full_list.php'));
diff --git a/gforge/www/softwaremap/tag_cloud.php b/gforge/www/softwaremap/tag_cloud.php
index b2a3ddd6d2..84a12e1e34 100644
--- a/gforge/www/softwaremap/tag_cloud.php
+++ b/gforge/www/softwaremap/tag_cloud.php
@@ -60,7 +60,7 @@ if ($GLOBALS['sys_use_project_tags']) {
$subMenuUrl[] = '/softwaremap/tag_cloud.php';
}
-if ($GLOBALS['sys_use_trove']) {
+if (forge_get_config('use_trove')) {
$subMenuTitle[] = _('Project Tree');
$subMenuUrl[] = '/softwaremap/trove_list.php';
}
diff --git a/gforge/www/softwaremap/trove_list.php b/gforge/www/softwaremap/trove_list.php
index a98d41386e..a9834320db 100644
--- a/gforge/www/softwaremap/trove_list.php
+++ b/gforge/www/softwaremap/trove_list.php
@@ -32,7 +32,7 @@ plugin_hook('tree');
require_once $gfwww.'include/trove.php';
-if (!$sys_use_trove) {
+if (!forge_get_config('use_trove')) {
exit_disabled();
}
@@ -69,7 +69,7 @@ if ($GLOBALS['sys_use_project_tags']) {
$subMenuUrl[] = '/softwaremap/tag_cloud.php';
}
-if ($GLOBALS['sys_use_trove']) {
+if (forge_get_config('use_trove')) {
$subMenuTitle[] = _('Project Tree');
$subMenuUrl[] = '/softwaremap/trove_list.php';
}
diff --git a/gforge/www/stats/graphs.php b/gforge/www/stats/graphs.php
index 4cbf653664..286c707c05 100644
--- a/gforge/www/stats/graphs.php
+++ b/gforge/www/stats/graphs.php
@@ -15,12 +15,12 @@ require_once $gfwww.'stats/site_stats_utils.php';
// require you to be a member of the sfstats group (group_id = 11084)
session_require( array('group'=>$sys_stats_group) );
-$HTML->header(array('title'=>sprintf(_('%1$s Site Statistics'), $GLOBALS['sys_name'])));
+$HTML->header(array('title'=>sprintf(_('%1$s Site Statistics'), forge_get_config ('forge_name'))));
echo "\n\n";
+print ''._('Sitewide Statistics Graphs').' ' . "\n";
print '' . "\n";
-print '
'._('Sitewide Statistics Graphs').' ' . "\n";
?>
diff --git a/gforge/www/stats/i18n.php b/gforge/www/stats/i18n.php
index e9a48f6882..ff1d76b6c5 100644
--- a/gforge/www/stats/i18n.php
+++ b/gforge/www/stats/i18n.php
@@ -15,8 +15,8 @@ require_once $gfwww.'stats/site_stats_utils.php';
// require you to be a member of the sfstats group
session_require( array('group'=>$sys_stats_group) );
-$HTML->header(array('title' => sprintf(_('%1$s I18n Statistics'), $GLOBALS['sys_name'])));
-echo "
".sprintf(_('Languages Distributions'), $GLOBALS['sys_name'])." ";
+$HTML->header(array('title' => sprintf(_('%1$s I18n Statistics'), forge_get_config ('forge_name'))));
+echo "
".sprintf(_('Languages Distributions'), forge_get_config ('forge_name'))." ";
echo $GLOBALS['HTML']->listTableTop(array(_('Language')."",_('Users')."","%"));
$total=db_result(db_query_params('SELECT count(user_name) AS total FROM users', array()),0,'total');
diff --git a/gforge/www/stats/index.php b/gforge/www/stats/index.php
index 57d1ba95e7..fd310190be 100644
--- a/gforge/www/stats/index.php
+++ b/gforge/www/stats/index.php
@@ -17,7 +17,7 @@ require_once $gfwww.'stats/site_stats_utils.php';
// require you to be a member of the sfstats group
session_require( array('group'=>$sys_stats_group) );
-$HTML->header(array('title'=>sprintf(_('%1$s Site Statistics'), $GLOBALS['sys_name'])));
+$HTML->header(array('title'=>sprintf(_('%1$s Site Statistics'), forge_get_config ('forge_name'))));
//
// BEGIN PAGE CONTENT CODE
@@ -43,12 +43,13 @@ print '
'._('Sitewide aggregate statistics').' ' . "\n";
';
+
stats_site_projects_daily( 7 );
-print '
';
+
stats_site_projects_monthly( );
-print '
' . "\n";
-echo '
'._('Other statistics:
');
+
+echo '
'._('Other statistics').' ';
+echo '
';
//
// END PAGE CONTENT CODE
diff --git a/gforge/www/stats/projects.php b/gforge/www/stats/projects.php
index a5202c638f..08bfc53ef2 100644
--- a/gforge/www/stats/projects.php
+++ b/gforge/www/stats/projects.php
@@ -23,12 +23,10 @@ $trovecatid=getIntFromRequest('trovecatid');
// require you to be a member of the sfstats group (group_id = 11084)
session_require( array('group'=>$sys_stats_group) );
-$HTML->header(array('title'=>sprintf(_('%1$s Site Statistics'), $GLOBALS['sys_name'])));
+$HTML->header(array('title'=>sprintf(_('%1$s Site Statistics'), forge_get_config ('forge_name'))));
?>
-
-
-
+
diff --git a/gforge/www/stats/site_stats_utils.php b/gforge/www/stats/site_stats_utils.php
index b2976782c0..34d0d75dae 100644
--- a/gforge/www/stats/site_stats_utils.php
+++ b/gforge/www/stats/site_stats_utils.php
@@ -222,24 +222,24 @@ function stats_site_projects( $report, $orderby, $projects, $trove ) {
if ( db_numrows( $res ) > 1 ) {
?>
-
+
-
+
-
+
-
+
-
+
@@ -262,10 +262,10 @@ function stats_site_projects( $report, $orderby, $projects, $trove ) {
-
+
-
+
@@ -275,11 +275,11 @@ function stats_site_projects( $report, $orderby, $projects, $trove ) {
-
+
-
+
@@ -294,10 +294,10 @@ function stats_site_projects( $report, $orderby, $projects, $trove ) {
. '' . ($i + 1)." " . util_make_link ('/project/stats/?group_id='.$row["group_id"], $row["group_name"]) . ' '
. ' ' . number_format( $row["site_views"],0 ) . ' '
. ' ' . number_format( $row["subdomain_views"],0 ) . ' ';
- if ($GLOBALS['sys_use_frs']) {
+ if (forge_get_config('use_frs')) {
print ' ' . number_format( $row["downloads"],0 ) . ' ';
}
- if ($GLOBALS['sys_use_tracker']) {
+ if (forge_get_config('use_tracker')) {
print ' ' . number_format( $row["bugs_opened"],0 ) . ' '
. ' ' . number_format( $row["bugs_closed"],0 ) . ' '
. ' ' . number_format( $row["support_opened"],0 ) . ' '
@@ -307,11 +307,11 @@ function stats_site_projects( $report, $orderby, $projects, $trove ) {
. ' ' . number_format( $row["artifacts_opened"],0 ) . ' '
. ' ' . number_format( $row["artifacts_closed"],0 ) . ' ';
}
- if ($GLOBALS['sys_use_pm']) {
+ if (forge_get_config('use_pm')) {
print ' ' . number_format( $row["tasks_opened"],0 ) . ' '
. ' ' . number_format( $row["tasks_opened"],0 ) . ' ';
}
- if ($GLOBALS['sys_use_scm']) {
+ if (forge_get_config('use_scm')) {
print ' ' . number_format( $row["cvs_checkouts"],0 ) . ' '
. ' ' . number_format( $row["cvs_commits"],0 ) . ' '
. ' ' . number_format( $row["cvs_adds"],0 ) . ' ';
@@ -353,7 +353,7 @@ function stats_site_projects_daily( $span ) {
if ( ($valid_days = db_numrows( $res )) > 1 ) {
?>
-
+
@@ -402,12 +402,12 @@ function stats_site_projects_monthly() {
echo db_error();
- // if there are any weeks, we have valid data.
+ // if there are any weeks, we have valid data.
if ( ($valid_months = db_numrows( $res )) > 1 ) {
?>
-
+
Month
@@ -466,7 +466,7 @@ function stats_site_aggregate( ) {
?>
-
+
diff --git a/gforge/www/survey/admin/add_question.php b/gforge/www/survey/admin/add_question.php
index 2066615149..73a05d37fa 100644
--- a/gforge/www/survey/admin/add_question.php
+++ b/gforge/www/survey/admin/add_question.php
@@ -32,7 +32,7 @@ $survey_id = getIntFromRequest('survey_id');
survey_header(array('title'=>_('Add A Question')));
if (!session_loggedin() || !user_ismember($group_id,'A')) {
- echo ""._('Permission denied')." ";
+ echo ''._('Permission denied').'
';
survey_footer(array());
exit;
}
diff --git a/gforge/www/survey/admin/add_survey.php b/gforge/www/survey/admin/add_survey.php
index 252a22c416..890f612b90 100644
--- a/gforge/www/survey/admin/add_survey.php
+++ b/gforge/www/survey/admin/add_survey.php
@@ -30,10 +30,10 @@ require_once $gfwww.'survey/admin/survey_utils.php';
$is_admin_page='y';
$group_id = getIntFromRequest('group_id');
$survey_id = getIntFromRequest('survey_id');
-survey_header(array('title'=>_('Add A Survey')));
+survey_header(array('title'=>_('Add a Survey')));
if (!session_loggedin() || !user_ismember($group_id,'A')) {
- echo "". _('Permission denied')." ";
+ echo ''. _('Permission denied').'
';
survey_footer(array());
exit;
}
diff --git a/gforge/www/survey/admin/edit_question.php b/gforge/www/survey/admin/edit_question.php
index 61cb051124..427312f07e 100644
--- a/gforge/www/survey/admin/edit_question.php
+++ b/gforge/www/survey/admin/edit_question.php
@@ -34,7 +34,7 @@ $survey_id = getIntFromRequest('survey_id');
survey_header(array('title'=>_('Edit A Question')));
if (!session_loggedin() || !user_ismember($group_id,'A')) {
- echo "" ._('Permission denied')." ";
+ echo '' ._('Permission denied'). '
';
survey_footer(array());
exit;
}
@@ -50,9 +50,9 @@ if (getStringFromRequest('post_changes')) {
$question_id,
$group_id));
if (db_affected_rows($result) < 1) {
- $feedback .= _('UPDATE FAILED');
+ $feedback .= _('Update Failed');
} else {
- $feedback .= _('UPDATE SUCCESSFUL');
+ $feedback .= _('Update Successful');
}
}
diff --git a/gforge/www/survey/admin/edit_survey.php b/gforge/www/survey/admin/edit_survey.php
index 24351ffc67..9e00af33de 100644
--- a/gforge/www/survey/admin/edit_survey.php
+++ b/gforge/www/survey/admin/edit_survey.php
@@ -34,7 +34,7 @@ $survey_id = getIntFromRequest('survey_id');
survey_header(array('title'=>_('Edit A Survey')));
if (!session_loggedin() || !user_ismember($group_id,'A')) {
- echo "" ._('Permission denied')." ";
+ echo ''._('Permission denied').'
';
survey_footer(array());
exit;
}
@@ -46,15 +46,15 @@ if (getStringFromRequest('post_changes')) {
if (!isset($survey_title) || $survey_title == "")
{
- $feedback .= _('UPDATE FAILED: Survey Title Required');
+ $feedback .= _('Update Failed: Survey Title Required');
}
elseif (!isset($survey_questions) || $survey_questions == "")
{
- $feedback .= _('UPDATE FAILED: Survey Questions Required');
+ $feedback .= _('Update Failed: Survey Questions Required');
}
if (!isset($survey_id) || !isset($group_id) || $survey_id == "" || $group_id == "")
{
- $feedback .= _('UPDATE FAILED: Missing Data');
+ $feedback .= _('Update Failed: Missing Data');
}
else
{
@@ -71,10 +71,10 @@ WHERE survey_id=$4 AND group_id=$5',
$survey_id,
$group_id));
if (db_affected_rows($result) < 1) {
- $feedback .= _('UPDATE FAILED');
+ $feedback .= _('Update Failed');
echo db_error();
} else {
- $feedback .= _('UPDATE SUCCESSFUL');
+ $feedback .= _('Update Successful');
}
}
}
diff --git a/gforge/www/survey/admin/index.php b/gforge/www/survey/admin/index.php
index 24f80540ee..888f88179f 100644
--- a/gforge/www/survey/admin/index.php
+++ b/gforge/www/survey/admin/index.php
@@ -33,18 +33,36 @@ $survey_id = getIntFromRequest('survey_id');
$sh = new SurveyHtml();
$sh->header(array('title'=>_('Survey Administration')));
+echo ''._('Survey Administration').' ';
+
if (!session_loggedin() || !user_ismember($group_id,'A')) {
- echo ''._('Permission denied').' ';
+ echo ''._('Permission denied').'
';
$sh->footer(array());
exit;
}
?>
-It\'s simple to create a survey.Create questions and comments using the forms above. Create a survey, listing the questions in order (choose from your list of questions). Link to the survey using this format: %1$s where XX is the survey number'), ''.util_make_url ('/survey/survey.php?group_id='.$group_id.'&survey_id=XX').' '); ?>
-
-
', ''); ?>
-
+
+
+
+
+
+
+
+
+ your list of questions).')); ?>
+
+
+ '.util_make_url('/survey/survey.php?group_id='.$group_id.'&survey_id=XX').' '); ?>
+
+
+
+',
+ '');
+?>
header(array('title'=>_('Add A Question')));
if (!session_loggedin() || !user_ismember($group_id,'A')) {
- echo ""._('You don\'t have a permission to access this page')." ";
+ echo ''._('Permission denied').'
';
$sh->footer(array());
exit;
}
@@ -43,9 +43,9 @@ if (!session_loggedin() || !user_ismember($group_id,'A')) {
/* Create a Survey Question for general purpose */
$sq = new SurveyQuestion($g, $question_id);
if (!$sq || !is_object($sq)) {
- echo ""._('Error'). ' Can not get Survey Question' ." ";
+ echo ''._('Error'). ' ' . _('Cannot get Survey Question') ."
";
} else if ( $sq->isError()) {
- echo ""._('Error'). $sq->getErrorMessage() ." ";
+ echo ''._('Error'). $sq->getErrorMessage() ."
";
}
/* Delete a question */
@@ -55,15 +55,16 @@ if (getStringFromRequest('delete')=="Y" && $question_id) {
/* Error */
if ( $sq->isError()) {
$msg = _('Delete failed').' '.$sq->getErrorMessage();
+ echo '' .$msg ."
";
} else {
$msg = _('Delete successful');
+ echo '' .$msg ."
";
}
- echo "".$msg ." ";
} else if (getStringFromRequest('post')=="Y") {
/* Modification */
if ($question_id) {
$sq->update($question, $question_type);
- $msg = _('UPDATE SUCCESSFUL');
+ $msg = _('Update Successful');
} else { /* adding new question */
$question = getStringFromRequest('question');
if (!form_key_is_valid(getStringFromRequest('form_key'))) {
@@ -77,9 +78,10 @@ if (getStringFromRequest('delete')=="Y" && $question_id) {
if ( $sq->isError()) {
$msg = $sq->getErrorMessage();
form_release_key(getStringFromRequest("form_key"));
+ echo '' .$msg ."
";
+ } else {
+ echo '' .$msg ."
";
}
-
- echo "".$msg ." ";
/* Add now Question */
$sq = false;
@@ -90,7 +92,7 @@ if (getStringFromRequest('delete')=="Y" && $question_id) {
*/
echo($sh->showAddQuestionForm($sq));
-/* Show existing questions
+/* Show existing questions (if any)
*/
$sqf = new SurveyQuestionFactory($g);
$sqs = & $sqf->getSurveyQuestions();
diff --git a/gforge/www/survey/admin/show_questions.php b/gforge/www/survey/admin/show_questions.php
index 9e9879572b..f0a5851cfd 100644
--- a/gforge/www/survey/admin/show_questions.php
+++ b/gforge/www/survey/admin/show_questions.php
@@ -33,7 +33,7 @@ $survey_id = getIntFromRequest('survey_id');
survey_header(array('title'=>_('Survey Questions')));
if (!session_loggedin() || !user_ismember($group_id,'A')) {
- echo ""._('Permission denied')." ";
+ echo ''._('Permission denied').'
';
survey_footer(array());
exit;
}
diff --git a/gforge/www/survey/admin/show_results.php b/gforge/www/survey/admin/show_results.php
index 3307a825b2..6af1235b8f 100644
--- a/gforge/www/survey/admin/show_results.php
+++ b/gforge/www/survey/admin/show_results.php
@@ -56,7 +56,7 @@ $is_admin_page='y';
$sh->header(array('title'=>_('Survey Results')));
if (!session_loggedin() || !user_ismember($group_id,'A')) {
- echo ""._('Permission denied')." ";
+ echo ''._('Permission denied').'
';
$sh->footer(array());
exit;
}
@@ -66,11 +66,11 @@ if ($survey_id) {
$s = new Survey($g, $survey_id);
if (!$s || !is_object($s)) {
- echo ""._('Error'). ' Can not get Survey' ." ";
+ echo ''._('Error'). ' ' . _('Cannot get Survey') ."
";
$sh->footer(array());
exit;
} else if ( $s->isError()) {
- echo ""._('Error'). $s->getErrorMessage() ." ";
+ echo ''._('Error'). $s->getErrorMessage() ."
";
$sh->footer(array());
exit;
}
@@ -81,9 +81,9 @@ if ($survey_id) {
/* Create a Survey Question for general purpose */
$sq = new SurveyQuestion($g, $question_id);
if (!$sq || !is_object($sq)) {
- echo ""._('Error'). ' Can not get Survey Question' ." ";
+ echo ''._('Error'). ' ' . _('Cannot get Survey Question') ."
";
} else if ( $sq->isError()) {
- echo ""._('Error'). $sq->getErrorMessage() ." ";
+ echo ''._('Error'). $sq->getErrorMessage() ."
";
} else {
showResult($sh, $s, $sq, 1, 0, $graph);
}
@@ -112,7 +112,7 @@ if ($survey_id) {
$sf = new SurveyFactory($g);
$ss = & $sf->getSurveys();
if (!$ss) {
- echo (_('No Survey Question is found'));
+ echo '' . _('No Survey Question is found') . '
';
} else {
echo($sh->ShowSurveys($ss, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1));
}
@@ -130,9 +130,9 @@ function ShowResult(&$SurveyHTML, &$Survey, &$Question, $show_comment=0, $q_num=
/* Get results */
$srf = new SurveyResponseFactory($Survey, $Question);
if (!$srf || !is_object($srf)) {
- echo ""._('Error'). ' Can not get Survey Response Factory' ." ";
+ echo ''._('Error'). ' ' . _('Cannot get Survey Response Factory') ."
";
} else if ( $srf->isError()) {
- echo ""._('Error'). $srf->getErrorMessage() ." ";
+ echo ''._('Error'). $srf->getErrorMessage() ."
";
} else {
/* Show result in HTML*/
echo ($SurveyHTML->ShowResult($srf, $show_comment, $q_num, $graph));
diff --git a/gforge/www/survey/admin/show_results_aggregate.php b/gforge/www/survey/admin/show_results_aggregate.php
index f93bd17d1c..09b3507b00 100644
--- a/gforge/www/survey/admin/show_results_aggregate.php
+++ b/gforge/www/survey/admin/show_results_aggregate.php
@@ -34,7 +34,7 @@ $survey_id = getIntFromRequest('survey_id');
survey_header(array('title'=>_('Survey Aggregate Results')));
if (!session_loggedin() || !user_ismember($group_id,'A')) {
- echo ""._('Permission denied')." ";
+ echo ''._('Permission denied').'
';
survey_footer(array());
exit;
}
@@ -128,19 +128,10 @@ for ($i=0; $i<$count; $i++) {
// average
if ($response_count > 0){
- if ( $sys_database_type == "mysql" ) {
-
- $result2 = db_query_params ('SELECT avg(response) AS avg FROM survey_responses WHERE survey_id=$1 AND question_id=$2 AND group_id=$3 AND response IN (1,2,3,4,5)',
- array ($survey_id,
- $quest_array[$i],
- $group_id));
- } else {
-
$result2 = db_query_params ('SELECT avg(response::int) AS avg FROM survey_responses WHERE survey_id=$1 AND question_id=$2 AND group_id=$3 AND response IN (1,2,3,4,5)',
array ($survey_id,
$quest_array[$i],
$group_id));
- }
if (!$result2 || db_numrows($result2) < 1) {
echo _('error');
echo db_error();
@@ -183,21 +174,12 @@ for ($i=0; $i<$count; $i++) {
}
// average
- if ( $sys_database_type == "mysql" ) {
-
- $result2 = db_query_params ('SELECT avg(response) AS avg FROM survey_responses WHERE survey_id=$1 AND question_id=$2 AND group_id=$3 and response != $4',
- array ($survey_id,
- $quest_array[$i],
- $group_id,
- ''));
- } else {
- $result2 = db_query_params ('SELECT avg(response::int) AS avg FROM survey_responses WHERE survey_id=$1 AND question_id=$2 AND group_id=$3 and response != $4',
- array ($survey_id,
- $quest_array[$i],
- $group_id,
- ''));
- }
+ $result2 = db_query_params ('SELECT avg(response::int) AS avg FROM survey_responses WHERE survey_id=$1 AND question_id=$2 AND group_id=$3 and response != $4',
+ array ($survey_id,
+ $quest_array[$i],
+ $group_id,
+ ''));
if (!$result2 || db_numrows($result2) < 1) {
echo _('error');
diff --git a/gforge/www/survey/admin/show_results_comments.php b/gforge/www/survey/admin/show_results_comments.php
index 26b9a4ac66..2039d8d6b4 100644
--- a/gforge/www/survey/admin/show_results_comments.php
+++ b/gforge/www/survey/admin/show_results_comments.php
@@ -35,7 +35,7 @@ $question_id = getIntFromRequest('question_id');
survey_header(array('title'=>'Survey Aggregate Results'));
if (!session_loggedin() || !user_ismember($group_id,'A')) {
- echo "Permission Denied ";
+ echo ''._('Permission denied').'
';
survey_footer(array());
exit;
}
diff --git a/gforge/www/survey/admin/show_results_csv.php b/gforge/www/survey/admin/show_results_csv.php
index 7fb407b2e7..81d068816d 100644
--- a/gforge/www/survey/admin/show_results_csv.php
+++ b/gforge/www/survey/admin/show_results_csv.php
@@ -32,7 +32,7 @@ $group_id = getIntFromRequest('group_id');
$survey_id = getIntFromRequest('survey_id');
if (!session_loggedin() || !user_ismember($group_id,'A')) {
- echo ""._('Permission denied')." ";
+ echo ''._('Permission denied').'
';
exit;
}
diff --git a/gforge/www/survey/admin/show_results_individual.php b/gforge/www/survey/admin/show_results_individual.php
index 17676e516b..f5ab023509 100644
--- a/gforge/www/survey/admin/show_results_individual.php
+++ b/gforge/www/survey/admin/show_results_individual.php
@@ -35,7 +35,7 @@ $customer_id = getIntFromRequest('customer_id');
survey_header(array('title'=>_('Results')));
if (!session_loggedin() || !user_ismember($group_id,'A')) {
- echo ""._('Permission denied')." ";
+ echo ''._('Permission denied').'
';
survey_footer(array());
exit;
}
diff --git a/gforge/www/survey/admin/survey.php b/gforge/www/survey/admin/survey.php
index 4ec87c5e97..4850515a40 100644
--- a/gforge/www/survey/admin/survey.php
+++ b/gforge/www/survey/admin/survey.php
@@ -34,10 +34,9 @@ $is_admin_page='y';
$sh = new SurveyHtml();
$s = new Survey($g, $survey_id);
-$sh->header(array('title'=>_('Add A Survey')));
-
if (!session_loggedin() || !user_ismember($group_id,'A')) {
- echo "". _('Permission denied')." ";
+ $sh->header(array());
+ echo '' . _('Permission denied') . '
';
$sh->footer(array());
exit;
}
@@ -53,7 +52,7 @@ if (getStringFromRequest('post')=="Y") {
if ($survey_id) { /* Modify */
$s->update($survey_title, $to_add, $to_del, $is_active);
- $feedback = _('UPDATE SUCCESSFUL');
+ $feedback = _('Update Successful');
} else { /* Add */
$s->create($survey_title, $to_add, $is_active);
$feedback = _('Survey Inserted');
@@ -66,7 +65,7 @@ if (getStringFromRequest('updown')=="Y") {
$is_up = getStringFromRequest('is_up');
$s->updateOrder($question_id, $is_up);
- $feedback = _('UPDATE SUCCESSFUL');
+ $feedback = _('Update Successful');
}
/* Error on previous transactions? */
@@ -75,13 +74,15 @@ if ($s->isError()) {
form_release_key(getStringFromRequest("form_key"));
}
+$sh->header(array('title'=>_('Add a Survey')));
+
echo ($sh->ShowAddSurveyForm($s));
-/* Show list of Servey */
+/* Show list of Survey */
$sf = new SurveyFactory($g);
$ss = & $sf->getSurveys();
if (!$ss) {
- echo (_('No Survey Question is found'));
+ echo '' . _('No Survey Question is found') . '
';
} else {
echo($sh->ShowSurveys($ss, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1));
}
diff --git a/gforge/www/survey/include/SurveyHTML.class.php b/gforge/www/survey/include/SurveyHTML.class.php
index 465ba6d7b4..bbb712ed99 100644
--- a/gforge/www/survey/include/SurveyHTML.class.php
+++ b/gforge/www/survey/include/SurveyHTML.class.php
@@ -31,9 +31,9 @@ class SurveyHTML extends Error {
* Show survey header
*/
function header($params) {
- global $group_id,$is_admin_page,$HTML,$sys_use_survey;
+ global $group_id,$is_admin_page,$HTML;
- if (!$sys_use_survey) {
+ if (!forge_get_config('use_survey')) {
exit_disabled();
}
@@ -99,8 +99,8 @@ class SurveyHTML extends Error {
global $group_id;
/* Default is add */
- $title = _('Add A Question');
- $question_button = _('Add This Question.');
+ $title = _('Add a Question');
+ $question_button = _('Add this Question');
/* If we have a question object, it is a Modify */
if ($q && is_object($q) && !$q->isError() && $q->getID()) {
@@ -119,17 +119,17 @@ class SurveyHTML extends Error {
$question_type = '';
}
- $ret = ''. $title. ' ';
+ $ret = ''. $title. ' ';
$ret.= $warning;
$ret.='';
- $ret.=' ';
+ $ret.=' ';
$ret.=' ';
$ret.=' ';
$ret.=' ';
$ret.=_('Question').': ';
- $ret.=' ';
- $ret.='
'. _('Question type').': ';
-
+ $ret.='
';
+ $ret.=''. _('Question Type').': ';
+
$result = db_query_params ('SELECT * FROM survey_question_types',
array());
$ret.= html_build_select_box($result,'question_type',$question_type,false);
@@ -149,9 +149,18 @@ class SurveyHTML extends Error {
global $group_id;
global $survey_id;
+ /* If no question is available */
+ if (! $survey_id && ! count($s->getAddableQuestionInstances())) {
+ $ret = '
' . sprintf(_('Please %1$s create a question %2$s before creating a survey'),
+ '',
+ ' ') .
+ '
';
+ return $ret;
+ }
+
/* Default is add */
- $title = _('Add A Survey');
- $survey_button = _('Add This Survey');
+ $title = _('Add a Survey');
+ $survey_button = _('Add this Survey');
$active = ' checked="checked" ';
$inactive = '';
@@ -193,7 +202,7 @@ class SurveyHTML extends Error {
$arr_to_del = & $s->getQuestionInstances();
if (count($arr_to_add)>0) {
- $ret.=''. _('Addable Questions').' ';
+ $ret.='
'. _('Addable Questions').' ';
$title_arr[] = " ";
$title_arr[] = _('Questions');
$title_arr[] = " ";
@@ -233,7 +242,7 @@ class SurveyHTML extends Error {
/* Deletable questions */
if (count($arr_to_del) > 0) {
- $ret.=''. _('Questions in this Survey').' ';
+ $ret.='
'. _('Questions in this Survey').'
';
$title_arr = array('Question ID', 'Question', 'Type', 'Order', 'Delete from this Survey');
$ret.=$GLOBALS['HTML']->listTableTop ($title_arr);
}
@@ -451,7 +460,7 @@ class SurveyHTML extends Error {
$ret="";
if ($s->isUserVote(user_getid())) {
- $ret.= ''. _('Warning - you are about to vote a second time on this survey.').' ';
+ $ret.= ''. _('Warning - you are about to vote a second time on this survey.').'
';
}
$ret.= ' '.
' '.
diff --git a/gforge/www/survey/index.php b/gforge/www/survey/index.php
index f8f1635919..206d763de8 100644
--- a/gforge/www/survey/index.php
+++ b/gforge/www/survey/index.php
@@ -43,14 +43,18 @@ if (!$g || !is_object($g) || $g->isError()) {
$user_id = user_getid();
/* Show header */
-$sh = new SurveyHtml();
-$sh->header(array('title'=>_('Survey')));
+$title = sprintf(_('Surveys for %1$s'), $g->getPublicName());
+$sh = new SurveyHtml();
+$sh->header(array('title'=>$title));
+echo '' . $title . ' ';
+
+plugin_hook ("blocks", "survey index");
/* Show list of Servey */
$sf = new SurveyFactory($g);
$ss = & $sf->getSurveys();
if (!$ss) {
- echo '' . (_('No Survey is found')) . ' ';
+ echo '' . (_('No Survey is found')) . '
';
} else {
echo($sh->showSurveys($ss, 0, 0, 1, 1, 1, 0));
}
diff --git a/gforge/www/survey/privacy.php b/gforge/www/survey/privacy.php
index 599a1e253c..a0d37dacf7 100644
--- a/gforge/www/survey/privacy.php
+++ b/gforge/www/survey/privacy.php
@@ -29,7 +29,7 @@ require_once $gfwww.'include/pre.php';
require_once $gfwww.'include/vote_function.php';
require_once $gfwww.'survey/survey_utils.php';
-echo $HTML->header(array('title'=>_('Survey')));
+echo $HTML->header(array('title'=>_('Survey Privacy')));
?>
@@ -37,6 +37,6 @@ echo $HTML->header(array('title'=>_('Survey')));
The information collected in these surveys will never be sold to third parties or used to solicit you to purchase any goods or services.This information is being gathered to build a profile of the projects and developers being surveyed. That profile will help visitors to the site understand the quality of a given project.
The ID\'s of those who answer surveys are suppressed and not viewable by project administrators or the public or third parties.
The information gathered is used only in aggregate form, not to single out specific users or developers.
If any changes are made to this policy, it will affect only future data that is collected and the user will of course have the ability to \'opt-out\'.'); ?>
-
+
footer(array()); ?>
diff --git a/gforge/www/survey/rating_resp.php b/gforge/www/survey/rating_resp.php
index eb32dfd36b..168e92d9ac 100644
--- a/gforge/www/survey/rating_resp.php
+++ b/gforge/www/survey/rating_resp.php
@@ -30,7 +30,7 @@ require_once $gfwww.'include/pre.php';
$HTML->header(array('title'=>_('Voting')));
if (!session_loggedin()) {
- echo ""._('You must be logged in to vote')." ";
+ echo ''._('You must be logged in to vote')."
";
} else {
$vote_on_id = getIntFromRequest('vote_on_id');
$response = getStringFromRequest('response');
diff --git a/gforge/www/survey/survey.php b/gforge/www/survey/survey.php
index 9c419f8483..71c248c139 100644
--- a/gforge/www/survey/survey.php
+++ b/gforge/www/survey/survey.php
@@ -50,11 +50,14 @@ if (!session_loggedin()) {
$sh = new SurveyHtml();
$s = new Survey($g, $survey_id);
-$sh->header(array('title'=>_('Survey')));
+$title = sprintf(_('Vote for Survey: %1$s'), $s->getTitle());
+$sh->header(array('title'=>$title));
+echo '' . $title . ' ';
if (!$survey_id) {
- echo ""._('For some reason, the Group ID or Survey ID did not make it to this page')." ";
+ echo ''._('For some reason, the Group ID or Survey ID did not make it to this page').'
';
} else {
+ plugin_hook ("blocks", "survey_".$s->getTitle());
echo($sh->ShowSurveyForm($s));
}
diff --git a/gforge/www/survey/survey_resp.php b/gforge/www/survey/survey_resp.php
index 61aa869960..71a63b0211 100644
--- a/gforge/www/survey/survey_resp.php
+++ b/gforge/www/survey/survey_resp.php
@@ -39,13 +39,15 @@ if (!$g || !is_object($g) || $g->isError()) {
}
$sh = new SurveyHtml();
-$sh->header(array('title'=>_('Survey Complete')));
+$title = _('Survey Complete');
+$sh->header(array('title'=>$title));
+echo '' . $title . ' ';
if (!$survey_id) {
/*
Quit if params are not provided
*/
- echo ""._('Error - For some reason group_id and/or survey_id did not make it he')." ";
+ echo ''._('For some reason, the Group ID or Survey ID did not make it to this page').'
';
$sh->footer(array());
exit;
}
@@ -54,8 +56,7 @@ if (!session_loggedin()) {
/*
Tell them they need to be logged in
*/
- echo ""._('You need to be logged in')." ";
- echo ""._('Unfortunately, you have to be logged in to participate in surveys.')."
";
+ echo ''._('You have to be logged in to participate in surveys.')."
";
$sh->footer(array());
exit;
}
@@ -66,7 +67,7 @@ if (!session_loggedin()) {
,
-
+
getUnixName();
$filename=$group_name.'-scmroot.tar.gz';
-if (file_exists($sys_scm_tarballs_path.'/'.$filename)) {
+if (file_exists(forge_get_config('scm_tarballs_path').'/'.$filename)) {
Header('Content-disposition: filename="'.str_replace('"', '', $filename).'"');
Header("Content-type: application/x-gzip");
- $length = filesize($sys_scm_tarballs_path.'/'.$filename);
+ $length = filesize(forge_get_config('scm_tarballs_path').'/'.$filename);
Header("Content-length: ".$length);
- readfile_chunked($sys_scm_tarballs_path.'/'.$filename);
+ readfile_chunked(forge_get_config('scm_tarballs_path').'/'.$filename);
} else {
session_redirect(util_make_url("/404.php"));
}
diff --git a/gforge/www/terms.php b/gforge/www/terms.php
index 966d44b9a1..6d36b99918 100644
--- a/gforge/www/terms.php
+++ b/gforge/www/terms.php
@@ -35,11 +35,11 @@ $HTML->header(array('title'=> _('Terms of use')));
-
+
diff --git a/gforge/www/themes/css/fusionforge.css b/gforge/www/themes/css/fusionforge.css
index d7a4fae64b..38e910c50f 100644
--- a/gforge/www/themes/css/fusionforge.css
+++ b/gforge/www/themes/css/fusionforge.css
@@ -66,4 +66,45 @@
.frs_release_name_version {
margin: 0 0 0 1em;
-}
\ No newline at end of file
+}
+
+/* Progress bargraph (trackers) */
+table.progress {
+ border: 1px solid #d7d7d7;
+ border-collapse: collapse;
+ border-spacing: 0;
+ margin: 0;
+ padding: 0;
+ margin-top: 1em;
+ empty-cells: show;
+ width: 50%;
+ margin-left: 25%;
+ margin-right: 25%;
+}
+table.progress_legend {
+ width: 50%;
+ margin-left: 25%;
+ margin-right: 25%;
+}
+table.progress a, table.progress :link, table.progress :visited,
+table.progress :link:hover, table.progress :visited:hover {
+ border: none;
+ display: block;
+ height: 1.2em;
+ padding: 0;
+ margin: 0;
+ text-decoration: none
+}
+table.progress td { background: #fff; padding: 0 }
+table.progress td :hover { background: none }
+
+/* style for warning messages box
+*/
+.warning_msg {
+ font-weight: bold;
+ border-width: 2px;
+ border-style: solid;
+ background-color: #ffd297; /* orange */
+ border-color: #FFA500; /* orange */
+ padding: 0.5em;
+}
diff --git a/gforge/www/themes/gforge-simple-theme/Theme.class.php b/gforge/www/themes/gforge-simple-theme/Theme.class.php
index d0661dfec8..ee9f6420c5 100644
--- a/gforge/www/themes/gforge-simple-theme/Theme.class.php
+++ b/gforge/www/themes/gforge-simple-theme/Theme.class.php
@@ -45,14 +45,14 @@ class Theme extends Layout {
*/
function Layout() {
- $this->themeroot=$GLOBALS['sys_themeroot'].$GLOBALS['sys_theme'];
+ $this->themeroot=forge_get_config('themes_root').forge_get_config('default_theme');
/* if images directory exists in theme, then use it as imgroot */
if (file_exists ($this->themeroot.'/images')){
- $this->imgroot='/themes/'.$GLOBALS['sys_theme'].'/images/';
+ $this->imgroot='/themes/'.forge_get_config('default_theme').'/images/';
}
// Constructor for parent class...
- if ( file_exists($GLOBALS['sys_custom_path'] . '/index_std.php') )
- $this->rootindex = $GLOBALS['sys_custom_path'] . '/index_std.php';
+ if ( file_exists(forge_get_config('custom_path') . '/index_std.php') )
+ $this->rootindex = forge_get_config('custom_path') . '/index_std.php';
$this->Error();
}
@@ -64,9 +64,9 @@ class Theme extends Layout {
*/
function headerStart($params) {
if (!$params['title']) {
- $params['title'] = $GLOBALS['sys_name'];
+ $params['title'] = forge_get_config ('forge_name');
} else {
- $params['title'] = $GLOBALS['sys_name'] . ': ' . $params['title'];
+ $params['title'] = forge_get_config ('forge_name') . ': ' . $params['title'];
}
print '
@@ -84,7 +84,7 @@ class Theme extends Layout {
headerLink(); ?>
';
echo $activity;
@@ -96,10 +96,10 @@ class Theme extends Layout {
this stylesheet
new stylesheets should use the .css file
*/
- $theme_cssfile=$GLOBALS['sys_themeroot'].$GLOBALS['sys_theme'].'/css/'.$GLOBALS['sys_theme'].'.css';
+ $theme_cssfile=forge_get_config('themes_root').forge_get_config('default_theme').'/css/'.forge_get_config('default_theme').'.css';
if (file_exists($theme_cssfile)){
echo '
- ';
+ ';
}
?>
@@ -144,7 +144,7 @@ if (session_loggedin()) {
} else {
echo util_make_link ('/account/login.php',_('Log In'));
echo ' ';
- if (!$GLOBALS['sys_user_reg_restricted']) {
+ if (!forge_get_config ('user_registration_restricted')) {
echo util_make_link ('/account/register.php',_('New Account'));
echo ' ';
}
@@ -338,7 +338,7 @@ function listTableBottom() {
function outerTabs($params) {
- global $sys_use_trove,$sys_use_snippet,$sys_use_people;
+
$selected=0;
$TABS_DIRS[]=util_make_url ('/') ;
@@ -352,7 +352,7 @@ function outerTabs($params) {
$selected=count($TABS_DIRS)-1;
}
- if ($sys_use_trove) {
+ if (forge_get_config('use_trove')) {
$TABS_IDS[]='softwaremap';
$TABS_DIRS[]=util_make_url ('/softwaremap/') ;
$TABS_TITLES[]=_('Project Tree');
@@ -360,7 +360,7 @@ function outerTabs($params) {
$selected=count($TABS_DIRS)-1;
}
}
- if ($sys_use_snippet) {
+ if (forge_get_config('use_snippet')) {
$TABS_IDS[]='snippet';
$TABS_DIRS[]=util_make_url ('/snippet/') ;
$TABS_TITLES[]=_('Code Snippets');
@@ -368,7 +368,7 @@ function outerTabs($params) {
$selected=count($TABS_DIRS)-1;
}
}
- if ($sys_use_people) {
+ if (forge_get_config('use_people')) {
$TABS_IDS[]='people';
$TABS_DIRS[]=util_make_url ('/people/') ;
$TABS_TITLES[]=_('Project Openings');
diff --git a/gforge/www/themes/gforge/Theme.class.php b/gforge/www/themes/gforge/Theme.class.php
index 7a80a8259c..d63e94e3e2 100644
--- a/gforge/www/themes/gforge/Theme.class.php
+++ b/gforge/www/themes/gforge/Theme.class.php
@@ -2,179 +2,95 @@
require_once $gfwww.'include/Layout.class.php';
-define('THEME_DIR', util_make_uri ('/themes/gforge'));
-
define('TOP_TAB_HEIGHT', 30);
define('BOTTOM_TAB_HEIGHT', 22);
class Theme extends Layout {
- function Theme() {
- // Parent constructor
- $this->Layout();
-
- $this->imgroot = THEME_DIR.'/images/';
- $this->jsroot = THEME_DIR.'/js/';
- }
-
- /**
- * Layout() - Constructor
- */
- function Layout() {
- // Constructor for parent class...
- if ( file_exists($GLOBALS['sys_custom_path'] . '/index_std.php') ) {
- $this->rootindex = $GLOBALS['sys_custom_path'] . '/index_std.php';
- } else {
- $this->rootindex = $GLOBALS['gfwww'].'index_std.php';
- }
- $this->Error();
- }
-
- /**
- * header() - "steel theme" top of page
- *
- * @param array Header parameters array
- */
- function header($params) {
- if (!isset($params['title'])) {
- $params['title'] = $GLOBALS['sys_name'];
- } else {
- $params['title'] = $GLOBALS['sys_name'] . ': ' . $params['title'];
+ function Theme() {
+ // Parent constructor
+ $this->Layout();
+ $this->doctype = 'strict';
+ $this->cssurls = array(
+ 'http://yui.yahooapis.com/2.6.0/build/reset-fonts-grids/reset-fonts-grids.css',
+ 'http://yui.yahooapis.com/2.6.0/build/base/base-min.css',
+ util_make_url ('/themes/css/fusionforge.css'),
+ $this->cssbaseurl .'theme.css',
+ $this->cssbaseurl .'theme-pages.css',
+ );
}
- print '';
- echo '
-
-
-
-
- '. $params['title'] . '
-
- ';
-
- echo $this->headerLink();
-
- echo '
-
- ';
-
- $this->headerCSS();
-
- echo '
-
-
- ';
-
- $this->bodyHeader($params);
- }
-
- function bodyHeader($params) {
- global $user_guide;
+ function bodyHeader($params) {
+ global $user_guide;
- echo '
+ echo '
';
- echo $this->outerTabs($params);
- echo '';
- if (isset($params['group']) && $params['group']) {
- echo $this->projectTabs($params['toptab'],$params['group']);
- }
- echo '
+ echo $this->outerTabs($params);
+ echo '';
+ if (isset($params['group']) && $params['group']) {
+ echo $this->projectTabs($params['toptab'],$params['group']);
+ }
+ echo '
';
- }
+ }
- function bodyFooter($params) {
- echo '
+ function bodyFooter($params) {
+ echo '
';
- }
+ }
- function footer($params) {
- $this->bodyFooter($params);
- echo '
+ function footer($params) {
+ $this->bodyFooter($params);
+ echo '
+ ' . $this->navigation->getPoweredBy() . '
+
+ ' . $this->navigation->getShowSource() . '
';
- global $sys_show_source;
- if ($sys_show_source) {
- global $SCRIPT_NAME;
- print util_make_link ('/source.php?file=' . $SCRIPT_NAME, _('Show source'), array ("class" => "showsource"));
- }
-
- echo '
+ echo '
';
- }
-
- function headerCSS() {
- echo '
-
-
-
-
-
- ';
+ }
- plugin_hook ('cssfile',$this);
- }
-
- function getRootIndex() {
- return $this->rootindex;
- }
-
- /**
- * boxTop() - Top HTML box
- *
- * @param string Box title
- * @param bool Whether to echo or return the results
- * @param string The box background color
- */
- function boxTop($title, $id = '') {
- $t_result = '
+ /**
+ * boxTop() - Top HTML box
+ *
+ * @param string Box title
+ * @param bool Whether to echo or return the results
+ * @param string The box background color
+ */
+ function boxTop($title, $id = '') {
+ $t_result = '
@@ -185,497 +101,311 @@ class Theme extends Layout {
';
- return $t_result;
- }
-
- /**
- * boxMiddle() - Middle HTML box
- *
- * @param string Box title
- * @param string The box background color
- */
- function boxMiddle($title, $id = '') {
- $t_result ='
+ return $t_result;
+ }
+
+ /**
+ * boxMiddle() - Middle HTML box
+ *
+ * @param string Box title
+ * @param string The box background color
+ */
+ function boxMiddle($title, $id = '') {
+ $t_result ='
'.$title.'
';
- return $t_result;
- }
-
- /**
- * boxBottom() - Bottom HTML box
- *
- */
- function boxBottom() {
- $t_result='
+ return $t_result;
+ }
+
+ /**
+ * boxBottom() - Bottom HTML box
+ *
+ */
+ function boxBottom() {
+ $t_result='
';
- return $t_result;
- }
-
- /**
- * boxGetAltRowStyle() - Get an alternating row style for tables
- *
- * @param int Row number
- */
- function boxGetAltRowStyle($i) {
- if ($i % 2 == 0) {
- return 'class="bgcolor-white"';
- } else {
- return 'class="bgcolor-grey"';
- }
- }
-
- /**
- * listTableTop() - Takes an array of titles and builds the first row of a new table.
- *
- * @param array The array of titles
- * @param array The array of title links
- * @param boolean Whether to highlight or not the entry
- */
- function listTableTop ($title_arr,$links_arr=false,$selected=false) {
- $return = '
+ return $t_result;
+ }
+
+ /**
+ * boxGetAltRowStyle() - Get an alternating row style for tables
+ *
+ * @param int Row number
+ */
+ function boxGetAltRowStyle($i) {
+ if ($i % 2 == 0) {
+ return 'class="bgcolor-white"';
+ } else {
+ return 'class="bgcolor-grey"';
+ }
+ }
+
+ /**
+ * listTableTop() - Takes an array of titles and builds the first row of a new table.
+ *
+ * @param array The array of titles
+ * @param array The array of title links
+ * @param boolean Whether to highlight or not the entry
+ */
+ function listTableTop ($title_arr,$links_arr=false,$selected=false) {
+ $return = '
';
- $count=count($title_arr);
- if ($links_arr) {
- for ($i=0; $i<$count; $i++) {
- $return .= '
+ $count=count($title_arr);
+ if ($links_arr) {
+ for ($i=0; $i<$count; $i++) {
+ $return .= '
'.$title_arr[$i].' ';
- }
- } else {
- for ($i=0; $i<$count; $i++) {
- $return .= '
+ }
+ } else {
+ for ($i=0; $i<$count; $i++) {
+ $return .= '
'.$title_arr[$i].' ';
- }
- }
- return $return.' ';
- }
+ }
+ }
+ return $return.'';
+ }
- function listTableBottom() {
- return '
+ function listTableBottom() {
+ return '
';
- }
+ }
- function tabGenerator($TABS_DIRS, $TABS_TITLES, $nested=false, $selected=false, $sel_tab_bgcolor='WHITE', $total_width='100%') {
+ function tabGenerator($TABS_DIRS, $TABS_TITLES, $nested=false,
+ $selected=false, $sel_tab_bgcolor='WHITE',
+ $total_width='100%') {
$count=count($TABS_DIRS);
if ($count < 1) {
return;
}
- $return = '
+ $return = '
imgroot.($nested ? 'bottomtab-new/' : 'toptab-new/');
-
- $accumulated_width = 0;
- for ($i=0; $i<$count; $i++) {
- $tabwidth = intval(ceil(($i+1)*100/$count)) - $accumulated_width ;
- $accumulated_width += $tabwidth ;
-
- if ($selected == $i) {
- $left_img = $folder.'selected-left.gif';
- $middle_img = $folder.'selected-middle.gif';
- $right_img = $folder.'selected-right.gif';
- $separ_img = $folder.'selected-separator.gif';
- $css_class = $nested ? 'bottomTabSelected' : 'topTabSelected';
- } else {
- $left_img = $folder.'left.gif';
- $middle_img = $folder.'middle.gif';
- $right_img = $folder.'right.gif';
- $separ_img = $folder.'separator.gif';
- $css_class = $nested ? 'bottomTab' : 'topTab';
- }
+/* $folder = $this->imgurl.($nested ? 'bottomtab-new/' : 'toptab-new/');*/
+
+ $accumulated_width = 0;
+ for ($i=0; $i<$count; $i++) {
+ $tabwidth = intval(ceil(($i+1)*100/$count)) - $accumulated_width ;
+ $accumulated_width += $tabwidth ;
+/*
+ if ($selected == $i) {
+ $left_img = $folder.'selected-left.gif';
+ $middle_img = $folder.'selected-middle.gif';
+ $right_img = $folder.'selected-right.gif';
+ $separ_img = $folder.'selected-separator.gif';
+ $css_class = $nested ? 'bottomTabSelected' : 'topTabSelected';
+ } else {
+ $left_img = $folder.'left.gif';
+ $middle_img = $folder.'middle.gif';
+ $right_img = $folder.'right.gif';
+ $separ_img = $folder.'separator.gif';
+ $css_class = $nested ? 'bottomTab' : 'topTab';
+ }
- $clear_img = $this->imgroot.'clear.png';
-
- $return .= "\n";
-
- // left part
- $return .= '' . "\n";
- $return .= 'imgurl.'clear.png';
+*/
+ $return .= "\n";
+
+ // left part
+ $return .= '
' . "\n";
+ $return .= '' . "\n";
- $return .= '
'.$TABS_TITLES[$i].'' . "\n";
- $return .= '
';
- $return .= '
' . "\n";
- $return .= ' ' . "\n";
-
- // right part
- // if the next tab is not selected, close this tab
- if ($selected != $i+1) {
- $return .= '
' . "\n";
- $return .= '' . "\n";
+ $return .= '
'.$TABS_TITLES[$i].'' . "\n";
+ $return .= '
';
+ $return .= '
' . "\n";
+ $return .= ' ' . "\n";
+
+ // right part
+ // if the next tab is not selected, close this tab
+ if ($selected != $i+1) {
+ $return .= '
' . "\n";
+ $return .= '
';
- return $return;
- }
-
- function searchBox() {
- global $words,$forum_id,$group_id,$group_project_id,$atid,$exact,$type_of_search;
+ return $return;
+ }
- if(get_magic_quotes_gpc()) {
- $defaultWords = stripslashes($words);
- } else {
- $defaultWords = $words;
- }
-
- // if there is no search currently, set the default
- if ( ! isset($type_of_search) ) {
- $exact = 1;
- }
- print '
-
- ';
- print ' ';
-
- }
-
- function advancedSearchBox($sectionsArray, $group_id, $words, $isExact) {
- // display the searchmask
- print '
-
-
-
- '
- .$this->createUnderSections($sectionsArray).'
- ';
-
-
- //create javascript methods for select none/all
- print '
-
- ';
+ /**
+ * printSubMenu() - Takes two array of titles and links and builds the contents of a menu.
+ *
+ * @param array The array of titles.
+ * @param array The array of title links.
+ * @return string Html to build a submenu.
+ */
+ function printSubMenu ($title_arr,$links_arr) {
+ $count=count($title_arr);
+ $count--;
+
+ $return = '';
+
+ for ($i=0; $i<$count; $i++) {
+ $return .= util_make_link ($links_arr[$i], $title_arr[$i]) . ' | ';
+ }
+ $return .= util_make_link ($links_arr[$i], $title_arr[$i]);
+ return $return;
+ }
- }
-
- function createUnderSections($sectionsArray) {
- global $group_subsection_names;
- $countLines = 0;
- foreach ($sectionsArray as $section) {
- if(is_array($section)) {
- $countLines += (3 + count ($section));
- } else {
- //2 lines one for section name and one for checkbox
- $countLines += 3;
- }
- }
- $breakLimit = round($countLines/3);
- $break = $breakLimit;
- $countLines = 0;
- $return = '
-
-
-
-
-
- '._('Search in').'
- '._('Select').' '._('all').' / '._('none').'
-
-
-
-
-
- ';
- foreach($sectionsArray as $key => $section) {
- $oldcountlines = $countLines;
- if (is_array($section)) {
- $countLines += (3 + count ($section));
- } else {
- $countLines += 3;
- }
-
- if ($countLines >= $break) {
- //if the next block is so large that shifting it to the next column hits the breakpoint better
- //the second part of statement (behind &&) proofs, that no 4th column is added
- if ((($countLines - $break) >= ($break - $countLines)) && ((($break + $breakLimit)/$breakLimit) <= 3)) {
- $return .= ' ';
- $break += $breakLimit;
- }
- }
-
- $return .= ' ';
-
- if ($countLines >= $break) {
- if (($countLines - $break) < ($break - $countLines)) {
- $return .= ' ';
- $break += $breakLimit;
- }
- }
- }
+ /**
+ * subMenu() - Takes two array of titles and links and build a menu.
+ *
+ * @param array The array of titles.
+ * @param array The array of title links.
+ * @return string Html to build a submenu.
+ */
+ function subMenu ($title_arr,$links_arr) {
+ $return = $this->beginSubMenu () ;
+ $return .= $this->printSubMenu ($title_arr,$links_arr) ;
+ $return .= $this->endSubMenu () ;
+ return $return;
+ }
- return $return.'
-
-
';
- }
-
- /**
- * beginSubMenu() - Opening a submenu.
- *
- * @return string Html to start a submenu.
- */
- function beginSubMenu () {
- $return = '
- ';
- return $return;
- }
-
- /**
- * endSubMenu() - Closing a submenu.
- *
- * @return string Html to end a submenu.
- */
- function endSubMenu () {
- $return = '
';
- return $return;
- }
-
- /**
- * printSubMenu() - Takes two array of titles and links and builds the contents of a menu.
- *
- * @param array The array of titles.
- * @param array The array of title links.
- * @return string Html to build a submenu.
- */
- function printSubMenu ($title_arr,$links_arr) {
- $count=count($title_arr);
- $count--;
-
- $return = '';
-
- for ($i=0; $i<$count; $i++) {
- $return .= util_make_link ($links_arr[$i], $title_arr[$i]) . ' | ';
- }
- $return .= util_make_link ($links_arr[$i], $title_arr[$i]);
- return $return;
- }
-
- /**
- * subMenu() - Takes two array of titles and links and build a menu.
- *
- * @param array The array of titles.
- * @param array The array of title links.
- * @return string Html to build a submenu.
- */
- function subMenu ($title_arr,$links_arr) {
- $return = $this->beginSubMenu () ;
- $return .= $this->printSubMenu ($title_arr,$links_arr) ;
- $return .= $this->endSubMenu () ;
- return $return;
- }
-
- /**
- * multiTableRow() - create a mutlilevel row in a table
- *
- * @param string the row attributes
- * @param array the array of cell data, each element is an array,
- * the first item being the text,
- * the subsequent items are attributes (dont include
- * the bgcolor for the title here, that will be
- * handled by $istitle
- * @param boolean is this row part of the title ?
- *
- */
- function multiTableRow($row_attr, $cell_data, $istitle) {
- $return= '
+ /**
+ * multiTableRow() - create a mutlilevel row in a table
+ *
+ * @param string the row attributes
+ * @param array the array of cell data, each element is an array,
+ * the first item being the text,
+ * the subsequent items are attributes (dont include
+ * the bgcolor for the title here, that will be
+ * handled by $istitle
+ * @param boolean is this row part of the title ?
+ *
+ */
+ function multiTableRow($row_attr, $cell_data, $istitle) {
+ $return= '
COLOR_HTMLBOX_TITLE .'"';
- }
- $return .= '>';
- for ( $c = 0; $c < count($cell_data); $c++ ) {
- $return .='FONTCOLOR_HTMLBOX_TITLE.'">';
- }
- $return .= $cell_data[$c][0];
- if ( $istitle ) {
- $return .=' ';
- }
- $return .= ' ';
+ if ( $istitle ) {
+ $return .=' align="center" bgcolor="'. $this->COLOR_HTMLBOX_TITLE .'"';
+ }
+ $return .= '>';
+ for ( $c = 0; $c < count($cell_data); $c++ ) {
+ $return .='FONTCOLOR_HTMLBOX_TITLE.'">';
+ }
+ $return .= $cell_data[$c][0];
+ if ( $istitle ) {
+ $return .=' ';
+ }
+ $return .= ' ';
- }
- $return .= '
+ }
+ $return .= '
';
- return $return;
- }
-
- /**
- * feedback() - returns the htmlized feedback string when an action is performed.
- *
- * @param string feedback string
- * @return string htmlized feedback
- */
- function feedback($feedback) {
- if (!$feedback) {
- return '';
- } else {
- return '
+ return $return;
+ }
+
+ /**
+ * feedback() - returns the htmlized feedback string when an action is performed.
+ *
+ * @param string feedback string
+ * @return string htmlized feedback
+ */
+ function feedback($feedback) {
+ if (!$feedback) {
+ return '';
+ } else {
+ return '
'.strip_tags($feedback, ' ').' ';
- }
- }
-
- /**
- * getThemeIdFromName()
- *
- * @param string the dirname of the theme
- * @return integer the theme id
- */
- function getThemeIdFromName($dirname) {
- $res=db_query_params ('SELECT theme_id FROM themes WHERE dirname=$1',
- array($dirname));
- return db_result($res,0,'theme_id');
- }
+ }
+ }
+
+ /**
+ * getThemeIdFromName()
+ *
+ * @param string the dirname of the theme
+ * @return integer the theme id
+ */
+ function getThemeIdFromName($dirname) {
+ $res=db_query_params ('SELECT theme_id FROM themes WHERE dirname=$1',
+ array($dirname));
+ return db_result($res,0,'theme_id');
+ }
}
// Local Variables:
diff --git a/gforge/www/themes/gforge/css/theme.css b/gforge/www/themes/gforge/css/theme.css
index d8c7587fc8..8b96877ffe 100644
--- a/gforge/www/themes/gforge/css/theme.css
+++ b/gforge/www/themes/gforge/css/theme.css
@@ -7,7 +7,7 @@
*/
/* HTML elements */
-body {color: rgb(68, 68, 68); background-color: rgb(247, 247, 247); }
+body {color: rgb(68, 68, 68); background-color: rgb(247, 247, 247); text-align: left; }
form {margin:0; }
img {border:0; }
h1 {margin:0; }
@@ -15,11 +15,10 @@ div#maindiv {margin:1em; }
a {text-decoration:none; color:rgb(1, 73, 144); }
a:hover {text-decoration: underline; color: rgb(247, 0, 0); }
-a.userlink {color: white; }
-a.userlink:hover {text-decoration: underline; color: white;}
-a.userlink:visited {text-decoration: none; color: white; }
+a.userlink, #searchBox a {color: white; }
+a.userlink:hover, #searchBox a:hover {text-decoration: underline; color: white;}
+a.userlink:visited, #searchBox a:visited {text-decoration: none; color: white; }
th, td {text-align:left; border:none; }
-#mydoc {text-align: left;}
input[type="text"], input[type="password"], textarea {
width: auto;
}
diff --git a/gforge/www/themes/gforge/images/logo200x200.png b/gforge/www/themes/gforge/images/logo200x200.png
new file mode 100644
index 0000000000..4aa3039837
Binary files /dev/null and b/gforge/www/themes/gforge/images/logo200x200.png differ
diff --git a/gforge/www/themes/gforge/images/wgLogo.png b/gforge/www/themes/gforge/images/wgLogo.png
index 9f64a81349..9ddd2792ac 100644
Binary files a/gforge/www/themes/gforge/images/wgLogo.png and b/gforge/www/themes/gforge/images/wgLogo.png differ
diff --git a/gforge/www/themes/lite/Theme.class.php b/gforge/www/themes/lite/Theme.class.php
index 377d8b2c0b..8c0804808c 100644
--- a/gforge/www/themes/lite/Theme.class.php
+++ b/gforge/www/themes/lite/Theme.class.php
@@ -84,7 +84,7 @@ class Theme extends Layout {
@@ -251,28 +251,28 @@ if (isset($params['group']) && $params['group']) {
}
function mainMenu($params) {
- global $sys_use_trove,$sys_use_snippet,$sys_use_people;
+
$TABS_DIRS[]='/';
$TABS_DIRS[]='/my/';
- if ($sys_use_trove) {
+ if (forge_get_config('use_trove')) {
$TABS_DIRS[]='/softwaremap/';
}
- if ($sys_use_snippet) {
+ if (forge_get_config('use_snippet')) {
$TABS_DIRS[]='/snippet/';
}
- if ($sys_use_people) {
+ if (forge_get_config('use_people')) {
$TABS_DIRS[]='/people/';
}
$TABS_TITLES[]=_('Home');
$TABS_TITLES[]=_('My Page');
- if ($sys_use_trove) {
+ if (forge_get_config('use_trove')) {
$TABS_TITLES[]=_('Projects');
}
- if ($sys_use_snippet) {
+ if (forge_get_config('use_snippet')) {
$TABS_TITLES[]=_('Code Snippets');
}
- if ($sys_use_people) {
+ if (forge_get_config('use_people')) {
$TABS_TITLES[]=_('Project Openings');
}
diff --git a/gforge/www/themes/osx/Theme.class.php b/gforge/www/themes/osx/Theme.class.php
index e98b1407c2..b57dc92700 100644
--- a/gforge/www/themes/osx/Theme.class.php
+++ b/gforge/www/themes/osx/Theme.class.php
@@ -57,8 +57,6 @@ class Theme extends Layout {
* @param array Header parameters array
*/
function header($params) {
- global $sys_name;
-
$this->headerStart($params); ?>
diff --git a/gforge/www/themes/ultralite/Theme.class.php b/gforge/www/themes/ultralite/Theme.class.php
index cc2d03e0b1..2dbfc2d3c8 100644
--- a/gforge/www/themes/ultralite/Theme.class.php
+++ b/gforge/www/themes/ultralite/Theme.class.php
@@ -17,11 +17,10 @@ class Theme extends Layout {
{
header("Location:".$_POST['menuList']);
}
- global $sys_name;
if (!$params['title']) {
- $params['title'] = "$sys_name";
+ $params['title'] = forge_get_config ('forge_name');
} else {
- $params['title'] = "$sys_name: " . $params['title'];
+ $params['title'] = forge_get_config ('forge_name').": " . $params['title'];
}
print '';
?>
diff --git a/gforge/www/top/index.php b/gforge/www/top/index.php
index 91a77456b8..a7a8d15b36 100644
--- a/gforge/www/top/index.php
+++ b/gforge/www/top/index.php
@@ -29,9 +29,9 @@ require_once $gfwww.'include/pre.php';
$HTML->header(array('title'=>_('Top Projects')));
?>
-
+
-
+
diff --git a/gforge/www/top/mostactive.php b/gforge/www/top/mostactive.php
index 281dc77281..0eae109268 100644
--- a/gforge/www/top/mostactive.php
+++ b/gforge/www/top/mostactive.php
@@ -44,8 +44,9 @@ if ($type == 'week') {
$HTML->header(array('title'=>$title));
-print ''.$title.'
-('._('Updated Daily').')
+print ''.$title.'
+
+('._('Updated Daily').')
'.util_make_link ('/top/','['._('View Other Top Categories').']').'
';
diff --git a/gforge/www/top/toplist.php b/gforge/www/top/toplist.php
index 9f08fc3625..de0641221d 100644
--- a/gforge/www/top/toplist.php
+++ b/gforge/www/top/toplist.php
@@ -38,7 +38,7 @@ if ($type == 'downloads_week') {
}
else if ($type == 'pageviews_proj') {
$res_top = $stats->getTopPageViews();
- $title = sprintf(_('Top Weekly Project Pageviews at *.%1$s (from impressions of %2$s logo)'), $GLOBALS['sys_default_domain'], $GLOBALS['sys_name']);
+ $title = sprintf(_('Top Weekly Project Pageviews at *.%1$s (from impressions of %2$s logo)'), forge_get_config('web_host'), forge_get_config ('forge_name'));
$column1 = _('Pageviews');
}
else if ($type == 'forumposts_week') {
@@ -53,7 +53,8 @@ else {
$column1 = _('Downloads');
}
$HTML->header(array('title'=>$title));
-print ''.util_make_link ('/top/','['._('View Other Top Categories').']');
+print '
'.$title.' ';
+print ''.util_make_link ('/top/','['._('View Other Top Categories').']').'
';
$arr=array(_('Rank'),_('Project name'),"$column1");
echo $HTML->listTableTop($arr);
diff --git a/gforge/www/tracker/admin/form-customizelist.php b/gforge/www/tracker/admin/form-customizelist.php
index 5407eced4e..31054ca71c 100644
--- a/gforge/www/tracker/admin/form-customizelist.php
+++ b/gforge/www/tracker/admin/form-customizelist.php
@@ -28,13 +28,22 @@
'assigned_to' => _('Assigned To'),
'submitted_by' => _('Submitted By'),
'close_date' => _('Close Date'),
- 'details' => _('Detailed description')
- );
+ 'details' => _('Detailed description'),
+ 'related_tasks' => _('Related tasks')
+ );
- if(count($ath->getExtraFields(ARTIFACT_EXTRAFIELDTYPE_STATUS)) > 0) {
- unset($fields['status_id']);
- }
+ if(count($ath->getExtraFields(ARTIFACT_EXTRAFIELDTYPE_STATUS)) > 0) {
+ unset($fields['status_id']);
+ }
+ // Extra fields
+ foreach ($efarr as $f) {
+ $fields[$f[0]] = $f['field_name'];
+ }
+
+ asort($fields);
+
+ // Display fields
foreach ($fields as $f => $name) {
$pos = array_search($f, $browse_fields);
echo " isError()) {
//build page title to make bookmarking easier
//if a user was selected, add the user_name to the title
//same for status
-$ath->header(array('atid'=>$ath->getID()));
+$ath->header(array('atid'=>$ath->getID(), 'title'=>$ath->getName()));
/**
*
@@ -232,6 +233,19 @@ if ($ath->usesCustomStatuses()) {
$status_box = $ath->statusBox('_status',$_status,true,_('Any'));
}
echo ''."\n";
+
+// start of RDFa
+$proj_name = $group->getUnixName();
+$proj_url = util_make_url_g($group->getUnixName(),$group_id);
+// the tracker's URIs are constructed in order to support addition of an OSLC-CM REST server
+// inside /tracker/cm/. There each tracker has a URL in the form .../project/PROJ_NAME/atid/ATID
+$tracker_stdzd_uri = util_make_url('/tracker/cm/project/'. $proj_name .'/atid/'. $ath->getID());
+print ''."\n";
+print ' '."\n";
+print ' '."\n";
+print "
\n"; // end of about
+
echo '
';
@@ -311,6 +325,16 @@ echo '
';
+// Compute the list of fields which can be sorted.
+// Currently, only text & integer are taken (for simplicity only).
+$efarr = $ath->getExtraFields(ARTIFACT_EXTRAFIELDTYPE_TEXT.",".ARTIFACT_EXTRAFIELDTYPE_INTEGER);
+$keys=array_keys($efarr);
+for ($k=0; $k' .
'(?) '.
@@ -334,6 +358,63 @@ echo '
if ($art_arr && count($art_arr) > 0) {
+ if ($query_id) {
+ $aq = new ArtifactQuery($ath,$query_id);
+ $has_bargraph = (in_array('bargraph', $aq->getQueryOptions()));
+ } else {
+ $has_bargraph = false;
+ }
+
+ if ($has_bargraph) {
+ // Display the roadmap block based on the values of the Status field.
+ $colors = array('#a71d16', '#ffa0a0', '#f5f5b5', '#bae0ba', '#16a716');
+ $count = array();
+ $percent = array();
+ foreach($art_arr as $art) {
+ if ($ath->usesCustomStatuses()) {
+ $custom_id = $ath->getCustomStatusField();
+ $extra_data = $art->getExtraFieldDataText();
+ $count[ $extra_data[$custom_id]['value'] ]++;
+ } else {
+ $count[ $art->getStatusName()]++;
+ }
+ }
+ foreach($count as $n => $c) {
+ $percent[$n] = round(100*$c/count($art_arr));
+ }
+
+ $i=0;
+ $efarr =& $ath->getExtraFields(ARTIFACT_EXTRAFIELDTYPE_STATUS);
+ $keys=array_keys($efarr);
+ $field_id = $keys[0];
+ $states = $ath->getExtraFieldElements($field_id);
+ $graph = '';
+ $legend = '';
+ if (is_array($states)) {
+ foreach($states as $state) {
+ $name = $state['element_name'];
+ if ($count[$name]) {
+ $graph .= ' ';
+ $legend .= ''."$name: $count[$name] ($percent[$name]%) ";
+ }
+ $i++;
+ }
+ }
+
+ if ($graph) {
+ ?>
+
+
+ getCustomStatusField(),$_extra_fields)) {
@@ -356,7 +437,7 @@ if ($art_arr && count($art_arr) > 0) {
foreach ($browse_fields as $f) {
$title=$f;
if (intval($f) > 0) {
- $title = $ath->getExtraFieldName($f);
+ $title = $ath->getExtraFieldName($f);
} else {
if ($f == 'id')
$title=_('ID');
@@ -376,6 +457,8 @@ if ($art_arr && count($art_arr) > 0) {
$title=_('Assigned to');
if ($f == 'submitted_by')
$title=_('Submitted by');
+ if ($f == 'related_tasks')
+ $title=_('Related tasks');
}
$title_arr[] = $title;
}
@@ -423,11 +506,31 @@ if ($art_arr && count($art_arr) > 0) {
date(_('Y-m-d H:i'),$art_arr[$i]->getCloseDate()) :' ') .' ';
} else if ($f == 'details') {
echo '
'. $art_arr[$i]->getDetails() .' ';
+ } else if ($f == 'related_tasks') {
+ echo '
';
+ $tasks_res = $art_arr[$i]->getRelatedTasks();
+ $s ='';
+ while ($rest = db_fetch_array($tasks_res)) {
+ $link = '/pm/task.php?func=detailtask&project_task_id='.$rest['project_task_id'].
+ '&group_id='.$group_id.'&group_project_id='.$rest['group_project_id'];
+ $title = '[T'.$rest['project_task_id'].']';
+ if ($rest['status_id'] == 2) {
+ $title = ''.$title.' ';
+ }
+ print $s.''.$title.' ';
+ $s = ' ';
+ }
+ echo ' ';
} else if (intval($f) > 0) {
// Now display extra-fields (fields are numbers).
$value = $extra_data[$f]['value'];
if ($extra_data[$f]['type'] == 9) {
$value = preg_replace('/\b(\d+)\b/e', "_artifactid2url('\\1')", $value);
+ } else if ($extra_data[$f]['type'] == 7) {
+ if ($art_arr[$i]->getStatusID() == 2) {
+ $value = '
'.$value.' ';
+ }
+
}
echo '
' . $value .' ';
} else {
@@ -568,15 +671,10 @@ if ($art_arr && count($art_arr) > 0) {
if (in_array('priority', $browse_fields)) {
show_priority_colors_key();
-
}
} else {
-
- echo '
-
'._('No items found').' ';
+ echo '
'._('No items found').'
';
echo db_error();
- //echo "";
-
}
$ath->footer(array());
diff --git a/gforge/www/tracker/detail.php b/gforge/www/tracker/detail.php
index f37ed9b310..5a22aca098 100644
--- a/gforge/www/tracker/detail.php
+++ b/gforge/www/tracker/detail.php
@@ -8,12 +8,15 @@
*
*/
-echo $ath->header(array ('title'=>_('Detail').': '.$ah->getID(). ' '.util_unconvert_htmlspecialchars($ah->getSummary()),'atid'=>$ath->getID()));
+$ath->header(array
+ ('title' => _('Detail').': [#'.$ah->getID(). '] '
+ . util_unconvert_htmlspecialchars($ah->getSummary()),
+ 'atid'=>$ath->getID()));
echo notepad_func();
?>
-
[#getID(); ?>] getSummary()); ?>
+
[#getID(); ?>] getSummary()); ?>
@@ -65,9 +68,11 @@ echo notepad_func();
getAssignedRealName(); ?> (getAssignedUnixName(); ?>)
- renderExtraFields($ah->getExtraFieldData(),true,'none',false,'Any','',false,'DISPLAY');
- ?>
+ renderExtraFields($ah->getExtraFieldData(),true,'none',false,'Any','',false,'DISPLAY');
+ $ath->renderRelatedTasks($group, $ah);
+ $ath->renderFiles($group_id, $ah);
+ ?>
: getSummary(); ?>
@@ -95,53 +100,13 @@ echo notepad_func();
-
+
showMessages();
?>
-usesPM()) {
-?>
-
-
-
- :
- getRelatedTasks();
- $taskcount = db_numrows($ah->relatedtasks);
- if ($taskcount > 0) {
- $titles[] = _('Task Id');
- $titles[] = _('Task Summary');
- $titles[] = _('Start Date');
- $titles[] = _('End Date');
- echo $GLOBALS['HTML']->listTableTop($titles);
- for ($i = 0; $i < $taskcount; $i++) {
- $taskinfo = db_fetch_array($ah->relatedtasks, $i);
- $taskid = $taskinfo['project_task_id'];
- $projectid = $taskinfo['group_project_id'];
- $groupid = $taskinfo['group_id'];
- $summary = util_unconvert_htmlspecialchars($taskinfo['summary']);
- $startdate = date(_('Y-m-d H:i'), $taskinfo['start_date']);
- $enddate = date(_('Y-m-d H:i'), $taskinfo['end_date']);
- echo ' boxGetAltRowStyle($i) .'>
- '.$taskid.'
- '.util_make_link ('/pm/task.php?func=detailtask&project_task_id='.$taskid.'&group_id='.$groupid.'&group_project_id='.$projectid,$summary).'
- '.$startdate.'
- '.$enddate.'
- ';
- }
- echo $GLOBALS['HTML']->listTableBottom();
- } else {
- echo _('No Related Tasks');
- }
- ?>
-
-
-
-
@@ -152,9 +117,9 @@ if ($group->usesPM()) {
-
+
- :
+ :
usesPM()) {
- :
+ :
showHistory();
diff --git a/gforge/www/tracker/include/ArtifactHtml.class.php b/gforge/www/tracker/include/ArtifactHtml.class.php
index 58ce91019d..d314653177 100644
--- a/gforge/www/tracker/include/ArtifactHtml.class.php
+++ b/gforge/www/tracker/include/ArtifactHtml.class.php
@@ -91,7 +91,7 @@ class ArtifactHtml extends Artifact {
} else {
echo '
- '._('No Followups Have Been Posted').' ';
+ '._('No Followups Have Been Posted').'
';
}
}
@@ -144,7 +144,7 @@ class ArtifactHtml extends Artifact {
} else {
echo '
- '._('No Changes Have Been Made to This Item').' ';
+ '._('No Changes Have Been Made to This Item').'
';
}
}
@@ -173,7 +173,7 @@ class ArtifactHtml extends Artifact {
- :
+ :
Group->getID();
@@ -219,7 +219,8 @@ class ArtifactTypeHtml extends ArtifactType {
$str = $this->renderRadio($efarr[$i]['extra_field_id'],$selected[$efarr[$i]['extra_field_id']],$show_100,$text_100,$show_any,$text_any);
- } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_TEXT) {
+ } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_TEXT ||
+ $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_INTEGER) {
$str = $this->renderTextField($efarr[$i]['extra_field_id'],$selected[$efarr[$i]['extra_field_id']],$efarr[$i]['attribute1'],$efarr[$i]['attribute2']);
if ($mode == 'QUERY') {
@@ -271,6 +272,59 @@ class ArtifactTypeHtml extends ArtifactType {
}
}
+ function renderRelatedTasks($group, $ah) {
+
+ if (!$group->usesPM()) {
+ return '';
+ }
+
+ $result = $ah->getRelatedTasks();
+ $taskcount = db_numrows($ah->relatedtasks);
+
+ if ($taskcount > 0) {
+ echo ' ';
+ echo ''._("Related Tasks").': '.' ';
+ echo '';
+ for ($i = 0; $i < $taskcount; $i++) {
+ $taskinfo = db_fetch_array($ah->relatedtasks, $i);
+ $taskid = $taskinfo['project_task_id'];
+ $projectid = $taskinfo['group_project_id'];
+ $groupid = $taskinfo['group_id'];
+ $summary = util_unconvert_htmlspecialchars($taskinfo['summary']);
+ $startdate = date(_('Y-m-d H:i'), $taskinfo['start_date']);
+ $enddate = date(_('Y-m-d H:i'), $taskinfo['end_date']);
+ echo '
+ [T'.$taskid.'] '.$summary.'
+ '.$startdate.'
+ '.$enddate.'
+ ';
+ }
+ echo '
';
+ echo ' ';
+ }
+ }
+
+ function renderFiles($group_id, $ah) {
+
+ $file_list =& $ah->getFiles();
+ $count=count($file_list);
+
+ if ($count > 0) {
+ echo '';
+ echo ''._("Attachments").': '.' ';
+ echo '';
+ echo ' ';
+ }
+ }
+
/**
* getRenderHTML
*
@@ -328,7 +382,8 @@ class ArtifactTypeHtml extends ArtifactType {
$return .= '
'.$name.' ';
- } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_TEXT) {
+ } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_TEXT ||
+ $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_INTEGER) {
//text fields might be really wide, so need a row to themselves.
if (($col_count == 1) && ($efarr[$i]['attribute1'] > 30)) {
diff --git a/gforge/www/tracker/ind.php b/gforge/www/tracker/ind.php
index 5f19b4f207..93e733f1a7 100644
--- a/gforge/www/tracker/ind.php
+++ b/gforge/www/tracker/ind.php
@@ -53,7 +53,7 @@ if (!$at_arr || count($at_arr) < 1) {
} else {
echo '
boxGetAltRowStyle($j) . '>
- '.
+ '.
html_image("ic/tracker20w.png","20","20",array("border"=>"0", "align"=>"middle")).' '.
$at_arr[$j]->getName() .'
diff --git a/gforge/www/tracker/index.php b/gforge/www/tracker/index.php
index 7386479630..b32e133594 100644
--- a/gforge/www/tracker/index.php
+++ b/gforge/www/tracker/index.php
@@ -36,7 +36,7 @@ require_once $gfwww.'tracker/include/ArtifactHtml.class.php';
require_once $gfcommon.'tracker/ArtifactCanned.class.php';
require_once $gfcommon.'tracker/ArtifactTypeFactory.class.php';
-if (!$sys_use_tracker) {
+if (!forge_get_config('use_tracker')) {
exit_disabled();
}
diff --git a/gforge/www/tracker/mod-limited.php b/gforge/www/tracker/mod-limited.php
index 40d052a9dd..630985d18f 100644
--- a/gforge/www/tracker/mod-limited.php
+++ b/gforge/www/tracker/mod-limited.php
@@ -9,10 +9,15 @@
*/
-$ath->header(array ('title'=>_('Modify').': '.$ah->getID(). ' - ' . $ah->getSummary(),'atid'=>$ath->getID()));
+$ath->header(array
+ ('title' => _('Modify').' [#'.$ah->getID(). '] '
+ . util_unconvert_htmlspecialchars($ah->getSummary()),
+ 'atid'=>$ath->getID()));
+
+echo notepad_func();
?>
- [#getID(); ?>] getSummary(); ?>
+ [#getID(); ?>] getSummary(); ?>
@@ -110,7 +115,10 @@ if (session_loggedin()) {
-
+ renderRelatedTasks($group, $ah);
+ $ath->renderFiles($group_id, $ah);
+ ?>
: (?)
getSummary(); ?>
@@ -130,7 +138,7 @@ if (session_loggedin()) {
: (?)
-
:
+ :
showMessages();
?>
@@ -147,7 +155,7 @@ if (session_loggedin()) {
-
:
+ :
boxGetAltRowStyle($i) .'>
- '._('Delete').'
+ '._('Delete').'
'. htmlspecialchars($file_list[$i]->getName()) .'
'. htmlspecialchars($file_list[$i]->getDescription()) .'
'.util_make_link ('/tracker/download.php/'.$group_id.'/'. $ath->getID().'/'. $ah->getID() .'/'.$file_list[$i]->getID().'/'.$file_list[$i]->getName(),_('Download')).'
@@ -193,7 +201,7 @@ if (session_loggedin()) {
- :
+ :
showHistory();
?>
diff --git a/gforge/www/tracker/mod.php b/gforge/www/tracker/mod.php
index e94beba59c..9ae9ea124f 100644
--- a/gforge/www/tracker/mod.php
+++ b/gforge/www/tracker/mod.php
@@ -8,7 +8,10 @@
*
*/
-$ath->header(array ('title'=>'[#'. $ah->getID(). '] ' . $ah->getSummary(), 'atid'=>$ath->getID()));
+$ath->header(array
+ ('title' => _('Modify').' [#'.$ah->getID(). '] '
+ . util_unconvert_htmlspecialchars($ah->getSummary()),
+ 'atid'=>$ath->getID()));
echo notepad_func();
@@ -153,7 +156,10 @@ if (session_loggedin()) {
-
+ renderRelatedTasks($group, $ah);
+ $ath->renderFiles($group_id, $ah);
+ ?>
: (?)
')">(?)
- :
+ :
showMessages();
?>
@@ -236,7 +242,7 @@ if ($group->usesPM()) {
-
:
+
:
:
@@ -289,7 +295,7 @@ if ($group->usesPM()) {
- :
+ :
showHistory();
?>
diff --git a/gforge/www/tracker/query.php b/gforge/www/tracker/query.php
index 616334ae6d..9e303cabc3 100644
--- a/gforge/www/tracker/query.php
+++ b/gforge/www/tracker/query.php
@@ -54,7 +54,10 @@ if (getStringFromRequest('submit')) {
$_summary = getStringFromRequest('_summary');
$_description = getStringFromRequest('_description');
$_followups = getStringFromRequest('_followups');
- if (!$aq->create($query_name,$_status,$_assigned_to,$_moddaterange,$_sort_col,$_sort_ord,$extra_fields,$_opendaterange,$_closedaterange,$_summary,$_description,$_followups,$query_type)) {
+ $query_options = array_keys(getArrayFromRequest('query_options'));
+ if (!$aq->create($query_name,$_status,$_assigned_to,$_moddaterange,$_sort_col,$_sort_ord,$extra_fields,$_opendaterange,$_closedaterange,
+ $_summary,$_description,$_followups,$query_type, $query_options)) {
+ form_release_key(getStringFromRequest('form_key'));
exit_error('Error',$aq->getErrorMessage());
} else {
$feedback .= 'Successfully Created';
@@ -101,7 +104,9 @@ if (getStringFromRequest('submit')) {
$_description = getStringFromRequest('_description');
$_followups = getStringFromRequest('_followups');
$extra_fields = getStringFromRequest('extra_fields');
- if (!$aq->update($query_name,$_status,$_assigned_to,$_moddaterange,$_sort_col,$_sort_ord,$extra_fields,$_opendaterange,$_closedaterange,$_summary,$_description,$_followups,$query_type)) {
+ $query_options = array_keys(getArrayFromRequest('query_options'));
+ if (!$aq->update($query_name,$_status,$_assigned_to,$_moddaterange,$_sort_col,$_sort_ord,$extra_fields,$_opendaterange,$_closedaterange,
+ $_summary,$_description,$_followups,$query_type, $query_options)) {
exit_error('Error',$aq->getErrorMessage());
} else {
$feedback .= 'Query Updated';
@@ -138,7 +143,9 @@ if (getStringFromRequest('submit')) {
$query_id=0;
header('Location: /tracker/?atid='.$atid.'&group_id='.$group_id.'&func=browse');
exit;
- }
+ } else {
+ exit_error('Error', 'Missing Build Query Action');
+ }
} else {
$user=session_get_user();
$query_id=$user->getPreference('art_query'.$ath->getID());
@@ -230,7 +237,7 @@ $res = db_query_params ('SELECT artifact_query_id,query_name FROM artifact_query
// Show the new pop-up boxes to select assigned to, status, etc
//
-$ath->header(array('atid'=>$ath->getID()));
+$ath->header(array('atid'=>$ath->getID(), 'title' =>_('Build Query')));
echo '' .
''.
@@ -238,8 +245,6 @@ echo '' .
'';
echo '
-'. $feedback .'
-
@@ -327,6 +332,22 @@ if ($ath->userIsAdmin()) {
';
$ath->renderExtraFields($extra_fields,true,'None',true,'Any','',false,'QUERY');
+ // Compute the list of fields which can be sorted.
+ // Currently, only scalar artifacts are taken.
+ $efarr = $ath->getExtraFields(ARTIFACT_EXTRAFIELDTYPE_TEXT.",".
+ ARTIFACT_EXTRAFIELDTYPE_TEXTAREA.",".
+ ARTIFACT_EXTRAFIELDTYPE_INTEGER.",".
+ ARTIFACT_EXTRAFIELDTYPE_SELECT.",".
+ ARTIFACT_EXTRAFIELDTYPE_RADIO.",".
+ ARTIFACT_EXTRAFIELDTYPE_STATUS);
+ $keys=array_keys($efarr);
+ for ($k=0; $k'._('(% for wildcards)').' ';
echo '
@@ -357,7 +378,15 @@ echo '
'.html_build_select_box_from_arrays($sort_arr,$sort_name_arr,'_sort_ord',$_sort_ord,false) .'
';
- echo '
+echo '
+ '.
+ '
Options:
+ getQueryOptions())) ? 'checked="checked"' : '')
+.'/> Display a short summary box on top of the list (roadmap status).
+
+ ';
+echo '
';
echo '
';
$ath->footer(array());
diff --git a/gforge/www/tracker/taskmgr.php b/gforge/www/tracker/taskmgr.php
index e8720b4324..0564e245fe 100644
--- a/gforge/www/tracker/taskmgr.php
+++ b/gforge/www/tracker/taskmgr.php
@@ -85,9 +85,9 @@ if (getStringFromRequest('add_to_task')) {
'._('Tracker Item').': [#'.$a->getID().'] '.$a->getSummary().'
- '._('Task Manager Project').': ';
+
'._('Tasks Project').': ';
echo $pg->getName().'
-
+
'._('Task').':
';
@@ -95,7 +95,7 @@ if (getStringFromRequest('add_to_task')) {
echo ''.$pt_arr[$i]->getSummary().' ';
}
echo '
-
+
';
//
@@ -138,7 +138,7 @@ if (getStringFromRequest('add_to_task')) {
echo ''._('Build Relationship Between Tracker Items and Task Manager').'
'._('Tracker Item').': [#'.$a->getID().'] '.$a->getSummary().'
- '._('Task Manager Project').':
+ '._('Tasks Project').':
';
for ($i=0; $i'.$pg_arr[$i]->getName().'';
diff --git a/gforge/www/tracker/tracker.php b/gforge/www/tracker/tracker.php
index 3b4a6c9475..795377c22b 100644
--- a/gforge/www/tracker/tracker.php
+++ b/gforge/www/tracker/tracker.php
@@ -253,7 +253,7 @@ switch (getStringFromRequest('func')) {
$ah=new ArtifactHtml($ath,$artifact_id);
if (!$ah || !is_object($ah)) {
- exit_error('ERROR','Artifact Could Not Be Created');
+ exit_error('ERROR', _('Artifact Could Not Be Created'));
} else if ($ah->isError()) {
exit_error('ERROR',$ah->getErrorMessage());
} else if (!$ath->allowsAnon() && !session_loggedin()) {
@@ -324,10 +324,12 @@ switch (getStringFromRequest('func')) {
$n = $i+1;
if ($error === 1 || $error === 2) {
// UPLOAD_ERR_INI_SIZE or UPLOAD_ERR_FORM_SIZE
- $ext_feedback .= " ERROR: Skipping attachement $n: file is too large.";
+ $ext_feedback .= " " .
+ sprintf(_("ERROR: Skipping attachment %d: file is too large."), $n);
} elseif ($error === 3) {
// UPLOAD_ERR_PARTIAL
- $ext_feedback .= " ERROR: Skipping attachement $n: transfert interrupted.";
+ $ext_feedback .= " " .
+ sprintf(_("ERROR: Skipping attachment %d: transfer interrupted."), $n);
}
continue;
}
diff --git a/gforge/www/trove/index.php b/gforge/www/trove/index.php
index 42fdd1d0c9..3cdf77f52e 100644
--- a/gforge/www/trove/index.php
+++ b/gforge/www/trove/index.php
@@ -18,7 +18,7 @@ require_once('TroveCategory.class.php');
require_once('TroveCategoryFactory.class.php');
require_once('include/utils.php');
-if (!$sys_use_trove) {
+if (!forge_get_config('use_trove')) {
exit_disabled();
}
diff --git a/htdocs/mirror b/htdocs/mirror
index 16dc7b7fed..69af08c946 100755
--- a/htdocs/mirror
+++ b/htdocs/mirror
@@ -1,10 +1,17 @@
#! /bin/sh
+DISTUBUBRC=jaunty,karmic,lucid
+DISTUBUTRK=jaunty,karmic,lucid
-debmirror /var/lib/gforge/chroot/home/groups/fusionforge/htdocs/debian --method=http --host=debian.fusionforge.org -r debian -d lenny,squeeze,sid -a i386,amd64 -s main -v --progress
-debmirror /var/lib/gforge/chroot/home/groups/fusionforge/htdocs/ubuntu --method=http --host=debian.fusionforge.org -r ubuntu -d hardy,intrepid,jaunty -a i386,amd64 -s main -v --progress
+DISTDEBBRC=lenny,squeeze,sid
+DISTDEBTRK=lenny,squeeze,sid
-debmirror /var/lib/gforge/chroot/home/groups/fusionforge/htdocs/debian-trk --method=http --host=debian.fusionforge.org -r debian-trk -d lenny,squeeze,sid -a i386,amd64 -s main -v --progress
-debmirror /var/lib/gforge/chroot/home/groups/fusionforge/htdocs/ubuntu-trk --method=http --host=debian.fusionforge.org -r ubuntu-trk -d hardy,intrepid,jaunty,karmic -a i386,amd64 -s main -v --progress
+MIRBASE=/var/lib/gforge/chroot/home/groups/fusionforge/htdocs
-debmirror /var/lib/gforge/chroot/home/groups/fusionforge/htdocs/debian-brc --method=http --host=debian.fusionforge.org -r debian-brc -d lenny,squeeze,sid -a i386,amd64 -s main -v --progress
-debmirror /var/lib/gforge/chroot/home/groups/fusionforge/htdocs/ubuntu-brc --method=http --host=debian.fusionforge.org -r ubuntu-brc -d hardy,intrepid,jaunty,karmic -a i386,amd64 -s main -v --progress
+debmirror $MIRBASE/debian --method=http --host=debian.fusionforge.org -r debian -d $DISTDEBTRK -a i386,amd64 -s main -v --progress
+debmirror $MIRBASE/ubuntu --method=http --host=debian.fusionforge.org -r ubuntu -d $DISTUBUTRK -a i386,amd64 -s main -v --progress
+
+debmirror $MIRBASE/debian-trk --method=http --host=debian.fusionforge.org -r debian-trk -d $DISTDEBTRK -a i386,amd64 -s main -v --progress
+debmirror $MIRBASE/ubuntu-trk --method=http --host=debian.fusionforge.org -r ubuntu-trk -d $DISTUBUTRK -a i386,amd64 -s main -v --progress
+
+debmirror $MIRBASE/debian-brc --method=http --host=debian.fusionforge.org -r debian-brc -d $DISTDEBBRC -a i386,amd64 -s main -v --progress
+debmirror $MIRBASE/ubuntu-brc --method=http --host=debian.fusionforge.org -r ubuntu-brc -d $DISTUBUBRC -a i386,amd64 -s main -v --progress
diff --git a/plugins/coclico/Makefile b/plugins/coclico/Makefile
new file mode 100644
index 0000000000..760f309994
--- /dev/null
+++ b/plugins/coclico/Makefile
@@ -0,0 +1,28 @@
+DISTDEBIAN=$(shell [ -f /etc/debian_version ] && echo debian)
+DISTREDHAT=$(shell grep -qi 'Red Hat' /etc/issue && echo rh)
+DISTSUSE=$(shell grep -qi 'SuSE' /etc/issue && echo rh)
+DIST=$(DISTDEBIAN)$(DISTREDHAT)$(DISTSUSE)
+
+PKGDIR1=mailman
+PKGDIR2=forumml
+PKGDIR=mailman
+
+MINOR=$(shell head -1 $(PKGDIR)/debian/changelog | sed 's/.*(.*-\([^-]*\)).*/\1/')
+
+PARAM=PKGDIR=$(PKGDIR) svnrev=$(MINOR)
+
+def:
+ @echo "#==============================================#"
+ @echo "Use make PKGDIR=<$(PKGDIR1)|$(PKGDIR2)> "
+ @#make -f Makefile.$(DIST) $(PARAM) default
+ @echo "target=default displays all params"
+ @echo "other available targets are: "
+ @echo "#==============================================#"
+ @cat ../../Makefile.$(DIST) | grep '^.*:.*#$$' | sed 's/FUSIONFORGE/$(FUSIONFORGE)/' | sed 's/^\(.*:\).*#\(.*\)#$$/\1 \2/'
+
+default:
+ @make -f Makefile.$(DIST) $(PARAM) default
+ @cat ../../Makefile.$(DIST) | grep '^.*:.*#$$' | sed 's/FUSIONFORGE/$(FUSIONFORGE)/' | sed 's/^\(.*:\).*#\(.*\)#$$/\1 \2/'
+
+%:
+ @make -f Makefile.$(DIST) $(PARAM) $@
diff --git a/plugins/coclico/Makefile.debian b/plugins/coclico/Makefile.debian
new file mode 100644
index 0000000000..1219f2c0e9
--- /dev/null
+++ b/plugins/coclico/Makefile.debian
@@ -0,0 +1 @@
+include ../../Makefile.debian
diff --git a/plugins/coclico/forumml/README.txt b/plugins/coclico/forumml/README.txt
new file mode 100644
index 0000000000..eada33e66d
--- /dev/null
+++ b/plugins/coclico/forumml/README.txt
@@ -0,0 +1,46 @@
+ForumML
+
+ForumML is a contraction of "Forum - Mailing List".
+The goal of the plugin is to add forum-like behaviors to mailing lists.
+
+ForumML is a plugin that adds a web interface to mailing list archives.
+It makes it easier to browse and search mailing lists.
+It also provides a way to post to a list from the web interface.
+In this case, Codendi uses your login email adress to post to the list.
+The actual acceptance/distribution/archival of the message still
+depends on mailman configuration.
+
+
+==== INSTALLATION ===
+
+bin/installFF.sh should do whatever is necessary for the plugin works
+* creation of directory with good rights
+* installation of pear packages
+* config mailman
+
+==== Importing existing list archives in Codendi ====
+
+## To import ML archives of specific projects, into ForumML DB,
+run 'mail_2_DB.php' script.
+1st argument: list name
+2nd argument: 2
+$> /usr/share/codendi/src/utils/php-launcher /usr/share/codendi/plugins/forumml/bin/mail_2_DB.php codex-support 2
+
+## To import ML archives of all Codendi projects, for which the plugin is enabled
+run 'ml_arch_2_DB.pl' script:
+$> /usr/share/codendi/plugins/forumml/bin/ml_arch_2_DB.pl
+
+
+==== Importing existing list archives in iFusionForge ====
+
+## To import ML archives of specific projects, into ForumML DB,
+run 'mail_2_DBFF.php' script.
+1st argument: list name
+2nd argument: 2
+$> /usr/bin/php -q -d include_path=.:/etc/gforge:/usr/share/gforge:/usr/share/gforge/www/include:/usr/share/gforge/plugins forumml/bin/mail_2_DBFF.php mylistname 2
+
+## To import ML archives of all projects, for which the plugin is enabled
+run 'ml_arch_2_DBFF.pl' script:
+$> forumml/bin/ml_arch_2_DBFF.pl
+
+
diff --git a/plugins/coclico/forumml/TODO b/plugins/coclico/forumml/TODO
new file mode 100644
index 0000000000..0a2a2b0e53
--- /dev/null
+++ b/plugins/coclico/forumml/TODO
@@ -0,0 +1,11 @@
+==== Current limitations ====
+- For HTML emails send in Text+HTML (aka multipart/alternative) we can display
+ the HTML version only because it's the first attachment we treat.
+
+==== For a future release ====
+- Refactor DB:
+-- Mime messages tables (esp. multipart/alternative)
+-- Store often used headers as table columns (date, ctype, subject, message_id)
+- Insert "Reply" form with Javascript to avoid page reload+move to anchor, which is a bit disturbing...
+- provide way to post to mailing list in the main List page.
+- extend search to message bodies (now only on subjects)
diff --git a/plugins/coclico/forumml/bin/db-upgrade.pl b/plugins/coclico/forumml/bin/db-upgrade.pl
new file mode 100755
index 0000000000..246cacb28c
--- /dev/null
+++ b/plugins/coclico/forumml/bin/db-upgrade.pl
@@ -0,0 +1,301 @@
+#!/usr/bin/perl -w
+#
+# Debian-specific script to upgrade the database between releases
+# Roland Mas
+
+use strict ;
+use diagnostics ;
+
+use DBI ;
+use MIME::Base64 ;
+use HTML::Entities ;
+
+use vars qw/$dbh @reqlist $query/ ;
+use vars qw/$sys_default_domain $sys_cvs_host $sys_download_host
+ $sys_shell_host $sys_users_host $sys_docs_host $sys_lists_host
+ $sys_dns1_host $sys_dns2_host $FTPINCOMING_DIR $FTPFILES_DIR
+ $sys_urlroot $sf_cache_dir $sys_name $sys_themeroot
+ $sys_news_group $sys_dbhost $sys_dbname $sys_dbuser $sys_dbpasswd
+ $sys_ldap_base_dn $sys_ldap_host $admin_login $admin_password
+ $server_admin $domain_name $newsadmin_groupid $statsadmin_groupid
+ $skill_list/ ;
+use vars qw/$pluginname/ ;
+
+sub is_lesser ( $$ ) ;
+sub is_greater ( $$ ) ;
+sub debug ( $ ) ;
+sub parse_sql_file ( $ ) ;
+
+require ("/usr/share/gforge/lib/include.pl") ; # Include a few predefined functions
+require ("/usr/share/gforge/lib/sqlparser.pm") ; # Our magic SQL parser
+
+debug "You'll see some debugging info during this installation." ;
+debug "Do not worry unless told otherwise." ;
+
+&db_connect ;
+
+# debug "Connected to the database OK." ;
+
+$pluginname = "forumml" ;
+
+$dbh->{AutoCommit} = 0;
+$dbh->{RaiseError} = 1;
+eval {
+ my ($sth, @array, $version, $path, $target) ;
+
+ &create_metadata_table ("0") ;
+
+ $version = &get_db_version ;
+ $target = "0.1" ;
+ if (is_lesser $version, $target) {
+ my @filelist = ( "/usr/share/gforge/plugins/$pluginname/db/$pluginname-init.sql" ) ;
+
+ foreach my $file (@filelist) {
+ debug "Processing $file" ;
+ @reqlist = @{ &parse_sql_file ($file) } ;
+
+ foreach my $s (@reqlist) {
+ $query = $s ;
+ # debug $query ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ $sth->finish () ;
+ }
+ }
+ @reqlist = () ;
+
+ &update_db_version ($target) ;
+ debug "Committing." ;
+ $dbh->commit () ;
+ }
+
+# $version = &get_db_version ;
+# $target = "0.2" ;
+# if (is_lesser $version, $target) {
+# debug "Adding local data." ;
+#
+# do "/etc/gforge/local.pl" or die "Cannot read /etc/gforge/local.pl" ;
+#
+# my $ip_address = qx/host $domain_name | awk '{print \}'/ ;
+#
+# @reqlist = (
+# "INSERT INTO plugin_".$pluginname."_sample_data (domain, ip_address) VALUES ('$domain_name', '$ip_address')",
+# ) ;
+#
+# foreach my $s (@reqlist) {
+# $query = $s ;
+# # debug $query ;
+# $sth = $dbh->prepare ($query) ;
+# $sth->execute () ;
+# $sth->finish () ;
+# }
+# @reqlist = () ;
+#
+# &update_db_version ($target) ;
+# debug "Committing." ;
+# $dbh->commit () ;
+# }
+
+ debug "It seems your database install/upgrade went well and smoothly. That's cool." ;
+ debug "Please enjoy using Debian FusionForge." ;
+
+ # There should be a commit at the end of every block above.
+ # If there is not, then it might be symptomatic of a problem.
+ # For safety, we roll back.
+ $dbh->rollback ();
+};
+
+if ($@) {
+ warn "Transaction aborted because $@" ;
+ debug "Transaction aborted because $@" ;
+ debug "Last SQL query was:\n$query\n(end of query)" ;
+ $dbh->rollback ;
+ debug "Please report this bug on the Debian bug-tracking system." ;
+ debug "Please include the previous messages as well to help debugging." ;
+ debug "You should not worry too much about this," ;
+ debug "your DB is still in a consistent state and should be usable." ;
+ exit 1 ;
+}
+
+$dbh->rollback ;
+$dbh->disconnect ;
+
+sub is_lesser ( $$ ) {
+ my $v1 = shift || 0 ;
+ my $v2 = shift || 0 ;
+
+ my $rc = system "dpkg --compare-versions $v1 lt $v2" ;
+
+ return (! $rc) ;
+}
+
+sub is_greater ( $$ ) {
+ my $v1 = shift || 0 ;
+ my $v2 = shift || 0 ;
+
+ my $rc = system "dpkg --compare-versions $v1 gt $v2" ;
+
+ return (! $rc) ;
+}
+
+sub debug ( $ ) {
+ my $v = shift ;
+ chomp $v ;
+ print STDERR "$v\n" ;
+}
+
+sub create_metadata_table ( $ ) {
+ my $v = shift || "0" ;
+ my $tablename = "plugin_" .$pluginname . "_meta_data" ;
+ # Do we have the metadata table?
+
+ $query = "SELECT count(*) FROM pg_class WHERE relname = '$tablename' and relkind = 'r'";
+ # debug $query ;
+ my $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ my @array = $sth->fetchrow_array () ;
+ $sth->finish () ;
+
+ # Let's create this table if we have it not
+
+ if ($array [0] == 0) {
+ debug "Creating $tablename table." ;
+ $query = "CREATE TABLE $tablename (key varchar primary key, value text not null)" ;
+ # debug $query ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ $sth->finish () ;
+ }
+
+ $query = "SELECT count(*) FROM $tablename WHERE key = 'db-version'";
+ # debug $query ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ @array = $sth->fetchrow_array () ;
+ $sth->finish () ;
+
+ # Empty table? We'll have to fill it up a bit
+
+ if ($array [0] == 0) {
+ debug "Inserting first data into $tablename table." ;
+ $query = "INSERT INTO $tablename (key, value) VALUES ('db-version', '$v')" ;
+ # debug $query ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ $sth->finish () ;
+ }
+}
+
+sub update_db_version ( $ ) {
+ my $v = shift or die "Not enough arguments" ;
+ my $tablename = "plugin_" .$pluginname . "_meta_data" ;
+
+ debug "Updating $tablename table." ;
+ $query = "UPDATE $tablename SET value = '$v' WHERE key = 'db-version'" ;
+ # debug $query ;
+ my $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ $sth->finish () ;
+}
+
+sub get_db_version () {
+ my $tablename = "plugin_" .$pluginname . "_meta_data" ;
+
+ $query = "SELECT value FROM $tablename WHERE key = 'db-version'" ;
+ # debug $query ;
+ my $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ my @array = $sth->fetchrow_array () ;
+ $sth->finish () ;
+
+ my $version = $array [0] ;
+
+ return $version ;
+}
+
+sub drop_table_if_exists ( $ ) {
+ my $tname = shift or die "Not enough arguments" ;
+ $query = "SELECT count(*) FROM pg_class WHERE relname='$tname' AND relkind='r'" ;
+ my $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ my @array = $sth->fetchrow_array () ;
+ $sth->finish () ;
+
+ if ($array [0] != 0) {
+ # debug "Dropping table $tname" ;
+ $query = "DROP TABLE $tname" ;
+ # debug $query ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ $sth->finish () ;
+ }
+}
+
+sub drop_sequence_if_exists ( $ ) {
+ my $sname = shift or die "Not enough arguments" ;
+ $query = "SELECT count(*) FROM pg_class WHERE relname='$sname' AND relkind='S'" ;
+ my $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ my @array = $sth->fetchrow_array () ;
+ $sth->finish () ;
+
+ if ($array [0] != 0) {
+ # debug "Dropping sequence $sname" ;
+ $query = "DROP SEQUENCE $sname" ;
+ # debug $query ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ $sth->finish () ;
+ }
+}
+
+sub drop_index_if_exists ( $ ) {
+ my $iname = shift or die "Not enough arguments" ;
+ $query = "SELECT count(*) FROM pg_class WHERE relname='$iname' AND relkind='i'" ;
+ my $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ my @array = $sth->fetchrow_array () ;
+ $sth->finish () ;
+
+ if ($array [0] != 0) {
+ # debug "Dropping index $iname" ;
+ $query = "DROP INDEX $iname" ;
+ # debug $query ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ $sth->finish () ;
+ }
+}
+
+sub drop_view_if_exists ( $ ) {
+ my $iname = shift or die "Not enough arguments" ;
+ $query = "SELECT count(*) FROM pg_class WHERE relname='$iname' AND relkind='v'" ;
+ my $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ my @array = $sth->fetchrow_array () ;
+ $sth->finish () ;
+
+ if ($array [0] != 0) {
+ # debug "Dropping view $iname" ;
+ $query = "DROP VIEW $iname" ;
+ # debug $query ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ $sth->finish () ;
+ }
+}
+
+sub bump_sequence_to ( $$ ) {
+ my ($sth, @array, $seqname, $targetvalue) ;
+
+ $seqname = shift ;
+ $targetvalue = shift ;
+
+ do {
+ $query = "select nextval ('$seqname')" ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ @array = $sth->fetchrow_array () ;
+ $sth->finish () ;
+ } until $array[0] >= $targetvalue ;
+}
diff --git a/plugins/coclico/forumml/bin/installFF.sh b/plugins/coclico/forumml/bin/installFF.sh
new file mode 100755
index 0000000000..0dff40f53b
--- /dev/null
+++ b/plugins/coclico/forumml/bin/installFF.sh
@@ -0,0 +1,26 @@
+#! /bin/sh
+
+echo "#"
+echo "# ForumML Plugin install"
+echo "#"
+
+## Chown ForumMl temp and data dir
+touch /var/log/gforge/forumml_hook.log
+chown root.list /var/log/gforge/forumml_hook.log
+chmod 664 /var/log/gforge/forumml_hook.log
+chown gforge.gforge /var/spool/forumml /var/lib/gforge/forumml
+chown gforge.gforge /usr/share/gforge/plugins/forumml/bin/mail_2_DBFF.pl
+chmod 06755 /usr/share/gforge/plugins/forumml/bin/mail_2_DBFF.pl
+
+## Update Mailman config to enable the Hook
+if ! grep -q ^PUBLIC_EXTERNAL_ARCHIVER /usr/lib/mailman/Mailman/mm_cfg.py
+then
+ cat <> /usr/lib/mailman/Mailman/mm_cfg.py
+# ForumML Plugin
+PUBLIC_EXTERNAL_ARCHIVER = '/usr/share/gforge/plugins/forumml/bin/mail_2_DBFF.pl %(listname)s ;'
+PRIVATE_EXTERNAL_ARCHIVER = '/usr/share/gforge/plugins/forumml/bin/mail_2_DBFF.pl %(listname)s ;'
+EOF
+fi
+
+## restart mailman
+invoke-rc.d mailman restart
diff --git a/plugins/coclico/forumml/bin/mail_2_DB.php b/plugins/coclico/forumml/bin/mail_2_DB.php
new file mode 100755
index 0000000000..0c15e147f0
--- /dev/null
+++ b/plugins/coclico/forumml/bin/mail_2_DB.php
@@ -0,0 +1,151 @@
+ 0) {
+ $id_list = db_result($res,0,'group_list_id');
+ $gr_id = db_result($res,0,'group_id');
+} else {
+ $stderr = fopen('php://stderr', 'w');
+ fwrite($stderr, "Invalid mailing-list $list \n");
+ fclose($stderr);
+ exit;
+}
+
+$plugin_manager =& PluginManager::instance();
+$p =& $plugin_manager->getPluginByName('forumml');
+if ($p && $plugin_manager->isPluginAvailable($p) ) {
+ $info =& $p->getPluginInfo();
+ if ($argv[2] == 2) {
+ // get list archive
+ $forumml_arch = $GLOBALS['forumml_arch'];
+ $mbox_file = $forumml_arch."/private/".$list.".mbox/".$list.".mbox";
+ // check if mbox file exists
+ if (! is_file($mbox_file)) {
+ $stderr = fopen('php://stderr', 'w');
+ fwrite($stderr, "Invalid mbox file $mbox_file \n");
+ fclose($stderr);
+ exit;
+ }
+
+ // Do not import from archives if there are already messages for this list
+ $sql = 'SELECT NULL FROM plugin_forumml_message WHERE id_list = '.db_ei($id_list).' LIMIT 1';
+ $res = db_query($sql);
+ if ($res && db_numrows($res) > 0) {
+ $stderr = fopen('php://stderr', 'w');
+ fwrite($stderr, "Cannot import messages from archive.\nThere are already messages in the database for $list ($mbox_file)\n");
+ fclose($stderr);
+ exit;
+ }
+ } else {
+ // get 3rd argument
+ $temp_file = $argv[3];
+ // get temp file parent dir
+ $forumml_tmp = $GLOBALS['forumml_tmp'];
+ $mbox_file = $forumml_tmp."/".$temp_file;
+print "mboxfile=".$mbox_file;
+ }
+
+ // Open the mail that has been temporary stored
+ $mbox = new Mail_Mbox($mbox_file);
+ $mbox->open();
+ if (PEAR::isError($mbox)) {
+ print "Unable to open mbox: ".$mbox->getMessage().PHP_EOL;
+ } else {
+ $nbMailInserted = 0;
+print "nb mail inserted=".$nbMailInserted;
+ $num_msg = $mbox->size();
+ for ($i = 0; $i < $num_msg; $i++) {
+ $thisMessage = $mbox->get($i);
+ if (PEAR::isError($thisMessage)) {
+ print "Unable to get message $i: ".$thisMessage->getMessage().PHP_EOL;
+ } else {
+ // Decode email
+ $args['include_bodies'] = TRUE;
+ $args['decode_bodies'] = TRUE;
+ $args['decode_headers'] = TRUE;
+ $args['crlf'] = "\r\n";
+ $decoder = new ForumML_mimeDecode($thisMessage, "\r\n");
+ $structure = $decoder->decode($args);
+
+ // Get ForumML storage
+ $forumml_dir = $GLOBALS['forumml_dir'];
+ $forumml_storage = new ForumML_FileStorage($forumml_dir);
+
+ // Store email
+ $insert = new ForumMLInsert($id_list);
+ $msgId = $insert->storeEmail($structure, $forumml_storage);
+ if ($msgId) {
+ $nbMailInserted++;
+ }
+ }
+ }
+
+ // Display message when importing a mail archive
+ if ($argv[2] == 2) {
+ if ($num_msg == $nbMailInserted) {
+ echo 'Operation Completed.'.$num_msg.' imported'.PHP_EOL;
+ } else {
+ echo '*** Error: '.$num_msg.' in '.$mbox_file.' file but '. $nbMailInserted.' stored in database'.PHP_EOL;
+ }
+ }
+ }
+}
+
+// delete temporary file
+if ($argv[2] == 1) {
+ if (is_file($mbox_file)) {
+ unlink($mbox_file);
+ }
+}
+
+?>
diff --git a/plugins/coclico/forumml/bin/mail_2_DB.pl b/plugins/coclico/forumml/bin/mail_2_DB.pl
new file mode 100755
index 0000000000..deaacb7bc8
--- /dev/null
+++ b/plugins/coclico/forumml/bin/mail_2_DB.pl
@@ -0,0 +1,105 @@
+#!/usr/bin/perl -UT
+
+# Copyright (c) STMicroelectronics, 2005. All Rights Reserved.
+#
+# Originally written by Jean-Philippe Giola, 2005
+#
+# This file is a part of codendi.
+#
+# codendi is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# codendi is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with codendi; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+# Taint mode enabled
+
+# mailing-list name should contain only alphabetical characters, '-' and '.'
+sub validate_listname {
+ my $arg = shift;
+ my $listname = "";
+ my $match = 0;
+
+ if($arg =~ /^([-.\w]+)$/) {
+ if ($match == 0) {
+ $listname = $1;
+ }
+ }
+ return $listname;
+}
+
+use strict;
+
+# Set default path (required by taint mode)
+$ENV{'PATH'} = '/usr/bin:/bin';
+
+# Hook log file
+my $logfile = "/var/log/codendi/forumml_hook.log";
+
+# Redirect outputs
+open STDOUT, ">>", $logfile or die "cannot append to '$logfile': $!\n";
+open STDERR, ">&STDOUT" or die "cannot append STDERR to STDOUT: $!\n";
+
+# Search if there are lists we shouldn't treat
+my $conf = '/etc/codendi/plugins/forumml/etc/forumml.inc';
+if (-f $conf) {
+ # Get the variable defined in forumml.inc
+ my @exc_lists;
+ open(FORUMML_INC, "<$conf");
+ while () {
+ if (m/^\$forumml_excluded_lists[ ]*=[ ]*"(.*)"[ ]*;[ ]*$/) {
+ @exc_lists = split(/[ ]*,[ ]*/, $1);
+ }
+ }
+ close(FORUMML_INC);
+
+ # Test if given list is excluded or not
+ foreach my $list (@exc_lists) {
+ if ($list eq $ARGV[0]) {
+ exit 2;
+ }
+ }
+}
+
+# First argument is mandatory (list name)
+my $listname = $ARGV[0];
+chomp($listname);
+if($listname eq "") {
+ exit 1
+}
+
+# Get mail from STDIN, store it in a temporary file, then pass it to php script
+my $range = 100;
+my $random = int(rand($range));
+my $temp = "mail_tmp_".$random."_".time();
+my $path = "/var/run/forumml/".$temp;
+open(OUT, ">>$path");
+while (defined($_ = )) {
+ print OUT $_;
+}
+close(OUT);
+
+# Get PHP_PARAMS variable from php-laucher.sh
+my $PHP_PARAMS="";
+open(PHP_LAUNCHER, ") {
+ if (m/^[ ]*PHP_PARAMS="(.*)"$/) {
+ $PHP_PARAMS=$1;
+ last;
+ }
+}
+close(PHP_LAUNCHER);
+
+# store mail in ForumML DB
+exec "/usr/bin/php $PHP_PARAMS /usr/share/codendi/plugins/forumml/bin/mail_2_DB.php $listname 1 $temp";
+
+close STDOUT;
+close STDERR;
diff --git a/plugins/coclico/forumml/bin/mail_2_DBFF.php b/plugins/coclico/forumml/bin/mail_2_DBFF.php
new file mode 100755
index 0000000000..fa08f6c690
--- /dev/null
+++ b/plugins/coclico/forumml/bin/mail_2_DBFF.php
@@ -0,0 +1,143 @@
+#! /usr/bin/php5
+ 0) {
+ $id_list = db_result($res,0,'group_list_id');
+ $gr_id = db_result($res,0,'group_id');
+} else {
+ $stderr = fopen('php://stderr', 'w');
+ fwrite($stderr, "Invalid mailing-list $list \n");
+ fclose($stderr);
+ exit;
+}
+$plugin_manager =& PluginManager::instance();
+$p =& $plugin_manager->getPluginByName('forumml');
+if ($p && $plugin_manager->isPluginAvailable($p) ) {
+ if ($argv[2] == 2) {
+ // get list archive
+ $forumml_arch = $GLOBALS['forumml_arch'];;
+ $mbox_file = $forumml_arch."/private/".$list.".mbox/".$list.".mbox";
+ // check if mbox file exists
+ if (! is_file($mbox_file)) {
+ $stderr = fopen('php://stderr', 'w');
+ fwrite($stderr, "Invalid mbox file $mbox_file \n");
+ fclose($stderr);
+ exit;
+ }
+ // Do not import from archives if there are already messages for this list
+ $sql = 'SELECT NULL FROM plugin_forumml_message WHERE id_list = $1 LIMIT 1';
+ $res = db_query_params($sql,array($id_list));
+ if ($res && db_numrows($res) > 0) {
+ $stderr = fopen('php://stderr', 'w');
+ fwrite($stderr, "Cannot import messages from archive.\nThere are already messages in the database for $list ($mbox_file)\n");
+ fclose($stderr);
+ exit;
+ }
+ } else {
+ // get 3rd argument
+ $temp_file = $argv[3];
+ // get temp file parent dir
+ $forumml_tmp = $GLOBALS['forumml_tmp'];
+ $mbox_file = $forumml_tmp."/".$temp_file;
+ }
+ // Open the mail that has been temporary stored
+ $mbox = new Mail_Mbox($mbox_file);
+ $mbox->open();
+ if (PEAR::isError($mbox)) {
+ print "Unable to open mbox: ".$mbox->getMessage().PHP_EOL;
+ } else {
+ $nbMailInserted = 0;
+ $num_msg = $mbox->size();
+ for ($i = 0; $i < $num_msg; $i++) {
+ $thisMessage = $mbox->get($i);
+ if (PEAR::isError($thisMessage)) {
+ print "Unable to get message $i: ".$thisMessage->getMessage().PHP_EOL;
+ } else {
+ // Decode email
+ $args['include_bodies'] = TRUE;
+ $args['decode_bodies'] = TRUE;
+ $args['decode_headers'] = TRUE;
+ $args['crlf'] = "\r\n";
+ $decoder = new ForumML_mimeDecode($thisMessage, "\r\n");
+ $structure = $decoder->decode($args);
+
+ // Get ForumML storage
+ $forumml_dir = $GLOBALS['forumml_dir'];
+ $forumml_storage = new ForumML_FileStorage($forumml_dir);
+
+ // Store email
+ $insert = new ForumMLInsert($id_list);
+ $msgId = $insert->storeEmail($structure, $forumml_storage);
+ if ($msgId) {
+ $nbMailInserted++;
+ }
+ }
+ }
+
+ // Display message when importing a mail archive
+ if ($argv[2] == 2) {
+ if ($num_msg == $nbMailInserted) {
+ echo 'Operation Completed.'.$num_msg.' imported'.PHP_EOL;
+ } else {
+ echo '*** Error: '.$num_msg.' in '.$mbox_file.' file but '. $nbMailInserted.' stored in database'.PHP_EOL;
+ }
+ }
+ }
+}
+
+// delete temporary file
+/*if ($argv[2] == 1) {
+ if (is_file($mbox_file)) {
+ unlink($mbox_file);
+ }
+}
+*/
+?>
diff --git a/plugins/coclico/forumml/bin/mail_2_DBFF.pl b/plugins/coclico/forumml/bin/mail_2_DBFF.pl
new file mode 100755
index 0000000000..acb133cc64
--- /dev/null
+++ b/plugins/coclico/forumml/bin/mail_2_DBFF.pl
@@ -0,0 +1,106 @@
+#!/usr/bin/perl -UT
+
+# Copyright (c) STMicroelectronics, 2005. All Rights Reserved.
+#
+# Originally written by Jean-Philippe Giola, 2005
+#
+# This file is a part of codendi.
+#
+# codendi is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# codendi is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with codendi; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+# Taint mode enabled
+
+# mailing-list name should contain only alphabetical characters, '-' and '.'
+sub validate_listname {
+ my $arg = shift;
+ my $listname = "";
+ my $match = 0;
+
+ if($arg =~ /^([-.\w]+)$/) {
+ if ($match == 0) {
+ $listname = $1;
+ }
+ }
+ return $listname;
+}
+
+use strict;
+
+# Set default path (required by taint mode)
+$ENV{'PATH'} = '/usr/bin:/bin';
+my $debug;
+open ( $debug , '>> /tmp/debugperl' );
+# Hook log file
+my $logfile = "/var/log/gforge/forumml_hook.log";
+
+# Redirect outputs
+open STDOUT, ">>", $logfile or die "cannot append to '$logfile': $!\n";
+open STDERR, ">&STDOUT" or die "cannot append STDERR to STDOUT: $!\n";
+
+# Search if there are lists we shouldn't treat
+my $conf = '/usr/share/gforge/plugins/forumml/etc/forumml.inc';
+if (-f $conf) {
+ # Get the variable defined in forumml.inc
+ my @exc_lists;
+ open(FORUMML_INC, "<$conf");
+ while () {
+ if (m/^\$forumml_excluded_lists[ ]*=[ ]*"(.*)"[ ]*;[ ]*$/) {
+ @exc_lists = split(/[ ]*,[ ]*/, $1);
+ }
+ }
+ close(FORUMML_INC);
+
+ # Test if given list is excluded or not
+ foreach my $list (@exc_lists) {
+ if ($list eq $ARGV[0]) {
+ exit 2;
+ }
+ }
+}
+
+# First argument is mandatory (list name)
+my $listname = $ARGV[0];
+chomp($listname);
+if($listname eq "") {
+ exit 1
+}
+
+# Get mail from STDIN, store it in a temporary file, then pass it to php script
+my $range = 100;
+my $random = int(rand($range));
+my $temp = "mail_tmp_".$random."_".time();
+my $path = "/var/spool/forumml/".$temp;
+open(OUT, ">>$path");
+while (defined($_ = )) {
+ print OUT $_;
+}
+close(OUT);
+
+# Get PHP_PARAMS variable from php-laucher.sh
+my $PHP_PARAMS="-q -d include_path=.:/etc/gforge:/usr/share/gforge:/usr/share/gforge/www/include:/usr/share/gforge/plugins";
+#open(PHP_LAUNCHER, ") {
+# if (m/^[ ]*PHP_PARAMS="(.*)"$/) {
+# $PHP_PARAMS=$1;
+# last;
+# }
+#}
+#close(PHP_LAUNCHER);
+
+# store mail in ForumML DB
+exec "/usr/bin/php $PHP_PARAMS /usr/share/gforge/plugins/forumml/bin/mail_2_DBFF.php $listname 1 $temp";
+
+close STDOUT;
+close STDERR;
diff --git a/plugins/coclico/forumml/bin/ml_arch_2_DB.pl b/plugins/coclico/forumml/bin/ml_arch_2_DB.pl
new file mode 100755
index 0000000000..d60e51c80d
--- /dev/null
+++ b/plugins/coclico/forumml/bin/ml_arch_2_DB.pl
@@ -0,0 +1,78 @@
+#!/usr/bin/perl
+
+#
+# Copyright (c) STMicroelectronics, 2007. All Rights Reserved.
+#
+# Originally written by Mohamed CHAARI, 2007
+#
+# This file is a part of codendi.
+#
+# codendi is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# codendi is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with codendi; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+=pod
+
+This script aims at achieving the migration of archives, of all _active_ mailing-lists, to the ForumML database.
+Only projects that enabled ForumML plugin are concerned by this migration.
+
+=cut
+
+# Search if there are lists we shouldn't treat
+print "Script launched";
+my $conf = '/etc/codendi/plugins/forumml/etc/forumml.inc';
+my %excluded_list;
+if (-f $conf) {
+ # Get the variable defined in forumml.inc
+ my @exc_lists;
+ open(FORUMML_INC, "<$conf");
+ while () {
+ if (m/^\$forumml_excluded_lists[ ]*=[ ]*"(.*)"[ ]*;[ ]*$/) {
+ @exc_lists = split(/[ ]*,[ ]*/, $1);
+ }
+ }
+ close(FORUMML_INC);
+
+ # Test if given list is excluded or not
+ foreach my $list (@exc_lists) {
+ $excluded_list{$list} = 0;
+ }
+}
+
+# Get PHP_PARAMS variable from php-laucher.sh
+my $PHP_PARAMS="";
+open(PHP_LAUNCHER, ") {
+ if (m/^[ ]*PHP_PARAMS="(.*)"$/) {
+ $PHP_PARAMS=$1
+ }
+}
+close(PHP_LAUNCHER);
+
+#use strict;
+use DBI;
+
+require "/usr/share/codendi/src/utils/include.pl";
+&db_connect;
+print "Connect to DB";
+# get all active mailing-lists
+my $query = "SELECT list_name, group_id FROM mail_group_list WHERE status = 3";
+my $req = $dbh->prepare($query);
+$req->execute();
+while (my ($list_name,$group_id) = $req->fetchrow()) {
+ if(! exists $excluded_list{$list_name}) {
+ print "Processing ".$list_name." mailing-list ... \n";
+ system("/usr/bin/php $PHP_PARAMS /usr/share/codendi/plugins/forumml/bin/mail_2_DB.php $list_name 2");
+ }
+}
diff --git a/plugins/coclico/forumml/bin/ml_arch_2_DBFF.pl b/plugins/coclico/forumml/bin/ml_arch_2_DBFF.pl
new file mode 100755
index 0000000000..6df75eeb3b
--- /dev/null
+++ b/plugins/coclico/forumml/bin/ml_arch_2_DBFF.pl
@@ -0,0 +1,71 @@
+#!/usr/bin/perl
+
+#
+# Copyright (c) STMicroelectronics, 2007. All Rights Reserved.
+#
+# Originally written by Mohamed CHAARI, 2007
+#
+# This file is a part of codendi.
+#
+# codendi is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# codendi is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with codendi; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+=pod
+
+This script aims at achieving the migration of archives, of all _active_ mailing-lists, to the ForumML database.
+Only projects that enabled ForumML plugin are concerned by this migration.
+
+=cut
+
+# Search if there are lists we shouldn't treat
+my $conf = '/usr/share/gforge/plugins/forumml/etc/forumml.inc';
+my %excluded_list;
+if (-f $conf) {
+ # Get the variable defined in forumml.inc
+ my @exc_lists;
+ open(FORUMML_INC, "<$conf");
+ while () {
+ if (m/^\$forumml_excluded_lists[ ]*=[ ]*"(.*)"[ ]*;[ ]*$/) {
+ @exc_lists = split(/[ ]*,[ ]*/, $1);
+ }
+ }
+ close(FORUMML_INC);
+
+ # Test if given list is excluded or not
+ foreach my $list (@exc_lists) {
+ $excluded_list{$list} = 0;
+ }
+}
+
+# Get PHP_PARAMS variable from php-laucher.sh
+my $PHP_PARAMS="-q -d include_path=.:/etc/gforge:/usr/share/gforge:/usr/share/gforge/www/include:/usr/share/gforge/plugins";
+
+#use strict;
+use DBI;
+
+require "/etc/gforge/local.pl";
+my $dbh = DBI->connect("DBI:Pg:host=localhost ;dbname=$sys_dbname ; user= $sys_dbuser ; password=$sys_dbpasswd") or die "Couldn't connect to database: " . DBI->errstr;
+
+
+# get all active mailing-lists
+my $query = "SELECT list_name, group_id FROM mail_group_list WHERE status = 3";
+my $req = $dbh->prepare($query);
+$req->execute();
+while (my ($list_name,$group_id) = $req->fetchrow()) {
+ if(! exists $excluded_list{$list_name}) {
+ print "Processing ".$list_name." mailing-list ...\n ";
+ system("/usr/bin/php $PHP_PARAMS /usr/share/gforge/plugins/forumml/bin/mail_2_DBFF.php $list_name 2");
+ }
+}
diff --git a/gforge/plugins/helloworld/common/helloworld-init.php b/plugins/coclico/forumml/common/forumml-init.php
similarity index 77%
rename from gforge/plugins/helloworld/common/helloworld-init.php
rename to plugins/coclico/forumml/common/forumml-init.php
index 4e6a85e537..6c8ff1cfcf 100644
--- a/gforge/plugins/helloworld/common/helloworld-init.php
+++ b/plugins/coclico/forumml/common/forumml-init.php
@@ -17,14 +17,16 @@
* You should have received a copy of the GNU General Public License
* along with GForge; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Portions Copyright 2010 (c) Mélanie Le Bail
*/
global $gfplugins;
-require_once $gfplugins.'helloworld/common/HelloWorldPlugin.class.php' ;
+require_once $gfplugins.'forumml/include/forummlPlugin.class.php' ;
+define('SEARCH__TYPE_IS_LIST', 'forumml');
+$forummlPluginObject = new forummlPlugin() ;
-$HelloWorldPluginObject = new HelloWorldPlugin ;
-
-register_plugin ($HelloWorldPluginObject) ;
+register_plugin ($forummlPluginObject) ;
// Local Variables:
// mode: php
diff --git a/plugins/coclico/forumml/db/forumml-init.sql b/plugins/coclico/forumml/db/forumml-init.sql
new file mode 100644
index 0000000000..90b9ae5f2b
--- /dev/null
+++ b/plugins/coclico/forumml/db/forumml-init.sql
@@ -0,0 +1,104 @@
+-- alter table plugin_forumml_message add column last_thread_update int unsigned not null default 0 after body;
+CREATE SEQUENCE plugin_forumml_pk_seq
+ START WITH 1
+ INCREMENT BY 1
+ MAXVALUE 2147483647
+ NO MINVALUE
+ CACHE 1;
+
+CREATE TABLE plugin_forumml_attachment (
+ id_attachment INTEGER DEFAULT nextval('plugin_forumml_pk_seq'::text) NOT NULL,
+ id_message INTEGER NOT NULL,
+ file_name TEXT NOT NULL,
+ file_type character varying(80) NOT NULL,
+ file_size INTEGER NOT NULL,
+ file_path character varying(255) NOT NULL,
+ content_id character varying(255) not null default '',
+ PRIMARY KEY(id_attachment)
+);
+
+
+
+CREATE SEQUENCE plugin_forumml_header_pk_seq
+ START WITH 1
+ INCREMENT BY 1
+ MAXVALUE 2147483647
+ NO MINVALUE
+ CACHE 1;
+
+CREATE TABLE plugin_forumml_header (
+ id_header INTEGER DEFAULT nextval('plugin_forumml_header_pk_seq'::text) NOT NULL,
+ name character varying(255) NOT NULL,
+ PRIMARY KEY(id_header)
+);
+
+CREATE SEQUENCE plugin_forumml_message_pk_seq
+ START WITH 1
+ INCREMENT BY 1
+ MAXVALUE 2147483647
+ NO MINVALUE
+ CACHE 1;
+
+CREATE TABLE plugin_forumml_message (
+ id_message INTEGER DEFAULT nextval('plugin_forumml_message_pk_seq'::text) NOT NULL,
+ id_list INTEGER NOT NULL,
+ id_parent INTEGER NOT NULL,
+ body TEXT NULL,
+ last_thread_update INTEGER NOT NULL DEFAULT 0,
+ msg_type character varying(30) not null default '',
+ cached_html text default null,
+ PRIMARY KEY(id_message)
+);
+
+CREATE TABLE plugin_forumml_messageheader (
+ id_message INTEGER NOT NULL,
+ id_header INTEGER NOT NULL,
+ value TEXT NOT NULL,
+ PRIMARY KEY(id_message, id_header)
+);
+
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('1','message-id');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('2','date');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('3','from');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('4','subject');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('5','return-path');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('6','delivered-to');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('7','to');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('8','in-reply-to');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('9','references');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('10','x-mailer');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('11','mime-version');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('12','content-type');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('13','content-transfer-encoding');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('14','sender');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('15','errors-to');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('16','x-beenthere');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('17','x-mailman-version');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('18','precedence');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('19','list-help');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('20','list-post');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('21','list-subscribe');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('22','list-id');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('23','list-unsubscribe');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('24','list-archive');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('25','x-original-to');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('26','x-priority');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('27','x-msmail-priority');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('28','importance');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('29','x-mimeole');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('30','reply-to');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('31','x-list-received-date');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('32','user-agent');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('33','x-mailman-approved-at');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('34','cc');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('35','x-mozilla-status');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('36','x-mozilla-status2');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('37','thread-index');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('38','x-accept-language');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('39','keywords');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('40','organization');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('41','x-reply-to');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('42','x-enigmail-version');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('43','x-enigmail-supports');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('44','x-ms-tnef-correlator');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('45','x-pgp-universal');
diff --git a/plugins/coclico/forumml/db/install.sql b/plugins/coclico/forumml/db/install.sql
new file mode 100644
index 0000000000..de6f259bf6
--- /dev/null
+++ b/plugins/coclico/forumml/db/install.sql
@@ -0,0 +1,85 @@
+-- alter table plugin_forumml_message add column last_thread_update int unsigned not null default 0 after body;
+CREATE TABLE plugin_forumml_attachment (
+ id_attachment INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
+ id_message INTEGER UNSIGNED NOT NULL,
+ file_name TEXT NOT NULL,
+ file_type VARCHAR(80) NOT NULL,
+ file_size INTEGER UNSIGNED NOT NULL,
+ file_path VARCHAR(255) NOT NULL,
+ content_id varchar(255) not null default '',
+ PRIMARY KEY(id_attachment),
+ KEY idx_fk_id_message (id_message, content_id(10))
+);
+
+CREATE TABLE plugin_forumml_header (
+ id_header INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
+ name VARCHAR(255) NOT NULL,
+ PRIMARY KEY(id_header),
+ KEY idx_name (name (20))
+);
+
+CREATE TABLE plugin_forumml_message (
+ id_message INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
+ id_list INTEGER UNSIGNED NOT NULL,
+ id_parent INTEGER UNSIGNED NOT NULL,
+ body TEXT NULL,
+ last_thread_update INTEGER UNSIGNED NOT NULL DEFAULT 0,
+ msg_type varchar(30) not null default '',
+ cached_html mediumtext default null,
+ PRIMARY KEY(id_message),
+ KEY idx_fk_id_list (id_list),
+ KEY idx_fk_id_parent (id_parent)
+);
+
+CREATE TABLE plugin_forumml_messageheader (
+ id_message INTEGER UNSIGNED NOT NULL,
+ id_header INTEGER UNSIGNED NOT NULL,
+ value TEXT NOT NULL,
+ PRIMARY KEY(id_message, id_header)
+);
+
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('1','message-id');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('2','date');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('3','from');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('4','subject');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('5','return-path');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('6','delivered-to');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('7','to');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('8','in-reply-to');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('9','references');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('10','x-mailer');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('11','mime-version');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('12','content-type');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('13','content-transfer-encoding');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('14','sender');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('15','errors-to');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('16','x-beenthere');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('17','x-mailman-version');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('18','precedence');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('19','list-help');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('20','list-post');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('21','list-subscribe');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('22','list-id');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('23','list-unsubscribe');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('24','list-archive');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('25','x-original-to');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('26','x-priority');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('27','x-msmail-priority');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('28','importance');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('29','x-mimeole');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('30','reply-to');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('31','x-list-received-date');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('32','user-agent');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('33','x-mailman-approved-at');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('34','cc');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('35','x-mozilla-status');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('36','x-mozilla-status2');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('37','thread-index');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('38','x-accept-language');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('39','keywords');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('40','organization');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('41','x-reply-to');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('42','x-enigmail-version');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('43','x-enigmail-supports');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('44','x-ms-tnef-correlator');
+INSERT INTO plugin_forumml_header (id_header, name) VALUES ('45','x-pgp-universal');
diff --git a/plugins/coclico/forumml/debian/README.Debian b/plugins/coclico/forumml/debian/README.Debian
new file mode 100644
index 0000000000..21c3a671a2
--- /dev/null
+++ b/plugins/coclico/forumml/debian/README.Debian
@@ -0,0 +1,6 @@
+fusionforge-plugin-forumml for Debian
+---------------------
+
+See README.Debian in fusionforge-common package
+
+ -- Christian Bayle Mon, 08 Mar 2010 16:37:51 +0100
diff --git a/plugins/coclico/forumml/debian/README.source b/plugins/coclico/forumml/debian/README.source
new file mode 100644
index 0000000000..c05e006444
--- /dev/null
+++ b/plugins/coclico/forumml/debian/README.source
@@ -0,0 +1,9 @@
+forumml for Debian
+---------------------
+
+
+
+
+
+
diff --git a/plugins/coclico/forumml/debian/changelog b/plugins/coclico/forumml/debian/changelog
new file mode 100644
index 0000000000..f1dca2366c
--- /dev/null
+++ b/plugins/coclico/forumml/debian/changelog
@@ -0,0 +1,11 @@
+fusionforge-plugin-forumml (1.1-1) karmic; urgency=low
+
+ * Bump new version
+
+ -- Mélanie Le Bail Fri, 16 Apr 2010 17:14:10 +0200
+
+fusionforge-plugin-forumml (1.0-1) unstable; urgency=low
+
+ * Initial release (Closes: #nnnn)
+
+ -- Christian Bayle Mon, 08 Mar 2010 16:37:51 +0100
diff --git a/plugins/coclico/forumml/debian/compat b/plugins/coclico/forumml/debian/compat
new file mode 100644
index 0000000000..7f8f011eb7
--- /dev/null
+++ b/plugins/coclico/forumml/debian/compat
@@ -0,0 +1 @@
+7
diff --git a/plugins/coclico/forumml/debian/control b/plugins/coclico/forumml/debian/control
new file mode 100644
index 0000000000..50412f1c59
--- /dev/null
+++ b/plugins/coclico/forumml/debian/control
@@ -0,0 +1,20 @@
+Source: fusionforge-plugin-forumml
+Section: devel
+Priority: optional
+Maintainer: Christian Bayle
+Uploaders: Roland Mas
+Build-Depends-Indep: devscripts
+Build-Depends: debhelper (>= 7), perl, gettext
+Standards-Version: 3.8.4
+Homepage: http://fusionforge.org/
+Vcs-Bzr: http://scm.fusionforge.org/bzr/fusionforge/svn-trunk-ro/
+
+Package: fusionforge-plugin-forumml
+Architecture: all
+Depends: gforge-common, gforge-db-postgresql | gforge-db, gforge-web-apache2 | gforge-web, php5-cli, php-mail, php-mail-mime, php-mail-mbox, php-mail-mimedecode, ${misc:Depends}
+Description: collaborative development tool - ForumML plugin
+ .
+ This plugin contains the ForumML subsystem of FusionForge. It allows each
+ FusionForge project to have its own ForumML, and gives some
+ control over it to the project's administrator.
+
diff --git a/plugins/coclico/forumml/debian/copyright b/plugins/coclico/forumml/debian/copyright
new file mode 100644
index 0000000000..33ab88a1c0
--- /dev/null
+++ b/plugins/coclico/forumml/debian/copyright
@@ -0,0 +1,63 @@
+The "sourceforge" package was first debianised on Wed, 22 Nov 2000
+22:06:35 +0100 by Roland Mas . Work has been
+constant since then, and the package evolved a great deal. It began
+to work, for a start, and then it evolved into GForge, what with the
+more recent versions of the Sourceforge software having been made
+proprietary. And then in early 2009 it evolved into FusionForge, what
+with the more recent versions of GForge having been rewritten as
+proprietary software without a name change.
+
+FusionForge is Copyright © 2009-2010 by several people, including:
+Alain Peyrat
+Alexandre Neymann
+Christian Bayle
+Roland Mas
+Gonéri Le Bouder
+Julien Heyman
+Olivier Meunier
+
+GForge itself is Copyright © 2000-2008 by a fair number of people,
+including:
+Tim Perdue
+Roland Mas <99.roland.mas@aist.enst.fr>
+Christian Bayle
+Tom Copeland
+Guillaume Smet
+Francisco Gimeno
+Sung Kim
+Alain Peyrat
+
+Past Members of the development team include:
+Reinhard Spisser
+Ryan T. Sammartino
+Edward Ritter
+Michael Jennings
+
+Since FusionForge, and GForge before it, was initially a fork of
+Sourceforge, here's the copyright info for the Sourceforge software:
+,----
+| The original sources were downloaded from http://www.sourceforge.net/
+|
+| Authors: The Sourceforge crew at VA Linux. They are many, they
+| change as time goes by, and they are listed on the Sourceforge
+| website. Let them be thanked for their work.
+|
+| Copyright:
+|
+| This software is Copyright © 1999-2000 by VA Linux.
+|
+| You are free to distribute this software under the terms of the GNU
+| General Public License.
+`----
+
+The packaging and installing scripts (in the debian/ and deb-specific/
+directories amongst others) are Copyright © 2000-2010 by Christian
+Bayle and Roland Mas . You
+are free to use and redistribute them under the terms of the GNU
+General Public License, version 2 or (at your option) any later
+version published by the Free Software Foundation.
+
+See Also Copyright file in fusionforge package
+
+On Debian systems, the complete text of the GNU General Public License
+can be found in the /usr/share/common-licenses directory.
diff --git a/plugins/coclico/forumml/debian/docs b/plugins/coclico/forumml/debian/docs
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/plugins/coclico/forumml/debian/dsf-in/plugin-forumml.postinst b/plugins/coclico/forumml/debian/dsf-in/plugin-forumml.postinst
new file mode 100644
index 0000000000..17d64f3dae
--- /dev/null
+++ b/plugins/coclico/forumml/debian/dsf-in/plugin-forumml.postinst
@@ -0,0 +1,55 @@
+#! /bin/sh
+# postinst script for @OLDPACKAGE@-plugin-forumml
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * `configure'
+# * `abort-upgrade'
+# * `abort-remove' `in-favour'
+#
+# * `abort-deconfigure' `in-favour'
+# `removing'
+#
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+#
+# quoting from the policy:
+# Any necessary prompting should almost always be confined to the
+# post-installation script, and should be protected with a conditional
+# so that unnecessary prompting doesn't happen if a package's
+# installation fails and the `postinst' is called with `abort-upgrade',
+# `abort-remove' or `abort-deconfigure'.
+
+case "$1" in
+ configure)
+ @OLDPACKAGE@-config
+
+ # Prepare database
+ su -s /bin/sh @OLDPACKAGE@ -c '/usr/share/@OLDPACKAGE@/bin/register-plugin forumml "ForumML"'
+ /usr/share/gforge/plugins/forumml/bin/installFF.sh
+ su -s /bin/sh @OLDPACKAGE@ -c '/usr/share/@OLDPACKAGE@/plugins/forumml/bin/db-upgrade.pl'
+ /usr/share/@OLDPACKAGE@/plugins/forumml/bin/ml_arch_2_DBFF.pl
+
+ ;;
+
+ abort-upgrade|abort-remove|abort-deconfigure)
+
+ ;;
+
+ *)
+ echo "postinst called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
+
+
diff --git a/plugins/coclico/forumml/debian/dsf-in/plugin-forumml.prerm b/plugins/coclico/forumml/debian/dsf-in/plugin-forumml.prerm
new file mode 100644
index 0000000000..8ca8633398
--- /dev/null
+++ b/plugins/coclico/forumml/debian/dsf-in/plugin-forumml.prerm
@@ -0,0 +1,45 @@
+#! /bin/sh
+# prerm script for @OLDPACKAGE@-plugin-forumml
+#
+# see: dh_installdeb(1)
+set -e
+
+#DEBHELPER#
+
+# summary of how this script can be called:
+# * `remove'
+# * `upgrade'
+# * `failed-upgrade'
+# * `remove' `in-favour'
+# * `deconfigure' `in-favour'
+# `removing'
+#
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+ remove|deconfigure)
+ if [ -f /var/run/postgresql/.s.PGSQL.5432 ]
+ then
+ /usr/share/@OLDPACKAGE@/bin/unregister-plugin forumml
+ else
+ echo "WARNING: database not available to unregister ForumML plugin"
+ fi
+ ;;
+ upgrade|failed-upgrade)
+ ;;
+ *)
+ echo "prerm called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+
+
+exit 0
+
+
diff --git a/plugins/coclico/forumml/debian/po/templates.pot b/plugins/coclico/forumml/debian/po/templates.pot
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/plugins/coclico/forumml/debian/rules b/plugins/coclico/forumml/debian/rules
new file mode 100755
index 0000000000..00deab1409
--- /dev/null
+++ b/plugins/coclico/forumml/debian/rules
@@ -0,0 +1,90 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+SRCPACKAGE=$(shell head -1 $(CURDIR)/debian/changelog | sed 's/\(.[^ ]*\) .*/\1/')
+MAJOR=$(shell head -1 $(CURDIR)/debian/changelog | sed 's/.*(\(.*\)-[^-]*).*/\1/')
+ORIGFILE=$(SRCPACKAGE)_$(MAJOR).orig.tar.gz
+OLDPACKAGE=gforge
+PACKAGE=fusionforge
+FORGENAME=FusionForge
+
+SED_REPLACE=sed -e 's/@PACKAGE@/$(PACKAGE)/g' -e 's/@SRCPACKAGE@/$(SRCPACKAGE)/g' -e 's/@FORGENAME@/$(FORGENAME)/g' -e 's/@OLDPACKAGE@/$(OLDPACKAGE)/g'
+
+CRONDFILES=$(patsubst packaging/cron.d/%,debian/$(PACKAGE)-%.cron.d,$(wildcard packaging/cron.d/[a-z]*))
+DIRSFILES=$(patsubst packaging/dirs/%,debian/$(PACKAGE)-%.dirs,$(wildcard packaging/dirs/[a-z]*))
+LINKSFILES=$(patsubst packaging/links/%,debian/$(PACKAGE)-%.links,$(wildcard packaging/links/[a-z]*))
+INSTALLFILES=$(patsubst packaging/install/%,debian/$(PACKAGE)-%.install,$(wildcard packaging/install/[a-z]*))
+DOCSFILES=$(patsubst packaging/docs/%,debian/$(PACKAGE)-%.docs,$(wildcard packaging/docs/[a-z]*))
+POFILES=$(patsubst debian/dsf-po/%,debian/po/%,$(wildcard debian/dsf-po/*) debian/po/POTFILES.in)
+DSFINFILES=$(patsubst debian/dsf-in/%,debian/$(PACKAGE)-%,$(wildcard debian/dsf-in/[a-z]*))
+
+.PHONY: conffiles
+conffiles: $(CRONDFILES) $(DIRSFILES) $(LINKSFILES) $(INSTALLFILES) $(DOCSFILES) $(DSFINFILES) debian/control
+
+debian/$(PACKAGE)-%.cron.d:
+ (cat $(CURDIR)/packaging/cron.d/00phpcron ; sed -e 's/\$$FFUSER/$(PACKAGE)/g' $(CURDIR)/packaging/cron.d/$*) > $@
+
+debian/$(PACKAGE)-%.dirs:
+ cp $(CURDIR)/packaging/dirs/$* $@
+
+debian/$(PACKAGE)-%.links:
+ cp $(CURDIR)/packaging/links/$* $@
+
+debian/$(PACKAGE)-%.install:
+ cp $(CURDIR)/packaging/install/$* $@
+
+debian/$(PACKAGE)-%.docs:
+ cp $(CURDIR)/packaging/docs/$* $@
+
+debian/control: $(wildcard packaging/control/*)
+ ls $(CURDIR)/packaging/control/[0-9][0-9][0-9]* | grep -v shortdesc | grep -v scmcpold | while read file ; do cat $${file}; if [ -f $${file}.shortdesc ] ; then cat $(CURDIR)/packaging/control/AAAdesc; echo ' .'; cat $${file}.shortdesc; fi; echo ''; done | $(SED_REPLACE) > $@
+
+debian/po/templates.pot: $(wildcard debian/dsf-in/*.templates.dsfh-in) $(wildcard debian/dsf-helper/*.templates)
+ @debconf-updatepo --podir=debian/dsf-po
+
+debian/po/%:
+ cat $(patsubst debian/po/%,debian/dsf-po/%,$@) | $(SED_REPLACE) > $@
+
+# postinst and prerm files
+debian/$(PACKAGE)-%:
+ cat $(patsubst debian/$(PACKAGE)-%,debian/dsf-in/%,$@) | $(SED_REPLACE) > $@
+
+build: debian/po/templates.pot conffiles
+ dh $@
+ # Build gettext *.mo files
+ utils/manage-translations.sh build
+
+clean:
+ dh $@
+ rm -f $(CURDIR)/debian/*.cron.d
+ rm -f $(CURDIR)/debian/*.dirs
+ rm -f $(CURDIR)/debian/*.links
+ rm -f $(CURDIR)/debian/*.install
+ rm -f $(CURDIR)/debian/*.docs
+ rm -f $(CURDIR)/debian/*.postinst
+ rm -f $(CURDIR)/debian/*.prerm
+ rm -rf locales
+ rm -f $(POFILES)
+
+makeorig:
+ find $(PKGDIR) -type f -or -type l | grep -v '/CVS/' | \
+ grep -v '/.svn/' | grep -v '/.testbox/' | \
+ grep -v rpm-specific | grep -v docs/phpdoc/docs | \
+ grep -v ^./debian/ | grep -v \\.jar$$ | \
+ grep -v \\.pdf$$ | grep -v plugins/fckeditor/www/_samples | \
+ cpio -o -H ustar | gzip > ../$(ORIGFILE)
+
+#binary:
+ #dh $@
+ #ls $(CURDIR)/debian/$(SRCPACKAGE)/
+ #chmod 06755 $(CURDIR)/debian/$(SRCPACKAGE)/usr/share/gforge
+
+%:
+ dh $@
diff --git a/plugins/coclico/forumml/debian/source/format b/plugins/coclico/forumml/debian/source/format
new file mode 100644
index 0000000000..d3827e75a5
--- /dev/null
+++ b/plugins/coclico/forumml/debian/source/format
@@ -0,0 +1 @@
+1.0
diff --git a/plugins/coclico/forumml/etc/forumml.inc.dist b/plugins/coclico/forumml/etc/forumml.inc.dist
new file mode 100644
index 0000000000..b748bd79d0
--- /dev/null
+++ b/plugins/coclico/forumml/etc/forumml.inc.dist
@@ -0,0 +1,15 @@
+
diff --git a/plugins/coclico/forumml/include/ForumMLGroupSearchEngine.class.php b/plugins/coclico/forumml/include/ForumMLGroupSearchEngine.class.php
new file mode 100644
index 0000000000..562b80841a
--- /dev/null
+++ b/plugins/coclico/forumml/include/ForumMLGroupSearchEngine.class.php
@@ -0,0 +1,30 @@
+GroupSearchEngine(SEARCH__TYPE_IS_LIST,
+ 'ForumMLHtmlSearchRenderer',
+ _('ForumML'));
+ }
+
+ function isAvailable($parameters) {
+ if (parent::isAvailable($parameters)) {
+ if ($this->Group->usesPlugin('forumml')) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
+?>
diff --git a/plugins/coclico/forumml/include/ForumMLHtmlSearchRenderer.class.php b/plugins/coclico/forumml/include/ForumMLHtmlSearchRenderer.class.php
new file mode 100644
index 0000000000..b540e943de
--- /dev/null
+++ b/plugins/coclico/forumml/include/ForumMLHtmlSearchRenderer.class.php
@@ -0,0 +1,123 @@
+groupId = $groupId;
+
+ $searchQuery = new ForumMLSearchQuery($words, $offset, $isExact, $groupId);
+
+ //init the searchrendererr
+ $this->HtmlGroupSearchRenderer(SEARCH__TYPE_IS_LIST, $words, $isExact,
+ $searchQuery, $groupId, 'list');
+
+ // $this->tableHeaders = array(_('Thread'),_('Submitted on'), _('Author'));
+
+
+
+ }
+
+ /**
+ * getRows - get the html output for result rows
+ *
+ * @return string html output
+ */
+ function getRows() {
+ $plugin_manager =& PluginManager::instance();
+ $p =& $plugin_manager->getPluginByName('forumml');
+ $rowsCount = $this->searchQuery->getRowsCount();
+ $result =& $this->searchQuery->getResult();
+ $dateFormat = _('Y-m-d H:i');
+
+ $group = group_get_object($this->groupId);
+ $group_name = $group->getUnixName();
+
+ $data = unserialize(db_result($result, 0, 'versiondata'));
+
+ $return = "
+
+ ".
+ _('Thread')."
+
+ ".
+ _('Submitted on')."
+
+ ".
+ _('Author')."
+
+ ";
+ $idx=0;
+ while ($rows = db_fetch_array($result)) {
+ $idx++;
+ if ($idx % 2 == 0) {
+ $class="boxitemalt bgcolor-white";
+ } else {
+ $class="boxitem bgcolor-grey";
+ }
+ $subject=$rows['subject'];
+
+ $res2 = $this->getForumMLDao()->getHeaderValue($rows['id_message'],array(2,3));
+ $k = 1;
+ while ($rows2 =$res2->getRow()) {
+ $header[$k] = $rows2['value'];
+ $k++;
+ }
+ $from = mb_decode_mimeheader($header[1]);
+
+ // Replace '<' by '<' and '>' by '>'. Otherwise the email adress won't be displayed
+ // because it will be considered as an xhtml tag.
+ $from = preg_replace('/\', '<', $from);
+ $from = preg_replace('/\>/', '>', $from);
+ $date = date("Y-m-d H:i",strtotime($header[2]));
+ // purify message subject (CODENDI_PURIFIER_FORUMML level)
+ $hp =& ForumML_HTMLPurifier::instance();
+ $subject = $hp->purify($subject,CODENDI_PURIFIER_FORUMML);
+
+ // display the resulting threads in rows
+ $return .= "
+
+
+ ".$subject."
+
+
+ ".$date."
+
+
+ ".$from."
+
+ ";
+ }
+ $return .='
';
+ return $return;
+ }
+
+ function getForumMLDao() {
+ return new ForumML_MessageDao(CodendiDataAccess::instance());
+ }
+}
+
+?>
diff --git a/plugins/coclico/forumml/include/ForumMLInsert.class.php b/plugins/coclico/forumml/include/ForumMLInsert.class.php
new file mode 100644
index 0000000000..4e4add3ec0
--- /dev/null
+++ b/plugins/coclico/forumml/include/ForumMLInsert.class.php
@@ -0,0 +1,332 @@
+id_list = $list_id;
+ $this->dao = new ForumML_MessageDao(CodendiDataAccess::instance());
+ }
+
+ // Insert values into forumml_messageheader table
+ function insertMessageHeader($id_header,$value) {
+ $this->dao->insertMessageHeader($this->id_message,$id_header,$value);
+ }
+
+ // Insert values into forumml_attachment table
+ function insertAttachment($id_message, $filename,$filetype,$filepath,$content_id="") {
+ if (is_file($filepath)) {
+ $filesize = filesize($filepath);
+ } else {
+ $filesize = 0;
+ }
+ $this->dao->insertAttachment($id_message, $filename, $filetype, $filesize, $filepath,$content_id);
+ }
+
+ // Insert values into forumml_header table
+ function insertHeader($header) {
+
+ // Search if the header is already in the table
+ $result = $this->dao->searchHeader($header);
+ // If not, insert it
+ if ($result->rowCount()<1) {
+ return $this->dao->insertHeader($header);
+ } else {
+ $row=$result->getRow();
+ return $row['id_header'];
+ }
+ }
+
+ function getParentMessageFromHeader($messageIdHeader) {
+ $result = $this->dao->getParentMessageFromHeader($messageIdHeader) ;
+ if ($result && $result->rowCount() >= 1 ) {
+ $row = $result->getRow();
+ return $row['id_message'];
+ }
+ return false;
+
+ }
+
+ function updateParentDate($messageId, $date) {
+ if ($messageId != 0) {
+ $dar = $this->dao->getParents($messageId);
+ if ($dar) {
+ $row = $dar->getRow();
+ if ($date > $row['last_thread_update']) {
+ $this->dao->updateParentDate($messageId, $date);
+
+ $this->updateParentDate($row['id_parent'], $date);
+ }
+ }
+ }
+ }
+
+ // Insert values into forumml_message table
+ function insertMessage($structure,$body,$ctype="") {
+
+ $this->mail = $structure;
+
+ if (isset($structure["in-reply-to"])) {
+ // special case: 'in-reply-to' header may contain "Message from ... "
+ if (preg_match('/^Message from.*$/',$structure["in-reply-to"])) {
+ $arr = explode(" ",$structure["in-reply-to"]);
+ $reply_to = $arr[count($structure["in-reply-to"]) - 1];
+ } else {
+ $reply_to = $structure["in-reply-to"];
+ }
+ } else {
+ if (isset($structure["references"])) {
+ // special case: 'in-reply-to' header is not set, but 'references' - which contain list of parent messages ids - is set
+ $ref_arr = explode(" ",$structure["references"]);
+ $reply_to = $ref_arr[count($structure["references"]) - 1];
+ } else {
+ $reply_to = "";
+ }
+ }
+
+ // Message date
+ // Cannot rely on server's date because it might be different
+ // and it doesn't work when it comes to load mail archives!
+ $messageDate = strtotime($structure['date']);
+
+ $id_parent = 0;
+ // If the current message is an answer
+ if ($reply_to != "") {
+ $id_parent = $this->getParentMessageFromHeader($reply_to);
+ }
+
+ if ($id_parent != 0) {
+ $this->updateParentDate($id_parent, $messageDate);
+ }
+$this->id_message = $this->dao->insertMessage($this->id_list, $id_parent , $body , $messageDate , $ctype);
+
+ // All headers of the current mail are stored in the forumml_messageheader table
+ $k=0;
+ foreach ($structure as $header => $value_header) {
+ $k++;
+ if ($k != 1) {
+ if ($header != "received") {
+ $id_header = $this->insertHeader($header);
+ if (is_array($value_header)) {
+ $value_header = implode(",",$value_header);
+ }
+ $this->insertMessageHeader($id_header,$value_header);
+ }
+ }
+ }
+
+ return $this->id_message;
+ }
+
+ /**
+ * Encode string in UTF8 if source charset given or if detected
+ */
+ function getUtf8String($string,$charset=null) {
+ if ($charset == null) {
+ $charset = mb_detect_encoding($string);
+ }
+ if ($charset) {
+ return mb_convert_encoding($string, 'UTF-8', $charset);
+ } else {
+ return $string;
+ }
+ }
+
+ /**
+ * Convert structure body to utf8 if charset defined in structure headers
+ */
+ function getUtf8Body($structure) {
+ $charset = null;
+ if (isset($structure->headers["content-type"]) && isset($structure->ctype_parameters['charset'])) {
+ $charset = $structure->ctype_parameters['charset'];
+ }
+ if (isset($structure->body)) {
+ return $this->getUtf8String($structure->body, $charset);
+ } else {
+ return '';
+ }
+ }
+
+ /**
+ * Extract from given structure the content and store it as an attachment of the given message
+ *
+ * @param Integer $messageId Message id
+ * @param Object $struct Subpart of a Mime message to treat
+ * @param Object $mailHeaders Headers of the message (not the subpart)
+ * @param ForumML_FileStorage $storage Object that manage the file storage on FS
+ */
+ function storePart($messageId, $struct, $mailHeaders, $storage) {
+ if (isset($struct->body) && trim($struct->body) != "") {
+ $body = $struct->body;
+ $filetype = $struct->headers["content-type"];
+ if ($struct->ctype_primary == 'text' && $struct->ctype_secondary == 'html') {
+ $filename = "message_".substr($mailHeaders["message-id"], 1, strpos($mailHeaders["message-id"], '@') - 1).".html";
+ } else {
+ if (! isset($struct->d_parameters["filename"])) {
+ // special case where a content is attached, without filename
+ $pos = strpos($filetype,"name=");
+ if ($pos === false) {
+ // set filename to 'attachment_'
+ $filename = "attachment";
+ } else {
+ // get filename from 'name' section
+ $filename = substr(substr($filetype,$pos),6,-1);
+ }
+ } else {
+ $filename = $struct->d_parameters["filename"];
+ }
+ }
+ $basename = basename($filename);
+
+ // For multipart/related emails
+ $content_id = '';
+ if (isset($struct->headers['content-id'])) {
+ $content_id = $struct->headers['content-id'];
+ }
+
+ // store attachment in /var/lib/codendi/forumml//
+ $date = date("Y_m_d",strtotime($mailHeaders["date"]));
+ $fpath = $storage->store($basename, $struct->body, $this->id_list, $date);
+
+ // insert attachment in the DB
+ $this->insertAttachment($messageId, $basename, $filetype, $fpath, $content_id);
+ }
+ }
+
+ /**
+ * Parse recursively Mime message to create the message and it's attachments in DB
+ *
+ * A MIME message is a hierarchical organization that maybe very
+ * simple for a text message (just one structure with headers and
+ * a text body) to a very complex HTML mail with inline images,
+ * attachments sent in Text+HTML.
+ *
+ * The main challenge of this method is to find the "root" of the
+ * MIME message to store it as a message in the DB, all the other
+ * stuff will be attached to this message as an attachment.
+ *
+ * The root message can be either:
+ * - The text version of the message. This applies for
+ * -> mail in plain text (with or without attachments)
+ * -> mail in HTML sent in Text+HTML
+ * - If no text version available:
+ * -> if their is an HTML version of the mail, we store it
+ * (happens with mail sent in HTML only).
+ * -> if their is no HTML, we store an empty body.
+ *
+ * How do we detect the root message:
+ * -> We crawl the hierarchy and we take the first text/plain or
+ * text/html part.
+ * -> Otherwise, if we are about to store an attachment (an
+ * attachment is everything but first text/plain or first
+ * text/html) we create a empty message.
+ *
+ * @see http://en.wikipedia.org/wiki/MIME
+ *
+ * @param Object $struct Subpart of a Mime message to treat
+ * @param Object $mailHeaders Headers of the message (not the subpart)
+ * @param ForumML_FileStorage $storage Object that manage the file storage on FS
+ * @param Integer $messageId Message id
+ */
+ function storeMime($struct, $mailHeaders, $storage, $messageId=0) {
+ if ($struct->ctype_primary == 'multipart') {
+ foreach ($struct->parts as $part) {
+ $messageId = $this->storeMime($part, $mailHeaders, $storage, $messageId);
+ }
+ } else {
+ $inserted = false;
+ if ($struct->ctype_primary == 'text') {
+ switch ($struct->ctype_secondary) {
+ case 'html':
+ case 'plain':
+ if ($messageId == null) {
+ $body = $this->getUtf8Body($struct);
+ if (isset($struct->headers["content-type"])) {
+ $ctype = $struct->headers["content-type"];
+ } else {
+ $ctype = "";
+ }
+ $messageId = $this->insertMessage($mailHeaders, $body, $ctype);
+ $inserted = true;
+ }
+ break;
+ }
+ }
+
+ if ($messageId == 0) {
+ if (isset($struct->headers["content-type"])) {
+ $ctype = $struct->headers["content-type"];
+ } else {
+ $ctype = "";
+ }
+ $messageId = $this->insertMessage($mailHeaders, "", $ctype);
+ }
+
+ if (!$inserted) {
+ $this->storePart($messageId, $struct, $mailHeaders, $storage);
+ }
+ }
+ return $messageId;
+ }
+
+ /**
+ * Abandon all hope you who enter here! Mail & MIME is at best a nightmare, take a couple of
+ * bottles before diving into this code...
+ * http://en.wikipedia.org/wiki/MIME
+ *
+ * List (not comprehensive) of email possibilities
+ * Text text/plain
+ * -> pure_text.mbox
+ * Text + attached files multipat/mixed (text/plain, other/mime)
+ * -> text_plus_attachment.mbox
+ * HTML (sent in Text + HTML) multipart/alternative (text/plain, text/html)
+ * -> pure_html_text_plus_html.mbox
+ * HTML (sent in HTML) text/html
+ * -> pure_html_in_html_only.mbox
+ * HTML + inline image (sent in Text + HTML) multipart/alternative(text/plain, multipart/related(text/html, image/png))
+ * -> html_with_inline_content_in_text_plus_html.mbox
+ * HTML + inline image (sent in HTML) multipart/related(text/html, image/png)
+ * -> html_with_inline_content_in_html_only.mbox
+ * HTML + attached file (sent in Text + HTML) multipart/mixed(multipart/alternative(text/plain, text/html), other/mime))
+ * HTML + attached file (sent in HTML) multipart/mixed(text/html, other/mime)
+ * HTML + inline image + attached file (sent in Text + HTML) multipart/mixed(multipart/alternative(text/plain, multipart/related(text/html, image/png)), other/mime)
+ * -> html_with_inline_content_and_attch_in_text_plus_html.mbox
+ * HTML + inline image + attached file (sent in HTML) multipart/mixed(multipart/related(text/html, image/png), other/mime)
+ * -> html_with_inline_content_and_attch_in_html_only.mbox
+ */
+ public function storeEmail($email, $storage) {
+ return $this->storeMime($email, $email->headers, $storage);
+ }
+}
+
+?>
diff --git a/plugins/coclico/forumml/include/ForumMLPluginDescriptor.class.php b/plugins/coclico/forumml/include/ForumMLPluginDescriptor.class.php
new file mode 100644
index 0000000000..f0d2fd9a12
--- /dev/null
+++ b/plugins/coclico/forumml/include/ForumMLPluginDescriptor.class.php
@@ -0,0 +1,29 @@
+.
+ */
+
+require_once('common/plugin/PluginDescriptor.class.php');
+
+class ForumMLPluginDescriptor extends PluginDescriptor {
+
+ function __construct() {
+ parent::__construct('ForumML', 'v2.0', $GLOBALS['Language']->getText('plugin_forumml', 'descriptor_description'));
+ }
+}
+?>
diff --git a/plugins/coclico/forumml/include/ForumMLPluginInfo.class.php b/plugins/coclico/forumml/include/ForumMLPluginInfo.class.php
new file mode 100644
index 0000000000..a7a55e1f9d
--- /dev/null
+++ b/plugins/coclico/forumml/include/ForumMLPluginInfo.class.php
@@ -0,0 +1,135 @@
+.
+ */
+
+require_once('common/plugin/PluginInfo.class.php');
+require_once('ForumMLPluginDescriptor.class.php');
+require_once('common/include/PropertyDescriptor.class.php');
+
+class ForumMLPluginInfo extends PluginInfo {
+
+ function __construct($plugin) {
+ parent::__construct($plugin);
+ $this->setPluginDescriptor(new ForumMLPluginDescriptor());
+ $this->_conf_path = $plugin->getPluginEtcRoot() .'/forumml.inc';
+ $this->loadProperties();
+
+ }
+
+ function loadProperties() {
+ if (is_file($this->_conf_path)) {
+ $this->checkConfigurationFiles($this->_conf_path);
+ $variables = $this->_getVariablesFromConfigurationFile($this->_conf_path);
+ foreach($variables as $variable) {
+ $key =& $variable['name'];
+ if (preg_match('`^"(.*)"$`', $variable['value'], $match) ||
+ preg_match('`^\'(.*)\'$`', $variable['value'], $match))
+ {
+ $value = $match[1];
+ }
+ else
+ {
+ $value = $variable['value'];
+ }
+ $descriptor =& new PropertyDescriptor($key, $value);
+ $this->_addPropertyDescriptor($descriptor);
+ }
+ }
+ }
+
+ function saveProperties() {
+ copy($this->_conf_path, $this->_conf_path .'.'. date('YmdHis'));
+ $content = file_get_contents($this->_conf_path);
+ $descs =& $this->getPropertyDescriptors();
+ $keys =& $descs->getKeys();
+ $iter =& $keys->iterator();
+ while($iter->valid()) {
+ $key =& $iter->current();
+ $desc =& $descs->get($key);
+ $desc_name =& $desc->getName();
+ if (is_bool($desc->getValue())) {
+ $replace = '$1'. ($desc->getValue() ? 'true' : 'false') .';';
+ } else {
+ $replace = '$1"'.addslashes($desc->getValue()).'";';
+ }
+ $content = preg_replace(
+ '`((?:^|\n)\$'. preg_quote($desc_name) .'\s*=\s*)(.*)\s*;`',
+ $replace,
+ $content
+ );
+ $iter->next();
+ }
+ $f = fopen($this->_conf_path, 'w');
+ if ($f) {
+ fwrite($f, $content);
+ fclose($f);
+ }
+ }
+
+ function getPropertyValueForName($name) {
+ $desc = $this->getPropertyDescriptorForName($name);
+ return $desc ? $desc->getValue() : $desc;
+ }
+
+ function _getVariablesFromConfigurationFile($file) {
+ $tokens = token_get_all(file_get_contents($file));
+
+ $variables = array();
+ $current = 0;
+ foreach($tokens as $token) {
+ switch ($token[0]) {
+ case T_VARIABLE:
+ $variables[$current] = array('name' => substr($token[1], 1), 'value' => '');
+ break;
+ case T_STRING:
+ case T_CONSTANT_ENCAPSED_STRING:
+ case T_DNUMBER:
+ case T_LNUMBER:
+ case T_NUM_STRING:
+ if (T_STRING == $token[0] && (!strcasecmp($token[1], "false") || !strcasecmp($token[1], "true"))) {
+ $val = (bool)strcasecmp($token[1], "false");
+ if (isset($variables[$current])) {
+ $variables[$current]['value'] = $val;
+ }
+ } else {
+ if (isset($variables[$current])) {
+ $variables[$current]['value'] .= $token[1];
+ }
+ }
+ break;
+ case '*':
+ if (isset($variables[$current])) {
+ $variables[$current]['value'] .= $token[0];
+ }
+ break;
+ case ';':
+ $current++;
+ break;
+ default:
+ break;
+ }
+ }
+ return $variables;
+ }
+
+ function checkConfigurationFiles() {
+ require($this->_conf_path);
+ }
+}
+?>
diff --git a/plugins/coclico/forumml/include/ForumMLSearchEngine.class.php b/plugins/coclico/forumml/include/ForumMLSearchEngine.class.php
new file mode 100644
index 0000000000..a4e37d0f95
--- /dev/null
+++ b/plugins/coclico/forumml/include/ForumMLSearchEngine.class.php
@@ -0,0 +1,43 @@
+groupId = $groupId;
+ $this->rendererClassName = $rendererClassName;
+
+ $this->GroupSearchEngine($type, $rendererClassName, $label);
+ }
+
+ function isAvailable($parameters) {
+ return true;
+ }
+
+ function & getSearchRenderer($words, $offset, $exact) {
+ require_once($this->rendererClassName.'.class.php');
+ $renderer = new $this->rendererClassName($words, $offset, $exact,
+ $this->groupId);
+ return $renderer;
+ }
+}
+
+?>
diff --git a/plugins/coclico/forumml/include/ForumMLSearchQuery.class.php b/plugins/coclico/forumml/include/ForumMLSearchQuery.class.php
new file mode 100644
index 0000000000..5442aa41a7
--- /dev/null
+++ b/plugins/coclico/forumml/include/ForumMLSearchQuery.class.php
@@ -0,0 +1,59 @@
+groupId = $groupId;
+
+ $this->SearchQuery($words, $offset, $isExact);
+ }
+
+ /**
+ * getQuery - get the query built to get the search results
+ *
+ * @return array query+params array
+ */
+ function getQuery() {
+
+ $pat = '_g'.$this->groupId.'_';
+ $len = strlen($pat)+1;
+ $qpa = db_construct_qpa () ;
+ $qpa = db_construct_qpa ($qpa,
+ 'SELECT mh.id_message, mh.value as subject, m.id_list '.
+ ' FROM plugin_forumml_message m, plugin_forumml_messageheader mh'.
+ ' WHERE mh.id_header = $1'.
+ ' AND m.id_parent = 0'.
+ ' AND m.id_message = mh.id_message AND ',
+ array (4)) ;
+ $qpa=$this->addIlikeCondition($qpa, 'mh.value');
+ return $qpa ;
+ }
+}
+
+?>
diff --git a/plugins/coclico/forumml/include/ForumML_Attachment.class.php b/plugins/coclico/forumml/include/ForumML_Attachment.class.php
new file mode 100644
index 0000000000..cbb36fa5b2
--- /dev/null
+++ b/plugins/coclico/forumml/include/ForumML_Attachment.class.php
@@ -0,0 +1,95 @@
+.
+ */
+
+require_once 'ForumML_AttachmentDao.class.php';
+
+class ForumML_Attachment {
+ private $_dao;
+
+ function getById($id) {
+ $attach = null;
+ $dar = $this->getDao()->getById($id);
+ if ($dar && !$dar->isError()) {
+ $attch = $dar->current();
+ $attch['type'] = $this->getType($attch);
+ }
+ return $attch;
+ }
+
+ /**
+ * Return attachment mime type
+ *
+ * Try to get it from the db and if it fails, try with filename
+ */
+ function getType($row) {
+ /*if (preg_match('/^[ ]*(.*\/.*)[ ]*;?.*$/', $row['file_type'], $matches)) {
+ $type = $matches[1];
+ } else {
+ // Retrieve the uploaded file type
+ switch(strtoupper(strrchr($row['file_name'], "."))) {
+ case ".GZ":
+ $type = "application/x-gzip";
+ break;
+ case ".TGZ":
+ $type = "application/x-gzip";
+ break;
+ case ".ZIP":
+ $type = "application/zip";
+ break;
+ case ".PDF":
+ $type = "application/pdf";
+ break;
+ case ".PNG":
+ $type = "image/png";
+ break;
+ case ".GIF":
+ $type = "image/gif";
+ break;
+ case ".JPG":
+ $type = "image/jpeg";
+ break;
+ case ".TXT":
+ $type = "text/plain";
+ break;
+ case ".HTM":
+ $type = "text/html";
+ break;
+ case ".HTML":
+ $type = "text/html";
+ break;
+ default:
+ $type = "application/octet-stream";
+ break;
+ }
+ }
+ return $type;*/
+ return mime_content_type($row['file_path']);
+ }
+
+ function getDao() {
+ if (!isset($this->_dao)) {
+ $this->_dao = new ForumML_AttachmentDao(CodendiDataAccess::instance());
+ }
+ return $this->_dao;
+ }
+
+}
+
+?>
diff --git a/plugins/coclico/forumml/include/ForumML_AttachmentDao.class.php b/plugins/coclico/forumml/include/ForumML_AttachmentDao.class.php
new file mode 100644
index 0000000000..0fdb8284c6
--- /dev/null
+++ b/plugins/coclico/forumml/include/ForumML_AttachmentDao.class.php
@@ -0,0 +1,36 @@
+.
+ */
+
+require_once 'common/dao/include/DataAccessObject.class.php';
+
+class ForumML_AttachmentDao extends DataAccessObject {
+
+ function __construct($da) {
+ parent::__construct($da);
+ }
+
+ function getById($id) {
+ $sql = 'SELECT * FROM plugin_forumml_attachment WHERE id_attachment = $1';
+ return $this->retrieve($sql,array($id));
+ }
+
+}
+
+?>
diff --git a/plugins/coclico/forumml/include/ForumML_FileStorage.class.php b/plugins/coclico/forumml/include/ForumML_FileStorage.class.php
new file mode 100644
index 0000000000..a885b4115b
--- /dev/null
+++ b/plugins/coclico/forumml/include/ForumML_FileStorage.class.php
@@ -0,0 +1,144 @@
+root = $root;
+ }
+
+ /**
+ * Store - stores attached files in the ForumML root dir
+ *
+ * @param filename: name of attached file
+ * @param content: content of attached file
+ * @param list: mailing-list name
+ * @param date: date of attachment in YYYY_MM_DD format
+ * @param encod: encoding of attachment
+ *
+ * @return int size of attached file
+ */
+ function store($filename, $content, $list, $date, $encod="") {
+ $path = $this->_getPath($filename, $list, $date, "store");
+ $ret = file_put_contents($path, $content);
+ if ($ret !== false) {
+ return $path;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Store:
+ * +---------------------------------------------------------------------------------+
+ * | +-----------------------------------------+ |
+ * | | | |
+ * _|__ _______ _|__ | |
+ * name list_id date v v
+ * Attach.doc 7 2007_10_19 => foruuml_dir//2007_10_19/Attach_doc
+ * | ^
+ * +---------------------------------------------+|
+ *
+ *
+ * Upload (to temporary location):
+ * +-----------------------------------------------------------------------+
+ * | |
+ * | |
+ * _|__ |
+ * name v
+ * Attach.doc => foruuml_dir/upload/Attach_doc
+ *
+ */
+
+ /**
+ * _getPath - Get the absolute path where to Upload/Store attached file
+ *
+ * @param name: basename of attached file
+ * @param list: mailing-list name
+ * @param date: attachment date (YYYY_MM_DD)
+ * @param string type: upload/store
+ *
+ * @return string path
+ */
+ function _getPath($name, $list, $date, $type) {
+ $name = trim($name);
+
+ if (trim($name) == '') {
+ $name = 'attachment';
+ } else {
+ $name = mb_convert_encoding($name, 'ascii', 'utf-8');
+ // restrict file name to 64 characters (maximum)
+ if (strlen($name) > 64) {
+ $name = substr($name, 0, 64);
+ }
+
+ $name = preg_replace('`[^a-z0-9_-]`i', '_', $name);
+ $name = preg_replace('`_{2,}`', '_', $name);
+ }
+
+ if ($type == "upload") {
+ $path_elements = array($this->root, $type);
+ } else if ($type == "store") {
+ $path_elements = array($this->root, $list, $date);
+ }
+
+ $path = '';
+ foreach($path_elements as $elem) {
+ $path .= $elem .'/';
+ if (!is_dir($path)) {
+ mkdir($path, 0755);
+ }
+ }
+
+ // Ensure that same file doesn't exists yet
+ $ext = '';
+ $i = 1;
+ while($this->fileExists($path.$name.$ext)) {
+ $ext = '_'.$i;
+ $i++;
+ }
+
+ return $path.$name.$ext;
+ }
+
+ function fileExists($path) {
+ return is_file($path);
+ }
+
+}
+
+?>
diff --git a/plugins/coclico/forumml/include/ForumML_HTMLPurifier.class.php b/plugins/coclico/forumml/include/ForumML_HTMLPurifier.class.php
new file mode 100644
index 0000000000..95a16f51b0
--- /dev/null
+++ b/plugins/coclico/forumml/include/ForumML_HTMLPurifier.class.php
@@ -0,0 +1,103 @@
+ and CSS styles
+ */
+ function getForumMLConfig() {
+
+ $config = $this->getCodendiConfig();
+ // allow html tag, used to display ForumML messages replies
+ $config->set('HTML.AllowedElements', 'blockquote');
+ // support CSS
+ $config->set('CSS.DefinitionRev', 1);
+ return $config;
+ }
+
+ /**
+ * HTML Purifier configuration factory
+ */
+ function getHPConfig($level) {
+ $config = null;
+ switch($level) {
+ case CODENDI_PURIFIER_FORUMML:
+ $config = $this->getForumMLConfig();
+ break;
+
+ default:
+ $config = parent::getHPConfig($level);
+ }
+ return $config;
+ }
+
+ /**
+ * Perform HTML purification depending of level purification required and create links.
+ */
+ function purify($html, $level=0, $groupId=0) {
+ $clean = '';
+ switch($level) {
+ case CODENDI_PURIFIER_FORUMML:
+ require_once($GLOBALS['htmlpurifier_dir'].'HTMLPurifier.auto.php');
+ $hp = HTMLPurifier::getInstance();
+ $config = $this->getHPConfig($level);
+ $clean = util_make_links($hp->purify($html, $config), $groupId);
+ break;
+ default:
+ $clean = parent::purify($html,$level,$groupId);
+ }
+ return $clean;
+ }
+}
+
+?>
diff --git a/plugins/coclico/forumml/include/ForumML_MessageDao.class.php b/plugins/coclico/forumml/include/ForumML_MessageDao.class.php
new file mode 100644
index 0000000000..08f4543cc2
--- /dev/null
+++ b/plugins/coclico/forumml/include/ForumML_MessageDao.class.php
@@ -0,0 +1,259 @@
+.
+ */
+
+require_once 'common/dao/include/DataAccessObject.class.php';
+
+define('FORUMML_MESSAGE_ID', 1);
+define('FORUMML_DATE', 2);
+define('FORUMML_FROM', 3);
+define('FORUMML_SUBJECT', 4);
+define('FORUMML_CONTENT_TYPE', 12);
+define('FORUMML_CC', 34);
+class ForumML_MessageDao extends DataAccessObject {
+
+ function __construct($da) {
+ parent::__construct($da);
+ }
+
+ function searchHeaderValue($messageId, $headerId) {
+ $messageId = $this->da->quoteSmart($messageId);
+ $headerId = $this->da->quoteSmart($headerId);
+ $sql = 'SELECT mh.value'.
+ ' FROM plugin_forumml_message m'.
+ ' JOIN plugin_forumml_messageheader mh'.
+ ' ON (mh.id_message = m.id_message)'.
+ ' JOIN plugin_forumml_header h'.
+ ' ON (h.id_header = mh.id_header)'.
+ ' WHERE m.id_message = $1'.
+ ' AND h.id_header = $2';
+ return $this->retrieve($sql,array($messageId,$headerId));
+ }
+
+ function getMessageHeaders($id_message) {
+ $id_message = $this->da->quoteSmart($id_message);
+ $sql = 'SELECT value'.
+ ' FROM plugin_forumml_messageheader'.
+ ' WHERE id_message = $1'.
+ ' AND id_header < 5'.
+ ' ORDER BY id_header';
+ return $this->retrieve($sql,array($id_message));
+ }
+
+ function getSpecificMessage($id_message,$list_id) {
+ $id_message = $this->da->quoteSmart($id_message);
+ $list_id = $this->da->quoteSmart($list_id);
+ $sql ='SELECT value, body'.
+ ' FROM plugin_forumml_message m, plugin_forumml_messageheader mh'.
+ ' WHERE m.id_message =$1 '.
+ ' AND mh.id_message = m.id_message'.
+ ' AND m.id_list = $2'.
+ ' AND mh.id_header = $3';
+ return $this->retrieve($sql,array($id_message,$list_id,FORUMML_SUBJECT));
+ }
+
+ function getHeaderValue($id, $ids) {
+ $id = $this->da->quoteSmart($id);
+ $ids = $this->da->quoteSmart($ids);
+ if (!isset($ids)) {
+ $ids = 'SELECT id_header FROM plugin_forumml_messageheader';
+ }
+ $sql = 'SELECT value , id_header FROM plugin_forumml_messageheader'.
+ ' WHERE id_message =$1 and id_header IN ($2,$3) ORDER BY id_header DESC';
+ return $this->retrieve($sql,array($id,$ids[0],$ids[1]));
+ }
+
+ function getAllThreadsFromList($list_id,$offset,$chunks) {
+ $list_id = $this->da->quoteSmart($list_id);
+ $offset = $this->da->quoteSmart($offset);
+ $chunks = $this->da->quoteSmart($chunks);
+ $sql = 'SELECT m.id_message, m.last_thread_update as lastup, mh_d.value as date, mh_f.value as sender, mh_s.value as subject'.
+ ' FROM plugin_forumml_message m'.
+ ' LEFT JOIN plugin_forumml_messageheader mh_d ON (mh_d.id_message = m.id_message AND mh_d.id_header = $1)'.
+ ' LEFT JOIN plugin_forumml_messageheader mh_f ON (mh_f.id_message = m.id_message AND mh_f.id_header = $2) '.
+ ' LEFT JOIN plugin_forumml_messageheader mh_s ON (mh_s.id_message = m.id_message AND mh_s.id_header = $3) '.
+ ' WHERE m.id_parent = 0'.
+ ' AND id_list = $4 '.
+ ' ORDER BY m.last_thread_update DESC'.
+ ' LIMIT $6'.
+ ' OFFSET $5';
+ return $this->retrieve($sql,array(FORUMML_DATE,FORUMML_FROM,FORUMML_SUBJECT,$list_id,$offset,$chunks));
+ }
+
+ function countAllThreadsFromList($list_id) {
+ $list_id = $this->da->quoteSmart($list_id);
+ $sql = 'SELECT COUNT(*) as nb'.
+ ' FROM plugin_forumml_message m'.
+ ' LEFT JOIN plugin_forumml_messageheader mh_d ON (mh_d.id_message = m.id_message AND mh_d.id_header = $1)'.
+ ' LEFT JOIN plugin_forumml_messageheader mh_f ON (mh_f.id_message = m.id_message AND mh_f.id_header = $2) '.
+ ' LEFT JOIN plugin_forumml_messageheader mh_s ON (mh_s.id_message = m.id_message AND mh_s.id_header = $3) '.
+ ' WHERE m.id_parent = 0'.
+ ' AND id_list = $4 GROUP BY m.last_thread_update'.
+ ' ORDER BY m.last_thread_update DESC';
+ return $this->retrieve($sql,array(FORUMML_DATE,FORUMML_FROM,FORUMML_SUBJECT,$list_id));
+ }
+
+ function countChildrenFromParents ($parents) {
+ $sql = 'SELECT id_message'.
+ ' FROM plugin_forumml_message m'.
+ ' WHERE m.id_parent IN ($1)';
+ return $this->retrieve($sql,array($parents));
+ }
+
+ function getChildrenFromDepthLevel($parents) {
+ $sql = 'SELECT m.*, mh_d.value as date, mh_f.value as sender, mh_s.value as subject, mh_ct.value as content_type, mh_cc.value as cc, a.id_attachment, a.file_name, a.file_type, a.file_size, a.file_path, a.content_id'.
+ ' FROM plugin_forumml_message m'.
+ ' LEFT JOIN plugin_forumml_messageheader mh_d ON (mh_d.id_message = m.id_message AND mh_d.id_header = $1)'.
+ ' LEFT JOIN plugin_forumml_messageheader mh_f ON (mh_f.id_message = m.id_message AND mh_f.id_header = $2) '.
+ ' LEFT JOIN plugin_forumml_messageheader mh_s ON (mh_s.id_message = m.id_message AND mh_s.id_header = $3) '.
+ ' LEFT JOIN plugin_forumml_messageheader mh_ct ON (mh_ct.id_message = m.id_message AND mh_ct.id_header = $4) '.
+ ' LEFT JOIN plugin_forumml_messageheader mh_cc ON (mh_cc.id_message = m.id_message AND mh_cc.id_header = $5) '.
+ " LEFT JOIN plugin_forumml_attachment a ON (a.id_message = m.id_message AND a.content_id = '')".
+ ' WHERE m.id_parent IN ($6)';
+
+ return $this->retrieve($sql,array(FORUMML_DATE,FORUMML_FROM,FORUMML_SUBJECT,FORUMML_CONTENT_TYPE,FORUMML_CC,$parents));
+ }
+
+ function getFlattenedThread($topic) {
+ $topic = $this->da->quoteSmart($topic);
+ $sql = 'SELECT m.*, mh_d.value as date, mh_f.value as sender, mh_s.value as subject, mh_ct.value as content_type, mh_cc.value as cc, a.id_attachment, a.file_name, a.file_type, a.file_size, a.file_path, a.content_id'.
+ ' FROM plugin_forumml_message m'.
+ ' LEFT JOIN plugin_forumml_messageheader mh_d ON (mh_d.id_message = m.id_message AND mh_d.id_header = $1)'.
+ ' LEFT JOIN plugin_forumml_messageheader mh_f ON (mh_f.id_message = m.id_message AND mh_f.id_header = $2)'.
+ ' LEFT JOIN plugin_forumml_messageheader mh_s ON (mh_s.id_message = m.id_message AND mh_s.id_header = $3)'.
+ ' LEFT JOIN plugin_forumml_messageheader mh_ct ON (mh_ct.id_message = m.id_message AND mh_ct.id_header = $4)'.
+ ' LEFT JOIN plugin_forumml_messageheader mh_cc ON (mh_cc.id_message = m.id_message AND mh_cc.id_header = $5)'.
+ " LEFT JOIN plugin_forumml_attachment a ON (a.id_message = m.id_message AND a.content_id = '')".
+ ' WHERE m.id_message =$6 ';
+ return $this->retrieve($sql,array(FORUMML_DATE,FORUMML_FROM,FORUMML_SUBJECT,FORUMML_CONTENT_TYPE,FORUMML_CC,$topic));
+ }
+
+ function updateCacheHTML($cache,$id) {
+ $cache = $this->da->quoteSmart($cache);
+ $id = $this->da->quoteSmart($id);
+ return $this->update('UPDATE plugin_forumml_message SET cached_html= $1 WHERE id_message= $2',array($cache,$id));
+ }
+
+ function getAttachment($id_message,$match) {
+ $id_message = $this->da->quoteSmart($id_message);
+ $match = $this->da->quoteSmart($match);
+ $sql = 'SELECT id_attachment FROM plugin_forumml_attachment WHERE id_message=$1 and content_id=<$2>';
+ return $this->retrieve($sql,array($id_message , $match));
+ }
+ function searchArchives($list_id,$pattern) {
+ $list_id = $this->da->quoteSmart($list_id);
+ $pattern = $this->da->quoteSmart($pattern);
+ $sql = 'SELECT mh.id_message, mh.value'.
+ ' FROM plugin_forumml_message m, plugin_forumml_messageheader mh'.
+ ' WHERE mh.id_header = $1'.
+ ' AND m.id_list = $2'.
+ ' AND m.id_parent = 0'.
+ ' AND m.id_message = mh.id_message'.
+ ' AND mh.value LIKE $3';
+ return $this->retrieve($sql,array(FORUMML_SUBJECT,$list_id,$pattern));
+
+ }
+
+ function hasArchives($list_id) {
+ $list_id = $this->da->quoteSmart($list_id);
+ $qry = 'SELECT NULL FROM plugin_forumml_message WHERE id_list = $1 LIMIT 1';
+ return $this->retrieve($qry,array($list_id));
+ }
+
+ function insertMessageHeader($id_message, $id_header,$value) {
+ $id_message = $this->da->quoteSmart($id_message);
+ $id_header = $this->da->quoteSmart($id_header);
+ $value = $this->da->quoteSmart($value);
+ $qry = 'INSERT INTO plugin_forumml_messageheader'.
+ ' (id_message, id_header, value)'.
+ ' VALUES ($1,$2,$3)';
+ return $this->update($qry,array($id_message , $id_header , $value));
+ }
+ function insertAttachment ($id_message, $filename,$filetype,$filesize,$filepath,$content_id) {
+
+ $id_message = $this->da->quoteSmart($id_message);
+ $filename = $this->da->quoteSmart($filename);
+ $filetype = $this->da->quoteSmart($filetype);
+ $filesize = $this->da->quoteSmart($filesize);
+ $filepath = $this->da->quoteSmart($filepath);
+ $content_id = $this->da->quoteSmart($content_id);
+ $qry = 'INSERT INTO plugin_forumml_attachment'.
+ ' (id_message, file_name, file_type, file_size, file_path, content_id)'.
+ ' VALUES ($1,$2,$3,$4,$5,$6)';
+ return $this->update($qry,array($id_message , $filename , $filetype , $filesize , $filepath , $content_id));
+ }
+ function searchHeader ($header) {
+ $header = $this->da->quoteSmart($header);
+ $qry = 'SELECT id_header'.
+ ' FROM plugin_forumml_header'.
+ ' WHERE name = $1';
+ return $this->retrieve($qry,array($header));
+
+ }
+ function insertHeader($header) {
+
+ $header = $this->da->quoteSmart($header);
+ $sql = 'INSERT INTO plugin_forumml_header'.
+ ' (name)'.
+ ' VALUES ($1)';
+ return db_insertid($this->update($sql,array($header)),'plugin_forumml_header','id_header');
+ }
+
+ function getParentMessageFromHeader ($id_header) {
+ $id_header = $this->da->quoteSmart($id_header);
+ $qry = 'SELECT id_message'.
+ ' FROM plugin_forumml_messageheader'.
+ ' WHERE id_header = 1'.
+ ' AND value = $1 ';
+ return $this->retrieve($qry,array($id_header));
+
+ }
+
+ function getParents($messageId) {
+ $messageId = $this->da->quoteSmart($messageId);
+ $sql = 'SELECT id_parent, last_thread_update FROM plugin_forumml_message WHERE id_message = $1';
+ return $this->retrieve($sql,array($messageId));
+
+ }
+ function updateParentDate($messageId,$date) {
+ $messageId = $this->da->quoteSmart($messageId);
+ $date = $this->da->quoteSmart($date);
+ $sql = 'UPDATE plugin_forumml_message'.
+ ' SET last_thread_update =$1 '.
+ ' WHERE id_message=$2';
+ $this->update($sql,array($date,$messageId));
+ }
+
+ function insertMessage ($id_list,$id_parent, $body, $messageDate, $ctype) {
+ $id_list = $this->da->quoteSmart($id_list);
+ $id_parent = $this->da->quoteSmart($id_parent);
+ $body = $this->da->quoteSmart($body);
+ $messageDate = $this->da->quoteSmart($messageDate);
+ $ctype = $this->da->quoteSmart($ctype);
+
+ $sql = 'INSERT INTO plugin_forumml_message'.
+ ' ( id_list, id_parent, body, last_thread_update, msg_type)'.
+ ' VALUES ($1, $2, $3, $4, $5)';
+ return db_insertid($this->update($sql,array($id_list , $id_parent , $body , $messageDate , $ctype)),'plugin_forumml_message' ,'id_message');
+
+ }
+
+}
+
+?>
diff --git a/plugins/coclico/forumml/include/ForumML_MessageManager.class.php b/plugins/coclico/forumml/include/ForumML_MessageManager.class.php
new file mode 100644
index 0000000000..2fabf1fba9
--- /dev/null
+++ b/plugins/coclico/forumml/include/ForumML_MessageManager.class.php
@@ -0,0 +1,44 @@
+.
+ */
+
+require_once 'ForumML_MessageDao.class.php';
+
+class ForumML_MessageManager {
+ private $_dao;
+
+ function getHeaderValue($messageId, $headerId) {
+ $dar = $this->getDao()->searchHeaderValue($messageId, $headerId);
+ if ($dar && !$dar->isError()) {
+ $row = $dar->current();
+ return $row['value'];
+ }
+ return false;
+ }
+
+ function getDao() {
+ if (!isset($this->_dao)) {
+ $this->_dao = new ForumML_MessageDao(CodendiDataAccess::instance());
+ }
+ return $this->_dao;
+ }
+
+}
+
+?>
\ No newline at end of file
diff --git a/plugins/coclico/forumml/include/ForumML_mimeDecode.class.php b/plugins/coclico/forumml/include/ForumML_mimeDecode.class.php
new file mode 100644
index 0000000000..6ef0c86b08
--- /dev/null
+++ b/plugins/coclico/forumml/include/ForumML_mimeDecode.class.php
@@ -0,0 +1,106 @@
+.
+ */
+
+require_once('Mail/mimeDecode.php');
+
+class ForumML_mimeDecode extends Mail_mimeDecode {
+
+ /**
+ * Redfined here just to avoid breakage on isStatic test (first line).
+ * It's just a copy/paste of parent's method
+ */
+ function decode($params = null)
+ {
+ // determine if this method has been called statically
+ $isStatic = !(isset($this) && get_class($this) == __CLASS__);
+
+ // Have we been called statically?
+ // If so, create an object and pass details to that.
+ if ($isStatic AND isset($params['input'])) {
+
+ $obj = new Mail_mimeDecode($params['input']);
+ $structure = $obj->decode($params);
+
+ // Called statically but no input
+ } elseif ($isStatic) {
+ return PEAR::raiseError('Called statically and no input given');
+
+ // Called via an object
+ } else {
+ $this->_include_bodies = isset($params['include_bodies']) ?
+ $params['include_bodies'] : false;
+ $this->_decode_bodies = isset($params['decode_bodies']) ?
+ $params['decode_bodies'] : false;
+ $this->_decode_headers = isset($params['decode_headers']) ?
+ $params['decode_headers'] : false;
+
+ $structure = $this->_decode($this->_header, $this->_body);
+ if ($structure === false) {
+ $structure = $this->raiseError($this->_error);
+ }
+ }
+
+ return $structure;
+ }
+
+ /**
+ * Redefined to convert headers to utf8 automatically. Same method than
+ * parent except code between // +++ Codendi: UTF8
+ */
+ function _decodeHeader($input)
+ {
+ // Remove white space between encoded-words
+ $input = preg_replace('/(=\?[^?]+\?(q|b)\?[^?]*\?=)(\s)+=\?/i', '\1=?', $input);
+
+ // For each encoded-word...
+ while (preg_match('/(=\?([^?]+)\?(q|b)\?([^?]*)\?=)/i', $input, $matches)) {
+
+ $encoded = $matches[1];
+ $charset = $matches[2];
+ $encoding = $matches[3];
+ $text = $matches[4];
+
+ switch (strtolower($encoding)) {
+ case 'b':
+ $text = base64_decode($text);
+ break;
+
+ case 'q':
+ $text = str_replace('_', ' ', $text);
+ preg_match_all('/=([a-f0-9]{2})/i', $text, $matches);
+ foreach($matches[1] as $value)
+ $text = str_replace('='.$value, chr(hexdec($value)), $text);
+ break;
+ }
+
+ // +++ Codendi: UTF8
+ if (function_exists('mb_convert_encoding')) {
+ $text = mb_convert_encoding($text, 'UTF-8', $charset);
+ }
+ // --- Codendi: UTF8
+
+ $input = str_replace($encoded, $text, $input);
+ }
+
+ return $input;
+ }
+}
+
+?>
diff --git a/plugins/coclico/forumml/include/forummlPlugin.class.php b/plugins/coclico/forumml/include/forummlPlugin.class.php
new file mode 100644
index 0000000000..41e5238359
--- /dev/null
+++ b/plugins/coclico/forumml/include/forummlPlugin.class.php
@@ -0,0 +1,237 @@
+.
+ */
+require_once('preplugins.php');
+require_once('ForumMLSearchEngine.class.php');
+
+
+class ForumMLPlugin extends Plugin {
+
+ function __construct($id=0) {
+ parent::__construct($id);
+ $this->name = "forumml" ;
+ $this->text = "ForumML" ; // To show in the tabs, use...
+ $this->_addHook("user_personal_links");//to make a link to the user�s personal part of the plugin
+ $this->_addHook("usermenu") ;
+ $this->_addHook("groupisactivecheckbox") ; // The "use ..." checkbox in editgroupinfo
+ $this->_addHook("groupisactivecheckboxpost") ; //
+ $this->_addHook("userisactivecheckbox") ; // The "use ..." checkbox in user account
+ $this->_addHook("userisactivecheckboxpost") ; //
+ $this->_addHook("project_admin_plugins"); // to show up in the admin page fro group
+ $this->_addHook('browse_archives','forumml_browse_archives',false);
+ $this->_addHook('cssfile','cssFile',false);
+ $this->_addHook('javascript_file', 'jsFile', false);
+ $this->_addHook('search_type', 'search_type', false);
+ $this->_addHook('layout_searchbox_options', 'forumml_searchbox_option', false);
+ $this->_addHook('layout_searchbox_hiddenInputs', 'forumml_searchbox_hiddenInput', false);
+ $this->_addHook('plugins_powered_search', 'forumml_search', false);
+ $this->_addHook('cssfile');
+ $this->_addHook('search_engines');
+ $this->_addHook('full_search_engines');
+ // Set ForumML plugin scope to 'Projects' wide
+ //$this->setScope(Plugin::SCOPE_PROJECT);
+ $this->allowedForProject = array();
+ }
+
+ function CallHook ($hookname, $params) {
+ global $use_mailmanplugin,$G_SESSION,$HTML,$gfcommon,$gfwww,$gfplugins;
+ if ($hookname == "usermenu") {
+ $text = $this->text; // this is what shows in the tab
+ if ($G_SESSION->usesPlugin("mailman")) {
+ $param = '?type=user&id=' . $G_SESSION->getId() . "&pluginname=" . $this->name; // we indicate the part we�re calling is the user one
+ echo ' | ' . $HTML->PrintSubMenu (array ($text),
+ array ('/plugins/mailman/index.php' . $param ));
+ }
+ } elseif ($hookname =='cssfile') {
+ echo ' ';
+ } elseif ($hookname == "groupisactivecheckbox") {
+ //Check if the group is active
+ // this code creates the checkbox in the project edit public info page to activate/deactivate the plugin
+ $group_id=$params['group'];
+ $group = &group_get_object($group_id);
+ echo "";
+ echo "";
+ echo ' usesPlugin ( $this->name ) ) {
+ echo "CHECKED";
+ }
+ echo "> ";
+ echo " ";
+ echo "";
+ echo "Use ".$this->text." Plugin ";
+ echo " ";
+ echo " ";
+
+ } elseif ($hookname == "groupisactivecheckboxpost") {
+ // this code actually activates/deactivates the plugin after the form was submitted in the project edit public info page
+ $group_id=$params['group'];
+ $group = &group_get_object($group_id);
+ $use_mailmanplugin = getStringFromRequest('use_forummlplugin');
+ if ( $use_mailmanplugin == 1 ) {
+ $group->setPluginUse ( $this->name );
+ } else {
+ $group->setPluginUse ( $this->name, false );
+ }
+ } elseif ($hookname == "userisactivecheckbox") {
+ //check if user is active
+ // this code creates the checkbox in the user account manteinance page to activate/deactivate the plugin
+ $user = $params['user'];
+ echo "";
+ echo "";
+ echo ' usesPlugin ( $this->name ) ) {
+ echo "CHECKED";
+ }
+ echo "> Use ".$this->text." Plugin";
+ echo " ";
+ echo " ";
+ } elseif ($hookname == "userisactivecheckboxpost") {
+ // this code actually activates/deactivates the plugin after the form was submitted in the user account manteinance page
+ $user = $params['user'];
+ $use_mailmanplugin = getStringFromRequest('use_forummlplugin');
+ if ( $use_mailmanplugin == 1 ) {
+ $user->setPluginUse ( $this->name );
+ } else {
+ $user->setPluginUse ( $this->name, false );
+ }
+ echo "";
+ echo "";
+ echo ' usesPlugin ( $this->name ) ) {
+ echo "CHECKED";
+ }
+ echo "> Use ".$this->text." Plugin";
+ echo " ";
+ echo " ";
+ } elseif ($hookname == 'search_engines') {
+ $myfile=fopen('/tmp/hook','a');
+ // FIXME: when the hook is called, the group_id is not set.
+ // So I use the global variable instead.
+ $request =& HTTPRequest::instance();
+ $group_id = (int) $request->get('group_id');
+ if ($group_id) {
+ $group =& group_get_object($group_id);
+ if ($group->usesPlugin('forumml')) {
+ $params->addSearchEngine(
+ SEARCH__TYPE_IS_LIST,
+ new ForumMLSearchEngine(SEARCH__TYPE_IS_LIST,
+ 'ForumMLHtmlSearchRenderer',
+ _("This project's mailing lists"), $group_id)
+ );
+ }
+ }
+ } elseif ($hookname == "browse_archives") {
+ $this->forumml_browse_archives($params);
+ } elseif ($hookname == "cssfile") {
+ $this->cssFile($params);
+ } elseif ($hookname == "javascript_file") {
+ $this->jsFile($params);
+ } elseif ($hookname == "search_type") {
+ $this->search_type($params);
+ } elseif ($hookname == "layout_searchbox_options") {
+ $this->forumml_searchbox_option($params);
+ } elseif ($hookname == "layout_searchbox_hiddenInputs") {
+ $this->forumml_searchbox_hiddenInput($params);
+ } elseif ($hookname == "plugins_powered_search") {
+ $this->forumml_search($params);
+
+ }
+ }
+
+ function &getPluginInfo() {
+ if (!is_a($this->pluginInfo, 'ForumMLPluginInfo')) {
+ require_once('ForumMLPluginInfo.class.php');
+ $this->pluginInfo =& new ForumMLPluginInfo($this);
+ }
+ return $this->pluginInfo;
+ }
+
+ /**
+ * Return true if current project has the right to use this plugin.
+ */
+ function isAllowed($group_id=false) {
+ if(!$group_id) {
+ $request =& HTTPRequest::instance();
+ $group_id = (int) $request->get('group_id');
+ }
+ if(!isset($this->allowedForProject[$group_id])) {
+ $pM =& PluginManager::instance();
+ $this->allowedForProject[$group_id] = $pM->isPluginAllowedForProject($this, $group_id);
+ }
+ return $this->allowedForProject[$group_id];
+ }
+
+ function forumml_searchbox_option($params) {
+ $request =& HTTPRequest::instance();
+ $group_id = (int) $request->get('group_id');
+ if(isset($_REQUEST['list']) && isset($group_id)) {
+ $params['option_html'] .= "\t"._('This List')." \n";
+ }
+ }
+
+ function forumml_searchbox_hiddenInput($params) {
+ if(isset($_REQUEST['list'])) {
+ $params['input_html'] .= "\t \n";
+ }
+ }
+
+ function forumml_browse_archives($params) {
+ if ($this->isAllowed()) {
+ $request =& HTTPRequest::instance();
+ $group_id = (int) $request->get('group_id');
+ $params['html'] = ' '._('Archives').' ';
+ }
+ }
+
+ function cssFile($params) {
+ $request =& HTTPRequest::instance();
+ if (strpos($_SERVER['REQUEST_URI'], $this->getPluginPath()) === 0) {
+ echo ' '."\n";
+ }
+ }
+
+ function jsFile($params) {
+ //$request =& HTTPRequest::instance();
+ if (strpos($_SERVER['REQUEST_URI'], $this->getPluginPath()) === 0) {
+ //echo ' '."\n";
+ echo ''."\n";
+ }
+ }
+
+ function forumml_search($params) {
+ if($params['type_of_search'] == 'mail') {
+ $params['plugins_powered_search'] = true;
+ }
+ }
+
+ function search_type($params) {
+ if(isset($params['type_of_search']) && $params['type_of_search'] == 'mail') {
+ $request =& HTTPRequest::instance();
+ $group_id = (int) $request->get('group_id');
+ $list = (int) $request->get('list');
+ util_return_to('/plugins/forumml/message.php?group_id='.$group_id.'&list='.$list.'&search='.urlencode($params['words']));
+ }
+ }
+
+}
+
+?>
diff --git a/plugins/coclico/forumml/packaging/control/000source b/plugins/coclico/forumml/packaging/control/000source
new file mode 100644
index 0000000000..105b726962
--- /dev/null
+++ b/plugins/coclico/forumml/packaging/control/000source
@@ -0,0 +1,10 @@
+Source: @SRCPACKAGE@
+Section: devel
+Priority: optional
+Maintainer: Christian Bayle
+Uploaders: Roland Mas
+Build-Depends-Indep: devscripts
+Build-Depends: debhelper (>= 7), perl, gettext
+Standards-Version: 3.8.4
+Homepage: http://fusionforge.org/
+Vcs-Bzr: http://scm.fusionforge.org/bzr/fusionforge/svn-trunk-ro/
diff --git a/plugins/coclico/forumml/packaging/control/222plugin-forumml b/plugins/coclico/forumml/packaging/control/222plugin-forumml
new file mode 100644
index 0000000000..17d8fffcf8
--- /dev/null
+++ b/plugins/coclico/forumml/packaging/control/222plugin-forumml
@@ -0,0 +1,4 @@
+Package: @SRCPACKAGE@
+Architecture: all
+Depends: @OLDPACKAGE@-common, @OLDPACKAGE@-db-postgresql | @OLDPACKAGE@-db, @OLDPACKAGE@-web-apache2 | @OLDPACKAGE@-web, php5-cli, php-mail, php-mail-mime, php-mail-mbox, php-mail-mimedecode, ${misc:Depends}
+Description: collaborative development tool - ForumML plugin
diff --git a/plugins/coclico/forumml/packaging/control/222plugin-forumml.shortdesc b/plugins/coclico/forumml/packaging/control/222plugin-forumml.shortdesc
new file mode 100644
index 0000000000..a3039f6537
--- /dev/null
+++ b/plugins/coclico/forumml/packaging/control/222plugin-forumml.shortdesc
@@ -0,0 +1,3 @@
+ This plugin contains the ForumML subsystem of FusionForge. It allows each
+ FusionForge project to have its own ForumML, and gives some
+ control over it to the project's administrator.
diff --git a/plugins/coclico/forumml/packaging/dirs/plugin-forumml b/plugins/coclico/forumml/packaging/dirs/plugin-forumml
new file mode 100644
index 0000000000..b03aa3e27d
--- /dev/null
+++ b/plugins/coclico/forumml/packaging/dirs/plugin-forumml
@@ -0,0 +1,8 @@
+etc/gforge/httpd.d
+etc/gforge/plugins/forumml
+usr/share/gforge/plugins/forumml/cgi-bin
+usr/share/gforge/plugins/forumml/common
+usr/share/gforge/plugins/forumml/www
+var/spool/forumml
+var/lib/gforge/forumml
+var/log/gforge
diff --git a/plugins/coclico/forumml/packaging/docs/plugin-forumml b/plugins/coclico/forumml/packaging/docs/plugin-forumml
new file mode 100644
index 0000000000..e174728f54
--- /dev/null
+++ b/plugins/coclico/forumml/packaging/docs/plugin-forumml
@@ -0,0 +1 @@
+debian/README.Debian
diff --git a/plugins/coclico/forumml/packaging/install/plugin-forumml b/plugins/coclico/forumml/packaging/install/plugin-forumml
new file mode 100644
index 0000000000..68dde05412
--- /dev/null
+++ b/plugins/coclico/forumml/packaging/install/plugin-forumml
@@ -0,0 +1,6 @@
+common/* usr/share/gforge/plugins/forumml/common/
+include/* usr/share/gforge/plugins/forumml/include/
+db/* usr/share/gforge/plugins/forumml/db/
+bin/* usr/share/gforge/plugins/forumml/bin/
+www/* usr/share/gforge/plugins/forumml/www/
+etc/* usr/share/gforge/plugins/forumml/etc/
diff --git a/plugins/coclico/forumml/packaging/links/plugin-forumml b/plugins/coclico/forumml/packaging/links/plugin-forumml
new file mode 100644
index 0000000000..c34289e82a
--- /dev/null
+++ b/plugins/coclico/forumml/packaging/links/plugin-forumml
@@ -0,0 +1 @@
+/usr/share/gforge/plugins/forumml/www /usr/share/gforge/www/plugins/forumml
diff --git a/plugins/coclico/forumml/selinux/forumml0.pp b/plugins/coclico/forumml/selinux/forumml0.pp
new file mode 100644
index 0000000000..d7c4f17fa2
Binary files /dev/null and b/plugins/coclico/forumml/selinux/forumml0.pp differ
diff --git a/plugins/coclico/forumml/selinux/forumml0.te b/plugins/coclico/forumml/selinux/forumml0.te
new file mode 100644
index 0000000000..fb2ba85fc6
--- /dev/null
+++ b/plugins/coclico/forumml/selinux/forumml0.te
@@ -0,0 +1,157 @@
+
+module forumml0 1.0;
+
+require {
+ type mailman_mail_t;
+ type unconfined_t;
+ type semanage_t;
+ type usr_t;
+ type var_run_t;
+ type postfix_smtpd_t;
+ type xfs_t;
+ type initrc_t;
+ type system_dbusd_t;
+ type tmp_t;
+ type mysqld_etc_t;
+ type avahi_t;
+ type mysqld_db_t;
+ type httpd_sys_content_t;
+ type logwatch_t;
+ type postfix_smtp_t;
+ type postfix_bounce_t;
+ type ifconfig_t;
+ type lib_t;
+ type mysqld_var_run_t;
+ type nscd_t;
+ type useradd_t;
+ type mysqld_t;
+ type named_t;
+ type postfix_cleanup_t;
+ type postfix_master_t;
+ type setroubleshootd_t;
+ type postfix_pickup_t;
+ type groupadd_t;
+ type crond_t;
+ type system_mail_t;
+ type postfix_qmgr_t;
+ type httpd_t;
+ class fifo_file { write read ioctl getattr };
+ class process signal;
+ class unix_stream_socket { connectto read write };
+ class tcp_socket { read write };
+ class file { execute read create ioctl execute_no_trans write getattr unlink append };
+ class sock_file write;
+ class lnk_file { read getattr };
+ class dir { write search getattr remove_name add_name };
+}
+
+#============= avahi_t ==============
+allow avahi_t mysqld_db_t:dir search;
+allow avahi_t mysqld_etc_t:file getattr;
+
+#============= groupadd_t ==============
+allow groupadd_t initrc_t:unix_stream_socket connectto;
+
+#============= httpd_t ==============
+allow httpd_t crond_t:unix_stream_socket { read write };
+allow httpd_t initrc_t:unix_stream_socket connectto;
+allow httpd_t mysqld_etc_t:file { read getattr };
+allow httpd_t system_mail_t:process signal;
+allow httpd_t tmp_t:file { read getattr };
+allow httpd_t unconfined_t:unix_stream_socket { read write };
+allow httpd_t usr_t:file { create unlink append };
+
+#============= ifconfig_t ==============
+allow ifconfig_t initrc_t:tcp_socket { read write };
+
+#============= logwatch_t ==============
+allow logwatch_t initrc_t:unix_stream_socket connectto;
+allow logwatch_t mysqld_etc_t:file read;
+allow logwatch_t mysqld_t:unix_stream_socket connectto;
+
+#============= mailman_mail_t ==============
+allow mailman_mail_t httpd_sys_content_t:dir { search getattr };
+allow mailman_mail_t httpd_sys_content_t:file { read getattr };
+allow mailman_mail_t httpd_sys_content_t:lnk_file { read getattr };
+allow mailman_mail_t initrc_t:unix_stream_socket connectto;
+allow mailman_mail_t lib_t:dir { write remove_name add_name };
+allow mailman_mail_t lib_t:file { write create unlink };
+allow mailman_mail_t self:fifo_file { write read ioctl getattr };
+allow mailman_mail_t usr_t:file { read getattr ioctl execute execute_no_trans };
+allow mailman_mail_t usr_t:lnk_file { read getattr };
+allow mailman_mail_t var_run_t:dir { write add_name };
+allow mailman_mail_t var_run_t:file { create ioctl append getattr };
+
+#============= named_t ==============
+allow named_t mysqld_db_t:dir search;
+allow named_t mysqld_etc_t:file { read getattr };
+
+#============= nscd_t ==============
+allow nscd_t useradd_t:unix_stream_socket { read write };
+
+#============= postfix_bounce_t ==============
+allow postfix_bounce_t initrc_t:unix_stream_socket connectto;
+allow postfix_bounce_t mysqld_db_t:dir search;
+allow postfix_bounce_t mysqld_etc_t:file { read getattr };
+allow postfix_bounce_t mysqld_t:unix_stream_socket connectto;
+allow postfix_bounce_t mysqld_var_run_t:sock_file write;
+
+#============= postfix_cleanup_t ==============
+allow postfix_cleanup_t initrc_t:unix_stream_socket connectto;
+allow postfix_cleanup_t mysqld_db_t:dir search;
+allow postfix_cleanup_t mysqld_etc_t:file { read getattr };
+allow postfix_cleanup_t mysqld_t:unix_stream_socket connectto;
+allow postfix_cleanup_t mysqld_var_run_t:sock_file write;
+allow postfix_cleanup_t usr_t:file { read getattr };
+
+#============= postfix_master_t ==============
+allow postfix_master_t initrc_t:unix_stream_socket connectto;
+allow postfix_master_t mysqld_etc_t:file { read getattr };
+
+#============= postfix_pickup_t ==============
+allow postfix_pickup_t initrc_t:unix_stream_socket connectto;
+allow postfix_pickup_t mysqld_db_t:dir search;
+allow postfix_pickup_t mysqld_etc_t:file { read getattr };
+allow postfix_pickup_t mysqld_var_run_t:sock_file write;
+
+#============= postfix_qmgr_t ==============
+allow postfix_qmgr_t initrc_t:unix_stream_socket connectto;
+allow postfix_qmgr_t mysqld_db_t:dir search;
+allow postfix_qmgr_t mysqld_etc_t:file getattr;
+
+#============= postfix_smtp_t ==============
+allow postfix_smtp_t initrc_t:unix_stream_socket connectto;
+allow postfix_smtp_t mysqld_db_t:dir search;
+allow postfix_smtp_t mysqld_etc_t:file { read getattr };
+allow postfix_smtp_t mysqld_t:unix_stream_socket connectto;
+allow postfix_smtp_t mysqld_var_run_t:sock_file write;
+allow postfix_smtp_t usr_t:file { read getattr };
+
+#============= postfix_smtpd_t ==============
+allow postfix_smtpd_t initrc_t:unix_stream_socket connectto;
+allow postfix_smtpd_t mysqld_db_t:dir search;
+allow postfix_smtpd_t mysqld_etc_t:file { read getattr };
+allow postfix_smtpd_t mysqld_t:unix_stream_socket connectto;
+allow postfix_smtpd_t mysqld_var_run_t:sock_file write;
+
+#============= semanage_t ==============
+allow semanage_t httpd_sys_content_t:lnk_file read;
+allow semanage_t initrc_t:unix_stream_socket connectto;
+allow semanage_t mysqld_t:unix_stream_socket connectto;
+allow semanage_t mysqld_var_run_t:sock_file write;
+
+#============= setroubleshootd_t ==============
+allow setroubleshootd_t httpd_sys_content_t:lnk_file read;
+
+#============= system_dbusd_t ==============
+allow system_dbusd_t initrc_t:unix_stream_socket connectto;
+allow system_dbusd_t mysqld_t:unix_stream_socket connectto;
+allow system_dbusd_t mysqld_var_run_t:sock_file write;
+
+#============= system_mail_t ==============
+allow system_mail_t crond_t:unix_stream_socket { read write };
+allow system_mail_t httpd_t:file read;
+allow system_mail_t initrc_t:unix_stream_socket connectto;
+
+#============= xfs_t ==============
+allow xfs_t mysqld_t:unix_stream_socket connectto;
diff --git a/plugins/coclico/forumml/selinux/forumml1.pp b/plugins/coclico/forumml/selinux/forumml1.pp
new file mode 100644
index 0000000000..b2ae71493c
Binary files /dev/null and b/plugins/coclico/forumml/selinux/forumml1.pp differ
diff --git a/plugins/coclico/forumml/selinux/forumml1.te b/plugins/coclico/forumml/selinux/forumml1.te
new file mode 100644
index 0000000000..959d572ed4
--- /dev/null
+++ b/plugins/coclico/forumml/selinux/forumml1.te
@@ -0,0 +1,157 @@
+
+module forumml1 1.0;
+
+require {
+ type mailman_mail_t;
+ type unconfined_t;
+ type semanage_t;
+ type usr_t;
+ type var_run_t;
+ type postfix_smtpd_t;
+ type xfs_t;
+ type initrc_t;
+ type system_dbusd_t;
+ type tmp_t;
+ type mysqld_etc_t;
+ type avahi_t;
+ type mysqld_db_t;
+ type httpd_sys_content_t;
+ type logwatch_t;
+ type postfix_smtp_t;
+ type postfix_bounce_t;
+ type ifconfig_t;
+ type lib_t;
+ type mysqld_var_run_t;
+ type nscd_t;
+ type useradd_t;
+ type mysqld_t;
+ type named_t;
+ type postfix_cleanup_t;
+ type postfix_master_t;
+ type setroubleshootd_t;
+ type postfix_pickup_t;
+ type groupadd_t;
+ type crond_t;
+ type system_mail_t;
+ type postfix_qmgr_t;
+ type httpd_t;
+ class fifo_file { write read ioctl getattr };
+ class process signal;
+ class unix_stream_socket { connectto read write };
+ class tcp_socket { read write };
+ class file { execute read create ioctl execute_no_trans write getattr unlink append };
+ class sock_file write;
+ class lnk_file { read getattr };
+ class dir { write search getattr remove_name add_name };
+}
+
+#============= avahi_t ==============
+allow avahi_t mysqld_db_t:dir search;
+allow avahi_t mysqld_etc_t:file getattr;
+
+#============= groupadd_t ==============
+allow groupadd_t initrc_t:unix_stream_socket connectto;
+
+#============= httpd_t ==============
+allow httpd_t crond_t:unix_stream_socket { read write };
+allow httpd_t initrc_t:unix_stream_socket connectto;
+allow httpd_t mysqld_etc_t:file { read getattr };
+allow httpd_t system_mail_t:process signal;
+allow httpd_t tmp_t:file { read getattr };
+allow httpd_t unconfined_t:unix_stream_socket { read write };
+allow httpd_t usr_t:file { create unlink append };
+
+#============= ifconfig_t ==============
+allow ifconfig_t initrc_t:tcp_socket { read write };
+
+#============= logwatch_t ==============
+allow logwatch_t initrc_t:unix_stream_socket connectto;
+allow logwatch_t mysqld_etc_t:file read;
+allow logwatch_t mysqld_t:unix_stream_socket connectto;
+
+#============= mailman_mail_t ==============
+allow mailman_mail_t httpd_sys_content_t:dir { search getattr };
+allow mailman_mail_t httpd_sys_content_t:file { read getattr };
+allow mailman_mail_t httpd_sys_content_t:lnk_file { read getattr };
+allow mailman_mail_t initrc_t:unix_stream_socket connectto;
+allow mailman_mail_t lib_t:dir { write remove_name add_name };
+allow mailman_mail_t lib_t:file { write create unlink };
+allow mailman_mail_t self:fifo_file { write read ioctl getattr };
+allow mailman_mail_t usr_t:file { read getattr ioctl execute execute_no_trans };
+allow mailman_mail_t usr_t:lnk_file { read getattr };
+allow mailman_mail_t var_run_t:dir { write add_name };
+allow mailman_mail_t var_run_t:file { create ioctl append getattr };
+
+#============= named_t ==============
+allow named_t mysqld_db_t:dir search;
+allow named_t mysqld_etc_t:file { read getattr };
+
+#============= nscd_t ==============
+allow nscd_t useradd_t:unix_stream_socket { read write };
+
+#============= postfix_bounce_t ==============
+allow postfix_bounce_t initrc_t:unix_stream_socket connectto;
+allow postfix_bounce_t mysqld_db_t:dir search;
+allow postfix_bounce_t mysqld_etc_t:file { read getattr };
+allow postfix_bounce_t mysqld_t:unix_stream_socket connectto;
+allow postfix_bounce_t mysqld_var_run_t:sock_file write;
+
+#============= postfix_cleanup_t ==============
+allow postfix_cleanup_t initrc_t:unix_stream_socket connectto;
+allow postfix_cleanup_t mysqld_db_t:dir search;
+allow postfix_cleanup_t mysqld_etc_t:file { read getattr };
+allow postfix_cleanup_t mysqld_t:unix_stream_socket connectto;
+allow postfix_cleanup_t mysqld_var_run_t:sock_file write;
+allow postfix_cleanup_t usr_t:file { read getattr };
+
+#============= postfix_master_t ==============
+allow postfix_master_t initrc_t:unix_stream_socket connectto;
+allow postfix_master_t mysqld_etc_t:file { read getattr };
+
+#============= postfix_pickup_t ==============
+allow postfix_pickup_t initrc_t:unix_stream_socket connectto;
+allow postfix_pickup_t mysqld_db_t:dir search;
+allow postfix_pickup_t mysqld_etc_t:file { read getattr };
+allow postfix_pickup_t mysqld_var_run_t:sock_file write;
+
+#============= postfix_qmgr_t ==============
+allow postfix_qmgr_t initrc_t:unix_stream_socket connectto;
+allow postfix_qmgr_t mysqld_db_t:dir search;
+allow postfix_qmgr_t mysqld_etc_t:file getattr;
+
+#============= postfix_smtp_t ==============
+allow postfix_smtp_t initrc_t:unix_stream_socket connectto;
+allow postfix_smtp_t mysqld_db_t:dir search;
+allow postfix_smtp_t mysqld_etc_t:file { read getattr };
+allow postfix_smtp_t mysqld_t:unix_stream_socket connectto;
+allow postfix_smtp_t mysqld_var_run_t:sock_file write;
+allow postfix_smtp_t usr_t:file { read getattr };
+
+#============= postfix_smtpd_t ==============
+allow postfix_smtpd_t initrc_t:unix_stream_socket connectto;
+allow postfix_smtpd_t mysqld_db_t:dir search;
+allow postfix_smtpd_t mysqld_etc_t:file { read getattr };
+allow postfix_smtpd_t mysqld_t:unix_stream_socket connectto;
+allow postfix_smtpd_t mysqld_var_run_t:sock_file write;
+
+#============= semanage_t ==============
+allow semanage_t httpd_sys_content_t:lnk_file read;
+allow semanage_t initrc_t:unix_stream_socket connectto;
+allow semanage_t mysqld_t:unix_stream_socket connectto;
+allow semanage_t mysqld_var_run_t:sock_file write;
+
+#============= setroubleshootd_t ==============
+allow setroubleshootd_t httpd_sys_content_t:lnk_file read;
+
+#============= system_dbusd_t ==============
+allow system_dbusd_t initrc_t:unix_stream_socket connectto;
+allow system_dbusd_t mysqld_t:unix_stream_socket connectto;
+allow system_dbusd_t mysqld_var_run_t:sock_file write;
+
+#============= system_mail_t ==============
+allow system_mail_t crond_t:unix_stream_socket { read write };
+allow system_mail_t httpd_t:file read;
+allow system_mail_t initrc_t:unix_stream_socket connectto;
+
+#============= xfs_t ==============
+allow xfs_t mysqld_t:unix_stream_socket connectto;
diff --git a/plugins/coclico/forumml/selinux/forumml2.pp b/plugins/coclico/forumml/selinux/forumml2.pp
new file mode 100644
index 0000000000..ed2112a0a4
Binary files /dev/null and b/plugins/coclico/forumml/selinux/forumml2.pp differ
diff --git a/plugins/coclico/forumml/selinux/forumml2.te b/plugins/coclico/forumml/selinux/forumml2.te
new file mode 100644
index 0000000000..c23e33bfcc
--- /dev/null
+++ b/plugins/coclico/forumml/selinux/forumml2.te
@@ -0,0 +1,158 @@
+
+module forumml2 1.0;
+
+require {
+ type mailman_mail_t;
+ type unconfined_t;
+ type semanage_t;
+ type usr_t;
+ type var_run_t;
+ type postfix_smtpd_t;
+ type xfs_t;
+ type initrc_t;
+ type system_dbusd_t;
+ type tmp_t;
+ type mysqld_etc_t;
+ type avahi_t;
+ type mysqld_db_t;
+ type httpd_sys_content_t;
+ type logwatch_t;
+ type postfix_smtp_t;
+ type postfix_bounce_t;
+ type ifconfig_t;
+ type lib_t;
+ type mysqld_var_run_t;
+ type nscd_t;
+ type useradd_t;
+ type mysqld_t;
+ type named_t;
+ type postfix_cleanup_t;
+ type postfix_master_t;
+ type setroubleshootd_t;
+ type postfix_pickup_t;
+ type groupadd_t;
+ type crond_t;
+ type system_mail_t;
+ type postfix_qmgr_t;
+ type httpd_t;
+ class fifo_file { write read ioctl getattr };
+ class process signal;
+ class unix_stream_socket { connectto read write };
+ class tcp_socket { read write };
+ class file { execute read create ioctl execute_no_trans write getattr unlink append };
+ class sock_file write;
+ class lnk_file { read getattr };
+ class dir { write search getattr read remove_name add_name };
+}
+
+#============= avahi_t ==============
+allow avahi_t mysqld_db_t:dir search;
+allow avahi_t mysqld_etc_t:file getattr;
+
+#============= groupadd_t ==============
+allow groupadd_t initrc_t:unix_stream_socket connectto;
+
+#============= httpd_t ==============
+allow httpd_t crond_t:unix_stream_socket { read write };
+allow httpd_t initrc_t:unix_stream_socket connectto;
+allow httpd_t mysqld_etc_t:file { read getattr };
+allow httpd_t system_mail_t:process signal;
+allow httpd_t tmp_t:file { read getattr };
+allow httpd_t unconfined_t:unix_stream_socket { read write };
+allow httpd_t usr_t:file { create unlink append };
+
+#============= ifconfig_t ==============
+allow ifconfig_t initrc_t:tcp_socket { read write };
+
+#============= logwatch_t ==============
+allow logwatch_t initrc_t:unix_stream_socket connectto;
+allow logwatch_t mysqld_etc_t:file read;
+allow logwatch_t mysqld_t:unix_stream_socket connectto;
+
+#============= mailman_mail_t ==============
+allow mailman_mail_t httpd_sys_content_t:dir { read search getattr };
+allow mailman_mail_t httpd_sys_content_t:file { read getattr };
+allow mailman_mail_t httpd_sys_content_t:lnk_file { read getattr };
+allow mailman_mail_t initrc_t:unix_stream_socket connectto;
+allow mailman_mail_t lib_t:dir { write remove_name add_name };
+allow mailman_mail_t lib_t:file { write create unlink };
+allow mailman_mail_t self:fifo_file { write read ioctl getattr };
+allow mailman_mail_t tmp_t:file { read getattr };
+allow mailman_mail_t usr_t:file { read getattr ioctl execute execute_no_trans };
+allow mailman_mail_t usr_t:lnk_file { read getattr };
+allow mailman_mail_t var_run_t:dir { write remove_name add_name };
+allow mailman_mail_t var_run_t:file { read create ioctl append getattr };
+
+#============= named_t ==============
+allow named_t mysqld_db_t:dir search;
+allow named_t mysqld_etc_t:file { read getattr };
+
+#============= nscd_t ==============
+allow nscd_t useradd_t:unix_stream_socket { read write };
+
+#============= postfix_bounce_t ==============
+allow postfix_bounce_t initrc_t:unix_stream_socket connectto;
+allow postfix_bounce_t mysqld_db_t:dir search;
+allow postfix_bounce_t mysqld_etc_t:file { read getattr };
+allow postfix_bounce_t mysqld_t:unix_stream_socket connectto;
+allow postfix_bounce_t mysqld_var_run_t:sock_file write;
+
+#============= postfix_cleanup_t ==============
+allow postfix_cleanup_t initrc_t:unix_stream_socket connectto;
+allow postfix_cleanup_t mysqld_db_t:dir search;
+allow postfix_cleanup_t mysqld_etc_t:file { read getattr };
+allow postfix_cleanup_t mysqld_t:unix_stream_socket connectto;
+allow postfix_cleanup_t mysqld_var_run_t:sock_file write;
+allow postfix_cleanup_t usr_t:file { read getattr };
+
+#============= postfix_master_t ==============
+allow postfix_master_t initrc_t:unix_stream_socket connectto;
+allow postfix_master_t mysqld_etc_t:file { read getattr };
+
+#============= postfix_pickup_t ==============
+allow postfix_pickup_t initrc_t:unix_stream_socket connectto;
+allow postfix_pickup_t mysqld_db_t:dir search;
+allow postfix_pickup_t mysqld_etc_t:file { read getattr };
+allow postfix_pickup_t mysqld_var_run_t:sock_file write;
+
+#============= postfix_qmgr_t ==============
+allow postfix_qmgr_t initrc_t:unix_stream_socket connectto;
+allow postfix_qmgr_t mysqld_db_t:dir search;
+allow postfix_qmgr_t mysqld_etc_t:file getattr;
+
+#============= postfix_smtp_t ==============
+allow postfix_smtp_t initrc_t:unix_stream_socket connectto;
+allow postfix_smtp_t mysqld_db_t:dir search;
+allow postfix_smtp_t mysqld_etc_t:file { read getattr };
+allow postfix_smtp_t mysqld_t:unix_stream_socket connectto;
+allow postfix_smtp_t mysqld_var_run_t:sock_file write;
+allow postfix_smtp_t usr_t:file { read getattr };
+
+#============= postfix_smtpd_t ==============
+allow postfix_smtpd_t initrc_t:unix_stream_socket connectto;
+allow postfix_smtpd_t mysqld_db_t:dir search;
+allow postfix_smtpd_t mysqld_etc_t:file { read getattr };
+allow postfix_smtpd_t mysqld_t:unix_stream_socket connectto;
+allow postfix_smtpd_t mysqld_var_run_t:sock_file write;
+
+#============= semanage_t ==============
+allow semanage_t httpd_sys_content_t:lnk_file read;
+allow semanage_t initrc_t:unix_stream_socket connectto;
+allow semanage_t mysqld_t:unix_stream_socket connectto;
+allow semanage_t mysqld_var_run_t:sock_file write;
+
+#============= setroubleshootd_t ==============
+allow setroubleshootd_t httpd_sys_content_t:lnk_file read;
+
+#============= system_dbusd_t ==============
+allow system_dbusd_t initrc_t:unix_stream_socket connectto;
+allow system_dbusd_t mysqld_t:unix_stream_socket connectto;
+allow system_dbusd_t mysqld_var_run_t:sock_file write;
+
+#============= system_mail_t ==============
+allow system_mail_t crond_t:unix_stream_socket { read write };
+allow system_mail_t httpd_t:file read;
+allow system_mail_t initrc_t:unix_stream_socket connectto;
+
+#============= xfs_t ==============
+allow xfs_t mysqld_t:unix_stream_socket connectto;
diff --git a/plugins/coclico/forumml/selinux/forumml3.pp b/plugins/coclico/forumml/selinux/forumml3.pp
new file mode 100644
index 0000000000..41d34e7b56
Binary files /dev/null and b/plugins/coclico/forumml/selinux/forumml3.pp differ
diff --git a/plugins/coclico/forumml/selinux/forumml3.te b/plugins/coclico/forumml/selinux/forumml3.te
new file mode 100644
index 0000000000..efee305523
--- /dev/null
+++ b/plugins/coclico/forumml/selinux/forumml3.te
@@ -0,0 +1,158 @@
+
+module forumml3 1.0;
+
+require {
+ type mailman_mail_t;
+ type unconfined_t;
+ type semanage_t;
+ type usr_t;
+ type var_run_t;
+ type postfix_smtpd_t;
+ type xfs_t;
+ type initrc_t;
+ type system_dbusd_t;
+ type tmp_t;
+ type mysqld_etc_t;
+ type avahi_t;
+ type mysqld_db_t;
+ type httpd_sys_content_t;
+ type logwatch_t;
+ type postfix_smtp_t;
+ type postfix_bounce_t;
+ type ifconfig_t;
+ type lib_t;
+ type mysqld_var_run_t;
+ type nscd_t;
+ type useradd_t;
+ type mysqld_t;
+ type named_t;
+ type postfix_cleanup_t;
+ type postfix_master_t;
+ type setroubleshootd_t;
+ type postfix_pickup_t;
+ type groupadd_t;
+ type crond_t;
+ type system_mail_t;
+ type postfix_qmgr_t;
+ type httpd_t;
+ class fifo_file { write read ioctl getattr };
+ class process signal;
+ class unix_stream_socket { connectto read write };
+ class tcp_socket { read write };
+ class file { execute read create ioctl execute_no_trans write getattr unlink append };
+ class sock_file write;
+ class lnk_file { read getattr };
+ class dir { write search getattr read remove_name add_name };
+}
+
+#============= avahi_t ==============
+allow avahi_t mysqld_db_t:dir search;
+allow avahi_t mysqld_etc_t:file getattr;
+
+#============= groupadd_t ==============
+allow groupadd_t initrc_t:unix_stream_socket connectto;
+
+#============= httpd_t ==============
+allow httpd_t crond_t:unix_stream_socket { read write };
+allow httpd_t initrc_t:unix_stream_socket connectto;
+allow httpd_t mysqld_etc_t:file { read getattr };
+allow httpd_t system_mail_t:process signal;
+allow httpd_t tmp_t:file { read getattr };
+allow httpd_t unconfined_t:unix_stream_socket { read write };
+allow httpd_t usr_t:file { create unlink append };
+
+#============= ifconfig_t ==============
+allow ifconfig_t initrc_t:tcp_socket { read write };
+
+#============= logwatch_t ==============
+allow logwatch_t initrc_t:unix_stream_socket connectto;
+allow logwatch_t mysqld_etc_t:file read;
+allow logwatch_t mysqld_t:unix_stream_socket connectto;
+
+#============= mailman_mail_t ==============
+allow mailman_mail_t httpd_sys_content_t:dir { read search getattr };
+allow mailman_mail_t httpd_sys_content_t:file { read getattr };
+allow mailman_mail_t httpd_sys_content_t:lnk_file { read getattr };
+allow mailman_mail_t initrc_t:unix_stream_socket connectto;
+allow mailman_mail_t lib_t:dir { write remove_name add_name };
+allow mailman_mail_t lib_t:file { write create unlink };
+allow mailman_mail_t self:fifo_file { write read ioctl getattr };
+allow mailman_mail_t tmp_t:file { read getattr };
+allow mailman_mail_t usr_t:file { read getattr ioctl execute execute_no_trans };
+allow mailman_mail_t usr_t:lnk_file { read getattr };
+allow mailman_mail_t var_run_t:dir { write remove_name add_name };
+allow mailman_mail_t var_run_t:file { getattr read create unlink ioctl append };
+
+#============= named_t ==============
+allow named_t mysqld_db_t:dir search;
+allow named_t mysqld_etc_t:file { read getattr };
+
+#============= nscd_t ==============
+allow nscd_t useradd_t:unix_stream_socket { read write };
+
+#============= postfix_bounce_t ==============
+allow postfix_bounce_t initrc_t:unix_stream_socket connectto;
+allow postfix_bounce_t mysqld_db_t:dir search;
+allow postfix_bounce_t mysqld_etc_t:file { read getattr };
+allow postfix_bounce_t mysqld_t:unix_stream_socket connectto;
+allow postfix_bounce_t mysqld_var_run_t:sock_file write;
+
+#============= postfix_cleanup_t ==============
+allow postfix_cleanup_t initrc_t:unix_stream_socket connectto;
+allow postfix_cleanup_t mysqld_db_t:dir search;
+allow postfix_cleanup_t mysqld_etc_t:file { read getattr };
+allow postfix_cleanup_t mysqld_t:unix_stream_socket connectto;
+allow postfix_cleanup_t mysqld_var_run_t:sock_file write;
+allow postfix_cleanup_t usr_t:file { read getattr };
+
+#============= postfix_master_t ==============
+allow postfix_master_t initrc_t:unix_stream_socket connectto;
+allow postfix_master_t mysqld_etc_t:file { read getattr };
+
+#============= postfix_pickup_t ==============
+allow postfix_pickup_t initrc_t:unix_stream_socket connectto;
+allow postfix_pickup_t mysqld_db_t:dir search;
+allow postfix_pickup_t mysqld_etc_t:file { read getattr };
+allow postfix_pickup_t mysqld_var_run_t:sock_file write;
+
+#============= postfix_qmgr_t ==============
+allow postfix_qmgr_t initrc_t:unix_stream_socket connectto;
+allow postfix_qmgr_t mysqld_db_t:dir search;
+allow postfix_qmgr_t mysqld_etc_t:file getattr;
+
+#============= postfix_smtp_t ==============
+allow postfix_smtp_t initrc_t:unix_stream_socket connectto;
+allow postfix_smtp_t mysqld_db_t:dir search;
+allow postfix_smtp_t mysqld_etc_t:file { read getattr };
+allow postfix_smtp_t mysqld_t:unix_stream_socket connectto;
+allow postfix_smtp_t mysqld_var_run_t:sock_file write;
+allow postfix_smtp_t usr_t:file { read getattr };
+
+#============= postfix_smtpd_t ==============
+allow postfix_smtpd_t initrc_t:unix_stream_socket connectto;
+allow postfix_smtpd_t mysqld_db_t:dir search;
+allow postfix_smtpd_t mysqld_etc_t:file { read getattr };
+allow postfix_smtpd_t mysqld_t:unix_stream_socket connectto;
+allow postfix_smtpd_t mysqld_var_run_t:sock_file write;
+
+#============= semanage_t ==============
+allow semanage_t httpd_sys_content_t:lnk_file read;
+allow semanage_t initrc_t:unix_stream_socket connectto;
+allow semanage_t mysqld_t:unix_stream_socket connectto;
+allow semanage_t mysqld_var_run_t:sock_file write;
+
+#============= setroubleshootd_t ==============
+allow setroubleshootd_t httpd_sys_content_t:lnk_file read;
+
+#============= system_dbusd_t ==============
+allow system_dbusd_t initrc_t:unix_stream_socket connectto;
+allow system_dbusd_t mysqld_t:unix_stream_socket connectto;
+allow system_dbusd_t mysqld_var_run_t:sock_file write;
+
+#============= system_mail_t ==============
+allow system_mail_t crond_t:unix_stream_socket { read write };
+allow system_mail_t httpd_t:file read;
+allow system_mail_t initrc_t:unix_stream_socket connectto;
+
+#============= xfs_t ==============
+allow xfs_t mysqld_t:unix_stream_socket connectto;
diff --git a/plugins/coclico/forumml/selinux/forumml4.pp b/plugins/coclico/forumml/selinux/forumml4.pp
new file mode 100644
index 0000000000..5085c6ea89
Binary files /dev/null and b/plugins/coclico/forumml/selinux/forumml4.pp differ
diff --git a/plugins/coclico/forumml/selinux/forumml4.te b/plugins/coclico/forumml/selinux/forumml4.te
new file mode 100644
index 0000000000..d732923fe8
--- /dev/null
+++ b/plugins/coclico/forumml/selinux/forumml4.te
@@ -0,0 +1,158 @@
+
+module forumml4 1.0;
+
+require {
+ type mailman_mail_t;
+ type unconfined_t;
+ type semanage_t;
+ type usr_t;
+ type var_run_t;
+ type postfix_smtpd_t;
+ type xfs_t;
+ type initrc_t;
+ type system_dbusd_t;
+ type tmp_t;
+ type mysqld_etc_t;
+ type avahi_t;
+ type mysqld_db_t;
+ type httpd_sys_content_t;
+ type logwatch_t;
+ type postfix_smtp_t;
+ type postfix_bounce_t;
+ type ifconfig_t;
+ type lib_t;
+ type mysqld_var_run_t;
+ type nscd_t;
+ type useradd_t;
+ type mysqld_t;
+ type named_t;
+ type postfix_cleanup_t;
+ type postfix_master_t;
+ type setroubleshootd_t;
+ type postfix_pickup_t;
+ type groupadd_t;
+ type crond_t;
+ type system_mail_t;
+ type postfix_qmgr_t;
+ type httpd_t;
+ class fifo_file { write read ioctl getattr };
+ class process signal;
+ class unix_stream_socket { connectto read write };
+ class tcp_socket { read write };
+ class file { execute read create ioctl execute_no_trans write getattr unlink append };
+ class sock_file write;
+ class lnk_file { read getattr };
+ class dir { write search getattr read remove_name add_name };
+}
+
+#============= avahi_t ==============
+allow avahi_t mysqld_db_t:dir search;
+allow avahi_t mysqld_etc_t:file getattr;
+
+#============= groupadd_t ==============
+allow groupadd_t initrc_t:unix_stream_socket connectto;
+
+#============= httpd_t ==============
+allow httpd_t crond_t:unix_stream_socket { read write };
+allow httpd_t initrc_t:unix_stream_socket connectto;
+allow httpd_t mysqld_etc_t:file { read getattr };
+allow httpd_t system_mail_t:process signal;
+allow httpd_t tmp_t:file { read getattr };
+allow httpd_t unconfined_t:unix_stream_socket { read write };
+allow httpd_t usr_t:file { create unlink append };
+
+#============= ifconfig_t ==============
+allow ifconfig_t initrc_t:tcp_socket { read write };
+
+#============= logwatch_t ==============
+allow logwatch_t initrc_t:unix_stream_socket connectto;
+allow logwatch_t mysqld_etc_t:file read;
+allow logwatch_t mysqld_t:unix_stream_socket connectto;
+
+#============= mailman_mail_t ==============
+allow mailman_mail_t httpd_sys_content_t:dir { read write search getattr };
+allow mailman_mail_t httpd_sys_content_t:file { read getattr };
+allow mailman_mail_t httpd_sys_content_t:lnk_file { read getattr };
+allow mailman_mail_t initrc_t:unix_stream_socket connectto;
+allow mailman_mail_t lib_t:dir { write remove_name add_name };
+allow mailman_mail_t lib_t:file { write create unlink };
+allow mailman_mail_t self:fifo_file { write read ioctl getattr };
+allow mailman_mail_t tmp_t:file { read getattr };
+allow mailman_mail_t usr_t:file { read getattr ioctl execute execute_no_trans };
+allow mailman_mail_t usr_t:lnk_file { read getattr };
+allow mailman_mail_t var_run_t:dir { write remove_name add_name };
+allow mailman_mail_t var_run_t:file { getattr read create unlink ioctl append };
+
+#============= named_t ==============
+allow named_t mysqld_db_t:dir search;
+allow named_t mysqld_etc_t:file { read getattr };
+
+#============= nscd_t ==============
+allow nscd_t useradd_t:unix_stream_socket { read write };
+
+#============= postfix_bounce_t ==============
+allow postfix_bounce_t initrc_t:unix_stream_socket connectto;
+allow postfix_bounce_t mysqld_db_t:dir search;
+allow postfix_bounce_t mysqld_etc_t:file { read getattr };
+allow postfix_bounce_t mysqld_t:unix_stream_socket connectto;
+allow postfix_bounce_t mysqld_var_run_t:sock_file write;
+
+#============= postfix_cleanup_t ==============
+allow postfix_cleanup_t initrc_t:unix_stream_socket connectto;
+allow postfix_cleanup_t mysqld_db_t:dir search;
+allow postfix_cleanup_t mysqld_etc_t:file { read getattr };
+allow postfix_cleanup_t mysqld_t:unix_stream_socket connectto;
+allow postfix_cleanup_t mysqld_var_run_t:sock_file write;
+allow postfix_cleanup_t usr_t:file { read getattr };
+
+#============= postfix_master_t ==============
+allow postfix_master_t initrc_t:unix_stream_socket connectto;
+allow postfix_master_t mysqld_etc_t:file { read getattr };
+
+#============= postfix_pickup_t ==============
+allow postfix_pickup_t initrc_t:unix_stream_socket connectto;
+allow postfix_pickup_t mysqld_db_t:dir search;
+allow postfix_pickup_t mysqld_etc_t:file { read getattr };
+allow postfix_pickup_t mysqld_var_run_t:sock_file write;
+
+#============= postfix_qmgr_t ==============
+allow postfix_qmgr_t initrc_t:unix_stream_socket connectto;
+allow postfix_qmgr_t mysqld_db_t:dir search;
+allow postfix_qmgr_t mysqld_etc_t:file getattr;
+
+#============= postfix_smtp_t ==============
+allow postfix_smtp_t initrc_t:unix_stream_socket connectto;
+allow postfix_smtp_t mysqld_db_t:dir search;
+allow postfix_smtp_t mysqld_etc_t:file { read getattr };
+allow postfix_smtp_t mysqld_t:unix_stream_socket connectto;
+allow postfix_smtp_t mysqld_var_run_t:sock_file write;
+allow postfix_smtp_t usr_t:file { read getattr };
+
+#============= postfix_smtpd_t ==============
+allow postfix_smtpd_t initrc_t:unix_stream_socket connectto;
+allow postfix_smtpd_t mysqld_db_t:dir search;
+allow postfix_smtpd_t mysqld_etc_t:file { read getattr };
+allow postfix_smtpd_t mysqld_t:unix_stream_socket connectto;
+allow postfix_smtpd_t mysqld_var_run_t:sock_file write;
+
+#============= semanage_t ==============
+allow semanage_t httpd_sys_content_t:lnk_file read;
+allow semanage_t initrc_t:unix_stream_socket connectto;
+allow semanage_t mysqld_t:unix_stream_socket connectto;
+allow semanage_t mysqld_var_run_t:sock_file write;
+
+#============= setroubleshootd_t ==============
+allow setroubleshootd_t httpd_sys_content_t:lnk_file read;
+
+#============= system_dbusd_t ==============
+allow system_dbusd_t initrc_t:unix_stream_socket connectto;
+allow system_dbusd_t mysqld_t:unix_stream_socket connectto;
+allow system_dbusd_t mysqld_var_run_t:sock_file write;
+
+#============= system_mail_t ==============
+allow system_mail_t crond_t:unix_stream_socket { read write };
+allow system_mail_t httpd_t:file read;
+allow system_mail_t initrc_t:unix_stream_socket connectto;
+
+#============= xfs_t ==============
+allow xfs_t mysqld_t:unix_stream_socket connectto;
diff --git a/plugins/coclico/forumml/selinux/forumml5.pp b/plugins/coclico/forumml/selinux/forumml5.pp
new file mode 100644
index 0000000000..c545fc9f87
Binary files /dev/null and b/plugins/coclico/forumml/selinux/forumml5.pp differ
diff --git a/plugins/coclico/forumml/selinux/forumml5.te b/plugins/coclico/forumml/selinux/forumml5.te
new file mode 100644
index 0000000000..c3a7994b15
--- /dev/null
+++ b/plugins/coclico/forumml/selinux/forumml5.te
@@ -0,0 +1,158 @@
+
+module forumml5 1.0;
+
+require {
+ type mailman_mail_t;
+ type unconfined_t;
+ type semanage_t;
+ type usr_t;
+ type var_run_t;
+ type postfix_smtpd_t;
+ type xfs_t;
+ type initrc_t;
+ type system_dbusd_t;
+ type tmp_t;
+ type mysqld_etc_t;
+ type avahi_t;
+ type mysqld_db_t;
+ type httpd_sys_content_t;
+ type logwatch_t;
+ type postfix_smtp_t;
+ type postfix_bounce_t;
+ type ifconfig_t;
+ type lib_t;
+ type mysqld_var_run_t;
+ type nscd_t;
+ type useradd_t;
+ type mysqld_t;
+ type named_t;
+ type postfix_cleanup_t;
+ type postfix_master_t;
+ type setroubleshootd_t;
+ type postfix_pickup_t;
+ type groupadd_t;
+ type crond_t;
+ type system_mail_t;
+ type postfix_qmgr_t;
+ type httpd_t;
+ class fifo_file { write read ioctl getattr };
+ class process signal;
+ class unix_stream_socket { connectto read write };
+ class tcp_socket { read write };
+ class file { execute read create ioctl execute_no_trans write getattr unlink append };
+ class sock_file write;
+ class lnk_file { read getattr };
+ class dir { write search getattr read remove_name add_name };
+}
+
+#============= avahi_t ==============
+allow avahi_t mysqld_db_t:dir search;
+allow avahi_t mysqld_etc_t:file getattr;
+
+#============= groupadd_t ==============
+allow groupadd_t initrc_t:unix_stream_socket connectto;
+
+#============= httpd_t ==============
+allow httpd_t crond_t:unix_stream_socket { read write };
+allow httpd_t initrc_t:unix_stream_socket connectto;
+allow httpd_t mysqld_etc_t:file { read getattr };
+allow httpd_t system_mail_t:process signal;
+allow httpd_t tmp_t:file { read getattr };
+allow httpd_t unconfined_t:unix_stream_socket { read write };
+allow httpd_t usr_t:file { create unlink append };
+
+#============= ifconfig_t ==============
+allow ifconfig_t initrc_t:tcp_socket { read write };
+
+#============= logwatch_t ==============
+allow logwatch_t initrc_t:unix_stream_socket connectto;
+allow logwatch_t mysqld_etc_t:file read;
+allow logwatch_t mysqld_t:unix_stream_socket connectto;
+
+#============= mailman_mail_t ==============
+allow mailman_mail_t httpd_sys_content_t:dir { read write search getattr add_name };
+allow mailman_mail_t httpd_sys_content_t:file { read getattr };
+allow mailman_mail_t httpd_sys_content_t:lnk_file { read getattr };
+allow mailman_mail_t initrc_t:unix_stream_socket connectto;
+allow mailman_mail_t lib_t:dir { write remove_name add_name };
+allow mailman_mail_t lib_t:file { write create unlink };
+allow mailman_mail_t self:fifo_file { write read ioctl getattr };
+allow mailman_mail_t tmp_t:file { read getattr };
+allow mailman_mail_t usr_t:file { read getattr ioctl execute execute_no_trans };
+allow mailman_mail_t usr_t:lnk_file { read getattr };
+allow mailman_mail_t var_run_t:dir { write remove_name add_name };
+allow mailman_mail_t var_run_t:file { getattr read create unlink ioctl append };
+
+#============= named_t ==============
+allow named_t mysqld_db_t:dir search;
+allow named_t mysqld_etc_t:file { read getattr };
+
+#============= nscd_t ==============
+allow nscd_t useradd_t:unix_stream_socket { read write };
+
+#============= postfix_bounce_t ==============
+allow postfix_bounce_t initrc_t:unix_stream_socket connectto;
+allow postfix_bounce_t mysqld_db_t:dir search;
+allow postfix_bounce_t mysqld_etc_t:file { read getattr };
+allow postfix_bounce_t mysqld_t:unix_stream_socket connectto;
+allow postfix_bounce_t mysqld_var_run_t:sock_file write;
+
+#============= postfix_cleanup_t ==============
+allow postfix_cleanup_t initrc_t:unix_stream_socket connectto;
+allow postfix_cleanup_t mysqld_db_t:dir search;
+allow postfix_cleanup_t mysqld_etc_t:file { read getattr };
+allow postfix_cleanup_t mysqld_t:unix_stream_socket connectto;
+allow postfix_cleanup_t mysqld_var_run_t:sock_file write;
+allow postfix_cleanup_t usr_t:file { read getattr };
+
+#============= postfix_master_t ==============
+allow postfix_master_t initrc_t:unix_stream_socket connectto;
+allow postfix_master_t mysqld_etc_t:file { read getattr };
+
+#============= postfix_pickup_t ==============
+allow postfix_pickup_t initrc_t:unix_stream_socket connectto;
+allow postfix_pickup_t mysqld_db_t:dir search;
+allow postfix_pickup_t mysqld_etc_t:file { read getattr };
+allow postfix_pickup_t mysqld_var_run_t:sock_file write;
+
+#============= postfix_qmgr_t ==============
+allow postfix_qmgr_t initrc_t:unix_stream_socket connectto;
+allow postfix_qmgr_t mysqld_db_t:dir search;
+allow postfix_qmgr_t mysqld_etc_t:file getattr;
+
+#============= postfix_smtp_t ==============
+allow postfix_smtp_t initrc_t:unix_stream_socket connectto;
+allow postfix_smtp_t mysqld_db_t:dir search;
+allow postfix_smtp_t mysqld_etc_t:file { read getattr };
+allow postfix_smtp_t mysqld_t:unix_stream_socket connectto;
+allow postfix_smtp_t mysqld_var_run_t:sock_file write;
+allow postfix_smtp_t usr_t:file { read getattr };
+
+#============= postfix_smtpd_t ==============
+allow postfix_smtpd_t initrc_t:unix_stream_socket connectto;
+allow postfix_smtpd_t mysqld_db_t:dir search;
+allow postfix_smtpd_t mysqld_etc_t:file { read getattr };
+allow postfix_smtpd_t mysqld_t:unix_stream_socket connectto;
+allow postfix_smtpd_t mysqld_var_run_t:sock_file write;
+
+#============= semanage_t ==============
+allow semanage_t httpd_sys_content_t:lnk_file read;
+allow semanage_t initrc_t:unix_stream_socket connectto;
+allow semanage_t mysqld_t:unix_stream_socket connectto;
+allow semanage_t mysqld_var_run_t:sock_file write;
+
+#============= setroubleshootd_t ==============
+allow setroubleshootd_t httpd_sys_content_t:lnk_file read;
+
+#============= system_dbusd_t ==============
+allow system_dbusd_t initrc_t:unix_stream_socket connectto;
+allow system_dbusd_t mysqld_t:unix_stream_socket connectto;
+allow system_dbusd_t mysqld_var_run_t:sock_file write;
+
+#============= system_mail_t ==============
+allow system_mail_t crond_t:unix_stream_socket { read write };
+allow system_mail_t httpd_t:file read;
+allow system_mail_t initrc_t:unix_stream_socket connectto;
+
+#============= xfs_t ==============
+allow xfs_t mysqld_t:unix_stream_socket connectto;
diff --git a/plugins/coclico/forumml/selinux/forumml6.pp b/plugins/coclico/forumml/selinux/forumml6.pp
new file mode 100644
index 0000000000..8e86513e10
Binary files /dev/null and b/plugins/coclico/forumml/selinux/forumml6.pp differ
diff --git a/plugins/coclico/forumml/selinux/forumml6.te b/plugins/coclico/forumml/selinux/forumml6.te
new file mode 100644
index 0000000000..23ee0bbdc6
--- /dev/null
+++ b/plugins/coclico/forumml/selinux/forumml6.te
@@ -0,0 +1,158 @@
+
+module forumml6 1.0;
+
+require {
+ type mailman_mail_t;
+ type unconfined_t;
+ type semanage_t;
+ type usr_t;
+ type var_run_t;
+ type postfix_smtpd_t;
+ type xfs_t;
+ type initrc_t;
+ type system_dbusd_t;
+ type tmp_t;
+ type mysqld_etc_t;
+ type avahi_t;
+ type mysqld_db_t;
+ type httpd_sys_content_t;
+ type logwatch_t;
+ type postfix_smtp_t;
+ type postfix_bounce_t;
+ type ifconfig_t;
+ type lib_t;
+ type mysqld_var_run_t;
+ type nscd_t;
+ type useradd_t;
+ type mysqld_t;
+ type named_t;
+ type postfix_cleanup_t;
+ type postfix_master_t;
+ type setroubleshootd_t;
+ type postfix_pickup_t;
+ type groupadd_t;
+ type crond_t;
+ type system_mail_t;
+ type postfix_qmgr_t;
+ type httpd_t;
+ class fifo_file { write read ioctl getattr };
+ class process signal;
+ class unix_stream_socket { connectto read write };
+ class tcp_socket { read write };
+ class file { execute read create ioctl execute_no_trans write getattr unlink append };
+ class sock_file write;
+ class lnk_file { read getattr };
+ class dir { write search getattr read remove_name add_name };
+}
+
+#============= avahi_t ==============
+allow avahi_t mysqld_db_t:dir search;
+allow avahi_t mysqld_etc_t:file getattr;
+
+#============= groupadd_t ==============
+allow groupadd_t initrc_t:unix_stream_socket connectto;
+
+#============= httpd_t ==============
+allow httpd_t crond_t:unix_stream_socket { read write };
+allow httpd_t initrc_t:unix_stream_socket connectto;
+allow httpd_t mysqld_etc_t:file { read getattr };
+allow httpd_t system_mail_t:process signal;
+allow httpd_t tmp_t:file { read getattr };
+allow httpd_t unconfined_t:unix_stream_socket { read write };
+allow httpd_t usr_t:file { create unlink append };
+
+#============= ifconfig_t ==============
+allow ifconfig_t initrc_t:tcp_socket { read write };
+
+#============= logwatch_t ==============
+allow logwatch_t initrc_t:unix_stream_socket connectto;
+allow logwatch_t mysqld_etc_t:file read;
+allow logwatch_t mysqld_t:unix_stream_socket connectto;
+
+#============= mailman_mail_t ==============
+allow mailman_mail_t httpd_sys_content_t:dir { read write search getattr add_name };
+allow mailman_mail_t httpd_sys_content_t:file { read getattr create };
+allow mailman_mail_t httpd_sys_content_t:lnk_file { read getattr };
+allow mailman_mail_t initrc_t:unix_stream_socket connectto;
+allow mailman_mail_t lib_t:dir { write remove_name add_name };
+allow mailman_mail_t lib_t:file { write create unlink };
+allow mailman_mail_t self:fifo_file { write read ioctl getattr };
+allow mailman_mail_t tmp_t:file { read getattr };
+allow mailman_mail_t usr_t:file { read getattr ioctl execute execute_no_trans };
+allow mailman_mail_t usr_t:lnk_file { read getattr };
+allow mailman_mail_t var_run_t:dir { write remove_name add_name };
+allow mailman_mail_t var_run_t:file { getattr read create unlink ioctl append };
+
+#============= named_t ==============
+allow named_t mysqld_db_t:dir search;
+allow named_t mysqld_etc_t:file { read getattr };
+
+#============= nscd_t ==============
+allow nscd_t useradd_t:unix_stream_socket { read write };
+
+#============= postfix_bounce_t ==============
+allow postfix_bounce_t initrc_t:unix_stream_socket connectto;
+allow postfix_bounce_t mysqld_db_t:dir search;
+allow postfix_bounce_t mysqld_etc_t:file { read getattr };
+allow postfix_bounce_t mysqld_t:unix_stream_socket connectto;
+allow postfix_bounce_t mysqld_var_run_t:sock_file write;
+
+#============= postfix_cleanup_t ==============
+allow postfix_cleanup_t initrc_t:unix_stream_socket connectto;
+allow postfix_cleanup_t mysqld_db_t:dir search;
+allow postfix_cleanup_t mysqld_etc_t:file { read getattr };
+allow postfix_cleanup_t mysqld_t:unix_stream_socket connectto;
+allow postfix_cleanup_t mysqld_var_run_t:sock_file write;
+allow postfix_cleanup_t usr_t:file { read getattr };
+
+#============= postfix_master_t ==============
+allow postfix_master_t initrc_t:unix_stream_socket connectto;
+allow postfix_master_t mysqld_etc_t:file { read getattr };
+
+#============= postfix_pickup_t ==============
+allow postfix_pickup_t initrc_t:unix_stream_socket connectto;
+allow postfix_pickup_t mysqld_db_t:dir search;
+allow postfix_pickup_t mysqld_etc_t:file { read getattr };
+allow postfix_pickup_t mysqld_var_run_t:sock_file write;
+
+#============= postfix_qmgr_t ==============
+allow postfix_qmgr_t initrc_t:unix_stream_socket connectto;
+allow postfix_qmgr_t mysqld_db_t:dir search;
+allow postfix_qmgr_t mysqld_etc_t:file getattr;
+
+#============= postfix_smtp_t ==============
+allow postfix_smtp_t initrc_t:unix_stream_socket connectto;
+allow postfix_smtp_t mysqld_db_t:dir search;
+allow postfix_smtp_t mysqld_etc_t:file { read getattr };
+allow postfix_smtp_t mysqld_t:unix_stream_socket connectto;
+allow postfix_smtp_t mysqld_var_run_t:sock_file write;
+allow postfix_smtp_t usr_t:file { read getattr };
+
+#============= postfix_smtpd_t ==============
+allow postfix_smtpd_t initrc_t:unix_stream_socket connectto;
+allow postfix_smtpd_t mysqld_db_t:dir search;
+allow postfix_smtpd_t mysqld_etc_t:file { read getattr };
+allow postfix_smtpd_t mysqld_t:unix_stream_socket connectto;
+allow postfix_smtpd_t mysqld_var_run_t:sock_file write;
+
+#============= semanage_t ==============
+allow semanage_t httpd_sys_content_t:lnk_file read;
+allow semanage_t initrc_t:unix_stream_socket connectto;
+allow semanage_t mysqld_t:unix_stream_socket connectto;
+allow semanage_t mysqld_var_run_t:sock_file write;
+
+#============= setroubleshootd_t ==============
+allow setroubleshootd_t httpd_sys_content_t:lnk_file read;
+
+#============= system_dbusd_t ==============
+allow system_dbusd_t initrc_t:unix_stream_socket connectto;
+allow system_dbusd_t mysqld_t:unix_stream_socket connectto;
+allow system_dbusd_t mysqld_var_run_t:sock_file write;
+
+#============= system_mail_t ==============
+allow system_mail_t crond_t:unix_stream_socket { read write };
+allow system_mail_t httpd_t:file read;
+allow system_mail_t initrc_t:unix_stream_socket connectto;
+
+#============= xfs_t ==============
+allow xfs_t mysqld_t:unix_stream_socket connectto;
diff --git a/plugins/coclico/forumml/selinux/forumml7.pp b/plugins/coclico/forumml/selinux/forumml7.pp
new file mode 100644
index 0000000000..deba6e7011
Binary files /dev/null and b/plugins/coclico/forumml/selinux/forumml7.pp differ
diff --git a/plugins/coclico/forumml/selinux/forumml7.te b/plugins/coclico/forumml/selinux/forumml7.te
new file mode 100644
index 0000000000..4a0608d061
--- /dev/null
+++ b/plugins/coclico/forumml/selinux/forumml7.te
@@ -0,0 +1,158 @@
+
+module forumml7 1.0;
+
+require {
+ type mailman_mail_t;
+ type unconfined_t;
+ type semanage_t;
+ type usr_t;
+ type var_run_t;
+ type postfix_smtpd_t;
+ type xfs_t;
+ type initrc_t;
+ type system_dbusd_t;
+ type tmp_t;
+ type mysqld_etc_t;
+ type avahi_t;
+ type mysqld_db_t;
+ type httpd_sys_content_t;
+ type logwatch_t;
+ type postfix_smtp_t;
+ type postfix_bounce_t;
+ type ifconfig_t;
+ type lib_t;
+ type mysqld_var_run_t;
+ type nscd_t;
+ type useradd_t;
+ type mysqld_t;
+ type named_t;
+ type postfix_cleanup_t;
+ type postfix_master_t;
+ type setroubleshootd_t;
+ type postfix_pickup_t;
+ type groupadd_t;
+ type crond_t;
+ type system_mail_t;
+ type postfix_qmgr_t;
+ type httpd_t;
+ class fifo_file { write read ioctl getattr };
+ class process signal;
+ class unix_stream_socket { connectto read write };
+ class tcp_socket { read write };
+ class file { execute read create ioctl execute_no_trans write getattr unlink append };
+ class sock_file write;
+ class lnk_file { read getattr };
+ class dir { write search getattr read remove_name add_name };
+}
+
+#============= avahi_t ==============
+allow avahi_t mysqld_db_t:dir search;
+allow avahi_t mysqld_etc_t:file getattr;
+
+#============= groupadd_t ==============
+allow groupadd_t initrc_t:unix_stream_socket connectto;
+
+#============= httpd_t ==============
+allow httpd_t crond_t:unix_stream_socket { read write };
+allow httpd_t initrc_t:unix_stream_socket connectto;
+allow httpd_t mysqld_etc_t:file { read getattr };
+allow httpd_t system_mail_t:process signal;
+allow httpd_t tmp_t:file { read getattr };
+allow httpd_t unconfined_t:unix_stream_socket { read write };
+allow httpd_t usr_t:file { create unlink append };
+
+#============= ifconfig_t ==============
+allow ifconfig_t initrc_t:tcp_socket { read write };
+
+#============= logwatch_t ==============
+allow logwatch_t initrc_t:unix_stream_socket connectto;
+allow logwatch_t mysqld_etc_t:file read;
+allow logwatch_t mysqld_t:unix_stream_socket connectto;
+
+#============= mailman_mail_t ==============
+allow mailman_mail_t httpd_sys_content_t:dir { read write search getattr add_name };
+allow mailman_mail_t httpd_sys_content_t:file { read write getattr create };
+allow mailman_mail_t httpd_sys_content_t:lnk_file { read getattr };
+allow mailman_mail_t initrc_t:unix_stream_socket connectto;
+allow mailman_mail_t lib_t:dir { write remove_name add_name };
+allow mailman_mail_t lib_t:file { write create unlink };
+allow mailman_mail_t self:fifo_file { write read ioctl getattr };
+allow mailman_mail_t tmp_t:file { read getattr };
+allow mailman_mail_t usr_t:file { read getattr ioctl execute execute_no_trans };
+allow mailman_mail_t usr_t:lnk_file { read getattr };
+allow mailman_mail_t var_run_t:dir { write remove_name add_name };
+allow mailman_mail_t var_run_t:file { getattr read create unlink ioctl append };
+
+#============= named_t ==============
+allow named_t mysqld_db_t:dir search;
+allow named_t mysqld_etc_t:file { read getattr };
+
+#============= nscd_t ==============
+allow nscd_t useradd_t:unix_stream_socket { read write };
+
+#============= postfix_bounce_t ==============
+allow postfix_bounce_t initrc_t:unix_stream_socket connectto;
+allow postfix_bounce_t mysqld_db_t:dir search;
+allow postfix_bounce_t mysqld_etc_t:file { read getattr };
+allow postfix_bounce_t mysqld_t:unix_stream_socket connectto;
+allow postfix_bounce_t mysqld_var_run_t:sock_file write;
+
+#============= postfix_cleanup_t ==============
+allow postfix_cleanup_t initrc_t:unix_stream_socket connectto;
+allow postfix_cleanup_t mysqld_db_t:dir search;
+allow postfix_cleanup_t mysqld_etc_t:file { read getattr };
+allow postfix_cleanup_t mysqld_t:unix_stream_socket connectto;
+allow postfix_cleanup_t mysqld_var_run_t:sock_file write;
+allow postfix_cleanup_t usr_t:file { read getattr };
+
+#============= postfix_master_t ==============
+allow postfix_master_t initrc_t:unix_stream_socket connectto;
+allow postfix_master_t mysqld_etc_t:file { read getattr };
+
+#============= postfix_pickup_t ==============
+allow postfix_pickup_t initrc_t:unix_stream_socket connectto;
+allow postfix_pickup_t mysqld_db_t:dir search;
+allow postfix_pickup_t mysqld_etc_t:file { read getattr };
+allow postfix_pickup_t mysqld_var_run_t:sock_file write;
+
+#============= postfix_qmgr_t ==============
+allow postfix_qmgr_t initrc_t:unix_stream_socket connectto;
+allow postfix_qmgr_t mysqld_db_t:dir search;
+allow postfix_qmgr_t mysqld_etc_t:file getattr;
+
+#============= postfix_smtp_t ==============
+allow postfix_smtp_t initrc_t:unix_stream_socket connectto;
+allow postfix_smtp_t mysqld_db_t:dir search;
+allow postfix_smtp_t mysqld_etc_t:file { read getattr };
+allow postfix_smtp_t mysqld_t:unix_stream_socket connectto;
+allow postfix_smtp_t mysqld_var_run_t:sock_file write;
+allow postfix_smtp_t usr_t:file { read getattr };
+
+#============= postfix_smtpd_t ==============
+allow postfix_smtpd_t initrc_t:unix_stream_socket connectto;
+allow postfix_smtpd_t mysqld_db_t:dir search;
+allow postfix_smtpd_t mysqld_etc_t:file { read getattr };
+allow postfix_smtpd_t mysqld_t:unix_stream_socket connectto;
+allow postfix_smtpd_t mysqld_var_run_t:sock_file write;
+
+#============= semanage_t ==============
+allow semanage_t httpd_sys_content_t:lnk_file read;
+allow semanage_t initrc_t:unix_stream_socket connectto;
+allow semanage_t mysqld_t:unix_stream_socket connectto;
+allow semanage_t mysqld_var_run_t:sock_file write;
+
+#============= setroubleshootd_t ==============
+allow setroubleshootd_t httpd_sys_content_t:lnk_file read;
+
+#============= system_dbusd_t ==============
+allow system_dbusd_t initrc_t:unix_stream_socket connectto;
+allow system_dbusd_t mysqld_t:unix_stream_socket connectto;
+allow system_dbusd_t mysqld_var_run_t:sock_file write;
+
+#============= system_mail_t ==============
+allow system_mail_t crond_t:unix_stream_socket { read write };
+allow system_mail_t httpd_t:file read;
+allow system_mail_t initrc_t:unix_stream_socket connectto;
+
+#============= xfs_t ==============
+allow xfs_t mysqld_t:unix_stream_socket connectto;
diff --git a/plugins/coclico/forumml/selinux/forumml8.pp b/plugins/coclico/forumml/selinux/forumml8.pp
new file mode 100644
index 0000000000..e5c4390899
Binary files /dev/null and b/plugins/coclico/forumml/selinux/forumml8.pp differ
diff --git a/plugins/coclico/forumml/selinux/forumml8.te b/plugins/coclico/forumml/selinux/forumml8.te
new file mode 100644
index 0000000000..ecda007496
--- /dev/null
+++ b/plugins/coclico/forumml/selinux/forumml8.te
@@ -0,0 +1,109 @@
+
+module forumml8 1.0;
+
+require {
+ type mailman_mail_t;
+ type usr_t;
+ type mysqld_t;
+ type postfix_smtpd_t;
+ type xfs_t;
+ type setroubleshootd_t;
+ type system_dbusd_t;
+ type tmp_t;
+ type mysqld_etc_t;
+ type initrc_t;
+ type mysqld_db_t;
+ type httpd_sys_content_t;
+ type logwatch_t;
+ type postfix_smtp_t;
+ type postfix_bounce_t;
+ type var_run_t;
+ type mysqld_var_run_t;
+ type named_t;
+ type postfix_cleanup_t;
+ type postfix_master_t;
+ type postfix_pickup_t;
+ type system_mail_t;
+ type postfix_qmgr_t;
+ type httpd_t;
+ type avahi_t;
+ class fifo_file { write read getattr ioctl };
+ class process signal;
+ class unix_stream_socket connectto;
+ class file { write getattr read create unlink };
+ class sock_file write;
+ class lnk_file read;
+ class dir { write search read remove_name create add_name };
+}
+
+#============= avahi_t ==============
+allow avahi_t mysqld_db_t:dir search;
+allow avahi_t mysqld_etc_t:file getattr;
+
+#============= httpd_t ==============
+allow httpd_t system_mail_t:process signal;
+
+#============= logwatch_t ==============
+allow logwatch_t initrc_t:unix_stream_socket connectto;
+allow logwatch_t mysqld_etc_t:file read;
+allow logwatch_t mysqld_t:unix_stream_socket connectto;
+
+#============= mailman_mail_t ==============
+allow mailman_mail_t httpd_sys_content_t:dir { read write create add_name };
+allow mailman_mail_t httpd_sys_content_t:file { read write create };
+allow mailman_mail_t httpd_sys_content_t:lnk_file read;
+allow mailman_mail_t self:fifo_file { write read getattr ioctl };
+allow mailman_mail_t tmp_t:file { read getattr };
+allow mailman_mail_t usr_t:file read;
+allow mailman_mail_t var_run_t:dir { write remove_name };
+allow mailman_mail_t var_run_t:file { read unlink };
+
+#============= named_t ==============
+allow named_t mysqld_db_t:dir search;
+allow named_t mysqld_etc_t:file { read getattr };
+
+#============= postfix_bounce_t ==============
+allow postfix_bounce_t initrc_t:unix_stream_socket connectto;
+allow postfix_bounce_t mysqld_db_t:dir search;
+allow postfix_bounce_t mysqld_etc_t:file getattr;
+allow postfix_bounce_t mysqld_t:unix_stream_socket connectto;
+
+#============= postfix_cleanup_t ==============
+allow postfix_cleanup_t initrc_t:unix_stream_socket connectto;
+allow postfix_cleanup_t mysqld_db_t:dir search;
+allow postfix_cleanup_t mysqld_etc_t:file getattr;
+
+#============= postfix_master_t ==============
+allow postfix_master_t initrc_t:unix_stream_socket connectto;
+allow postfix_master_t mysqld_etc_t:file getattr;
+
+#============= postfix_pickup_t ==============
+allow postfix_pickup_t initrc_t:unix_stream_socket connectto;
+allow postfix_pickup_t mysqld_db_t:dir search;
+allow postfix_pickup_t mysqld_etc_t:file { read getattr };
+allow postfix_pickup_t mysqld_var_run_t:sock_file write;
+
+#============= postfix_qmgr_t ==============
+allow postfix_qmgr_t initrc_t:unix_stream_socket connectto;
+allow postfix_qmgr_t mysqld_db_t:dir search;
+allow postfix_qmgr_t mysqld_etc_t:file getattr;
+
+#============= postfix_smtp_t ==============
+allow postfix_smtp_t initrc_t:unix_stream_socket connectto;
+allow postfix_smtp_t mysqld_db_t:dir search;
+allow postfix_smtp_t mysqld_etc_t:file getattr;
+
+#============= postfix_smtpd_t ==============
+allow postfix_smtpd_t initrc_t:unix_stream_socket connectto;
+allow postfix_smtpd_t mysqld_db_t:dir search;
+allow postfix_smtpd_t mysqld_etc_t:file getattr;
+
+#============= setroubleshootd_t ==============
+allow setroubleshootd_t httpd_sys_content_t:lnk_file read;
+
+#============= system_dbusd_t ==============
+allow system_dbusd_t mysqld_t:unix_stream_socket connectto;
+allow system_dbusd_t mysqld_var_run_t:sock_file write;
+
+#============= xfs_t ==============
+allow xfs_t mysqld_t:unix_stream_socket connectto;
diff --git a/plugins/coclico/forumml/site-content/en_US/forumml.tab b/plugins/coclico/forumml/site-content/en_US/forumml.tab
new file mode 100644
index 0000000000..82126c9ed8
--- /dev/null
+++ b/plugins/coclico/forumml/site-content/en_US/forumml.tab
@@ -0,0 +1,100 @@
+#/**
+# *
+# * Plugin forumml scripts message catalog (English)
+# *
+# *
+# * Copyright (c) STMicroelectronics, 2007. All Rights Reserved.
+# *
+# * Originally written by Mohamed CHAARI, 2007. STMicroelectronics.
+# *
+# * This file is a part of codendi.
+# *
+# * codendi is free software; you can redistribute it and/or modify
+# * it under the terms of the GNU General Public License as published by
+# * the Free Software Foundation; either version 2 of the License, or
+# * (at your option) any later version.
+# *
+# * codendi is distributed in the hope that it will be useful,
+# * but WITHOUT ANY WARRANTY; without even the implied warranty of
+# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# * GNU General Public License for more details.
+# *
+# * You should have received a copy of the GNU General Public License
+# * along with codendi; if not, write to the Free Software
+# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+# *
+# *
+# *
+# *
+# */
+#
+#
+#-----------------------------------------------
+# Script:plugins/forumml/www/index.php
+#
+plugin_forumml descriptor_description ForumML provide a nice view of GNU Mailman archives.
+plugin_forumml post Post a New Thread
+plugin_forumml archives Archives
+plugin_forumml browse_arch Browse Archives
+plugin_forumml attach_file Attach file
+plugin_forumml title_root Mailing-List '$1'
+plugin_forumml list_arch Archives
+plugin_forumml list_new_thread Mailing-List '$1' - New Thread
+plugin_forumml new_thread Submit a new Thread:
+plugin_forumml subject_exist Your subject already exist, please Change it...
+plugin_forumml last_by last by
+plugin_forumml subject Subject
+plugin_forumml add_cc Add cc
+plugin_forumml attach Attach:
+plugin_forumml message Message:
+plugin_forumml cc Cc:
+plugin_forumml from From:
+plugin_forumml reply Reply
+plugin_forumml erase Erase
+plugin_forumml wrong_list The mailing-list does not exist or is inactive.
+plugin_forumml specify_list You must specify the mailing-list id.
+plugin_forumml type_subject Submit failed. You must specify the mail subject.
+plugin_forumml email_delay There can be some delay before to see the message in the archives.
+plugin_forumml back_to_list Back to the list
+plugin_forumml warn_permission Please check that you are allowed to post to this list. Otherwise, your message may not be distributed.
+#
+#-----------------------------------------------
+# Script:plugins/forumml/www/message.php
+#
+plugin_forumml post_thread Post a new Thread
+plugin_forumml original_archive Mailman Archives
+plugin_forumml thread Thread
+plugin_forumml submitted_on Submitted on
+plugin_forumml author Author
+plugin_forumml empty_archives Empty Archives
+plugin_forumml search_result Search results for '$1'
+plugin_forumml found thread(s) found
+#
+#-----------------------------------------------
+# Script:plugins/forumml/www/upload.php
+#
+plugin_forumml missing_param Missing 'date' and/or 'filename' parameters.
+plugin_forumml attchment_not_found Attachment not found
+#
+#-----------------------------------------------
+# Script:plugins/forumml/www/forumml_utils.php
+#
+plugin_forumml show_message_from From:
+plugin_forumml show_message_cc Cc:
+plugin_forumml show_message_date on $1
+plugin_forumml show_message_subject Subject:
+plugin_forumml begin First messages
+plugin_forumml previous Previous $1 messages
+plugin_forumml threads Threads
+plugin_forumml next Next $1 messages
+plugin_forumml end Last messages
+plugin_forumml invalid_mail Submit failed. Invalid e-mail address in CC List. '$1'
+plugin_forumml mail_succeed Mail Sent successfully.
+plugin_forumml mail_fail Sending Mail failed.
+plugin_forumml msg_html_format Message (in HTML format)
+plugin_forumml toggle_font Toggle font familly (typewriter/normal)
+#
+#-----------------------------------------------
+# Script:plugins/forumml/include/forummlPlugin.class.php
+#
+plugin_forumml this_list This Mailing-List
diff --git a/plugins/coclico/forumml/site-content/fr_FR/forumml.tab b/plugins/coclico/forumml/site-content/fr_FR/forumml.tab
new file mode 100644
index 0000000000..8cdc89d742
--- /dev/null
+++ b/plugins/coclico/forumml/site-content/fr_FR/forumml.tab
@@ -0,0 +1,100 @@
+#/**
+# *
+# * Plugin forumml scripts message catalog (French)
+# *
+# *
+# * Copyright (c) STMicroelectronics, 2007. All Rights Reserved.
+# *
+# * Originally written by Mohamed CHAARI, 2007. STMicroelectronics.
+# *
+# * This file is a part of codendi.
+# *
+# * codendi is free software; you can redistribute it and/or modify
+# * it under the terms of the GNU General Public License as published by
+# * the Free Software Foundation; either version 2 of the License, or
+# * (at your option) any later version.
+# *
+# * codendi is distributed in the hope that it will be useful,
+# * but WITHOUT ANY WARRANTY; without even the implied warranty of
+# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# * GNU General Public License for more details.
+# *
+# * You should have received a copy of the GNU General Public License
+# * along with codendi; if not, write to the Free Software
+# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+# *
+# *
+# *
+# *
+# */
+#
+#
+#-----------------------------------------------
+# Script:plugins/forumml/www/index.php
+#
+plugin_forumml descriptor_description ForumML fournit une interface plus conviviale pour naviger dans des archives Mailman.
+plugin_forumml post Soumettre un nouveau fil de discussion
+plugin_forumml archives Archives
+plugin_forumml browse_arch Naviguer dans les archives
+plugin_forumml attach_file Attacher un fichier
+plugin_forumml title_root Liste de diffusion '$1'
+plugin_forumml list_arch Archives
+plugin_forumml list_new_thread Liste de diffusion '$1' - Nouveau fil de discussion
+plugin_forumml new_thread Soumettre un nouveau fil de discussion:
+plugin_forumml subject_exist Le sujet choisi existe déjà, veuillez le changer...
+plugin_forumml last_by Dernier auteur
+plugin_forumml subject Sujet
+plugin_forumml add_cc Ajouter Cc
+plugin_forumml attach Attacher:
+plugin_forumml message Message:
+plugin_forumml cc Cc:
+plugin_forumml from Envoyé par:
+plugin_forumml reply Répondre
+plugin_forumml erase Effacer
+plugin_forumml wrong_list Cette liste de diffusion n'existe pas ou bien elle est inactive.
+plugin_forumml specify_list Vous devez spécifier l'identificateur (id) de la liste de diffusion.
+plugin_forumml type_subject L'envoi a échoué. Vous devez spécifier le sujet du mail.
+plugin_forumml email_delay Il peut y avoir un délai avant de le voir apparaître dans les archives.
+plugin_forumml back_to_list Retour àla liste
+plugin_forumml warn_permission Veillez vérifier que vous êtes autorisé àposter dans cette liste, sans quoi votre message pourrait ne pas être distribué
+#
+#-----------------------------------------------
+# Script:plugins/forumml/www/message.php
+#
+plugin_forumml post_thread Soumettre un nouveau fil de discussion
+plugin_forumml original_archive Archives Mailman
+plugin_forumml thread Fil de discussion
+plugin_forumml submitted_on Date
+plugin_forumml author Auteur
+plugin_forumml empty_archives Archives vides
+plugin_forumml search_result Résultat de recherche pour '$1'
+plugin_forumml found Fil(s) trouvé(s)
+#
+#-----------------------------------------------
+# Script:plugins/forumml/www/upload.php
+#
+plugin_forumml missing_param Les paramètres 'date' et/ou 'filename' sont manquants.
+plugin_forumml attchment_not_found Attachement manquant
+#
+#-----------------------------------------------
+# Script:plugins/forumml/www/forumml_utils.php
+#
+plugin_forumml show_message_from De :
+plugin_forumml show_message_cc Cc :
+plugin_forumml show_message_date le $1
+plugin_forumml show_message_subject Sujet :
+plugin_forumml begin Premiers fils
+plugin_forumml previous Les $1 fils précédents
+plugin_forumml threads Fils
+plugin_forumml next Les $1 fils suivants
+plugin_forumml end Derniers fils
+plugin_forumml invalid_mail Echec d'envoi. Adresse courriel en Cc non valide. '$1'
+plugin_forumml mail_succeed E-mail envoyé avec succès.
+plugin_forumml mail_fail Echec d'envoi de l'e-mail.
+plugin_forumml msg_html_format Message (en format HTML)
+plugin_forumml toggle_font Changer la police (courier/normal)
+#
+#-----------------------------------------------
+# Script:plugins/forumml/include/forummlPlugin.class.php
+#
+plugin_forumml this_list Cette Liste
diff --git a/plugins/coclico/forumml/tests/ForumML_FileStorageTest.php b/plugins/coclico/forumml/tests/ForumML_FileStorageTest.php
new file mode 100644
index 0000000000..bae5f68727
--- /dev/null
+++ b/plugins/coclico/forumml/tests/ForumML_FileStorageTest.php
@@ -0,0 +1,185 @@
+_fixture = dirname(__FILE__).'/_fixtures';
+ // validchar for attachment name
+ $this->_namePattern = "`[^a-z0-9_-]`i";
+ }
+
+ private function _deleteIfExists($path) {
+ if (is_dir($path)) {
+ rmdir($path);
+ } elseif (file_exists($path)) {
+ unlink($path);
+ }
+ }
+
+ private function _getFileStorage($path) {
+ $fs = new ForumML_FileStorageTestVersion($this);
+ $fs->root = $path;
+ $fs->setReturnValue('fileExists', false);
+ return $fs;
+ }
+
+ function setUp() {
+ }
+
+ function tearDown() {
+ $this->_deleteIfExists($this->_fixture.'/gpig-interest/2007_10_24/Screenshot_jpg');
+ $this->_deleteIfExists($this->_fixture.'/gpig-interest/2007_10_24');
+ $this->_deleteIfExists($this->_fixture.'/gpig-interest');
+
+ }
+
+ function testForumML_FileStorage() {
+ $fstorage = $this->_getFileStorage($this->_fixture);
+ $this->assertNotNull($fstorage->root);
+ $this->assertIsA($fstorage->root, 'string');
+ $this->assertEqual($fstorage->root,$this->_fixture);
+ $this->assertNoErrors();
+ }
+
+ // case 1: an attachment file whose name has more than 64 characters
+ function test_getPathFileNameWithMoreThan64Char() {
+ $fs1 = $this->_getFileStorage($this->_fixture);
+ $name1 = "a string with more than 64 characters, which is the limit allowed for ForumML attachments";
+ $list1 = "gpig-interest";
+ $date1 = "2007_10_24";
+ $type1 = "store";
+
+ // check returned path
+ $path1 = $fs1->_getPath($name1,$list1,$date1,$type1);
+ $this->assertNotNull($path1);
+ $this->assertIsA($path1, 'string');
+ $this->assertNoErrors();
+ // check filename length is restricted to 64 characters
+ $path_array1 = explode("/",$path1);
+ $fname1 = $path_array1[count($path_array1) - 1];
+ $this->assertNotEqual($name1,$fname1);
+ $this->assertEqual(strlen($fname1),63);
+ // check other path components
+ $flist1 = $path_array1[count($path_array1) - 3];
+ $this->assertEqual($flist1,$list1);
+ $fdate1 = $path_array1[count($path_array1) - 2];
+ $this->assertEqual($fdate1,$date1);
+ // check regexp
+ $this->assertWantedPattern($this->_namePattern,$name1);
+ }
+
+ // case 2: an attachment file whose name has less than 64 characters
+ function test_getPathFileNameWithLessThan64Char() {
+ $fs1 = $this->_getFileStorage($this->_fixture);
+ $name2 = "filename less than 64 chars";
+ $list1 = "gpig-interest";
+ $date1 = "2007_10_24";
+ $type1 = "store";
+
+ $path2 = $fs1->_getPath($name2,$list1,$date1,$type1);
+ $this->assertNotNull($path2);
+ $this->assertIsA($path2, 'string');
+ $this->assertNoErrors();
+ $path_array2 = explode("/",$path2);
+ $fname2 = $path_array2[count($path_array2) - 1];
+ $this->assertEqual($fname2,"filename_less_than_64_chars");
+ $this->assertNotEqual(strlen($fname2),64);
+ // check path components
+ $flist2 = $path_array2[count($path_array2) - 3];
+ $this->assertEqual($flist2,$list1);
+ $fdate2 = $path_array2[count($path_array2) - 2];
+ $this->assertEqual($fdate2,$date1);
+ // check regexp
+ $this->assertWantedPattern($this->_namePattern,$name2);
+ }
+
+ // case 3: attachment filename with only alphanumeric characters
+ function test_getPathFileNameWithAlphaNumCharsOnly() {
+ $fs1 = $this->_getFileStorage($this->_fixture);
+ $name3 = "Cx2008-requirements";
+ $list1 = "gpig-interest";
+ $date1 = "2007_10_24";
+ $type1 = "store";
+
+ $path3 = $fs1->_getPath($name3,$list1,$date1,$type1);
+ $this->assertNotNull($path3);
+ $this->assertIsA($path3, 'string');
+ $this->assertNoErrors();
+ $path_array3 = explode("/",$path3);
+ $fname3 = $path_array3[count($path_array3) - 1];
+ $this->assertNoUnwantedPattern($this->_namePattern,$name3);
+ }
+
+ // case 4: attachment filename is an empty string
+ function test_getPathFileNameEmpty() {
+ $fs1 = $this->_getFileStorage($this->_fixture);
+ $name4 = "";
+ $list1 = "gpig-interest";
+ $date1 = "2007_10_24";
+ $type1 = "store";
+
+ $path4 = $fs1->_getPath($name4,$list1,$date1,$type1);
+ $this->assertNoErrors();
+ $this->assertNotNull($path4);
+ $this->assertIsA($path4, 'string');
+ $path_array4 = explode("/",$path4);
+ $fname4 = $path_array4[count($path_array4) - 1];
+ $this->assertWantedPattern('/^attachment.*/', $fname4);
+ }
+
+ // case 5: same attachment name submitted 2 times same day for same list
+ function testGetPathWithSameFileName() {
+ $fs = new ForumML_FileStorageTestVersion($this);
+ $fs->root = $this->_fixture;
+ $fs->setReturnValueAt(0, 'fileExists', false);
+ $fs->setReturnValueAt(1, 'fileExists', true);
+
+ $list = "gpig-interest";
+ $date = "2007_10_24";
+ $type = "store";
+ $name = 'Screenshot.jpg';
+
+ // First file stored that day
+ $path1 = $fs->_getPath($name,$list,$date,$type);
+
+ // Second file with same name
+ $path2 = $fs->_getPath($name,$list,$date,$type);
+
+ $this->assertNotEqual($path1, $path2);
+ }
+
+}
+
+?>
\ No newline at end of file
diff --git a/plugins/coclico/forumml/tests/ForumML_InsertTest.php b/plugins/coclico/forumml/tests/ForumML_InsertTest.php
new file mode 100644
index 0000000000..0a6e394609
--- /dev/null
+++ b/plugins/coclico/forumml/tests/ForumML_InsertTest.php
@@ -0,0 +1,221 @@
+_fixture = dirname(__FILE__).'/_fixtures/samples';
+ }
+
+
+ function getEmailStructure($path) {
+ $message = file_get_contents($this->_fixture.'/'.$path);
+ $args['include_bodies'] = TRUE;
+ $args['decode_bodies'] = TRUE;
+ $args['decode_headers'] = TRUE;
+ $args['crlf'] = "\r\n";
+ $decoder = new ForumML_mimeDecode($message, "\r\n");
+ $structure = $decoder->decode($args);
+ return $structure;
+ }
+
+ /**
+ * Text only
+ */
+ function testInsertTextOnly() {
+ $structure = $this->getEmailStructure('pure_text.mbox');
+
+ $storage = new MockForumML_FileStorage($this);
+
+ $i = new ForumMLInsertTest($this);
+ $i->setReturnValue('insertMessage', 2);
+
+ $txtBody='Pure text
+';
+ $i->expectOnce('insertMessage', array('*', $txtBody, 'text/plain; charset=ISO-8859-1; format=flowed'));
+ $i->expectNever('insertAttachment');
+
+ $i->storeEmail($structure, $storage);
+ }
+
+ /**
+ * Attachment only
+ */
+ function testInsertAttachmentOnly() {
+ $structure = $this->getEmailStructure('attachment_only.mbox');
+
+ $storage = new MockForumML_FileStorage($this);
+ $storage->setReturnValue('store', '/a/b/c');
+
+ $i = new ForumMLInsertTest($this);
+ $i->setReturnValue('insertMessage', 2);
+
+ $txtBody='
+
+';
+ $i->expectOnce('insertMessage', array('*', $txtBody, 'text/plain; charset=ISO-8859-1; format=flowed'));
+ $i->expectOnce('insertAttachment', array(2, 'lock.png', 'image/png; name="lock.png"', '/a/b/c', ''));
+
+ $i->storeEmail($structure, $storage);
+ }
+
+
+ /**
+ * Text + attachment
+ */
+ function testInsertTextWithAttachment() {
+ $structure = $this->getEmailStructure('text_plus_attachment.mbox');
+
+ $storage = new MockForumML_FileStorage($this);
+ $storage->setReturnValue('store', '/a/b/c');
+
+ $i = new ForumMLInsertTest($this);
+ $i->setReturnValue('insertMessage', 2);
+
+ $txtBody='Some text
+
+';
+ $i->expectOnce('insertMessage', array('*', $txtBody, 'text/plain; charset=ISO-8859-1; format=flowed'));
+ $i->expectOnce('insertAttachment', array(2, 'lock.png', 'image/png; name="lock.png"', '/a/b/c', ''));
+
+ $i->storeEmail($structure, $storage);
+ }
+
+ /**
+ * Pure HTML sent in Text+HTML
+ */
+ function testInsertHTMLInTextHtmlMode() {
+ $structure = $this->getEmailStructure('pure_html_text_plus_html.mbox');
+
+ $storage = new MockForumML_FileStorage($this);
+ $storage->setReturnValue('store', '/a/b/c');
+
+ $i = new ForumMLInsertTest($this);
+ $i->setReturnValue('insertMessage', 2);
+
+ $txtBody='My *fault
+
+*
+
+';
+ $i->expectOnce('insertMessage', array('*', $txtBody, 'text/plain; charset=ISO-8859-1; format=flowed'));
+ $i->expectOnce('insertAttachment', array(2, 'message_4ACB049C.6020506.html', 'text/html; charset=ISO-8859-1', '/a/b/c', ''));
+
+ $i->storeEmail($structure, $storage);
+ }
+
+ /**
+ * Pure HTML sent in HTML Only
+ */
+ function testInsertHTMLInHtmlOnlyMode() {
+ $structure = $this->getEmailStructure('pure_html_in_html_only.mbox');
+
+ $storage = new MockForumML_FileStorage($this);
+ $storage->setReturnValue('store', '/a/b/c');
+
+ $i = new ForumMLInsertTest($this);
+ $i->setReturnValue('insertMessage', 2);
+
+ $i->expectOnce('insertMessage', array('*', '*', 'text/html; charset=ISO-8859-1'));
+ $i->expectNever('insertAttachment');
+
+ $i->storeEmail($structure, $storage);
+ }
+
+ /**
+ * HTML with inline content in Text+HTML mode
+ */
+ function testInsertHtmlWithInlineContentInTextPlusHtml() {
+ $structure = $this->getEmailStructure('html_with_inline_content_in_text_plus_html.mbox');
+
+ $storage = new MockForumML_FileStorage($this);
+ $storage->setReturnValue('store', '/a/b/c');
+
+ $i = new ForumMLInsertTest($this);
+ $i->setReturnValue('insertMessage', 2);
+
+ $txtBody='My *test
+
+*
+
+';
+ $i->expectOnce('insertMessage', array('*', $txtBody, 'text/plain; charset=ISO-8859-1; format=flowed'));
+ $i->expectAt(0, 'insertAttachment', array(2, '*', 'text/html; charset=ISO-8859-1', '/a/b/c', ''));
+ $i->expectAt(1, 'insertAttachment', array(2, 'lock.png', 'image/png; name="lock.png"', '/a/b/c', ''));
+ $i->expectCallCount('insertAttachment', 2);
+
+ $i->storeEmail($structure, $storage);
+ }
+
+ /**
+ * HTML with inline content in HTML Only mode
+ */
+ function testInsertHtmlWithInlineContentInHtmlOnly() {
+ $structure = $this->getEmailStructure('html_with_inline_content_in_html_only.mbox');
+
+ $storage = new MockForumML_FileStorage($this);
+ $storage->setReturnValue('store', '/a/b/c');
+
+ $i = new ForumMLInsertTest($this);
+ $i->setReturnValue('insertMessage', 2);
+
+ $i->expectOnce('insertMessage', array('*', '*', 'text/html; charset=ISO-8859-1'));
+ $i->expectOnce('insertAttachment', array(2, 'attachment', 'image/png', '/a/b/c', ''));
+
+ $i->storeEmail($structure, $storage);
+ }
+
+ function testInsertHtmlWithInlineContentAndAttachmentInTextPlusHtml() {
+ $structure = $this->getEmailStructure('html_with_inline_content_and_attch_in_text_plus_html.mbox');
+
+ $storage = new MockForumML_FileStorage($this);
+ $storage->setReturnValue('store', '/a/b/c');
+
+ $i = new ForumMLInsertTest($this);
+ $i->setReturnValue('insertMessage', 2);
+
+ $txtBody='My *test
+
+*
+
+';
+ $i->expectOnce('insertMessage', array('*', $txtBody, 'text/plain; charset=ISO-8859-1; format=flowed'));
+ $i->expectAt(0, 'insertAttachment', array(2, '*', 'text/html; charset=ISO-8859-1', '/a/b/c', ''));
+ $i->expectAt(1, 'insertAttachment', array(2, 'attachment', 'image/png', '/a/b/c', ''));
+ $i->expectAt(2, 'insertAttachment', array(2, 'new_trk_severity_migr.png', 'image/png; name="new_trk_severity_migr.png"', '/a/b/c', ''));
+ $i->expectCallCount('insertAttachment', 3);
+
+ $i->storeEmail($structure, $storage);
+ }
+
+ function testInsertHtmlWithInlineContentAndAttachmentInHtmlOnly() {
+ $structure = $this->getEmailStructure('html_with_inline_content_and_attch_in_html_only.mbox');
+
+ $storage = new MockForumML_FileStorage($this);
+ $storage->setReturnValue('store', '/a/b/c');
+
+ $i = new ForumMLInsertTest($this);
+ $i->setReturnValue('insertMessage', 2);
+
+ $i->expectOnce('insertMessage', array('*', '*', 'text/html; charset=ISO-8859-1'));
+ $i->expectAt(0, 'insertAttachment', array(2, 'attachment', 'image/png', '/a/b/c', ''));
+ $i->expectAt(1, 'insertAttachment', array(2, 'new_trk_severity_migr.png', 'image/png; name="new_trk_severity_migr.png"', '/a/b/c', ''));
+ $i->expectCallCount('insertAttachment', 2);
+
+ $i->storeEmail($structure, $storage);
+ }
+
+
+
+}
+
+?>
diff --git a/plugins/coclico/forumml/tests/_fixtures/samples/attachment_only.mbox b/plugins/coclico/forumml/tests/_fixtures/samples/attachment_only.mbox
new file mode 100644
index 0000000000..1dedeb7873
--- /dev/null
+++ b/plugins/coclico/forumml/tests/_fixtures/samples/attachment_only.mbox
@@ -0,0 +1,238 @@
+From john.doh@codendi.org Tue Oct 6 13:14:43 2009
+Return-Path:
+X-Original-To: gpig-test@codendi.org
+Delivered-To: gpig-test@codendi.org
+Received: from alpha.codendi.org (ns2.codendi.org [192.168.1.2])
+ by codendi.org (Postfix) with ESMTP id B2FC7AD70A
+ for ;
+ Tue, 6 Oct 2009 13:14:43 +0200 (CEST)
+Received: from mail2.foobar.org (mail2.foobar.org [192.168.1.3])
+ by alpha.codendi.org (FooBar) with ESMTP id 46082AA3
+ for ;
+ Tue, 6 Oct 2009 11:14:43 +0000 (GMT)
+Received: from [192.168.1.4] (yoyo.foobar.org [192.168.1.4])
+ by mail2.foobar.org (MOS 3.8.7a)
+ with ESMTP id CTB94911 (AUTH johndoh);
+ Tue, 6 Oct 2009 13:14:08 +0200 (CEST)
+Message-ID: <4ACB26A3.8010602@codendi.org>
+Date: Tue, 06 Oct 2009 13:14:43 +0200
+From: Manuel VACELET
+User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US;
+ rv:1.8.1.6) Gecko/20070728 Thunderbird/2.0.0.6 Mnenhy/0.7.5.666
+MIME-Version: 1.0
+To: gpig-test@codendi.org
+Content-Type: multipart/mixed; boundary="------------080307020605020807030502"
+Subject: [Gpig-testsabri] attchement only
+X-BeenThere: gpig-test@codendi.org
+X-Mailman-Version: 2.1.9
+Precedence: list
+List-Id:
+List-Unsubscribe: ,
+
+List-Archive:
+List-Post:
+List-Help:
+List-Subscribe: ,
+
+X-List-Received-Date: Tue, 06 Oct 2009 11:14:43 -0000
+
+This is a multi-part message in MIME format.
+--------------080307020605020807030502
+Content-Type: text/plain; charset=ISO-8859-1; format=flowed
+Content-Transfer-Encoding: 7bit
+
+
+
+--------------080307020605020807030502
+Content-Type: image/png;
+ name="lock.png"
+Content-Transfer-Encoding: base64
+Content-Disposition: inline;
+ filename="lock.png"
+
+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
+EoQAAAL4YkJQbolQTkcNChoKAAAADUlIRFIAAADHAAABDggCAAAAsveUWQAAAr9JREFUeNrt
+0kEJADAMwMDVv+mZCBTKnYI8Mg9qsx3AQa6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucq
+eq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLn
+Knquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i
+5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnqu
+oucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6
+rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucq
+eq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLn
+Knquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i
+5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnqu
+oucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6
+rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucq
+eq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLn
+Knquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnofXqoBD6rh
+8GQAAAAASUVORK5CYIJIZtRDAAAAAElFTkSuQmCC
+--------------080307020605020807030502--
diff --git a/plugins/coclico/forumml/tests/_fixtures/samples/html_with_inline_content_and_attch_in_html_only.mbox b/plugins/coclico/forumml/tests/_fixtures/samples/html_with_inline_content_and_attch_in_html_only.mbox
new file mode 100644
index 0000000000..259870d5d9
--- /dev/null
+++ b/plugins/coclico/forumml/tests/_fixtures/samples/html_with_inline_content_and_attch_in_html_only.mbox
@@ -0,0 +1,391 @@
+From john.doh@codendi.org Tue Oct 6 13:45:32 2009
+Return-Path:
+X-Original-To: gpig-test@codendi.org
+Delivered-To: gpig-test@codendi.org
+Received: from alpha.codendi.org (ns2.codendi.org [192.168.1.2])
+ by codendi.org (Postfix) with ESMTP id 469A6AD70A
+ for ;
+ Tue, 6 Oct 2009 13:45:32 +0200 (CEST)
+Received: from mail2.foobar.org (mail2.foobar.org [192.168.1.3])
+ by alpha.codendi.org (FooBar) with ESMTP id 0A2D7AC6
+ for ;
+ Tue, 6 Oct 2009 11:45:32 +0000 (GMT)
+Received: from [192.168.1.4] (yoyo.foobar.org [192.168.1.4])
+ by mail2.foobar.org (MOS 3.8.7a)
+ with ESMTP id CTB95761 (AUTH johndoh);
+ Tue, 6 Oct 2009 13:44:56 +0200 (CEST)
+Message-ID: <4ACB2DDC.1090507@codendi.org>
+Date: Tue, 06 Oct 2009 13:45:32 +0200
+From: Manuel VACELET
+User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US;
+ rv:1.8.1.6) Gecko/20070728 Thunderbird/2.0.0.6 Mnenhy/0.7.5.666
+MIME-Version: 1.0
+To: gpig-test@codendi.org
+Content-Type: multipart/mixed; boundary="------------020002020307040308020901"
+Subject: [Gpig-testsabri] HTML with inline content and attachment in HTML
+ only mode
+X-BeenThere: gpig-test@codendi.org
+X-Mailman-Version: 2.1.9
+Precedence: list
+List-Id:
+List-Unsubscribe: ,
+
+List-Archive:
+List-Post:
+List-Help:
+List-Subscribe: ,
+
+X-List-Received-Date: Tue, 06 Oct 2009 11:45:32 -0000
+
+This is a multi-part message in MIME format.
+--------------020002020307040308020901
+Content-Type: multipart/related;
+ boundary="------------010008070805010506010307"
+
+
+--------------010008070805010506010307
+Content-Type: text/html; charset=ISO-8859-1
+Content-Transfer-Encoding: 7bit
+
+
+
+
+
+
+My test
+
+
+
+
+
+
+--------------010008070805010506010307
+Content-Type: image/png
+Content-Transfer-Encoding: base64
+Content-ID:
+
+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
+EoQAAAL4YkJQbolQTkcNChoKAAAADUlIRFIAAADHAAABDggCAAAAsveUWQAAAr9JREFUeNrt
+0kEJADAMwMDVv+mZCBTKnYI8Mg9qsx3AQa6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucq
+eq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLn
+Knquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i
+5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnqu
+oucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6
+rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucq
+eq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLn
+Knquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i
+5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnqu
+oucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6
+rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucq
+eq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLn
+Knquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnofXqoBD6rh
+8GQAAAAASUVORK5CYIJIZtRDAAAAAElFTkSuQmCC
+--------------010008070805010506010307--
+
+--------------020002020307040308020901
+Content-Type: image/png;
+ name="new_trk_severity_migr.png"
+Content-Transfer-Encoding: base64
+Content-Disposition: inline;
+ filename="new_trk_severity_migr.png"
+
+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
+--------------020002020307040308020901--
diff --git a/plugins/coclico/forumml/tests/_fixtures/samples/html_with_inline_content_and_attch_in_text_plus_html.mbox b/plugins/coclico/forumml/tests/_fixtures/samples/html_with_inline_content_and_attch_in_text_plus_html.mbox
new file mode 100644
index 0000000000..a7d1353208
--- /dev/null
+++ b/plugins/coclico/forumml/tests/_fixtures/samples/html_with_inline_content_and_attch_in_text_plus_html.mbox
@@ -0,0 +1,406 @@
+From john.doh@codendi.org Tue Oct 6 13:44:25 2009
+Return-Path:
+X-Original-To: gpig-test@codendi.org
+Delivered-To: gpig-test@codendi.org
+Received: from alpha.codendi.org (ns2.codendi.org [192.168.1.2])
+ by codendi.org (Postfix) with ESMTP id C1C9CAD70A
+ for ;
+ Tue, 6 Oct 2009 13:44:25 +0200 (CEST)
+Received: from mail2.foobar.org (mail2.foobar.org [192.168.1.3])
+ by alpha.codendi.org (FooBar) with ESMTP id E84AB41E
+ for ;
+ Tue, 6 Oct 2009 11:44:24 +0000 (GMT)
+Received: from [192.168.1.4] (yoyo.foobar.org [192.168.1.4])
+ by mail2.foobar.org (MOS 3.8.7a)
+ with ESMTP id CTB95731 (AUTH johndoh);
+ Tue, 6 Oct 2009 13:43:49 +0200 (CEST)
+Message-ID: <4ACB2D99.3080203@codendi.org>
+Date: Tue, 06 Oct 2009 13:44:25 +0200
+From: Manuel VACELET
+User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US;
+ rv:1.8.1.6) Gecko/20070728 Thunderbird/2.0.0.6 Mnenhy/0.7.5.666
+MIME-Version: 1.0
+To: gpig-test@codendi.org
+Content-Type: multipart/mixed; boundary="------------040401030508020408000101"
+Subject: [Gpig-testsabri] HTML with inline content and attachment in
+ HTML+Text mode
+X-BeenThere: gpig-test@codendi.org
+X-Mailman-Version: 2.1.9
+Precedence: list
+List-Id:
+List-Unsubscribe: ,
+
+List-Archive:
+List-Post:
+List-Help:
+List-Subscribe: ,
+
+X-List-Received-Date: Tue, 06 Oct 2009 11:44:26 -0000
+
+This is a multi-part message in MIME format.
+--------------040401030508020408000101
+Content-Type: multipart/alternative;
+ boundary="------------090705050704060401010401"
+
+
+--------------090705050704060401010401
+Content-Type: text/plain; charset=ISO-8859-1; format=flowed
+Content-Transfer-Encoding: 7bit
+
+My *test
+
+*
+
+--------------090705050704060401010401
+Content-Type: multipart/related;
+ boundary="------------060704030302020603080603"
+
+
+--------------060704030302020603080603
+Content-Type: text/html; charset=ISO-8859-1
+Content-Transfer-Encoding: 7bit
+
+
+
+
+
+
+My test
+
+
+
+
+
+
+--------------060704030302020603080603
+Content-Type: image/png
+Content-Transfer-Encoding: base64
+Content-ID:
+
+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
+EoQAAAL4YkJQbolQTkcNChoKAAAADUlIRFIAAADHAAABDggCAAAAsveUWQAAAr9JREFUeNrt
+0kEJADAMwMDVv+mZCBTKnYI8Mg9qsx3AQa6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucq
+eq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLn
+Knquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i
+5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnqu
+oucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6
+rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucq
+eq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLn
+Knquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i
+5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnqu
+oucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6
+rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucq
+eq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLn
+Knquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnofXqoBD6rh
+8GQAAAAASUVORK5CYIJIZtRDAAAAAElFTkSuQmCC
+--------------060704030302020603080603--
+
+--------------090705050704060401010401--
+
+--------------040401030508020408000101
+Content-Type: image/png;
+ name="new_trk_severity_migr.png"
+Content-Transfer-Encoding: base64
+Content-Disposition: inline;
+ filename="new_trk_severity_migr.png"
+
+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
+--------------040401030508020408000101--
diff --git a/plugins/coclico/forumml/tests/_fixtures/samples/html_with_inline_content_in_html_only.mbox b/plugins/coclico/forumml/tests/_fixtures/samples/html_with_inline_content_in_html_only.mbox
new file mode 100644
index 0000000000..a83336de75
--- /dev/null
+++ b/plugins/coclico/forumml/tests/_fixtures/samples/html_with_inline_content_in_html_only.mbox
@@ -0,0 +1,248 @@
+From john.doh@codendi.org Tue Oct 6 13:38:07 2009
+Return-Path:
+X-Original-To: gpig-test@codendi.org
+Delivered-To: gpig-test@codendi.org
+Received: from alpha.codendi.org (ns2.codendi.org [192.168.1.2])
+ by codendi.org (Postfix) with ESMTP id ACCA5AD70A
+ for ;
+ Tue, 6 Oct 2009 13:38:07 +0200 (CEST)
+Received: from mail2.foobar.org (mail2.foobar.org [192.168.1.3])
+ by alpha.codendi.org (FooBar) with ESMTP id 51FCDAF5
+ for ;
+ Tue, 6 Oct 2009 11:38:07 +0000 (GMT)
+Received: from [192.168.1.4] (yoyo.foobar.org [192.168.1.4])
+ by mail2.foobar.org (MOS 3.8.7a)
+ with ESMTP id CTB95497 (AUTH johndoh);
+ Tue, 6 Oct 2009 13:37:31 +0200 (CEST)
+Message-ID: <4ACB2C1F.8030704@codendi.org>
+Date: Tue, 06 Oct 2009 13:38:07 +0200
+From: Manuel VACELET
+User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US;
+ rv:1.8.1.6) Gecko/20070728 Thunderbird/2.0.0.6 Mnenhy/0.7.5.666
+MIME-Version: 1.0
+To: gpig-test@codendi.org
+Content-Type: multipart/related;
+ boundary="------------000600080502000100090303"
+Subject: [Gpig-testsabri] HTML with inline content in HTML mode
+X-BeenThere: gpig-test@codendi.org
+X-Mailman-Version: 2.1.9
+Precedence: list
+List-Id:
+List-Unsubscribe: ,
+
+List-Archive:
+List-Post:
+List-Help:
+List-Subscribe: ,
+
+X-List-Received-Date: Tue, 06 Oct 2009 11:38:08 -0000
+
+This is a multi-part message in MIME format.
+--------------000600080502000100090303
+Content-Type: text/html; charset=ISO-8859-1
+Content-Transfer-Encoding: 7bit
+
+
+
+
+
+
+My test
+
+
+
+
+
+
+--------------000600080502000100090303
+Content-Type: image/png
+Content-Transfer-Encoding: base64
+Content-ID:
+
+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
+EoQAAAL4YkJQbolQTkcNChoKAAAADUlIRFIAAADHAAABDggCAAAAsveUWQAAAr9JREFUeNrt
+0kEJADAMwMDVv+mZCBTKnYI8Mg9qsx3AQa6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucq
+eq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLn
+Knquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i
+5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnqu
+oucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6
+rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucq
+eq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLn
+Knquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i
+5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnqu
+oucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6
+rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucq
+eq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLn
+Knquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnofXqoBD6rh
+8GQAAAAASUVORK5CYIJIZtRDAAAAAElFTkSuQmCC
+--------------000600080502000100090303--
diff --git a/plugins/coclico/forumml/tests/_fixtures/samples/html_with_inline_content_in_text_plus_html.mbox b/plugins/coclico/forumml/tests/_fixtures/samples/html_with_inline_content_in_text_plus_html.mbox
new file mode 100644
index 0000000000..a523504de1
--- /dev/null
+++ b/plugins/coclico/forumml/tests/_fixtures/samples/html_with_inline_content_in_text_plus_html.mbox
@@ -0,0 +1,265 @@
+From john.doh@codendi.org Tue Oct 6 13:30:52 2009
+Return-Path:
+X-Original-To: gpig-test@codendi.org
+Delivered-To: gpig-test@codendi.org
+Received: from alpha.codendi.org (ns2.codendi.org [192.168.1.2])
+ by codendi.org (Postfix) with ESMTP id 6924DAD70A
+ for ;
+ Tue, 6 Oct 2009 13:30:52 +0200 (CEST)
+Received: from mail2.foobar.org (mail2.foobar.org [192.168.1.3])
+ by alpha.codendi.org (FooBar) with ESMTP id 097BEAD2
+ for ;
+ Tue, 6 Oct 2009 11:30:51 +0000 (GMT)
+Received: from [192.168.1.4] (yoyo.foobar.org [192.168.1.4])
+ by mail2.foobar.org (MOS 3.8.7a)
+ with ESMTP id CTB95305 (AUTH johndoh);
+ Tue, 6 Oct 2009 13:30:16 +0200 (CEST)
+Message-ID: <4ACB2A6C.10802@codendi.org>
+Date: Tue, 06 Oct 2009 13:30:52 +0200
+From: Manuel VACELET
+User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US;
+ rv:1.8.1.6) Gecko/20070728 Thunderbird/2.0.0.6 Mnenhy/0.7.5.666
+MIME-Version: 1.0
+To: gpig-test@codendi.org
+Content-Type: multipart/alternative;
+ boundary="------------010203040608090400030709"
+Subject: [Gpig-testsabri] HTML with inline content in Text+HTML mode
+X-BeenThere: gpig-test@codendi.org
+X-Mailman-Version: 2.1.9
+Precedence: list
+List-Id:
+List-Unsubscribe: ,
+
+List-Archive:
+List-Post:
+List-Help:
+List-Subscribe: ,
+
+X-List-Received-Date: Tue, 06 Oct 2009 11:30:52 -0000
+
+This is a multi-part message in MIME format.
+--------------010203040608090400030709
+Content-Type: text/plain; charset=ISO-8859-1; format=flowed
+Content-Transfer-Encoding: 7bit
+
+My *test
+
+*
+
+--------------010203040608090400030709
+Content-Type: multipart/related;
+ boundary="------------090608030705080500080106"
+
+
+--------------090608030705080500080106
+Content-Type: text/html; charset=ISO-8859-1
+Content-Transfer-Encoding: 7bit
+
+
+
+
+
+
+My test
+
+
+
+
+
+--------------090608030705080500080106
+Content-Type: image/png;
+ name="lock.png"
+Content-Transfer-Encoding: base64
+Content-ID:
+Content-Disposition: inline;
+ filename="lock.png"
+
+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
+EoQAAAL4YkJQbolQTkcNChoKAAAADUlIRFIAAADHAAABDggCAAAAsveUWQAAAr9JREFUeNrt
+0kEJADAMwMDVv+mZCBTKnYI8Mg9qsx3AQa6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucq
+eq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLn
+Knquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i
+5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnqu
+oucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6
+rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucq
+eq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLn
+Knquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i
+5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnqu
+oucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6
+rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucq
+eq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLn
+Knquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnofXqoBD6rh
+8GQAAAAASUVORK5CYIJIZtRDAAAAAElFTkSuQmCC
+--------------090608030705080500080106--
+
+--------------010203040608090400030709--
diff --git a/plugins/coclico/forumml/tests/_fixtures/samples/pure_html_in_html_only.mbox b/plugins/coclico/forumml/tests/_fixtures/samples/pure_html_in_html_only.mbox
new file mode 100644
index 0000000000..40c089cadb
--- /dev/null
+++ b/plugins/coclico/forumml/tests/_fixtures/samples/pure_html_in_html_only.mbox
@@ -0,0 +1,49 @@
+From john.doh@codendi.org Tue Oct 6 13:26:30 2009
+Return-Path:
+X-Original-To: gpig-test@codendi.org
+Delivered-To: gpig-test@codendi.org
+Received: from alpha.codendi.org (ns2.codendi.org [192.168.1.2])
+ by codendi.org (Postfix) with ESMTP id 6255FAD70A
+ for ;
+ Tue, 6 Oct 2009 13:26:30 +0200 (CEST)
+Received: from mail2.foobar.org (mail2.foobar.org [192.168.1.3])
+ by alpha.codendi.org (FooBar) with ESMTP id E7A72AC1
+ for ;
+ Tue, 6 Oct 2009 11:26:29 +0000 (GMT)
+Received: from [192.168.1.4] (yoyo.foobar.org [192.168.1.4])
+ by mail2.foobar.org (MOS 3.8.7a)
+ with ESMTP id CTB95171 (AUTH johndoh);
+ Tue, 6 Oct 2009 13:25:54 +0200 (CEST)
+Message-ID: <4ACB2965.7050004@codendi.org>
+Date: Tue, 06 Oct 2009 13:26:29 +0200
+From: Manuel VACELET
+User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US;
+ rv:1.8.1.6) Gecko/20070728 Thunderbird/2.0.0.6 Mnenhy/0.7.5.666
+MIME-Version: 1.0
+To: gpig-test@codendi.org
+Content-Type: text/html; charset=ISO-8859-1
+Content-Transfer-Encoding: 7bit
+Subject: [Gpig-testsabri] HTML only
+X-BeenThere: gpig-test@codendi.org
+X-Mailman-Version: 2.1.9
+Precedence: list
+List-Id:
+List-Unsubscribe: ,
+
+List-Archive:
+List-Post:
+List-Help:
+List-Subscribe: ,
+
+X-List-Received-Date: Tue, 06 Oct 2009 11:26:30 -0000
+
+
+
+
+
+
+My fault
+
+
+
+
diff --git a/plugins/coclico/forumml/tests/_fixtures/samples/pure_html_text_plus_html.mbox b/plugins/coclico/forumml/tests/_fixtures/samples/pure_html_text_plus_html.mbox
new file mode 100644
index 0000000000..08e2283d4c
--- /dev/null
+++ b/plugins/coclico/forumml/tests/_fixtures/samples/pure_html_text_plus_html.mbox
@@ -0,0 +1,64 @@
+From john.doh@codendi.org Tue Oct 6 10:49:32 2009
+Return-Path:
+X-Original-To: gpig-test@codendi.org
+Delivered-To: gpig-test@codendi.org
+Received: from zeta.codendi.org (ns2.codendi.org [192.168.1.2])
+ by codendi.org (Postfix) with ESMTP id 508FEAD70A
+ for ;
+ Tue, 6 Oct 2009 10:49:32 +0200 (CEST)
+Received: from mail2.codendi.org (mail2.codendi.org [192.168.1.3])
+ by alpha.codendi.org (FooBar) with ESMTP id E53E0841
+ for ;
+ Tue, 6 Oct 2009 08:49:31 +0000 (GMT)
+Received: from [192.168.1.5] (toto.codendi.org [192.168.1.4])
+ by mail2.codendi.org (MOS 3.8.7a)
+ with ESMTP id CTB90634 (AUTH johndoh);
+ Tue, 6 Oct 2009 10:48:56 +0200 (CEST)
+Message-ID: <4ACB049C.6020506@codendi.org>
+Date: Tue, 06 Oct 2009 10:49:32 +0200
+From: John DOH
+User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US;
+ rv:1.8.1.6) Gecko/20070728 Thunderbird/2.0.0.6 Mnenhy/0.7.5.666
+MIME-Version: 1.0
+To: gpig-test@codendi.org
+Content-Type: multipart/alternative;
+ boundary="------------010402000506030002060206"
+Subject: [Gpig-test] HTML T+H
+X-BeenThere: gpig-test@codendi.org
+X-Mailman-Version: 2.1.9
+Precedence: list
+List-Id:
+List-Unsubscribe: ,
+
+List-Archive:
+List-Post:
+List-Help:
+List-Subscribe: ,
+
+X-List-Received-Date: Tue, 06 Oct 2009 08:49:32 -0000
+
+This is a multi-part message in MIME format.
+--------------010402000506030002060206
+Content-Type: text/plain; charset=ISO-8859-1; format=flowed
+Content-Transfer-Encoding: 7bit
+
+My *fault
+
+*
+
+--------------010402000506030002060206
+Content-Type: text/html; charset=ISO-8859-1
+Content-Transfer-Encoding: 7bit
+
+
+
+
+
+
+My fault
+
+
+
+
+
+--------------010402000506030002060206--
diff --git a/plugins/coclico/forumml/tests/_fixtures/samples/pure_text.mbox b/plugins/coclico/forumml/tests/_fixtures/samples/pure_text.mbox
new file mode 100644
index 0000000000..869405cb75
--- /dev/null
+++ b/plugins/coclico/forumml/tests/_fixtures/samples/pure_text.mbox
@@ -0,0 +1,40 @@
+From john.doh@codendi.org Tue Oct 6 13:10:02 2009
+Return-Path:
+X-Original-To: gpig-test@codendi.org
+Delivered-To: gpig-test@codendi.org
+Received: from alpha.codendi.org (ns2.codendi.org [192.168.1.2])
+ by codendi.org (Postfix) with ESMTP id 052DFAD70A
+ for ;
+ Tue, 6 Oct 2009 13:10:01 +0200 (CEST)
+Received: from mail2.foobar.org (mail2.foobar.org [192.168.1.3])
+ by alpha.codendi.org (FooBar) with ESMTP id 97F4DA9F
+ for ;
+ Tue, 6 Oct 2009 11:10:01 +0000 (GMT)
+Received: from [192.168.1.4] (yoyo.foobar.org [192.168.1.4])
+ by mail2.foobar.org (MOS 3.8.7a)
+ with ESMTP id CTB94795 (AUTH johndoh);
+ Tue, 6 Oct 2009 13:09:25 +0200 (CEST)
+Message-ID: <4ACB2585.5020501@codendi.org>
+Date: Tue, 06 Oct 2009 13:09:57 +0200
+From: Manuel VACELET
+User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US;
+ rv:1.8.1.6) Gecko/20070728 Thunderbird/2.0.0.6 Mnenhy/0.7.5.666
+MIME-Version: 1.0
+To: gpig-test@codendi.org
+Content-Type: text/plain; charset=ISO-8859-1; format=flowed
+Content-Transfer-Encoding: 7bit
+Subject: [Gpig-testsabri] Test Pure Text
+X-BeenThere: gpig-test@codendi.org
+X-Mailman-Version: 2.1.9
+Precedence: list
+List-Id:
+List-Unsubscribe: ,
+
+List-Archive:
+List-Post:
+List-Help:
+List-Subscribe: ,
+
+X-List-Received-Date: Tue, 06 Oct 2009 11:10:02 -0000
+
+Pure text
diff --git a/plugins/coclico/forumml/tests/_fixtures/samples/text_plus_attachment.mbox b/plugins/coclico/forumml/tests/_fixtures/samples/text_plus_attachment.mbox
new file mode 100644
index 0000000000..749dfd6a46
--- /dev/null
+++ b/plugins/coclico/forumml/tests/_fixtures/samples/text_plus_attachment.mbox
@@ -0,0 +1,238 @@
+From john.doh@codendi.org Tue Oct 6 13:22:47 2009
+Return-Path:
+X-Original-To: gpig-test@codendi.org
+Delivered-To: gpig-test@codendi.org
+Received: from alpha.codendi.org (ns2.codendi.org [192.168.1.2])
+ by codendi.org (Postfix) with ESMTP id 6C634AD70A
+ for ;
+ Tue, 6 Oct 2009 13:22:47 +0200 (CEST)
+Received: from mail2.foobar.org (mail2.foobar.org [192.168.1.3])
+ by alpha.codendi.org (FooBar) with ESMTP id 0FE67AC3
+ for ;
+ Tue, 6 Oct 2009 11:22:46 +0000 (GMT)
+Received: from [192.168.1.4] (yoyo.foobar.org [192.168.1.4])
+ by mail2.foobar.org (MOS 3.8.7a)
+ with ESMTP id CTB95087 (AUTH johndoh);
+ Tue, 6 Oct 2009 13:22:11 +0200 (CEST)
+Message-ID: <4ACB2886.8080300@codendi.org>
+Date: Tue, 06 Oct 2009 13:22:46 +0200
+From: Manuel VACELET
+User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US;
+ rv:1.8.1.6) Gecko/20070728 Thunderbird/2.0.0.6 Mnenhy/0.7.5.666
+MIME-Version: 1.0
+To: gpig-test@codendi.org
+Content-Type: multipart/mixed; boundary="------------000903020203080700000508"
+Subject: [Gpig-testsabri] Text + attachment
+X-BeenThere: gpig-test@codendi.org
+X-Mailman-Version: 2.1.9
+Precedence: list
+List-Id:
+List-Unsubscribe: ,
+
+List-Archive:
+List-Post:
+List-Help:
+List-Subscribe: ,
+
+X-List-Received-Date: Tue, 06 Oct 2009 11:22:47 -0000
+
+This is a multi-part message in MIME format.
+--------------000903020203080700000508
+Content-Type: text/plain; charset=ISO-8859-1; format=flowed
+Content-Transfer-Encoding: 7bit
+
+Some text
+
+--------------000903020203080700000508
+Content-Type: image/png;
+ name="lock.png"
+Content-Transfer-Encoding: base64
+Content-Disposition: inline;
+ filename="lock.png"
+
+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
+EoQAAAL4YkJQbolQTkcNChoKAAAADUlIRFIAAADHAAABDggCAAAAsveUWQAAAr9JREFUeNrt
+0kEJADAMwMDVv+mZCBTKnYI8Mg9qsx3AQa6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucq
+eq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLn
+Knquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i
+5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnqu
+oucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6
+rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucq
+eq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLn
+Knquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i
+5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnqu
+oucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6
+rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucq
+eq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLn
+Knquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnquoucqeq6i5yp6rqLnKnofXqoBD6rh
+8GQAAAAASUVORK5CYIJIZtRDAAAAAElFTkSuQmCC
+--------------000903020203080700000508--
diff --git a/plugins/coclico/forumml/translations/en.po b/plugins/coclico/forumml/translations/en.po
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/plugins/coclico/forumml/translations/gforge.pot b/plugins/coclico/forumml/translations/gforge.pot
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/plugins/coclico/forumml/utils/manage-translations.sh b/plugins/coclico/forumml/utils/manage-translations.sh
new file mode 100755
index 0000000000..9902490044
--- /dev/null
+++ b/plugins/coclico/forumml/utils/manage-translations.sh
@@ -0,0 +1,56 @@
+#! /bin/sh -e
+
+if [ -e gforge/translations/gforge.pot ] ; then # We're in the parent dir
+ cd gforge
+elif [ -e translations/gforge.pot ] ; then # probably in gforge/ (or a renamed gforge/)
+ cd . # do nothing, but shell syntax requires an instruction in a then-block
+elif [ -e ../gforge/translations/gforge.pot ] ; then # in tools/ or tests/ or something
+ cd ../gforge
+elif [ -e ../translations/gforge.pot ] ; then # In a subdir of gforge/
+ cd ..
+else
+ echo "Couldn't find translations directory..."
+ exit 1
+fi
+
+locales=$(ls translations/*.po \
+ | xargs -n1 -iFILE basename FILE .po \
+ | egrep '^[a-z][a-z](_[A-Z][A-Z]$)?' \
+ | sort)
+
+print_stats () {
+ for l in $(echo $locales | xargs -n 1 | sort) ; do
+ printf "* %5s: " $l
+ msgfmt --statistics -o /dev/null translations/$l.po
+ done
+}
+
+case $1 in
+ stats)
+ print_stats
+ ;;
+ refresh)
+ rm translations/gforge.pot
+
+ find -type f -\( -name \*.php -or -name users -or -name projects -\) \
+ | grep -v -e {arch} -e svn-base \
+ | grep -v ^./plugins/wiki \
+ | LANG=C sort \
+ | xargs xgettext -d gforge -o translations/gforge.pot -L PHP --from-code=iso-8859-1
+
+ for l in $locales ; do
+ echo "Processing $l..."
+ msgmerge -U translations/$l.po translations/gforge.pot
+ done
+ ;;
+ build)
+ for l in $locales ; do
+ mkdir -p locales/$l/LC_MESSAGES
+ msgfmt -o locales/$l/LC_MESSAGES/gforge.mo translations/$l.po
+ done
+ ;;
+ *)
+ echo "Unknown operation"
+ exit 1
+ ;;
+esac
diff --git a/plugins/coclico/forumml/www/forumml_utils.php b/plugins/coclico/forumml/www/forumml_utils.php
new file mode 100644
index 0000000000..d014b94ecd
--- /dev/null
+++ b/plugins/coclico/forumml/www/forumml_utils.php
@@ -0,0 +1,742 @@
+getMessageHeaders($id_message)->getRow();
+}
+
+// Display search results
+function plugin_forumml_show_search_results($p,$result,$group_id,$list_id) {
+
+ echo "
+
+ ".
+ _('Thread')."
+
+ ".
+ _('Submitted on')."
+
+ ".
+ _('Author')."
+
+ ";
+
+ $idx = 0;
+ // Build a table full of search results
+ while ($rows = $result->getRow()) {
+ $idx++;
+ if ($idx % 2 == 0) {
+ $class="boxitemalt bgcolor-white";
+ } else {
+ $class="boxitem bgcolor-grey";
+ }
+
+ $res1 = getForumMLDao()->getSpecificMessage($rows['id_message'],$list_id)->getRow();
+ $subject = mb_decode_mimeheader($res1['value']);
+ $res2 = getForumMLDao()->getHeaderValue($rows['id_message'],array(2,3));
+ $k = 1;
+ while ($rows2 =$res2->getRow()) {
+ $header[$k] = $rows2['value'];
+ $k++;
+ }
+ $from = mb_decode_mimeheader($header[1]);
+
+ // Replace '<' by '<' and '>' by '>'. Otherwise the email adress won't be displayed
+ // because it will be considered as an xhtml tag.
+ $from = preg_replace('/\', '<', $from);
+ $from = preg_replace('/\>/', '>', $from);
+
+ $date = date("Y-m-d H:i",strtotime($header[2]));
+ // purify message subject (CODENDI_PURIFIER_FORUMML level)
+ $hp =& ForumML_HTMLPurifier::instance();
+ $subject = $hp->purify($subject,CODENDI_PURIFIER_FORUMML);
+
+ // display the resulting threads in rows
+ printf ("
+
+
+ ".$subject."
+
+
+ ".$date."
+
+
+ ".$from."
+
+ ");
+ }
+ echo "
";
+
+}
+
+// List all threads
+function plugin_forumml_show_all_threads($p,$list_id,$list_name,$offset) {
+
+ $chunks = 30;
+ $request =& HTTPRequest::instance();
+
+ // all threads
+ $result = getForumMLDao()->getAllThreadsFromList($list_id,$offset,$chunks);
+ $nbRowFound = $result->rowCount();
+
+ // Total number of threads
+ $nbThreads = 0;
+$res = getForumMLDao()->countAllThreadsFromList($list_id);
+ if ($res && !db_error($res)) {
+ $row = $res->getRow();
+ $nbThreads = $row['nb'];
+ }
+
+ $start = $offset;
+ $end = min($start + $chunks - 1, $nbRowFound - 1);
+
+ // all threads to be displayed
+ $colspan = "";
+ $item = _('Thread');
+
+ if (isset($offset) && $offset != 0) {
+ $begin = "get('group_id')."&list=".$list_id.
+ "\"> ";
+ $previous = "get('group_id')."&list=".$list_id."&offset=".($offset - $chunks).
+ "\"> ";
+ } else {
+ $begin = " ";
+ $previous = " ";
+ }
+
+ if (($offset + $chunks ) < $nbThreads) {
+ $next = "get('group_id')."&list=".$list_id."&offset=".($offset + $chunks)."\"> ";
+ $finish = "get('group_id')."&list=".$list_id."&offset=".($chunks * (int) (($nbThreads - 1) / $chunks))."\"> ";
+ } else {
+ $next = " ";
+ $finish = " ";
+ }
+
+ // display page-splitting information, at the top of threads table
+ echo "
+
+ ".
+ $begin
+ ."
+ ".
+ $previous
+ ."
+ ".
+ _('Threads')." ".($start + 1)." - ".($end + 1)." (".$nbThreads.")
+
+
+ $next
+
+
+ $finish
+
+
+
";
+
+ if ($nbRowFound > 0) {
+
+ echo "
+
+ ".$item."
+ "._('Last updated')."
+ "._('Submitted on')."
+ "._('Author')."
+ ";
+
+
+
+ $hp =& ForumML_HTMLPurifier::instance();
+ $i = 0;
+ while (($msg = $result->getRow())) {
+ $i++;
+ if ($i % 2 == 0) {
+ $class="boxitemalt bgcolor-white";
+ $headerclass="headerlabelalt";
+ } else {
+ $class="boxitem bgcolor-grey";
+ $headerclass="headerlabel";
+ }
+
+ // Get the number of messages in thread
+ // nb of children + message
+ $count = 1 + plugin_forumml_nb_children(array($msg['id_message']));
+
+
+ // all threads
+ print "
+ ";
+ if ($count > 1) {
+ print " ";
+ }
+ else {
+ print " ";
+ }
+
+ // Remove listname from suject
+ $subject = preg_replace('/^[ ]*\['.$list_name.'\]/i', '', $msg['subject']);
+
+ print "get('list')."'>
+ ".$hp->purify($subject, CODENDI_PURIFIER_CONVERT_HTML)."
+ (".$count.")
+ ".
+ "".strftime("%a, %e %h %G %R",$msg['lastup'])." ".
+ "".strftime("%a, %e %h %G %R",strtotime($msg['date']))."
+ ".$hp->purify($msg['sender'], CODENDI_PURIFIER_CONVERT_HTML)."
+ ";
+ }
+
+ echo '
';
+ // display page-splitting information, at the bottom of threads table
+ echo "
+
+ ".
+ $begin
+ ."
+ ".
+ $previous
+ ."
+ ".
+ _('Threads')." ".($start + 1)." - ".($end + 1)." (".$nbThreads.")
+
+
+ $next
+
+
+ $finish
+
+
+
";
+ }
+
+}
+
+function plugin_forumml_nb_children($parents) {
+ if (count($parents) == 0) {
+ return 0;
+ } else {
+ $result = getForumMLDao()->countChildrenFromParents(implode(',',$parents));
+ if ($result && !$result->isError()) {
+ $p = array();
+ while (($row = $result->getRow())) {
+ $p[] = $row['id_message'];
+ }
+ $num = $result->rowCount();
+ return $num + plugin_forumml_nb_children($p);
+ }
+ }
+}
+
+/**
+ * Extract attachment info from a database result
+ *
+ * @see plugin_forumml_build_flattened_thread
+ */
+function plugin_forumml_new_attach($row) {
+ if (isset($row['id_attachment']) && $row['id_attachment']) {
+ return array('id_attachment' => $row['id_attachment'],
+ 'file_name' => $row['file_name'],
+ 'file_type' => $row['file_type'],
+ 'file_size' =>$row['file_size'],
+ 'file_path' =>$row['file_path'],
+ 'content_id' =>$row['content_id']);
+ } else {
+ return null;
+ }
+}
+
+/**
+ * Insert a message in the thread list with a unique date
+ *
+ * @see plugin_forumml_build_flattened_thread
+ */
+function plugin_forumml_insert_in_thread(&$thread, $row) {
+ $date = strtotime($row['date']);
+ while (isset($thread[$date])) {
+ $date++;
+ }
+ $thread[$date] = $row;
+ return $date;
+}
+
+/**
+ * Insert all messages returned by a SQL query in the thread list with
+ * the attachments
+ *
+ * @see plugin_forumml_build_flattened_thread
+ */
+function plugin_forumml_insert_msg_attach(&$thread, $result) {
+ $parents = array();
+ $prev = -1;
+ while ($row = $result->getRow()) {
+ if ($row['id_message'] != $prev) {
+ // new message
+ $parents[] = $row['id_message'];
+ $curMsg = plugin_forumml_insert_in_thread($thread, $row);
+ $thread[$curMsg]['attachments'] = array();
+ }
+
+ $attch = plugin_forumml_new_attach($row);
+ if ($attch) {
+ $thread[$curMsg]['attachments'][] = $attch;
+ }
+ $prev = $row['id_message'];
+ }
+ return $parents;
+}
+
+/**
+ * Search all chilrens at a given level of depth
+ *
+ * @see plugin_forumml_build_flattened_thread
+ */
+function plugin_forumml_build_flattened_thread_children(&$thread, $parents) {
+ if (count($parents) > 0) {
+ $result = getForumMLDao()->getChildrenFromDepthLevel(implode(',',$parents));
+ if ($result && !$result->isError()){
+ $p = plugin_forumml_insert_msg_attach($thread, $result);
+ plugin_forumml_build_flattened_thread_children($thread, $p);
+ }
+ }
+}
+
+/**
+ * Entry point to create a flattened view of a message thread.
+ *
+ * In order to display the messages in the right order, we fetch the
+ * all the messages with the needed hearders and attachments.
+ * To lower the number of SQL queries, there is 1 query per message
+ * tree depth level.
+ * All the messages are stored in an array indexed by the message
+ * date. If dates conflict we add +1s to the message date.
+ * Once all the messages are fetched, we just sort the array based on
+ * the keys values.
+ * The thread array looks like:
+ * array (
+ * 123342334 => array(
+ * 'message_id' => '1234',
+ * 'subject' => 'toto',
+ * ...
+ * 'attachments' => array(
+ * 'id_attachment' => '5678',
+ * ...
+ * )
+ * ),
+ * ...
+ * );
+ *
+ */
+function plugin_forumml_build_flattened_thread($topic) {
+ $thread = array();
+ $result = getForumMLDao()->getFlattenedThread($topic);
+ if ($result && !$result->isError()) {
+ $p = plugin_forumml_insert_msg_attach($thread, $result);
+ plugin_forumml_build_flattened_thread_children($thread, $p);
+ }
+ ksort($thread, SORT_NUMERIC);
+ return $thread;
+}
+
+// List all messages inside a thread
+function plugin_forumml_show_thread($p, $list_id, $parentId, $purgeCache) {
+ $hp = ForumML_HTMLPurifier::instance();
+ $thread = plugin_forumml_build_flattened_thread($parentId);
+ foreach ($thread as $message) {
+ plugin_forumml_show_message($p, $hp, $message, $parentId, $purgeCache);
+ }
+}
+
+
+// Display a message
+function plugin_forumml_show_message($p, $hp, $msg, $id_parent, $purgeCache) {
+ $body = $msg['body'];
+ $request = HTTPRequest::instance();
+
+ // Is "ready to display" body already in cache or not
+ $bodyIsCached = false;
+ if (isset($msg['cached_html']) && !$purgeCache) {
+ $bodyIsCached = true;
+ }
+
+ if (PEAR::isError($from_info = Mail_RFC822::parseAddressList($msg['sender'], $GLOBALS['sys_default_domain'])) || !isset($from_info[0]) || !$from_info[0]->personal) {
+ $from_info = $hp->purify($msg['sender'], CODENDI_PURIFIER_CONVERT_HTML);
+ } else {
+ $from_info = ''. $hp->purify($from_info[0]->personal, CODENDI_PURIFIER_CONVERT_HTML) .' ';
+ }
+
+ echo '';
+ // specific thread
+ echo '';
+
+ print '
';
+ $body = str_replace("\r\n","\n", $body);
+
+ // If there is no cached html of if user requested to regenerate the cache, do it, otherwise use cached HTML.
+ if (!$bodyIsCached) {
+ // Purify message body, according to the content-type
+ if ($is_html) {
+ // Update attachment links
+ $body = plugin_forumml_replace_attachment($msg['id_message'], $request->get('group_id'), $request->get('list'), $id_parent, $body);
+
+ // Use CODENDI_PURIFIER_FULL for html mails
+ $msg['cached_html'] = $hp->purify($body,CODENDI_PURIFIER_FULL,$request->get('group_id'));
+ } else {
+ // CODENDI_PURIFIER_FORUMML level : no basic html markups, no forms, no javascript,
+ // Allowed: url + automagic links +
+ $purified_body = $hp->purify($body,CODENDI_PURIFIER_CONVERT_HTML,$request->get('group_id'));
+ $purified_body = str_replace('>', '>', $purified_body);
+ $tab_body = '';
+ $level = 0;
+ $current_level = 0;
+ $search_for_quotes = false;
+ $maxi = strlen($purified_body);
+ for($i = 0 ; $i < $maxi ; ++$i) {
+ if ($search_for_quotes) {
+ if($purified_body{$i} == ">") {
+ ++$current_level;
+ if($level < $current_level) {
+ $tab_body .= '';
+ ++$level;
+ }
+ } else {
+ $search_for_quotes = false;
+ if($level > $current_level) {
+ $tab_body .= ' ';
+ --$level;
+ }
+ if($purified_body{$i} == "\n" && $i < $maxi - 1) {
+ $search_for_quotes = true;
+ $current_level = 0;
+ }
+ $tab_body .= $purified_body{$i};
+ }
+ } else {
+ if($purified_body{$i} == "\n" && $i < $maxi - 1) {
+ $search_for_quotes = true;
+ $current_level = 0;
+ }
+ $tab_body .= $purified_body{$i};
+ }
+ }
+ $purified_body = str_replace('>', '>', $purified_body);
+ $msg['cached_html'] = nl2br($tab_body);
+ }
+ getForumMLDao()->updateCacheHTML($msg['cached_html'] , $msg['id_message']);
+ }
+ echo $msg['cached_html'];
+ echo ' ';
+
+ // Reply
+ echo '';
+ echo '
';
+}
+
+// Display the post form under the current post
+function plugin_forumml_reply($hp,$subject,$in_reply_to,$id_parent,$body,$author) {
+
+ $request =& HTTPRequest::instance();
+ $tab_tmp = explode("\n",$body);
+ $tab_tmp = array_pad($tab_tmp,-count($tab_tmp)-1,"$author wrote :");
+
+ echo '';
+ echo ' ";
+}
+
+// Search & replace reference to attached content
+// This happens for images attached to html messages (multipart/related)
+function plugin_forumml_replace_attachment($id_message, $group_id, $list, $id_parent, $body) {
+ if (preg_match_all('/"cid:([^"]*)"/m', $body, $matches)) {
+ $search_parts = array();
+ $replace_parts = array();
+ foreach ($matches[1] as $match) {
+ $result = getForumMLDao()->getAttachment($id_mesage , $match) ;
+ if ($res && $res->rowCount() == 1) {
+ $row = $res->getRow();
+ $url = "upload.php?group_id=".$group_id."&list=".$list."&id=".$row['id_attachment']."&topic=".$id_parent;
+ $search_parts[] = 'cid:'.$match;
+ $replace_parts[] = $url;
+ }
+ }
+ if (count($replace_parts) > 0) {
+ $body = str_replace($search_parts, $replace_parts, $body);
+ }
+}
+return $body;
+}
+
+// Build Mail headers, and send the mail
+function plugin_forumml_process_mail($plug,$reply=false) {
+ global $feedback;
+ $request = HTTPRequest::instance();
+ $hp = ForumML_HTMLPurifier::instance();
+
+ // Instantiate a new Mail class
+ $mail = new Mail();
+
+ // Build mail headers
+ $list = new MailmanList($request->get('group_id') , $request->get('list'));
+ $to = $list->getName()."@".$GLOBALS['sys_lists_host'];
+ $mail->setTo($to);
+
+ $mail->setFrom(UserManager::instance()->getCurrentUser()->getEmail());
+
+ $vMsg = new Valid_Text('message');
+ if ($request->valid($vMsg)) {
+ $message = $request->get('message');
+ }
+
+ $subject = $request->get('subject');
+ $mail->setSubject($subject);
+
+ if ($reply) {
+ // set In-Reply-To header
+ $hres = plugin_forumml_get_message_headers($request->get('reply_to'));
+ $reply_to = $hres['value'];
+ $mail->addAdditionalHeader("In-Reply-To",$reply_to);
+ }
+ $continue = true;
+
+ if ($request->validArray(new Valid_Email('ccs')) && $request->exist('ccs')) {
+ $cc_array = array();
+ $idx = 0;
+ foreach ($request->get('ccs') as $cc) {
+ if (trim($cc) != "") {
+ $cc_array[$idx] = $hp->purify($cc,CODENDI_PURIFIER_FULL);
+ $idx++;
+ }
+ }
+ // Checks sanity of CC List
+ $err = '';
+ $valid=true;
+ foreach ($cc_array as $key => $cc) {
+ $umanager = UserManager::instance();
+ $user = $umanager->existEmail($cc);
+ if (!$user) {
+ $valid = false;
+ $err .= $cc.' ';
+ }
+ }
+ if (!$valid) {
+ $continue=false;
+ $feedback .=_('Invalid email ').$err;
+ } else {
+ // add list of cc users to mail mime
+ if (count($cc_array) > 0) {
+ $cc_list = implode(',',$cc_array);
+ $mail->setCc($cc_list,true);
+ }
+ }
+ }
+
+ if ($continue) {
+ // Process attachments
+
+ // Define boundaries as specified in RFC:
+ // http://www.w3.org/Protocols/rfc1341/7_2_Multipart.html
+ $boundary = '----=_NextPart';
+ $boundaryStart = '--'.$boundary;
+ $boundaryEnd = '--'.$boundary.'--';
+
+ // Attachments headers
+ if (isset($_FILES["files"]) && count($_FILES["files"]['name']) > 0) {
+ $attachment = "";
+ $text = "This is a multi-part message in MIME format.\n";
+ $text = "$boundaryStart\n";
+ $text .= "Content-Type: text/plain; charset=\"UTF-8\"\n";
+ $text .= "Content-Transfer-Encoding: 8bit\n\n";
+ $text .= $message;
+ $text .= "\n\n";
+ foreach($_FILES["files"]['name'] as $i => $fileName) {
+ $attachment .= "$boundaryStart\n";
+ $attachment .= "Content-Type:".$_FILES["files"]["type"][$i]."; name=".$fileName."\n";
+ $attachment .= "Content-Transfer-Encoding: base64\n";
+ $attachment .= "Content-Disposition: attachment; filename=".$fileName."\n\n";
+ $attachment .= chunk_split(base64_encode(file_get_contents($_FILES["files"]["tmp_name"][$i])));
+ }
+ $attachment .= "\n$boundaryEnd\n";
+ $body = $text.$attachment;
+ // force MimeType to multipart/mixed as default (when instantiating new Mail object) is text/plain
+ $mail->setMimeType('multipart/mixed; boundary="'.$boundary.'"');
+ $mail->addAdditionalHeader("MIME-Version","1.0");
+ } else {
+ $body = $message;
+ }
+
+ $mail->setBody($body);
+
+ if ($mail->send()) {
+ $feedback .= _('Mail successfully sent ');
+ } else {
+ $feedback .= _('Sending mail failed');
+ $continue = false;
+ }
+ }
+ return $continue;
+
+}
+?>
diff --git a/plugins/coclico/forumml/www/index.php b/plugins/coclico/forumml/www/index.php
new file mode 100644
index 0000000000..d88b1c261a
--- /dev/null
+++ b/plugins/coclico/forumml/www/index.php
@@ -0,0 +1,137 @@
+getPluginByName('forumml');
+if ($p && $plugin_manager->isPluginAvailable($p) && $p->isAllowed()) {
+
+ $request =& HTTPRequest::instance();
+
+ if ($request->valid(new Valid_UInt('group_id'))) {
+ $group_id = $request->get('group_id');
+ } else {
+ $group_id = "";
+ }
+
+ // Checks 'list' parameter
+ if (! $request->valid(new Valid_UInt('list'))) {
+ exit_error(_('Error'),_('No list specified'));
+ } else {
+ $list_id = $request->get('list');
+$list = new MailmanList($group_id,$list_id);
+ if (!isLogged() || ($list->isPublic()!=1 && !$current_user->isMember($group_id))) {
+ exit_error(_('error'),_('You are not allowed to access this page'));
+ }
+ if ($list->getStatus() !=3) {
+ exit_error(_('Error'),_('The mailing list does not exist or is inactive'));
+ }
+ }
+
+ // If message is posted, send a mail
+ if ($request->isPost() && $request->get('post')) {
+ // Checks if mail subject is empty
+ $vSub = new Valid_String('subject');
+ $vSub->required();
+ if (! $request->valid($vSub)) {
+ $feedback .=_('Submit failed you must specify the mail subject.');
+ } else {
+ // process the mail
+ $return = plugin_forumml_process_mail($p);
+ if ($return) {
+ $feedback .=_('There can be some delay before to see the message in the archives.')._(' Redirecting to archive page, please wait ...');
+ //htmlRedirect('/plugins/forumml/message.php?'. http_build_query(array(
+ // 'group_id' => $group_id,
+ // 'list' => $list_id,
+ //'topic' => 0
+ // )));
+ }
+ }
+ }
+
+ $params['title'] = 'ForumML';
+ $params['group'] = $group_id;
+ $params['toptab'] = 'mail';
+ $params['help'] = "CommunicationServices.html#MailingLists";
+ mailman_header($params);
+
+ if ($request->isPost() && $request->get('post') && $request->valid($vSub)) {
+ if (isset($return) && $return) {
+ // wait few seconds before redirecting to archives page
+ echo "";
+ }
+ }
+
+ $list_link = ''.$list->getName().' ';
+ echo ''._('Mailing List ').$list_link._(' - New Thread').'
+ ['._('Browse Archives').']
+ '._('Submit a new thread').' ';
+
+ // New thread form
+ echo '';
+ echo "
+ ";
+ echo '';
+ echo " ";
+
+ mail_footer($params);
+
+} else {
+ header('Location: '.get_server_url());
+}
+
+?>
diff --git a/plugins/coclico/forumml/www/message.php b/plugins/coclico/forumml/www/message.php
new file mode 100644
index 0000000000..7fe7d99c18
--- /dev/null
+++ b/plugins/coclico/forumml/www/message.php
@@ -0,0 +1,224 @@
+getProject($group_id);
+$plugin_manager =& PluginManager::instance();
+$p =& $plugin_manager->getPluginByName('forumml');
+if ($p && $plugin_manager->isPluginAvailable($p) && $p->isAllowed()) {
+
+ $current_user=UserManager::instance()->getCurrentUser();
+ $request =& HTTPRequest::instance();
+
+ $vGrp = new Valid_UInt('group_id');
+ $vGrp->required();
+ if ($request->valid($vGrp)) {
+ $group_id = $request->get('group_id');
+ } else {
+ $group_id = "";
+ }
+
+ $vTopic = new Valid_UInt('topic');
+ $vTopic->required();
+ if ($request->valid($vTopic)) {
+ $topic = $request->get('topic');
+ $fmlMessageMgr = new ForumML_MessageManager();
+ $topicSubject = $fmlMessageMgr->getHeaderValue($topic, FORUMML_SUBJECT);
+ } else {
+ $topic = 0;
+ $topicSubject = '';
+ }
+
+ $vOff = new Valid_UInt('offset');
+ $vOff->required();
+ if ($request->valid($vOff)) {
+ $offset = $request->get('offset');
+ } else {
+ $offset = 0;
+ }
+
+ // Do we need to pure html cache
+ $vPurge = new Valid_WhiteList('purge_cache', array('true'));
+ $vPurge->required();
+ if ($request->valid($vPurge)) {
+ $purgeCache = true;
+ } else {
+ $purgeCache = false;
+ }
+
+ // Checks 'list' parameter
+ $vList = new Valid_UInt('list');
+ $vList->required();
+ if (! $request->valid($vList)) {
+ exit_error(_('Error'),_('No list specified'));
+ } else {
+ $list_id = $request->get('list');
+ $list = new MailmanList($group_id,$list_id);
+ if (!isLogged() || ($list->isPublic()!=1 && !$current_user->isMember($group_id))) {
+ exit_error(_('error'),_('You are not allowed to access this page'));
+ }
+ if ($list->getStatus() !=3) {
+ exit_error(_('error'),_('This list is not active'));
+ }
+ }
+
+ // If the list is private, search if the current user is a member of that list. If not, permission denied
+ $list_name = $list->getName();
+ if ($list->isPublic()==0) {
+ exec("{$GLOBALS['mailman_bin_dir']}/list_members ".$list_name , $members);
+ $user = $current_user->getEmail();
+ if (! in_array($user,$members)) {
+ exit_permission_denied();
+ }
+ }
+
+ // Build the mail to be sent
+ if ($request->get('send_reply')) {
+ // process the mail
+ $ret = plugin_forumml_process_mail($p,true);
+ if ($ret) {
+ $feedback .=_('Email succefully sent. It can take some time before being displayed');
+ //htmlRedirect('/plugins/forumml/message.php?'. http_build_query(array(
+ // 'group_id' => $group_id,
+ // 'list' => $list_id,
+ // 'topic' => $topic
+ //)));
+ echo "ok";
+ }
+ else { echo "erreur"; }
+ }
+
+ $params['title'] = $Group->getPublicName().' - ForumML - '.$list_name;
+ if ($topicSubject) {
+ $params['title'] .= ' - '.$topicSubject;
+ }
+ $params['group'] = $group_id;
+ $params['toptab']='mail';
+ $params['help'] = "CommunicationServices.html#MailingLists";
+ if ($request->valid(new Valid_Pv('pv'))) {
+ $params['pv'] = $request->get('pv');
+ }
+ mailman_header($params);
+
+ if ($request->get('send_reply') && $request->valid($vTopic)) {
+ if (isset($ret) && $ret) {
+ // wait few seconds before redirecting to archives page
+ echo "";
+ }
+ }
+
+ $list_link = ''.$list_name.' ';
+ $title = _('Mailing List '.$list_link);
+ if ($topic) {
+ $fmlMessageMgr = new ForumML_MessageManager();
+ $value = $fmlMessageMgr->getHeaderValue($topic, FORUMML_SUBJECT);
+ if ($value) {
+ $title = $value;
+ }
+ } else {
+ $title .= _(' Archives');
+ }
+ echo ''.$title.' ';
+
+ if (! $request->exist('pv') || ($request->exist('pv') && $request->get('pv') == 0)) {
+ echo " ";
+ }
+
+ $vSrch = new Valid_String('search');
+ $vSrch->required();
+ if (! $request->valid($vSrch)) {
+ // Check if there are archives to browse
+ $res = getForumMLDao()->hasArchives($list_id);
+ if ($res->rowCount() > 0) {
+ // Call to show_thread() function to display the archives
+ if (isset($topic) && $topic != 0) {
+ // specific thread
+ plugin_forumml_show_thread($p, $list_id, $topic, $purgeCache);
+ } else {
+ plugin_forumml_show_all_threads($p,$list_id,$list_name,$offset);
+ }
+ } else {
+ echo ""._('Empty archives')." ";
+ }
+ } else {
+ // search archives
+ $pattern = "%".$request->get('search')."%";
+ $result = getForumMLDao()->searchArchives($list_id,$pattern);
+ echo ""._('Search result for ').$request->get('search')." (".$result->rowCount()." "._('Thread(s) found').") ";
+ if ($result->rowCount() > 0) {
+ plugin_forumml_show_search_results($p,$result,$group_id,$list_id);
+ }
+ }
+
+ mail_footer($params);
+
+} else {
+ header('Location: '.get_server_url());
+}
+
+?>
diff --git a/plugins/coclico/forumml/www/scripts/cc_attach_js.php b/plugins/coclico/forumml/www/scripts/cc_attach_js.php
new file mode 100644
index 0000000000..e99acf653f
--- /dev/null
+++ b/plugins/coclico/forumml/www/scripts/cc_attach_js.php
@@ -0,0 +1,71 @@
+
+
+function addHeader(cc,file,header_type)
+{
+ var ni = document.getElementById('mail_header');
+ var numi = document.getElementById('header_val');
+ var num = (document.getElementById('header_val').value -1)+ 2;
+ numi.value = num;
+ var divIdName = "mail_header_"+num+"_div";
+ var newdiv = document.createElement('div');
+
+ newdiv.setAttribute("id",divIdName);
+ if (header_type == 1) {
+ newdiv.innerHTML += "";
+ } else {
+ newdiv.innerHTML += "";
+ }
+ ni.appendChild(newdiv);
+}
+
+function removeHeader(divNum)
+{
+ var d = document.getElementById('mail_header');
+ var olddiv = document.getElementById(divNum);
+ d.removeChild(olddiv);
+}
+
+
diff --git a/plugins/coclico/forumml/www/scripts/forumml.js b/plugins/coclico/forumml/www/scripts/forumml.js
new file mode 100644
index 0000000000..46133209ee
--- /dev/null
+++ b/plugins/coclico/forumml/www/scripts/forumml.js
@@ -0,0 +1,53 @@
+/**
+* Copyright (c) STMicroelectronics, 2004-2009. All rights reserved
+*
+* Originally written by Manuel VACELET, 2009
+*
+* This file is a part of Codendi.
+*
+* Codendi is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* Codendi is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with Codendi; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+var codendi = codendi || { };
+
+/**
+ *
+ */
+codendi.PluginForumml = Class.create({
+ initialize: function(element) {
+ // Toggle mail class name when click on the right button
+ element.observe('click', function (event) {
+ var link = Event.element(event);
+ if (link) {
+ var msgId = link.id.replace('plugin_forumml_toogle_msg_', '');
+ var content = $('plugin_forumml_message_content_'+msgId);
+ if (content) {
+ if (content.className == 'plugin_forumml_message_content_pre') {
+ content.className = 'plugin_forumml_message_content_std';
+ } else {
+ content.className = 'plugin_forumml_message_content_pre';
+ }
+ }
+ }
+ event.stop();
+ });
+ },
+});
+
+document.observe('dom:loaded', function() {
+ $$('.plugin_forumml_toggle_font').each(function (elmt) {
+ new codendi.PluginForumml(elmt);
+ });
+});
\ No newline at end of file
diff --git a/plugins/coclico/forumml/www/themes/default/css/style.css b/plugins/coclico/forumml/www/themes/default/css/style.css
new file mode 100644
index 0000000000..95ada01cb4
--- /dev/null
+++ b/plugins/coclico/forumml/www/themes/default/css/style.css
@@ -0,0 +1,110 @@
+/*
+// Copyright (c) STMicroelectronics, 2007. All Rights Reserved.
+// Originally written by Mohamed CHAARI, 2007
+//
+// This file is a part of codendi.
+//
+// codendi is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// codendi is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with codendi; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+*/
+
+
+/* {{{ ForumML */
+th.forumml {
+ background-color: #cdcdc1;
+ text-align: left;
+ font-size: medium;
+}
+
+.subject {font-size: small;}
+.info {font-size: small;}
+
+blockquote.grep {
+ color: #848696;
+ margin: 0;
+ margin-left: 1em;
+ padding: 0;
+ border: 0;
+}
+
+font.headerlabel {
+ color: #83731a;
+}
+
+font.headerlabelalt {
+ color: #8a604a
+}
+
+.plugin_forumml_message {
+ border: 2px solid #cdcdc1;
+ margin-bottom: 1em;
+}
+.plugin_forumml_message_header {
+ color:#999;
+}
+.plugin_forumml_message_header_subject {
+ float:right;
+ padding-right:1em;
+}
+.plugin_forumml_message_header_cc,
+.plugin_forumml_message_header_attachments {
+ padding-left:20px;
+}
+.plugin_forumml_message_header_from {
+ white-space:nowrap;
+ font-size:1.2em;
+ font-weight:bold;
+ color:#666;
+}
+
+.plugin_forumml_toggle_font {
+ font-size: x-small;
+}
+
+.plugin_forumml_message_content_pre {
+ padding: 0.5em;
+ font-family: courier, monospace;
+}
+
+.plugin_forumml_message_content_std {
+ padding: 0.5em;
+}
+
+.plugin_forumml_message_footer {
+ border-top: 1px solid #cdcdc1;
+}
+
+.plugin_forumml_message_reply {
+ padding-left: 1em;
+}
+
+
+.plugin_forumml_message_content_std blockquote, .plugin_forumml_message_content_pre blockquote{
+ border-left:1px solid blue;
+ padding-left:1em;
+ margin-left:0.5em;
+}
+.plugin_forumml_message_content_std blockquote blockquote { border-color:red; }
+.plugin_forumml_message_content_std blockquote blockquote blockquote { border-color:green; }
+.plugin_forumml_message_content_std blockquote blockquote blockquote blockquote { border-color:darkorange; }
+.plugin_forumml_message_content_std blockquote blockquote blockquote blockquote blockquote { border-color:#8A2BE2; }
+
+.plugin_forumml_message_content_pre blockquote blockquote { border-color:red; }
+.plugin_forumml_message_content_pre blockquote blockquote blockquote { border-color:green; }
+.plugin_forumml_message_content_pre blockquote blockquote blockquote blockquote { border-color:darkorange; }
+.plugin_forumml_message_content_pre blockquote blockquote blockquote blockquote blockquote { border-color:#8A2BE2; }
+
+
+/* }}} */
diff --git a/plugins/coclico/forumml/www/themes/default/images/ic/attach.png b/plugins/coclico/forumml/www/themes/default/images/ic/attach.png
new file mode 100644
index 0000000000..ea897cc9f1
Binary files /dev/null and b/plugins/coclico/forumml/www/themes/default/images/ic/attach.png differ
diff --git a/plugins/coclico/forumml/www/themes/default/images/ic/comment.png b/plugins/coclico/forumml/www/themes/default/images/ic/comment.png
new file mode 100644
index 0000000000..7bc9233ea6
Binary files /dev/null and b/plugins/coclico/forumml/www/themes/default/images/ic/comment.png differ
diff --git a/plugins/coclico/forumml/www/themes/default/images/ic/comment_add.png b/plugins/coclico/forumml/www/themes/default/images/ic/comment_add.png
new file mode 100644
index 0000000000..75e78dede2
Binary files /dev/null and b/plugins/coclico/forumml/www/themes/default/images/ic/comment_add.png differ
diff --git a/plugins/coclico/forumml/www/themes/default/images/ic/comments.png b/plugins/coclico/forumml/www/themes/default/images/ic/comments.png
new file mode 100644
index 0000000000..39433cf78a
Binary files /dev/null and b/plugins/coclico/forumml/www/themes/default/images/ic/comments.png differ
diff --git a/plugins/coclico/forumml/www/themes/default/images/ic/msg.png b/plugins/coclico/forumml/www/themes/default/images/ic/msg.png
new file mode 100644
index 0000000000..50cbb6b719
Binary files /dev/null and b/plugins/coclico/forumml/www/themes/default/images/ic/msg.png differ
diff --git a/plugins/coclico/forumml/www/themes/default/images/ic/resultset_first.png b/plugins/coclico/forumml/www/themes/default/images/ic/resultset_first.png
new file mode 100644
index 0000000000..b03eaf8b54
Binary files /dev/null and b/plugins/coclico/forumml/www/themes/default/images/ic/resultset_first.png differ
diff --git a/plugins/coclico/forumml/www/themes/default/images/ic/resultset_first_disabled.png b/plugins/coclico/forumml/www/themes/default/images/ic/resultset_first_disabled.png
new file mode 100644
index 0000000000..44578fe04d
Binary files /dev/null and b/plugins/coclico/forumml/www/themes/default/images/ic/resultset_first_disabled.png differ
diff --git a/plugins/coclico/forumml/www/themes/default/images/ic/resultset_last.png b/plugins/coclico/forumml/www/themes/default/images/ic/resultset_last.png
new file mode 100644
index 0000000000..8ec8947847
Binary files /dev/null and b/plugins/coclico/forumml/www/themes/default/images/ic/resultset_last.png differ
diff --git a/plugins/coclico/forumml/www/themes/default/images/ic/resultset_last_disabled.png b/plugins/coclico/forumml/www/themes/default/images/ic/resultset_last_disabled.png
new file mode 100644
index 0000000000..9cc62ef6ac
Binary files /dev/null and b/plugins/coclico/forumml/www/themes/default/images/ic/resultset_last_disabled.png differ
diff --git a/plugins/coclico/forumml/www/themes/default/images/ic/resultset_next.png b/plugins/coclico/forumml/www/themes/default/images/ic/resultset_next.png
new file mode 100644
index 0000000000..e252606d3e
Binary files /dev/null and b/plugins/coclico/forumml/www/themes/default/images/ic/resultset_next.png differ
diff --git a/plugins/coclico/forumml/www/themes/default/images/ic/resultset_next_disabled.png b/plugins/coclico/forumml/www/themes/default/images/ic/resultset_next_disabled.png
new file mode 100644
index 0000000000..bac339e7ce
Binary files /dev/null and b/plugins/coclico/forumml/www/themes/default/images/ic/resultset_next_disabled.png differ
diff --git a/plugins/coclico/forumml/www/themes/default/images/ic/resultset_previous.png b/plugins/coclico/forumml/www/themes/default/images/ic/resultset_previous.png
new file mode 100644
index 0000000000..18f9cc1094
Binary files /dev/null and b/plugins/coclico/forumml/www/themes/default/images/ic/resultset_previous.png differ
diff --git a/plugins/coclico/forumml/www/themes/default/images/ic/resultset_previous_disabled.png b/plugins/coclico/forumml/www/themes/default/images/ic/resultset_previous_disabled.png
new file mode 100644
index 0000000000..1d7abba3dd
Binary files /dev/null and b/plugins/coclico/forumml/www/themes/default/images/ic/resultset_previous_disabled.png differ
diff --git a/plugins/coclico/forumml/www/themes/default/images/ic/spinner-greenie.gif b/plugins/coclico/forumml/www/themes/default/images/ic/spinner-greenie.gif
new file mode 100644
index 0000000000..9351497e8c
Binary files /dev/null and b/plugins/coclico/forumml/www/themes/default/images/ic/spinner-greenie.gif differ
diff --git a/plugins/coclico/forumml/www/themes/default/images/ic/trash.png b/plugins/coclico/forumml/www/themes/default/images/ic/trash.png
new file mode 100644
index 0000000000..af10be03e0
Binary files /dev/null and b/plugins/coclico/forumml/www/themes/default/images/ic/trash.png differ
diff --git a/plugins/coclico/forumml/www/upload.php b/plugins/coclico/forumml/www/upload.php
new file mode 100644
index 0000000000..408123de81
--- /dev/null
+++ b/plugins/coclico/forumml/www/upload.php
@@ -0,0 +1,92 @@
+getPluginByName('forumml');
+if ($p && $plugin_manager->isPluginAvailable($p) && $p->isAllowed()) {
+ $request = HTTPRequest::instance();
+ $current_user=UserManager::instance()->getCurrentUser();
+ $groupId = $request->getValidated('group_id', 'UInt', 0);
+
+ $vList = new Valid_UInt('list');
+ $vList->required();
+ // Checks 'list' parameter
+ if (! $request->valid($vList)) {
+ exit_error('error','No list specified');
+ } else {
+ $list_id = $request->get('list');
+ $list = new MailmanList($groupId,$list_id);
+ if (!isLogged() || ($list->isPublic()!=1 && !$current_user->isMember($groupId))) {
+ exit_error(_('error'),_('You are not allowed to access this page'));
+ }
+ if ($list->getStatus() !=3) {
+ exit_error(_('error'),_('This list is not active'));
+ }
+ }
+
+ // Topic
+ $vTopic = new Valid_UInt('topic');
+ $vTopic->required();
+ if ($request->valid($vTopic)) {
+ $topic = $request->get('topic');
+ } else {
+ $topic = 0;
+ }
+ $attchmentId = $request->getValidated('id', 'UInt', 0);
+ if ($attchmentId) {
+ $fmlAttch = new ForumML_Attachment();
+ $attch = $fmlAttch->getById($attchmentId);
+echo $attch['file_path'];
+ if ( file_exists($attch['file_path'])) {
+//if (1==1) {
+ header('Content-disposition: filename="'.$attch['file_name'].'"');
+ header("Content-Type: ".$attch['type']);
+ header("Content-Transfer-Encoding: ".$attch['type']);
+ if ($attch['file_size'] > 0) {
+ header("Content-Length: ".$attch['file_size']);
+ }
+ header("Pragma: no-cache");
+ header("Cache-Control: must-revalidate, post-check=0, pre-check=0, public");
+ header("Expires: 0");
+ readfile($attch['file_path']);
+ exit;
+ } else {
+ $feedback.= _('Error : Attachment not found');
+ }
+ } else {
+ $feedback.= _('Error : Missing parameter ');
+ }
+ htmlRedirect('/plugins/forumml/message.php?group_id='.$groupId.'&list='.$list_id.'&topic='.$topic);
+} else {
+ header('Location: '.get_server_url());
+}
+
+?>
diff --git a/plugins/coclico/mailman/README.txt b/plugins/coclico/mailman/README.txt
new file mode 100644
index 0000000000..917f3023b4
--- /dev/null
+++ b/plugins/coclico/mailman/README.txt
@@ -0,0 +1,4 @@
+This is the readme of the plugin.
+You should put here any useful information about
+the plugin : install, configuration, ...
+
diff --git a/plugins/coclico/mailman/bin/db-delete.pl b/plugins/coclico/mailman/bin/db-delete.pl
new file mode 100755
index 0000000000..8aa379c739
--- /dev/null
+++ b/plugins/coclico/mailman/bin/db-delete.pl
@@ -0,0 +1,187 @@
+#!/usr/bin/perl -w
+#
+# Debian-specific script to delete plugin-specific tables
+# Roland Mas
+
+use strict ;
+use diagnostics ;
+
+use DBI ;
+use MIME::Base64 ;
+use HTML::Entities ;
+
+use vars qw/$dbh @reqlist $query/ ;
+use vars qw/$sys_default_domain $sys_cvs_host $sys_download_host
+ $sys_shell_host $sys_users_host $sys_docs_host $sys_lists_host
+ $sys_dns1_host $sys_dns2_host $FTPINCOMING_DIR $FTPFILES_DIR
+ $sys_urlroot $sf_cache_dir $sys_name $sys_themeroot
+ $sys_news_group $sys_dbhost $sys_dbname $sys_dbuser $sys_dbpasswd
+ $sys_ldap_base_dn $sys_ldap_host $admin_login $admin_password
+ $server_admin $domain_name $newsadmin_groupid $statsadmin_groupid
+ $skill_list/ ;
+use vars qw/$pluginname/ ;
+
+sub is_lesser ( $$ ) ;
+sub is_greater ( $$ ) ;
+sub debug ( $ ) ;
+sub parse_sql_file ( $ ) ;
+
+require ("/usr/share/gforge/lib/include.pl") ; # Include a few predefined functions
+require ("/usr/share/gforge/lib/sqlparser.pm") ; # Our magic SQL parser
+
+debug "You'll see some debugging info during this installation." ;
+debug "Do not worry unless told otherwise." ;
+
+&db_connect ;
+
+# debug "Connected to the database OK." ;
+
+$pluginname = "mailman" ;
+
+$dbh->{AutoCommit} = 0;
+$dbh->{RaiseError} = 1;
+eval {
+ my ($sth, @array, $version, $action, $path, $target, $rname) ;
+
+ my $pattern = "plugin_" . $pluginname . '_%' ;
+
+ $query = "SELECT relname FROM pg_class WHERE relname LIKE '$pattern' AND relkind='v'" ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ while (@array = $sth->fetchrow_array ()) {
+ $rname = $array [0] ;
+ &drop_view_if_exists ($rname) ;
+ }
+ $sth->finish () ;
+
+ $query = "SELECT relname FROM pg_class WHERE relname LIKE '$pattern' AND relkind='r'" ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ while (@array = $sth->fetchrow_array ()) {
+ $rname = $array [0] ;
+ &drop_table_if_exists ($rname) ;
+ }
+ $sth->finish () ;
+
+ $query = "SELECT relname FROM pg_class WHERE relname LIKE '$pattern' AND relkind='i'" ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ while (@array = $sth->fetchrow_array ()) {
+ $rname = $array [0] ;
+ &drop_index_if_exists ($rname) ;
+ }
+ $sth->finish () ;
+
+ $query = "SELECT relname FROM pg_class WHERE relname LIKE '$pattern' AND relkind='s'" ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ while (@array = $sth->fetchrow_array ()) {
+ $rname = $array [0] ;
+ &drop_sequence_if_exists ($rname) ;
+ }
+ $sth->finish () ;
+
+ $dbh->commit ();
+
+
+ debug "It seems your database deletion went well and smoothly. That's cool." ;
+ debug "Please enjoy using Debian FusionForge." ;
+
+ # There should be a commit at the end of every block above.
+ # If there is not, then it might be symptomatic of a problem.
+ # For safety, we roll back.
+ $dbh->rollback ();
+};
+
+if ($@) {
+ warn "Transaction aborted because $@" ;
+ debug "Transaction aborted because $@" ;
+ debug "Last SQL query was:\n$query\n(end of query)" ;
+ $dbh->rollback ;
+ debug "Please report this bug on the Debian bug-tracking system." ;
+ debug "Please include the previous messages as well to help debugging." ;
+ debug "You should not worry too much about this," ;
+ debug "your DB is still in a consistent state and should be usable." ;
+ exit 1 ;
+}
+
+$dbh->rollback ;
+$dbh->disconnect ;
+
+sub debug ( $ ) {
+ my $v = shift ;
+ chomp $v ;
+ print STDERR "$v\n" ;
+}
+
+sub drop_table_if_exists ( $ ) {
+ my $tname = shift or die "Not enough arguments" ;
+ $query = "SELECT count(*) FROM pg_class WHERE relname='$tname' AND relkind='r'" ;
+ my $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ my @array = $sth->fetchrow_array () ;
+ $sth->finish () ;
+
+ if ($array [0] != 0) {
+ # debug "Dropping table $tname" ;
+ $query = "DROP TABLE $tname" ;
+ # debug $query ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ $sth->finish () ;
+ }
+}
+
+sub drop_sequence_if_exists ( $ ) {
+ my $sname = shift or die "Not enough arguments" ;
+ $query = "SELECT count(*) FROM pg_class WHERE relname='$sname' AND relkind='S'" ;
+ my $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ my @array = $sth->fetchrow_array () ;
+ $sth->finish () ;
+
+ if ($array [0] != 0) {
+ # debug "Dropping sequence $sname" ;
+ $query = "DROP SEQUENCE $sname" ;
+ # debug $query ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ $sth->finish () ;
+ }
+}
+
+sub drop_index_if_exists ( $ ) {
+ my $iname = shift or die "Not enough arguments" ;
+ $query = "SELECT count(*) FROM pg_class WHERE relname='$iname' AND relkind='i'" ;
+ my $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ my @array = $sth->fetchrow_array () ;
+ $sth->finish () ;
+
+ if ($array [0] != 0) {
+ # debug "Dropping index $iname" ;
+ $query = "DROP INDEX $iname" ;
+ # debug $query ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ $sth->finish () ;
+ }
+}
+
+sub drop_view_if_exists ( $ ) {
+ my $iname = shift or die "Not enough arguments" ;
+ $query = "SELECT count(*) FROM pg_class WHERE relname='$iname' AND relkind='v'" ;
+ my $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ my @array = $sth->fetchrow_array () ;
+ $sth->finish () ;
+
+ if ($array [0] != 0) {
+ # debug "Dropping view $iname" ;
+ $query = "DROP VIEW $iname" ;
+ # debug $query ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ $sth->finish () ;
+ }
+}
diff --git a/plugins/coclico/mailman/bin/db-upgrade.pl b/plugins/coclico/mailman/bin/db-upgrade.pl
new file mode 100755
index 0000000000..2e2e4a5e1f
--- /dev/null
+++ b/plugins/coclico/mailman/bin/db-upgrade.pl
@@ -0,0 +1,301 @@
+#!/usr/bin/perl -w
+#
+# Debian-specific script to upgrade the database between releases
+# Roland Mas
+
+use strict ;
+use diagnostics ;
+
+use DBI ;
+use MIME::Base64 ;
+use HTML::Entities ;
+
+use vars qw/$dbh @reqlist $query/ ;
+use vars qw/$sys_default_domain $sys_cvs_host $sys_download_host
+ $sys_shell_host $sys_users_host $sys_docs_host $sys_lists_host
+ $sys_dns1_host $sys_dns2_host $FTPINCOMING_DIR $FTPFILES_DIR
+ $sys_urlroot $sf_cache_dir $sys_name $sys_themeroot
+ $sys_news_group $sys_dbhost $sys_dbname $sys_dbuser $sys_dbpasswd
+ $sys_ldap_base_dn $sys_ldap_host $admin_login $admin_password
+ $server_admin $domain_name $newsadmin_groupid $statsadmin_groupid
+ $skill_list/ ;
+use vars qw/$pluginname/ ;
+
+sub is_lesser ( $$ ) ;
+sub is_greater ( $$ ) ;
+sub debug ( $ ) ;
+sub parse_sql_file ( $ ) ;
+
+require ("/usr/share/gforge/lib/include.pl") ; # Include a few predefined functions
+require ("/usr/share/gforge/lib/sqlparser.pm") ; # Our magic SQL parser
+
+debug "You'll see some debugging info during this installation." ;
+debug "Do not worry unless told otherwise." ;
+
+&db_connect ;
+
+# debug "Connected to the database OK." ;
+
+$pluginname = "mailman" ;
+
+$dbh->{AutoCommit} = 0;
+$dbh->{RaiseError} = 1;
+eval {
+ my ($sth, @array, $version, $path, $target) ;
+
+ &create_metadata_table ("0") ;
+
+ $version = &get_db_version ;
+ $target = "0.1" ;
+ if (is_lesser $version, $target) {
+ my @filelist = ( "/usr/share/gforge/plugins/$pluginname/db/$pluginname-init.sql" ) ;
+
+ foreach my $file (@filelist) {
+ debug "Processing $file" ;
+ @reqlist = @{ &parse_sql_file ($file) } ;
+
+ foreach my $s (@reqlist) {
+ $query = $s ;
+ # debug $query ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ $sth->finish () ;
+ }
+ }
+ @reqlist = () ;
+
+ &update_db_version ($target) ;
+ debug "Committing." ;
+ $dbh->commit () ;
+ }
+
+# $version = &get_db_version ;
+# $target = "0.2" ;
+# if (is_lesser $version, $target) {
+# debug "Adding local data." ;
+#
+# do "/etc/gforge/local.pl" or die "Cannot read /etc/gforge/local.pl" ;
+#
+# my $ip_address = qx/host $domain_name | awk '{print \}'/ ;
+#
+# @reqlist = (
+# "INSERT INTO plugin_".$pluginname."_sample_data (domain, ip_address) VALUES ('$domain_name', '$ip_address')",
+# ) ;
+#
+# foreach my $s (@reqlist) {
+# $query = $s ;
+# # debug $query ;
+# $sth = $dbh->prepare ($query) ;
+# $sth->execute () ;
+# $sth->finish () ;
+# }
+# @reqlist = () ;
+#
+# &update_db_version ($target) ;
+# debug "Committing." ;
+# $dbh->commit () ;
+# }
+
+ debug "It seems your database install/upgrade went well and smoothly. That's cool." ;
+ debug "Please enjoy using Debian FusionForge." ;
+
+ # There should be a commit at the end of every block above.
+ # If there is not, then it might be symptomatic of a problem.
+ # For safety, we roll back.
+ $dbh->rollback ();
+};
+
+if ($@) {
+ warn "Transaction aborted because $@" ;
+ debug "Transaction aborted because $@" ;
+ debug "Last SQL query was:\n$query\n(end of query)" ;
+ $dbh->rollback ;
+ debug "Please report this bug on the Debian bug-tracking system." ;
+ debug "Please include the previous messages as well to help debugging." ;
+ debug "You should not worry too much about this," ;
+ debug "your DB is still in a consistent state and should be usable." ;
+ exit 1 ;
+}
+
+$dbh->rollback ;
+$dbh->disconnect ;
+
+sub is_lesser ( $$ ) {
+ my $v1 = shift || 0 ;
+ my $v2 = shift || 0 ;
+
+ my $rc = system "dpkg --compare-versions $v1 lt $v2" ;
+
+ return (! $rc) ;
+}
+
+sub is_greater ( $$ ) {
+ my $v1 = shift || 0 ;
+ my $v2 = shift || 0 ;
+
+ my $rc = system "dpkg --compare-versions $v1 gt $v2" ;
+
+ return (! $rc) ;
+}
+
+sub debug ( $ ) {
+ my $v = shift ;
+ chomp $v ;
+ print STDERR "$v\n" ;
+}
+
+sub create_metadata_table ( $ ) {
+ my $v = shift || "0" ;
+ my $tablename = "plugin_" .$pluginname . "_meta_data" ;
+ # Do we have the metadata table?
+
+ $query = "SELECT count(*) FROM pg_class WHERE relname = '$tablename' and relkind = 'r'";
+ # debug $query ;
+ my $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ my @array = $sth->fetchrow_array () ;
+ $sth->finish () ;
+
+ # Let's create this table if we have it not
+
+ if ($array [0] == 0) {
+ debug "Creating $tablename table." ;
+ $query = "CREATE TABLE $tablename (key varchar primary key, value text not null)" ;
+ # debug $query ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ $sth->finish () ;
+ }
+
+ $query = "SELECT count(*) FROM $tablename WHERE key = 'db-version'";
+ # debug $query ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ @array = $sth->fetchrow_array () ;
+ $sth->finish () ;
+
+ # Empty table? We'll have to fill it up a bit
+
+ if ($array [0] == 0) {
+ debug "Inserting first data into $tablename table." ;
+ $query = "INSERT INTO $tablename (key, value) VALUES ('db-version', '$v')" ;
+ # debug $query ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ $sth->finish () ;
+ }
+}
+
+sub update_db_version ( $ ) {
+ my $v = shift or die "Not enough arguments" ;
+ my $tablename = "plugin_" .$pluginname . "_meta_data" ;
+
+ debug "Updating $tablename table." ;
+ $query = "UPDATE $tablename SET value = '$v' WHERE key = 'db-version'" ;
+ # debug $query ;
+ my $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ $sth->finish () ;
+}
+
+sub get_db_version () {
+ my $tablename = "plugin_" .$pluginname . "_meta_data" ;
+
+ $query = "SELECT value FROM $tablename WHERE key = 'db-version'" ;
+ # debug $query ;
+ my $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ my @array = $sth->fetchrow_array () ;
+ $sth->finish () ;
+
+ my $version = $array [0] ;
+
+ return $version ;
+}
+
+sub drop_table_if_exists ( $ ) {
+ my $tname = shift or die "Not enough arguments" ;
+ $query = "SELECT count(*) FROM pg_class WHERE relname='$tname' AND relkind='r'" ;
+ my $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ my @array = $sth->fetchrow_array () ;
+ $sth->finish () ;
+
+ if ($array [0] != 0) {
+ # debug "Dropping table $tname" ;
+ $query = "DROP TABLE $tname" ;
+ # debug $query ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ $sth->finish () ;
+ }
+}
+
+sub drop_sequence_if_exists ( $ ) {
+ my $sname = shift or die "Not enough arguments" ;
+ $query = "SELECT count(*) FROM pg_class WHERE relname='$sname' AND relkind='S'" ;
+ my $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ my @array = $sth->fetchrow_array () ;
+ $sth->finish () ;
+
+ if ($array [0] != 0) {
+ # debug "Dropping sequence $sname" ;
+ $query = "DROP SEQUENCE $sname" ;
+ # debug $query ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ $sth->finish () ;
+ }
+}
+
+sub drop_index_if_exists ( $ ) {
+ my $iname = shift or die "Not enough arguments" ;
+ $query = "SELECT count(*) FROM pg_class WHERE relname='$iname' AND relkind='i'" ;
+ my $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ my @array = $sth->fetchrow_array () ;
+ $sth->finish () ;
+
+ if ($array [0] != 0) {
+ # debug "Dropping index $iname" ;
+ $query = "DROP INDEX $iname" ;
+ # debug $query ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ $sth->finish () ;
+ }
+}
+
+sub drop_view_if_exists ( $ ) {
+ my $iname = shift or die "Not enough arguments" ;
+ $query = "SELECT count(*) FROM pg_class WHERE relname='$iname' AND relkind='v'" ;
+ my $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ my @array = $sth->fetchrow_array () ;
+ $sth->finish () ;
+
+ if ($array [0] != 0) {
+ # debug "Dropping view $iname" ;
+ $query = "DROP VIEW $iname" ;
+ # debug $query ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ $sth->finish () ;
+ }
+}
+
+sub bump_sequence_to ( $$ ) {
+ my ($sth, @array, $seqname, $targetvalue) ;
+
+ $seqname = shift ;
+ $targetvalue = shift ;
+
+ do {
+ $query = "select nextval ('$seqname')" ;
+ $sth = $dbh->prepare ($query) ;
+ $sth->execute () ;
+ @array = $sth->fetchrow_array () ;
+ $sth->finish () ;
+ } until $array[0] >= $targetvalue ;
+}
diff --git a/plugins/coclico/mailman/common/mailman-init.php b/plugins/coclico/mailman/common/mailman-init.php
new file mode 100644
index 0000000000..7d773de5b9
--- /dev/null
+++ b/plugins/coclico/mailman/common/mailman-init.php
@@ -0,0 +1,36 @@
+
diff --git a/plugins/coclico/mailman/cronjobs/manage_mailmanlists.php b/plugins/coclico/mailman/cronjobs/manage_mailmanlists.php
new file mode 100644
index 0000000000..de858d3b6a
--- /dev/null
+++ b/plugins/coclico/mailman/cronjobs/manage_mailmanlists.php
@@ -0,0 +1,68 @@
+#! /usr/bin/php5 -f
+createList($data['parameters']);
+ } elseif ($data['type'] == 'MAILMAN_LIST_DELETE') {
+ $result = BackendMailmanList::instance()->deleteList($data['parameters']);
+ }
+ $result ? $log="DONE":$test="ERROR";
+ $events[$data['id']]=$log;
+ echo "\n Event ".$data['id']." : ".$data['type']." ".$log." for list id=".$data['parameters'];
+}
+if(isset($events)) {
+ foreach($events as $event_id => $log) {
+ $sql = "UPDATE system_event SET end_date=$1, log=$2, status='3' WHERE id=$3;";
+ $result = db_query_params($sql,array(time(),$log,$event_id));
+ if (!$result) {
+ printf('Unable to update the list of events: '.db_error());
+ return false;
+ }
+ }
+
+}
+
+
+// Local Variables:
+// mode: php
+// c-file-style: "bsd"
+// End:
+
+?>
diff --git a/plugins/coclico/mailman/db/mailman-init.sql b/plugins/coclico/mailman/db/mailman-init.sql
new file mode 100644
index 0000000000..85eda9d091
--- /dev/null
+++ b/plugins/coclico/mailman/db/mailman-init.sql
@@ -0,0 +1,24 @@
+CREATE TABLE plugin_mailman (
+ listname character varying(100) NOT NULL,
+ address character varying(255) NOT NULL,
+ hide character varying(255) NOT NULL default 'N',
+ nomail character varying(255) NOT NULL default 'N',
+ ack character varying(255) NOT NULL default 'Y',
+ not_metoo character varying(255) NOT NULL default 'Y',
+ digest character varying(255) NOT NULL default 'N',
+ plain character varying(255) NOT NULL default 'N',
+ password character varying(255) NOT NULL default '!',
+ lang character varying(255) NOT NULL default 'en',
+ name character varying(255) default NULL,
+ one_last_digest character varying(255) NOT NULL default 'N',
+ user_options bigint NOT NULL default 0,
+ delivery_status integer NOT NULL default 0,
+ topics_userinterest character varying(255) default NULL,
+ delivery_status_timestamp timestamp without time zone default '1901-01-01 01:01:01',
+ bi_cookie character varying(255) default NULL,
+ bi_score double precision NOT NULL default '0',
+ bi_noticesleft double precision NOT NULL default '0',
+ bi_lastnotice date NOT NULL default '1901-01-01',
+ bi_date date NOT NULL default '1901-01-01',
+ PRIMARY KEY (listname, address)
+);
diff --git a/plugins/coclico/mailman/debian/README.Debian b/plugins/coclico/mailman/debian/README.Debian
new file mode 100644
index 0000000000..b22b43b04a
--- /dev/null
+++ b/plugins/coclico/mailman/debian/README.Debian
@@ -0,0 +1,6 @@
+fusionforge-plugin-mailman for Debian
+---------------------
+
+See README.Debian in fusionforge-common package
+
+ -- Christian Bayle Mon, 08 Mar 2010 16:37:51 +0100
diff --git a/plugins/coclico/mailman/debian/README.source b/plugins/coclico/mailman/debian/README.source
new file mode 100644
index 0000000000..883d4f4805
--- /dev/null
+++ b/plugins/coclico/mailman/debian/README.source
@@ -0,0 +1,9 @@
+mailman for Debian
+---------------------
+
+
+
+
+
+
diff --git a/plugins/coclico/mailman/debian/changelog b/plugins/coclico/mailman/debian/changelog
new file mode 100644
index 0000000000..52dc23d1fd
--- /dev/null
+++ b/plugins/coclico/mailman/debian/changelog
@@ -0,0 +1,42 @@
+fusionforge-plugin-mailman (1.3.0-1) karmic; urgency=low
+
+ * Add mailman mailing list creation
+
+ -- Christian Bayle Wed, 21 Apr 2010 00:11:46 +0200
+
+fusionforge-plugin-mailman (1.2.9-1) karmic; urgency=low
+
+ * Make plugin nicer
+
+ -- Mélanie Le Bail Wed, 14 Apr 2010 15:02:58 +0200
+
+fusionforge-plugin-mailman (1.2.5-1) unstable; urgency=low
+
+ * Some FusionForge renaming
+ * Use default host so single sign on works
+
+ -- Christian Bayle Thu, 08 Apr 2010 22:35:50 +0200
+
+fusionforge-plugin-mailman (1.2.4-1) karmic; urgency=low
+
+ * Remove "powered by GForge" on the main age of mailman plugin
+
+ -- Mélanie Le Bail Fri, 02 Apr 2010 09:28:40 +0200
+
+fusionforge-plugin-mailman (1.2.3-1) karmic; urgency=low
+
+ * Modify the creation processus to let admin re-create list with problems
+
+ -- Mélanie Le Bail Thu, 01 Apr 2010 17:26:57 +0200
+
+fusionforge-plugin-mailman (1.2.2-1) karmic; urgency=low
+
+ * Modify the lists status code to make it the same as original "Lists" in forges.
+
+ -- Mélanie Le Bail Thu, 01 Apr 2010 13:59:46 +0200
+
+fusionforge-plugin-mailman (1.2-1) unstable; urgency=low
+
+ * Initial release
+
+ -- Christian Bayle Mon, 08 Mar 2010 16:37:51 +0100
diff --git a/plugins/coclico/mailman/debian/compat b/plugins/coclico/mailman/debian/compat
new file mode 100644
index 0000000000..7f8f011eb7
--- /dev/null
+++ b/plugins/coclico/mailman/debian/compat
@@ -0,0 +1 @@
+7
diff --git a/plugins/coclico/mailman/debian/control b/plugins/coclico/mailman/debian/control
new file mode 100644
index 0000000000..d5737826c9
--- /dev/null
+++ b/plugins/coclico/mailman/debian/control
@@ -0,0 +1,22 @@
+Source: fusionforge-plugin-mailman
+Section: devel
+Priority: optional
+Maintainer: Christian Bayle
+Uploaders: Roland Mas