This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "FusionForge".

The branch, feature/plugin-globalactivity-6.0 has been created
        at  f137e2ac63aeff70c14b8de285abab92138ca8f1 (commit)

- Log -----------------------------------------------------------------
https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=f137e2ac63aeff70c14b8de285abab92138ca8f1

commit f137e2ac63aeff70c14b8de285abab92138ca8f1
Author: Roland Mas <[email protected]>
Date:   Thu Oct 6 15:35:16 2016 +0200

    Fixed testsuite

diff --git a/tests/func/50_PluginsScmGit/gitSSHTest.php 
b/tests/func/50_PluginsScmGit/gitSSHTest.php
index 036d18f..2d4021e 100644
--- a/tests/func/50_PluginsScmGit/gitSSHTest.php
+++ b/tests/func/50_PluginsScmGit/gitSSHTest.php
@@ -86,6 +86,8 @@ class ScmGitSSHTest extends FForge_SeleniumTestCase
                $this->activatePlugin('globalactivity');
 
                $this->open(ROOT.'/plugins/globalactivity/');
+               $this->select("//select[@name='show[]']","label=Git Commits");
+               $this->clickAndWait("submit");
                $this->assertTextPresent("scm commit: Modifying file");
                $this->assertTextPresent("scm commit: Adding file");
 

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=202c40661c37261df194ca928f790652004b717c

commit 202c40661c37261df194ca928f790652004b717c
Author: Roland Mas <[email protected]>
Date:   Thu Aug 18 15:54:21 2016 +0200

    Improve test script

diff --git a/src/plugins/globalactivity/bin/test-globalactivity.py 
b/src/plugins/globalactivity/bin/test-globalactivity.py
index c37cb7c..be0403c 100644
--- a/src/plugins/globalactivity/bin/test-globalactivity.py
+++ b/src/plugins/globalactivity/bin/test-globalactivity.py
@@ -18,6 +18,12 @@ t1 = int(time.time())
 t0 = t1 - 864000
 results = []
 print ("Global activity")
+results = client.service.globalactivity_getActivity(session,t0,t1,[])
+project_id = 0
+for r in results:
+    print r
+
+print ("Global activity,restricted to some sections")
 results = 
client.service.globalactivity_getActivity(session,t0,t1,['trackeropen','trackerclose','scmgit'])
 project_id = 0
 for r in results:

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=dba8eec4a8338442bf2d8397506ef0cef99d62ca

commit dba8eec4a8338442bf2d8397506ef0cef99d62ca
Author: Roland Mas <[email protected]>
Date:   Thu Aug 18 15:50:07 2016 +0200

    Added sample SOAP client for global activity plugin

diff --git a/src/plugins/globalactivity/bin/test-globalactivity.py 
b/src/plugins/globalactivity/bin/test-globalactivity.py
new file mode 100644
index 0000000..c37cb7c
--- /dev/null
+++ b/src/plugins/globalactivity/bin/test-globalactivity.py
@@ -0,0 +1,34 @@
+#! /usr/bin/python
+
+from suds.client import Client
+import time
+import logging
+
+logging.basicConfig(level=logging.INFO)
+logging.getLogger('suds.client').setLevel(logging.DEBUG)
+logging.getLogger('suds.transport').setLevel(logging.DEBUG)
+
+url = "https://adullact.net/soap/?wsdl=1";
+client = Client(url)
+session = ''
+# session = client.service.login('admin','secretpass')
+# print client
+
+t1 = int(time.time())
+t0 = t1 - 864000
+results = []
+print ("Global activity")
+results = 
client.service.globalactivity_getActivity(session,t0,t1,['trackeropen','trackerclose','scmgit'])
+project_id = 0
+for r in results:
+    print r
+    # print r['section']
+    # print r['description']
+    if r['section'] == 'scm':
+        project_id = r['group_id']
+
+print ("For project %d" % (project_id,))
+results = 
client.service.globalactivity_getActivityForProject(session,t0,t1,project_id,['trackeropen','trackerclose','scmgit'])
+project_id = 0
+for r in results:
+    print r

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=11081a3e586521c2fdf558bdc875c1fadb2de357

commit 11081a3e586521c2fdf558bdc875c1fadb2de357
Author: Roland Mas <[email protected]>
Date:   Thu Aug 18 15:30:31 2016 +0200

    Debug

diff --git a/src/plugins/globalactivity/include/globalactivityPlugin.class.php 
b/src/plugins/globalactivity/include/globalactivityPlugin.class.php
index 7d359d8..7526534 100644
--- a/src/plugins/globalactivity/include/globalactivityPlugin.class.php
+++ b/src/plugins/globalactivity/include/globalactivityPlugin.class.php
@@ -288,7 +288,7 @@ function 
&globalactivity_getActivity($session_ser,$begin,$end,$show=array()) {
        if (!forge_get_config('use_activity')
                || !$plugin) {
                $fault = new soap_fault 
('','globalactivity_getActivity','Global activity not available','Global 
activity not available');
-               return &$fault;
+               return $fault;
        }
 
        $ids = array();

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=1e3c0af6361bb0dec043ccbaa3e97836dd83b707

commit 1e3c0af6361bb0dec043ccbaa3e97836dd83b707
Author: Roland Mas <[email protected]>
Date:   Thu Aug 18 15:26:36 2016 +0200

    Debug

diff --git a/src/plugins/globalactivity/include/globalactivityPlugin.class.php 
b/src/plugins/globalactivity/include/globalactivityPlugin.class.php
index a353967..7d359d8 100644
--- a/src/plugins/globalactivity/include/globalactivityPlugin.class.php
+++ b/src/plugins/globalactivity/include/globalactivityPlugin.class.php
@@ -244,7 +244,7 @@ class globalactivityPlugin extends Plugin {
                        $group_id = $arr['group_id'];
                        $hookParams['group'] = $group_id;
                        $hookParams['results'] = &$results;
-                       $hookParams['show'] = &$show;
+                       $hookParams['show'] = &$section;
                        $hookParams['begin'] = $begin;
                        $hookParams['end'] = $end;
                        $hookParams['ids'] = &$ids;
@@ -253,11 +253,12 @@ class globalactivityPlugin extends Plugin {
                }
 
                if (count($show) < 1) {
-                       $show = $ids;
+                       $show = $section;
                }
 
                foreach ($show as $showthis) {
                        if (array_search($showthis, $ids) === false) {
+error_log('anurst '.$showthis);
                                throw new Exception(_('Invalid Data Passed to 
query'));
                        }
                }
@@ -286,7 +287,8 @@ function 
&globalactivity_getActivity($session_ser,$begin,$end,$show=array()) {
        $plugin = plugin_get_object('globalactivity');
        if (!forge_get_config('use_activity')
                || !$plugin) {
-               return new soap_fault ('','globalactivity_getActivity','Global 
activity not available','Global activity not available');
+               $fault = new soap_fault 
('','globalactivity_getActivity','Global activity not available','Global 
activity not available');
+               return &$fault;
        }
 
        $ids = array();
diff --git a/src/plugins/scmgit/common/GitPlugin.class.php 
b/src/plugins/scmgit/common/GitPlugin.class.php
index 30e0c39..44d4a24 100644
--- a/src/plugins/scmgit/common/GitPlugin.class.php
+++ b/src/plugins/scmgit/common/GitPlugin.class.php
@@ -970,10 +970,14 @@ control over it to the project's administrator.");
                        // Grab commit log
                        $protocol = forge_get_config('use_ssl', 'scmgit') ? 
'https://' : 'http://';
                        $u = session_get_user();
-                       if ($project->enableAnonSCM())
+                       if ($project->enableAnonSCM()) {
                                $server_script = '/anonscm/gitlog';
-                       else
+                       } else {
+                               if (!$u) {
+                                       return true;
+                               } 
                                $server_script = 
'/authscm/'.$u->getUnixName().'/gitlog';
+                       }
                        $script_url = $protocol . forge_get_config('scm_host')
                                . $server_script
                                .'?unix_group_name='.$project->getUnixName()

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=1749857fdc96e3a0c604d5b2ace1cb87c164e3d9

commit 1749857fdc96e3a0c604d5b2ace1cb87c164e3d9
Merge: 4b0f9c8 e63278e
Author: Roland Mas <[email protected]>
Date:   Wed Jun 15 13:57:01 2016 +0200

    Merge remote-tracking branch 'upstream/6.0' into 
adullact/6.0/globalactivity-plugin

diff --cc autoinstall/install-src.sh
index 111baa0,edd6c43..8983b50
--- a/autoinstall/install-src.sh
+++ b/autoinstall/install-src.sh
@@@ -56,10 -56,6 +56,7 @@@ f
      make install-base install-shell install-scm \
          install-plugin-scmsvn install-plugin-scmgit \
          install-plugin-blocks install-plugin-moinmoin \
 -        install-plugin-online_help install-plugin-taskboard 
install-plugin-message
 +        install-plugin-online_help install-plugin-taskboard 
install-plugin-message \
 +      install-plugin-globalactivity
-     if [ -e /etc/debian_version ]; then
-       make install-plugin-mediawiki
-     fi
      make post-install
  )
diff --cc autoinstall/install.sh
index 8dd4c3d,39c256b..e3dc82d
--- a/autoinstall/install.sh
+++ b/autoinstall/install.sh
@@@ -41,9 -41,9 +41,9 @@@ if [ -e /etc/debian_version ]; the
        # Additional components for testsuite
        $APT install fusionforge-shell fusionforge-scm \
            fusionforge-plugin-scmgit fusionforge-plugin-scmsvn 
fusionforge-plugin-scmbzr \
-           fusionforge-plugin-mediawiki fusionforge-plugin-moinmoin \
+           fusionforge-plugin-moinmoin \
            fusionforge-plugin-blocks fusionforge-plugin-taskboard \
 -          fusionforge-plugin-message
 +          fusionforge-plugin-message fusionforge-plugin-globalactivity
        if ! dpkg-vendor --is Ubuntu; then
            apt-get install locales-all  # 
https://bugs.launchpad.net/ubuntu/+source/glibc/+bug/1394929
        fi

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=4b0f9c860d4df59e3a41d6eb4f8b52d4d0e36b37

commit 4b0f9c860d4df59e3a41d6eb4f8b52d4d0e36b37
Author: Roland Mas <[email protected]>
Date:   Wed Jun 15 13:00:51 2016 +0200

    Fixed testsuite

diff --git a/tests/func/60_PluginsGlobalactivity/globalactivityTest.php 
b/tests/func/60_PluginsGlobalactivity/globalactivityTest.php
index 762e625..d23d9ba 100644
--- a/tests/func/60_PluginsGlobalactivity/globalactivityTest.php
+++ b/tests/func/60_PluginsGlobalactivity/globalactivityTest.php
@@ -155,7 +155,7 @@ class Activity extends FForge_SeleniumTestCase
                $this->assertTrue($found);
                $found = False;
                foreach ($response as $data) {
-                       if ($data->description == 'Message1') {
+                       if ($data->description == 'Message1 in a bottle') {
                                $found = True;
                                break;
                        }
@@ -171,7 +171,7 @@ class Activity extends FForge_SeleniumTestCase
                $this->assertTrue($found);
 
                // Now restrict to ProjectA only
-               $response = 
$soapclient->globalactivity_getActivityForProject($session,time()-3600,time(),6,array('forumpost'));
+               $response = 
$soapclient->globalactivity_getActivityForProject($session,time()-3600,time(),7,array('forumpost'));
                $found = False;
                foreach ($response as $data) {
                        if ($data->description == 'Welcome to 
developers-discussion') {
@@ -182,7 +182,7 @@ class Activity extends FForge_SeleniumTestCase
                $this->assertTrue($found);
                $found = False;
                foreach ($response as $data) {
-                       if ($data->description == 'Message1') {
+                       if ($data->description == 'Message1 in a bottle') {
                                $found = True;
                                break;
                        }

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=9d79158661171c0b8661f835b251818d299bab24

commit 9d79158661171c0b8661f835b251818d299bab24
Author: Roland Mas <[email protected]>
Date:   Wed Jun 15 11:13:27 2016 +0200

    Fixed method name in testsuite

diff --git a/tests/func/60_PluginsGlobalactivity/globalactivityTest.php 
b/tests/func/60_PluginsGlobalactivity/globalactivityTest.php
index f9a3d2b..762e625 100644
--- a/tests/func/60_PluginsGlobalactivity/globalactivityTest.php
+++ b/tests/func/60_PluginsGlobalactivity/globalactivityTest.php
@@ -72,7 +72,7 @@ class Activity extends FForge_SeleniumTestCase
                $this->type("body", "ninetynine of them on Charlie's wall - 
also, ZONGO");
                $this->clickAndWait("submit");
 
-               $this->createAndGote('ProjectB');
+               $this->createAndGoto('ProjectB');
                $this->clickAndWait("link=Forums");
                $this->clickAndWait("link=open-discussion");
                $this->click("link=Start New Thread");

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=ab9b99ae29175499f4abe8007ac00795c71ad3e1

commit ab9b99ae29175499f4abe8007ac00795c71ad3e1
Author: Roland Mas <[email protected]>
Date:   Tue Jun 14 10:07:42 2016 +0200

    Added globalactivity_getActivityForProject method

diff --git a/src/plugins/globalactivity/README 
b/src/plugins/globalactivity/README
index bfb0011..571b9ef 100644
--- a/src/plugins/globalactivity/README
+++ b/src/plugins/globalactivity/README
@@ -32,3 +32,8 @@ ref_id (meaning differs across sections), subref_id (ditto),
 description (title, commit number, or otherwise descriptive text),
 activity_date (as a Unix timestamp).
 
+Despite its name, the plugin also provides a non-global SOAP method
+called globalactivity_getActivityForProject, which takes a group_id as
+an extra parameter between the end date and the list of sections.  It
+returns an array of GlobalActivityEntry that only concerns the
+requested project.
diff --git a/src/plugins/globalactivity/include/globalactivityPlugin.class.php 
b/src/plugins/globalactivity/include/globalactivityPlugin.class.php
index 8f697e1..a353967 100644
--- a/src/plugins/globalactivity/include/globalactivityPlugin.class.php
+++ b/src/plugins/globalactivity/include/globalactivityPlugin.class.php
@@ -69,9 +69,20 @@ class globalactivityPlugin extends Plugin {
                        array('return'=>'tns:ArrayOfGlobalActivityEntry'),
                        $uri,
                        $uri.'#globalactivity_getActivity','rpc','encoded');
+
+               $server->register(
+                       'globalactivity_getActivityForProject',
+                       array('session_ser'=>'xsd:string',
+                                 'begin'=>'xsd:int',
+                                 'end'=>'xsd:int',
+                                 'group_id'=>'xsd:int',
+                                 'show'=>'tns:ArrayOfstring',),
+                       array('return'=>'tns:ArrayOfGlobalActivityEntry'),
+                       $uri,
+                       
$uri.'#globalactivity_getActivityForProject','rpc','encoded');
        }
 
-       public function getData($begin,$end,$show,&$ids,&$texts) {
+       public function getData($begin,$end,$show,&$ids,&$texts,$gid = NULL) {
                if ($begin > $end) {
                        $tmp = $end;
                        $end = $begin;
@@ -183,11 +194,18 @@ class globalactivityPlugin extends Plugin {
                        return $cached_perms[$s][$ref];
                }
 
-               $res = db_query_params('SELECT * FROM activity_vw WHERE 
activity_date BETWEEN $1 AND $2
-                       AND section = ANY ($3) ORDER BY activity_date DESC',
+               if ($gid) {
+                       $res = db_query_params('SELECT * FROM activity_vw WHERE 
activity_date BETWEEN $1 AND $2 AND section = ANY ($3) AND group_id = $4 ORDER 
BY activity_date DESC',
+                                                          array($begin,
+                                                                        $end,
+                                                                        
db_string_array_to_any_clause($section),
+                                                                        $gid));
+               } else {
+                       $res = db_query_params('SELECT * FROM activity_vw WHERE 
activity_date BETWEEN $1 AND $2 AND section = ANY ($3) ORDER BY activity_date 
DESC',
                                                           array($begin,
                                                                         $end,
                                                                         
db_string_array_to_any_clause($section)));
+               }
 
                if (db_error()) {
                        exit_error(db_error(), 'home');
@@ -205,9 +223,14 @@ class globalactivityPlugin extends Plugin {
                        $results[] = $arr;
                }
 
-               $res = db_query_params('SELECT group_id FROM groups WHERE 
status=$1',
-                                                          array('A'));
-
+               if ($gid) {
+                       $res = db_query_params('SELECT group_id FROM groups 
WHERE status=$1 AND group_id=$2',
+                                                                  array('A', 
$gid));
+               } else {
+                       $res = db_query_params('SELECT group_id FROM groups 
WHERE status=$1',
+                                                                  array('A'));
+               }
+               
                if (db_error()) {
                        exit_error(db_error(), 'home');
                }
@@ -299,6 +322,48 @@ function 
&globalactivity_getActivity($session_ser,$begin,$end,$show=array()) {
        return $res2;
 }
 
+function 
&globalactivity_getActivityForProject($session_ser,$begin,$end,$group_id,$show=array())
 {
+       continue_session($session_ser);
+
+       $plugin = plugin_get_object('globalactivity');
+       if (!forge_get_config('use_activity')
+               || !$plugin) {
+               return new soap_fault ('','globalactivity_getActivity','Global 
activity not available','Global activity not available');
+       }
+
+       $ids = array();
+       $texts = array();
+
+       try {
+               $results = 
$plugin->getData($begin,$end,$show,$ids,$texts,$group_id);
+       } catch (Exception $e) {
+               $msg = "Error in global activity: ".$e->getMessage();
+               return new soap_fault 
('','globalactivity_getActivity',$msg,$msg);
+       }
+
+       $keys = array(
+               'group_id',
+               'section',
+               'ref_id',
+               'subref_id',
+               'description',
+               'activity_date',
+               );
+
+
+       $res2 = array();
+       foreach ($results as $res) {
+               $r = array();
+               
+               foreach ($keys as $k) {
+                       $r[$k] = $res[$k];
+               }
+               $res2[] = $r;
+       }
+
+       return $res2;
+}
+
 // Local Variables:
 // mode: php
 // c-file-style: "bsd"
diff --git a/tests/func/60_PluginsGlobalactivity/globalactivityTest.php 
b/tests/func/60_PluginsGlobalactivity/globalactivityTest.php
index dfbb6b7..f9a3d2b 100644
--- a/tests/func/60_PluginsGlobalactivity/globalactivityTest.php
+++ b/tests/func/60_PluginsGlobalactivity/globalactivityTest.php
@@ -72,6 +72,15 @@ class Activity extends FForge_SeleniumTestCase
                $this->type("body", "ninetynine of them on Charlie's wall - 
also, ZONGO");
                $this->clickAndWait("submit");
 
+               $this->createAndGote('ProjectB');
+               $this->clickAndWait("link=Forums");
+               $this->clickAndWait("link=open-discussion");
+               $this->click("link=Start New Thread");
+               $this->waitForPageToLoad("30000");
+               $this->type("subject", "Message2");
+               $this->type("body", "Forum post in project B");
+               $this->clickAndWait("submit");
+
                // Create a document
 
                $this->gotoProject('ProjectA');
@@ -144,6 +153,49 @@ class Activity extends FForge_SeleniumTestCase
                        }
                }
                $this->assertTrue($found);
+               $found = False;
+               foreach ($response as $data) {
+                       if ($data->description == 'Message1') {
+                               $found = True;
+                               break;
+                       }
+               }
+               $this->assertTrue($found);
+               $found = False;
+               foreach ($response as $data) {
+                       if ($data->description == 'Message2') {
+                               $found = True;
+                               break;
+                       }
+               }
+               $this->assertTrue($found);
+
+               // Now restrict to ProjectA only
+               $response = 
$soapclient->globalactivity_getActivityForProject($session,time()-3600,time(),6,array('forumpost'));
+               $found = False;
+               foreach ($response as $data) {
+                       if ($data->description == 'Welcome to 
developers-discussion') {
+                               $found = True;
+                               break;
+                       }
+               }
+               $this->assertTrue($found);
+               $found = False;
+               foreach ($response as $data) {
+                       if ($data->description == 'Message1') {
+                               $found = True;
+                               break;
+                       }
+               }
+               $this->assertTrue($found);
+               $found = False;
+               foreach ($response as $data) {
+                       if ($data->description == 'Message2') {
+                               $found = True;
+                               break;
+                       }
+               }
+               $this->assertFalse($found);
 
                $response = 
$soapclient->globalactivity_getActivity($session,time()-3600,time(),array('scmsvn'));
                $found = False;

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=7a10dafdeba3261632dd82bb8f2c4019f2909828

commit 7a10dafdeba3261632dd82bb8f2c4019f2909828
Author: Roland Mas <[email protected]>
Date:   Fri Jun 3 16:17:13 2016 +0200

    Skip SCM activity by default

diff --git a/src/plugins/globalactivity/www/index.php 
b/src/plugins/globalactivity/www/index.php
index 92e272d..09203f0 100644
--- a/src/plugins/globalactivity/www/index.php
+++ b/src/plugins/globalactivity/www/index.php
@@ -34,7 +34,18 @@ global $HTML;
 
 $received_begin = getStringFromRequest("start_date");
 $received_end = getStringFromRequest("end_date");
-$show = getArrayFromRequest("show");
+$show = getArrayFromRequest("show",array('forumpost',
+                                                                               
 'trackeropen',
+                                                                               
 'trackerclose',
+                                                                               
 'news',
+                                                                               
 'taskopen',
+                                                                               
 'taskclose',
+                                                                               
 'taskdelete',
+                                                                               
 'frsrelease',
+                                                                               
 'docmannew',
+                                                                               
 'docmanupdate',
+                                                                               
 'docgroupnew'
+));
 
 $date_format = _('%Y-%m-%d');
 

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=d750bdd10d0f673549bbf7f76c35cd216f1c1916

commit d750bdd10d0f673549bbf7f76c35cd216f1c1916
Author: Roland Mas <[email protected]>
Date:   Tue May 31 15:33:22 2016 +0200

    Include the globalactivity plugin in *.rpm

diff --git a/src/rpm/plugins b/src/rpm/plugins
index 784144e..6b467e7 100644
--- a/src/rpm/plugins
+++ b/src/rpm/plugins
@@ -37,6 +37,9 @@ Requires: php-pear-HTTP
 %package plugin-externalsearch
 Requires:
 
+%package plugin-globalactivity
+Requires:
+
 %package plugin-gravatar
 Requires:
 

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=8fbcb198a45246e4c26e7f1337fd5e65ac278a92

commit 8fbcb198a45246e4c26e7f1337fd5e65ac278a92
Author: Roland Mas <[email protected]>
Date:   Tue May 31 15:23:51 2016 +0200

    Include the globalactivity plugin in *.deb

diff --git a/src/debian/plugins b/src/debian/plugins
index f2a4228..1ef362e 100644
--- a/src/debian/plugins
+++ b/src/debian/plugins
@@ -62,6 +62,9 @@ Depends: libarc-php, fusionforge-plugin-compactpreview
 Package: fusionforge-plugin-foafprofiles
 Depends:
 
+Package: fusionforge-plugin-globalactivity
+Depends:
+
 Package: fusionforge-plugin-globalsearch
 Depends: libxml-rss-perl, libgetopt-mixed-perl, libdbi-perl, libwww-perl, 
libcrypt-ssleay-perl, libunicode-string-perl, ${perl:Depends}
 

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=761423d0fcbb59fa7a0f2a40512ba309b55f697f

commit 761423d0fcbb59fa7a0f2a40512ba309b55f697f
Author: Roland Mas <[email protected]>
Date:   Tue May 31 13:47:57 2016 +0200

    Doc for the globalactivity plugin

diff --git a/src/plugins/globalactivity/README 
b/src/plugins/globalactivity/README
index c8b6935..bfb0011 100644
--- a/src/plugins/globalactivity/README
+++ b/src/plugins/globalactivity/README
@@ -1 +1,34 @@
-Globalactivity plugin
\ No newline at end of file
+Globalactivity plugin
+
+This plugin provides a forge-wide view into the activities of all
+projects (modulo permissions).  It can be seen as an aggregate of all
+the project-wide "activity" pages.
+
+The relevant data is also made available through a SOAP API.
+
+The method is called globalactivity_getActivity.  It takes four
+parameters:
+
+- a session token (as for the rest of the SOAP API): string (as
+  returned from the login method), possibly empty if the API is to be
+  used anonymously;
+
+- a start date: integer (Unix timestamp: number of seconds since
+  1970-01-01 00:00:00 UTC);
+
+- an end date: integer (ditto);
+
+- a list of sections for which to list events (array of strings), to
+  be picked among: scmsvn, svngit, svnhg, trackeropen, trackerclose,
+  frsrelease, forumpost, news, taskopen, taskclose, taskdelete,
+  docmannew, docmanupdate, docgroupnew.  An empty list means no
+  filtering.
+
+The return value is an array of GlobalActivityEntry; a
+GlobalActivityEntry is a hash with the following keys: group_id
+(identifier for the project on the forge), section (see above, with a
+quirk: scmsvn, scmgit and scmhg all end up in the same "scm" section),
+ref_id (meaning differs across sections), subref_id (ditto),
+description (title, commit number, or otherwise descriptive text),
+activity_date (as a Unix timestamp).
+

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=77510bc4f9f6c783cc8f4dc6d5a11e3eaf2f3869

commit 77510bc4f9f6c783cc8f4dc6d5a11e3eaf2f3869
Author: Roland Mas <[email protected]>
Date:   Tue May 31 13:47:57 2016 +0200

    Don't do HTML redirects in SOAP

diff --git a/src/plugins/globalactivity/include/globalactivityPlugin.class.php 
b/src/plugins/globalactivity/include/globalactivityPlugin.class.php
index a09cb10..8f697e1 100644
--- a/src/plugins/globalactivity/include/globalactivityPlugin.class.php
+++ b/src/plugins/globalactivity/include/globalactivityPlugin.class.php
@@ -235,7 +235,7 @@ class globalactivityPlugin extends Plugin {
 
                foreach ($show as $showthis) {
                        if (array_search($showthis, $ids) === false) {
-                               exit_error(_('Invalid Data Passed to query'), 
'home');
+                               throw new Exception(_('Invalid Data Passed to 
query'));
                        }
                }
 
@@ -268,8 +268,13 @@ function 
&globalactivity_getActivity($session_ser,$begin,$end,$show=array()) {
 
        $ids = array();
        $texts = array();
-       
-       $results = $plugin->getData($begin,$end,$show,$ids,$texts);
+
+       try {
+               $results = $plugin->getData($begin,$end,$show,$ids,$texts);
+       } catch (Exception $e) {
+               $msg = "Error in global activity: ".$e->getMessage();
+               return new soap_fault 
('','globalactivity_getActivity',$msg,$msg);
+       }
 
        $keys = array(
                'group_id',
diff --git a/src/plugins/globalactivity/www/index.php 
b/src/plugins/globalactivity/www/index.php
index e13a552..92e272d 100644
--- a/src/plugins/globalactivity/www/index.php
+++ b/src/plugins/globalactivity/www/index.php
@@ -85,7 +85,11 @@ site_header(array('title'=>_('Global activity')));
 $ids = array();
 $texts = array();
 
-$results = $plugin->getData($begin,$end,$show,$ids,$texts);
+try {
+       $results = $plugin->getData($begin,$end,$show,$ids,$texts);
+} catch (Exception $e) {
+       exit_error($e->getMessage(), 'home');
+}
 
 if (count($ids) < 1) {
        echo $HTML->information(_('No Activity Found'));

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=02b84da21d1b0b4588a5fb4f8f550173a76ddb20

commit 02b84da21d1b0b4588a5fb4f8f550173a76ddb20
Author: Roland Mas <[email protected]>
Date:   Tue May 31 13:47:57 2016 +0200

    Testsuite for globalactivity

diff --git a/tests/func/50_PluginsScmGit/gitSSHTest.php 
b/tests/func/50_PluginsScmGit/gitSSHTest.php
index e1a5aa5..036d18f 100644
--- a/tests/func/50_PluginsScmGit/gitSSHTest.php
+++ b/tests/func/50_PluginsScmGit/gitSSHTest.php
@@ -81,6 +81,14 @@ class ScmGitSSHTest extends FForge_SeleniumTestCase
                $this->assertTextPresent("Adding file");
                $this->selectFrame("relative=top");
 
+               // Check that the changes appear in the global activity page
+
+               $this->activatePlugin('globalactivity');
+
+               $this->open(ROOT.'/plugins/globalactivity/');
+               $this->assertTextPresent("scm commit: Modifying file");
+               $this->assertTextPresent("scm commit: Adding file");
+
                system("rm -fr $t");
        }
 }
diff --git a/tests/func/60_PluginsGlobalactivity/globalactivityTest.php 
b/tests/func/60_PluginsGlobalactivity/globalactivityTest.php
new file mode 100644
index 0000000..dfbb6b7
--- /dev/null
+++ b/tests/func/60_PluginsGlobalactivity/globalactivityTest.php
@@ -0,0 +1,186 @@
+<?php
+/**
+ * Copyright 2011, Roland Mas
+ * Copyright 2013, Franck Villaume - TrivialDev
+ * Copyright (C) 2015  Inria (Sylvain Beucler)
+ *
+ * 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+require_once dirname(dirname(__FILE__)).'/SeleniumForge.php';
+
+class Activity extends FForge_SeleniumTestCase
+{
+       public $fixture = 'projecta';
+
+       function testActivity()
+       {
+               $this->loadAndCacheFixture();
+
+               $this->activatePlugin('globalactivity');
+
+               // Open a tracker item
+
+               $this->gotoProject('ProjectA');
+               $this->clickAndWait("link=Tracker");
+               $this->clickAndWait("link=Bugs");
+               $this->clickAndWait("link=Submit New");
+               $this->type("summary", "Bug1 boustrophédon");
+               $this->type("details", "brebis outremanchienne");
+               
$this->clickAndWait("//form[@id='trackeraddform']//input[@type='submit']");
+               $this->clickAndWait("link=Bug1 boustrophédon");
+               $this->type("details", 'Ceci était une référence au « Génie des 
Alpages », rien à voir avec Charlie - also, ZONGO, and needle');
+               $this->clickAndWait("submit");
+
+               // Create a task
+
+               $this->gotoProject('ProjectA');
+               $this->clickAndWait("link=Tasks");
+               $this->clickAndWait("link=To Do");
+               $this->clickAndWait("link=Add Task");
+               $this->type("summary", "Task1 the brain");
+               $this->type("details", "The same thing we do every night, Pinky 
- try to take over the world! - also, ZONGO");
+               $this->type("hours", "199");
+               $this->clickAndWait("submit");
+
+               $this->clickAndWait("link=Task1 the brain");
+               $this->type("details", 'This is the needle for tasks');
+               $this->clickAndWait("submit");
+
+               // Post a message in a forum
+
+               $this->gotoProject('ProjectA');
+               $this->clickAndWait("link=Forums");
+               $this->clickAndWait("link=open-discussion");
+               $this->click("link=Start New Thread");
+               $this->waitForPageToLoad("30000");
+               $this->type("subject", "Message1 in a bottle");
+               $this->type("body", "ninetynine of them on Charlie's wall - 
also, ZONGO");
+               $this->clickAndWait("submit");
+
+               // Create a document
+
+               $this->gotoProject('ProjectA');
+               $this->clickAndWait("link=Docs");
+               $this->clickAndWait("addItemDocmanMenu");
+               // ugly hack until we fix behavior in docman when no folders 
exist. We need to click twice on the link
+               $this->clickAndWait("addItemDocmanMenu");
+               $this->click("id=tab-new-document");
+               $this->type("title", "Doc1 Vladimir");
+               $this->type("//input[@name='description']", "Main website (the 
needle) - also, ZONGO");
+               $this->click("//input[@name='type' and @value='pasteurl']");
+               $this->type("file_url", "http://fusionforge.org/";);
+               $this->clickAndWait("submit");
+
+               // Create some news
+
+               $this->gotoProject('ProjectA');
+               $this->clickAndWait("link=News");
+               $this->clickAndWait("link=Submit");
+               $this->type("summary", "News1 daily planet");
+               $this->type("details", "Clark Kent's newspaper - also, ZONGO");
+               $this->clickAndWait("submit");
+
+               // Check global activity
+
+               $this->open(ROOT.'/plugins/globalactivity/');
+               $this->assertTrue($this->isTextPresent("Bug1"));
+               $this->assertTrue($this->isTextPresent("Task1"));
+               $this->assertTrue($this->isTextPresent("Message1"));
+               $this->assertTrue($this->isTextPresent("Document 
http://fusionforge.org/";));
+               $this->assertTrue($this->isTextPresent("News1"));
+
+               // Also check anonymously
+
+               $this->logout();
+               $this->open(ROOT.'/plugins/globalactivity/');
+               $this->assertTrue($this->isTextPresent("Bug1"));
+               $this->assertTrue($this->isTextPresent("Task1"));
+               $this->assertTrue($this->isTextPresent("Message1"));
+               $this->assertFalse($this->isTextPresent("Document 
http://fusionforge.org/";));
+               $this->assertTrue($this->isTextPresent("News1"));
+
+               // Check SOAP
+
+               $soapclient = new SoapClient(WSDL_URL);
+               $this->assertNotNull($soapclient);
+               
+               $userid = FORGE_ADMIN_USERNAME;
+               $passwd = FORGE_ADMIN_PASSWORD;
+               
+               $response = $soapclient->login($userid, $passwd);
+               $session = $response;
+               
+               $response = 
$soapclient->globalactivity_getActivity($session,time()-3600,time(),array());
+               $found = False;
+               foreach ($response as $data) {
+                       if ($data->description == 'Welcome to 
developers-discussion') {
+                               $found = True;
+                               break;
+                       }
+               }
+               $this->assertTrue($found);
+
+               $response = 
$soapclient->globalactivity_getActivity($session,time()-3600,time(),array('forumpost'));
+               $found = False;
+               foreach ($response as $data) {
+                       if ($data->description == 'Welcome to 
developers-discussion') {
+                               $found = True;
+                               break;
+                       }
+               }
+               $this->assertTrue($found);
+
+               $response = 
$soapclient->globalactivity_getActivity($session,time()-3600,time(),array('scmsvn'));
+               $found = False;
+               foreach ($response as $data) {
+                       if ($data->description == 'Welcome to 
developers-discussion') {
+                               $found = True;
+                               break;
+                       }
+               }
+               $this->assertFalse($found);
+
+               // Now change permissions
+
+               $this->login(FORGE_ADMIN_USERNAME);
+               $this->gotoProject('ProjectA');
+               $this->clickAndWait("link=Admin");
+               $this->clickAndWait("link=Users and permissions");
+               $this->clickAndWait 
("//td/form/div[contains(.,'Anonymous')]/../div/input[@value='Edit 
Permissions']") ;
+               $this->select("//select[contains(@name,'data[project_read]')]", 
"label=Visible");
+               
$this->select("//tr/td[.='Bugs']/../td/select[contains(@name,'data[tracker]')]",
 "label=No Access");
+               
$this->select("//tr/td[.='Patches']/../td/select[contains(@name,'data[tracker]')]",
 "label=No Access");
+               $this->select("//tr/td[.='To 
Do']/../td/select[contains(@name,'data[pm]')]", "label=No Access");
+               $this->select("//tr/td[.='Next 
Release']/../td/select[contains(@name,'data[pm]')]", "label=No Access");
+               
$this->select("//tr/td[.='open-discussion']/../td/select[contains(@name,'data[forum]')]",
 "label=No Access");
+               
$this->select("//tr/td[.='developers-discussion']/../td/select[contains(@name,'data[forum]')]",
 "label=No Access");
+               $this->select("//select[contains(@name,'data[docman]')]", 
"label=Read only");
+               $this->clickAndWait ("//input[@value='Submit']") ;
+
+               // Recheck perms on anonymous global activity page
+
+               $this->logout();
+               $this->open(ROOT.'/plugins/globalactivity/');
+               $this->assertFalse($this->isTextPresent("Bug1"));
+               $this->assertFalse($this->isTextPresent("Task1"));
+               $this->assertFalse($this->isTextPresent("Message1"));
+               $this->assertTrue($this->isTextPresent("Document 
http://fusionforge.org/";));
+               $this->assertTrue($this->isTextPresent("News1"));
+
+       }
+}

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=bfe524428ac5352ff41089dc65cd8100735a8022

commit bfe524428ac5352ff41089dc65cd8100735a8022
Author: Roland Mas <[email protected]>
Date:   Tue May 31 13:47:57 2016 +0200

    SOAP for globalactivity

diff --git a/src/plugins/globalactivity/include/globalactivityPlugin.class.php 
b/src/plugins/globalactivity/include/globalactivityPlugin.class.php
index 3565e30..a09cb10 100644
--- a/src/plugins/globalactivity/include/globalactivityPlugin.class.php
+++ b/src/plugins/globalactivity/include/globalactivityPlugin.class.php
@@ -26,9 +26,49 @@ class globalactivityPlugin extends Plugin {
                $this->Plugin($id) ;
                $this->name = "globalactivity";
                $this->text = "Global Activity"; // To show in the tabs, use...
+
+               $this->_addHook('register_soap');
        }
 
-       function CallHook ($hookname, &$params) {
+       public function register_soap(&$params) {
+               $server = &$params['server'];
+               $uri = 'http://'.forge_get_config('web_host');
+
+               $server->wsdl->addComplexType(
+                       'GlobalActivityEntry',
+                       'complexType',
+                       'struct',
+                       'sequence',
+                       '',
+                       array(
+                               'group_id' => array('name'=>'group_id', 'type' 
=> 'xsd:int'),
+                               'section' => array('name'=>'section', 'type' => 
'xsd:string'),
+                               'ref_id' => array('name'=>'ref_id', 'type' => 
'xsd:string'),
+                               'subref_id' => array('name'=>'subref_id', 
'type' => 'xsd:string'),
+                               'description' => array('name'=>'description', 
'type' => 'xsd:string'),
+                               'activity_date' => 
array('name'=>'activity_date', 'type' => 'xsd:int')
+                               )
+                       );
+
+               $server->wsdl->addComplexType(
+                       'ArrayOfGlobalActivityEntry',
+                       'complexType',
+                       'array',
+                       '',
+                       'SOAP-ENC:Array',
+                       array(),
+                       
array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:GlobalActivityEntry[]')),
+                       'tns:GlobalActivityEntry');
+               
+               $server->register(
+                       'globalactivity_getActivity',
+                       array('session_ser'=>'xsd:string',
+                                 'begin'=>'xsd:int',
+                                 'end'=>'xsd:int',
+                                 'show'=>'tns:ArrayOfstring',),
+                       array('return'=>'tns:ArrayOfGlobalActivityEntry'),
+                       $uri,
+                       $uri.'#globalactivity_getActivity','rpc','encoded');
        }
 
        public function getData($begin,$end,$show,&$ids,&$texts) {
@@ -87,7 +127,7 @@ class globalactivityPlugin extends Plugin {
                        $section = $show;
                }
 
-               function date_compare($a, $b) {
+               function activity_date_compare($a, $b) {
                        if ($a['activity_date'] == $b['activity_date']) {
                                return 0;
                        }
@@ -174,6 +214,7 @@ class globalactivityPlugin extends Plugin {
 
                // If plugins wants to add activities.
                while ($arr = db_fetch_array($res)) {
+                       $group_id = $arr['group_id'];
                        if (!forge_check_perm('project_read', $group_id)) {
                                continue;
                        }
@@ -210,12 +251,49 @@ class globalactivityPlugin extends Plugin {
                        $res2[] = $arr;
                }
 
-               usort($res2, 'date_compare');
+               usort($res2, 'activity_date_compare');
 
                return $res2;
        }
 }
 
+function &globalactivity_getActivity($session_ser,$begin,$end,$show=array()) {
+       continue_session($session_ser);
+
+       $plugin = plugin_get_object('globalactivity');
+       if (!forge_get_config('use_activity')
+               || !$plugin) {
+               return new soap_fault ('','globalactivity_getActivity','Global 
activity not available','Global activity not available');
+       }
+
+       $ids = array();
+       $texts = array();
+       
+       $results = $plugin->getData($begin,$end,$show,$ids,$texts);
+
+       $keys = array(
+               'group_id',
+               'section',
+               'ref_id',
+               'subref_id',
+               'description',
+               'activity_date',
+               );
+
+
+       $res2 = array();
+       foreach ($results as $res) {
+               $r = array();
+               
+               foreach ($keys as $k) {
+                       $r[$k] = $res[$k];
+               }
+               $res2[] = $r;
+       }
+
+       return $res2;
+}
+
 // Local Variables:
 // mode: php
 // c-file-style: "bsd"

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=c7ff793c1cdbb8d4ff0413430e64a8a95a8d5814

commit c7ff793c1cdbb8d4ff0413430e64a8a95a8d5814
Author: Roland Mas <[email protected]>
Date:   Tue May 31 13:47:57 2016 +0200

    Factor gathering of data into plugin class

diff --git a/src/plugins/globalactivity/include/globalactivityPlugin.class.php 
b/src/plugins/globalactivity/include/globalactivityPlugin.class.php
index 14ca531..3565e30 100644
--- a/src/plugins/globalactivity/include/globalactivityPlugin.class.php
+++ b/src/plugins/globalactivity/include/globalactivityPlugin.class.php
@@ -25,100 +25,194 @@ class globalactivityPlugin extends Plugin {
        public function __construct($id=0) {
                $this->Plugin($id) ;
                $this->name = "globalactivity";
-               $this->text = "HelloWorld!"; // 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("groupmenu");   // To put into the project tabs
-               $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->text = "Global Activity"; // To show in the tabs, use...
        }
 
        function CallHook ($hookname, &$params) {
-               global $use_helloworldplugin,$G_SESSION,$HTML;
-               if ($hookname == "usermenu") {
-                       $text = $this->text; // this is what shows in the tab
-                       if ($G_SESSION->usesPlugin("helloworld")) {
-                               $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/helloworld/index.php' . $param ));
+       }
 
+       public function getData($begin,$end,$show,&$ids,&$texts) {
+               if ($begin > $end) {
+                       $tmp = $end;
+                       $end = $begin;
+                       $begin = $tmp;
+                       $tmp = $rendered_end;
+                       $rendered_end = $rendered_begin;
+                       $rendered_begin = $tmp;
+               }
+               
+               if (forge_get_config('use_forum')) {
+                       $ids[]          = 'forumpost';
+                       $texts[]        = _('Forum Post');
+               }
+
+               if (forge_get_config('use_tracker')) {
+                       $ids[]          = 'trackeropen';
+                       $texts[]        = _('Tracker Opened');
+                       $ids[]          = 'trackerclose';
+                       $texts[]        = _('Tracker Closed');
+               }
+
+               if (forge_get_config('use_news')) {
+                       $ids[]          = 'news';
+                       $texts[]        = _('News');
+               }
+
+               if (forge_get_config('use_pm')) {
+                       $ids[]          = 'taskopen';
+                       $texts[]        = _('Tasks Opened');
+                       $ids[]          = 'taskclose';
+                       $texts[]        = _('Tasks Closed');
+                       $ids[]          = 'taskdelete';
+                       $texts[]        = _('Tasks Deleted');
+               }
+
+               if (forge_get_config('use_frs')) {
+                       $ids[]          = 'frsrelease';
+                       $texts[]        = _('FRS Release');
+               }
+
+               if (forge_get_config('use_docman')) {
+                       $ids[]          = 'docmannew';
+                       $texts[]        = _('New Documents');
+                       $ids[]          = 'docmanupdate';
+                       $texts[]        = _('Updated Documents');
+                       $ids[]          = 'docgroupnew';
+                       $texts[]        = _('New Directories');
+               }
+
+               if (count($show) < 1) {
+                       $section = $ids;
+               } else {
+                       $section = $show;
+               }
+
+               function date_compare($a, $b) {
+                       if ($a['activity_date'] == $b['activity_date']) {
+                               return 0;
                        }
-               } elseif ($hookname == "groupmenu") {
-                       $group_id=$params['group'];
-                       $project = group_get_object($group_id);
-                       if (!$project || !is_object($project)) {
-                               return;
-                       }
-                       if ($project->isError()) {
-                               return;
+                       return ($a['activity_date'] > $b['activity_date']) ? -1 
: 1;
+               }
+
+               global $cached_perms;
+               $cached_perms = array();
+               function check_perm_for_activity($arr) {
+                       global $cached_perms;
+                       $s = $arr['section'];
+                       $ref = $arr['ref_id'];
+                       $group_id = $arr['group_id'];
+
+                       if (!isset($cached_perms[$s][$ref])) {
+                               switch ($s) {
+                                       case 'scm': {
+                                               $cached_perms[$s][$ref] = 
forge_check_perm('scm', $group_id, 'read');
+                                               break;
+                                       }
+                                       case 'trackeropen':
+                                       case 'trackerclose': {
+                                               $cached_perms[$s][$ref] = 
forge_check_perm('tracker', $ref, 'read');
+                                               break;
+                                       }
+                                       case 'frsrelease': {
+                                               $cached_perms[$s][$ref] = 
forge_check_perm('frs', $ref, 'read');
+                                               break;
+                                       }
+                                       case 'forumpost':
+                                       case 'news': {
+                                               $cached_perms[$s][$ref] = 
forge_check_perm('forum', $ref, 'read');
+                                               break;
+                                       }
+                                       case 'taskopen':
+                                       case 'taskclose':
+                                       case 'taskdelete': {
+                                               $cached_perms[$s][$ref] = 
forge_check_perm('pm', $ref, 'read');
+                                               break;
+                                       }
+                                       case 'docmannew':
+                                       case 'docmanupdate':
+                                       case 'docgroupnew': {
+                                               $cached_perms[$s][$ref] = 
forge_check_perm('docman', $group_id, 'read');
+                                               break;
+                                       }
+                                       default: {
+                                               // Must be a bug somewhere, 
we're supposed to handle all types
+                                               $cached_perms[$s][$ref] = false;
+                                       }
+                               }
                        }
-                       if (!$project->isProject()) {
-                               return;
+                       return $cached_perms[$s][$ref];
+               }
+
+               $res = db_query_params('SELECT * FROM activity_vw WHERE 
activity_date BETWEEN $1 AND $2
+                       AND section = ANY ($3) ORDER BY activity_date DESC',
+                                                          array($begin,
+                                                                        $end,
+                                                                        
db_string_array_to_any_clause($section)));
+
+               if (db_error()) {
+                       exit_error(db_error(), 'home');
+               }
+
+               $results = array();
+               while ($arr = db_fetch_array($res)) {
+                       $group_id = $arr['group_id'];
+                       if (!forge_check_perm('project_read', $group_id)) {
+                               continue;
                        }
-                       if ( $project->usesPlugin ( $this->name ) ) {
-                               $params['TITLES'][]=$this->text;
-                               $params['DIRS'][]=util_make_url 
('/plugins/helloworld/index.php?type=group&id=' . $group_id . "&pluginname=" . 
$this->name) ; // we indicate the part we're calling is the project one
-                       } else {
-                               $params['TITLES'][]=$this->text." is [Off]";
-                               $params['DIRS'][]='';
+                       if (!check_perm_for_activity($arr)) {
+                               continue;
                        }
-                       (($params['toptab'] == $this->name) ? 
$params['selected']=(count($params['TITLES'])-1) : '' );
-               } 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 "<tr>";
-                       echo "<td>";
-                       echo ' <input type="checkbox" 
name="use_helloworldplugin" value="1" ';
-                       // checked or unchecked?
-                       if ( $group->usesPlugin ( $this->name ) ) {
-                               echo "checked";
+                       $results[] = $arr;
+               }
+
+               $res = db_query_params('SELECT group_id FROM groups WHERE 
status=$1',
+                                                          array('A'));
+
+               if (db_error()) {
+                       exit_error(db_error(), 'home');
+               }
+
+               // If plugins wants to add activities.
+               while ($arr = db_fetch_array($res)) {
+                       if (!forge_check_perm('project_read', $group_id)) {
+                               continue;
                        }
-                       echo " /><br/>";
-                       echo "</td>";
-                       echo "<td>";
-                       echo "<strong>Use ".$this->text." Plugin</strong>";
-                       echo "</td>";
-                       echo "</tr>";
-               } 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_helloworldplugin = 
getStringFromRequest('use_helloworldplugin');
-                       if ( $use_helloworldplugin == 1 ) {
-                               $group->setPluginUse ( $this->name );
-                       } else {
-                               $group->setPluginUse ( $this->name, false );
+                       $group_id = $arr['group_id'];
+                       $hookParams['group'] = $group_id;
+                       $hookParams['results'] = &$results;
+                       $hookParams['show'] = &$show;
+                       $hookParams['begin'] = $begin;
+                       $hookParams['end'] = $end;
+                       $hookParams['ids'] = &$ids;
+                       $hookParams['texts'] = &$texts;
+                       plugin_hook("activity", $hookParams);
+               }
+
+               if (count($show) < 1) {
+                       $show = $ids;
+               }
+
+               foreach ($show as $showthis) {
+                       if (array_search($showthis, $ids) === false) {
+                               exit_error(_('Invalid Data Passed to query'), 
'home');
                        }
-               } elseif ($hookname == "user_personal_links") {
-                       // this displays the link in the user's profile page to 
it's personal HelloWorld (if you want other sto access it, youll have to change 
the permissions in the index.php
-                       $userid = $params['user_id'];
-                       $user = user_get_object($userid);
-                       $text = $params['text'];
-                       //check if the user has the plugin activated
-                       if ($user->usesPlugin($this->name)) {
-                               echo '  <p>' ;
-                               echo util_make_link 
("/plugins/helloworld/index.php?id=$userid&type=user&pluginname=".$this->name,
-                                                    _('View Personal 
HelloWorld')
-                                       );
-                               echo '</p>';
+               }
+
+               $res2 = array();
+               foreach ($results as $arr) {
+                       $group_id = $arr['group_id'];
+                       if (!forge_check_perm('project_read', $group_id)) {
+                               continue;
                        }
-               } elseif ($hookname == "project_admin_plugins") {
-                       // this displays the link in the project admin options 
page to it's  HelloWorld administration
-                       $group_id = $params['group_id'];
-                       $group = group_get_object($group_id);
-                       if ( $group->usesPlugin ( $this->name ) ) {
-                               echo '<p>'.util_make_link 
("/plugins/helloworld/admin/index.php?id=".$group->getID().'&type=admin&pluginname='.$this->name,
-                                                    _('HelloWorld 
Admin')).'</p>' ;
+                       if (!check_perm_for_activity($arr)) {
+                               continue;
                        }
+                       $res2[] = $arr;
                }
-               elseif ($hookname == "blahblahblah") {
-                       // ...
-               }
+
+               usort($res2, 'date_compare');
+
+               return $res2;
        }
 }
 
diff --git a/src/plugins/globalactivity/www/index.php 
b/src/plugins/globalactivity/www/index.php
index 9663aff..e13a552 100644
--- a/src/plugins/globalactivity/www/index.php
+++ b/src/plugins/globalactivity/www/index.php
@@ -70,114 +70,22 @@ if (!$received_end || $received_end == 0) {
        }
 }
 
-if ($begin > $end) {
-       $tmp = $end;
-       $end = $begin;
-       $begin = $tmp;
-       $tmp = $rendered_end;
-       $rendered_end = $rendered_begin;
-       $rendered_begin = $tmp;
-}
+$plugin = plugin_get_object('globalactivity');
 
 if (!forge_get_config('use_activity')) {
        exit_disabled();
 }
+if (!$plugin) {
+       exit_disabled();
+}
+       
 
 site_header(array('title'=>_('Global activity')));
 
 $ids = array();
 $texts = array();
 
-if (forge_get_config('use_forum')) {
-       $ids[]          = 'forumpost';
-       $texts[]        = _('Forum Post');
-}
-
-if (forge_get_config('use_tracker')) {
-       $ids[]          = 'trackeropen';
-       $texts[]        = _('Tracker Opened');
-       $ids[]          = 'trackerclose';
-       $texts[]        = _('Tracker Closed');
-}
-
-if (forge_get_config('use_news')) {
-       $ids[]          = 'news';
-       $texts[]        = _('News');
-}
-
-if (forge_get_config('use_pm')) {
-       $ids[]          = 'taskopen';
-       $texts[]        = _('Tasks Opened');
-       $ids[]          = 'taskclose';
-       $texts[]        = _('Tasks Closed');
-       $ids[]          = 'taskdelete';
-       $texts[]        = _('Tasks Deleted');
-}
-
-if (forge_get_config('use_frs')) {
-       $ids[]          = 'frsrelease';
-       $texts[]        = _('FRS Release');
-}
-
-if (forge_get_config('use_docman')) {
-       $ids[]          = 'docmannew';
-       $texts[]        = _('New Documents');
-       $ids[]          = 'docmanupdate';
-       $texts[]        = _('Updated Documents');
-       $ids[]          = 'docgroupnew';
-       $texts[]        = _('New Directories');
-}
-
-if (count($show) < 1) {
-       $section = $ids;
-} else {
-       $section = $show;
-}
-
-$res = db_query_params('SELECT * FROM activity_vw WHERE activity_date BETWEEN 
$1 AND $2
-                       AND section = ANY ($3) ORDER BY activity_date DESC',
-                       array($begin,
-                               $end,
-                               db_string_array_to_any_clause($section)));
-
-if (db_error()) {
-       exit_error(db_error(), 'home');
-}
-
-$results = array();
-while ($arr = db_fetch_array($res)) {
-       $results[] = $arr;
-}
-
-$res = db_query_params('SELECT group_id FROM groups WHERE status=$1',
-    array('A'));
-
-if (db_error()) {
-       exit_error(db_error(), 'home');
-}
-
-// If plugins wants to add activities.
-while ($arr = db_fetch_array($res)) {
-       $group_id = $arr['group_id'];
-       $hookParams['group'] = $group_id;
-       $hookParams['results'] = &$results;
-       $hookParams['show'] = &$show;
-       $hookParams['begin'] = $begin;
-       $hookParams['end'] = $end;
-       $hookParams['ids'] = &$ids;
-       $hookParams['texts'] = &$texts;
-       plugin_hook("activity", $hookParams);
-}
-
-if (count($show) < 1) {
-       $show = $ids;
-}
-
-foreach ($show as $showthis) {
-       if (array_search($showthis, $ids) === false) {
-               exit_error(_('Invalid Data Passed to query'), 'home');
-       }
-}
+$results = $plugin->getData($begin,$end,$show,$ids,$texts);
 
 if (count($ids) < 1) {
        echo $HTML->information(_('No Activity Found'));
@@ -217,77 +125,12 @@ if (count($ids) < 1) {
                echo $HTML->information(_('No Activity Found'));
        } else {
 
-               function date_compare($a, $b)
-               {
-                       if ($a['activity_date'] == $b['activity_date']) {
-                               return 0;
-                       }
-                       return ($a['activity_date'] > $b['activity_date']) ? -1 
: 1;
-               }
-
-               $cached_perms = array();
-               function check_perm_for_activity($arr) {
-                       global $cached_perms;
-                       $s = $arr['section'];
-                       $ref = $arr['ref_id'];
-                       $group_id = $arr['group_id'];
-
-                       if (!isset($cached_perms[$s][$ref])) {
-                               switch ($s) {
-                                       case 'scm': {
-                                               $cached_perms[$s][$ref] = 
forge_check_perm('scm', $group_id, 'read');
-                                               break;
-                                       }
-                                       case 'trackeropen':
-                                       case 'trackerclose': {
-                                               $cached_perms[$s][$ref] = 
forge_check_perm('tracker', $ref, 'read');
-                                               break;
-                                       }
-                                       case 'frsrelease': {
-                                               $cached_perms[$s][$ref] = 
forge_check_perm('frs', $ref, 'read');
-                                               break;
-                                       }
-                                       case 'forumpost':
-                                       case 'news': {
-                                               $cached_perms[$s][$ref] = 
forge_check_perm('forum', $ref, 'read');
-                                               break;
-                                       }
-                                       case 'taskopen':
-                                       case 'taskclose':
-                                       case 'taskdelete': {
-                                               $cached_perms[$s][$ref] = 
forge_check_perm('pm', $ref, 'read');
-                                               break;
-                                       }
-                                       case 'docmannew':
-                                       case 'docmanupdate':
-                                       case 'docgroupnew': {
-                                               $cached_perms[$s][$ref] = 
forge_check_perm('docman', $group_id, 'read');
-                                               break;
-                                       }
-                                       default: {
-                                               // Must be a bug somewhere, 
we're supposed to handle all types
-                                               $cached_perms[$s][$ref] = false;
-                                       }
-                               }
-                       }
-                       return $cached_perms[$s][$ref];
-               }
-
-               usort($results, 'date_compare');
 
                $displayTableTop = 0;
                $j = 0;
                $last_day = 0;
                foreach ($results as $arr) {
-
                        $group_id = $arr['group_id'];
-                       if (!forge_check_perm('project_read', $group_id)) {
-                               continue;
-                       }
-
-                       if (!check_perm_for_activity($arr)) {
-                               continue;
-                       }
                        if (!$displayTableTop) {
                                $theader = array();
                                $theader[] = _('Project');

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=13ded74c807fa544665e2d9655d2db1b311dceaa

commit 13ded74c807fa544665e2d9655d2db1b311dceaa
Author: Roland Mas <[email protected]>
Date:   Tue May 31 13:47:57 2016 +0200

    Global activity plugin: new plugin
    
    New page at /plugins/globalactivity/ aggregating activities for all
    projects (modulo permissions)

diff --git a/autoinstall/install-src.sh b/autoinstall/install-src.sh
index 9b5d2a1..111baa0 100755
--- a/autoinstall/install-src.sh
+++ b/autoinstall/install-src.sh
@@ -56,7 +56,8 @@ fi
     make install-base install-shell install-scm \
         install-plugin-scmsvn install-plugin-scmgit \
         install-plugin-blocks install-plugin-moinmoin \
-        install-plugin-online_help install-plugin-taskboard 
install-plugin-message
+        install-plugin-online_help install-plugin-taskboard 
install-plugin-message \
+       install-plugin-globalactivity
     if [ -e /etc/debian_version ]; then
        make install-plugin-mediawiki
     fi
diff --git a/autoinstall/install.sh b/autoinstall/install.sh
index 609d3f4..8dd4c3d 100755
--- a/autoinstall/install.sh
+++ b/autoinstall/install.sh
@@ -43,7 +43,7 @@ if [ -e /etc/debian_version ]; then
            fusionforge-plugin-scmgit fusionforge-plugin-scmsvn 
fusionforge-plugin-scmbzr \
            fusionforge-plugin-mediawiki fusionforge-plugin-moinmoin \
            fusionforge-plugin-blocks fusionforge-plugin-taskboard \
-           fusionforge-plugin-message
+           fusionforge-plugin-message fusionforge-plugin-globalactivity
        if ! dpkg-vendor --is Ubuntu; then
            apt-get install locales-all  # 
https://bugs.launchpad.net/ubuntu/+source/glibc/+bug/1394929
        fi
@@ -58,6 +58,6 @@ else
        yum --enablerepo=epel install -y fusionforge fusionforge-shell 
fusionforge-scm \
            fusionforge-plugin-scmgit fusionforge-plugin-scmsvn \
            fusionforge-plugin-blocks fusionforge-plugin-online_help 
fusionforge-plugin-taskboard \
-           fusionforge-plugin-message
+           fusionforge-plugin-message fusionforge-plugin-globalactivity
     fi
 fi
diff --git a/src/plugins/globalactivity/INSTALL 
b/src/plugins/globalactivity/INSTALL
new file mode 100644
index 0000000..4b3b059
--- /dev/null
+++ b/src/plugins/globalactivity/INSTALL
@@ -0,0 +1,13 @@
+0. INSTALLATION of Globalactivity Plugin
+
+i.e. : if the directory where the plugins are is  /srv/www/gforge/plugins you 
should end up 
+       with /srv/www/gforge/plugins/globalactivity and all the files in it
+
+1. CONFIGURATION
+
+A) Make the symbolic links for each section
+
+(this is just an example, you should change the variables for what you have on 
your installation)
+
+/$GFORGEDIR/www/plugins/globalactivity -> /$GFORGEPLUGINSDIR/globalactivity/www
+/$ETC/gforge ->  /$GFORGEPLUGINSDIR/globalactivity/etc/plugins/globalactivity
diff --git a/src/plugins/globalactivity/README 
b/src/plugins/globalactivity/README
new file mode 100644
index 0000000..c8b6935
--- /dev/null
+++ b/src/plugins/globalactivity/README
@@ -0,0 +1 @@
+Globalactivity plugin
\ No newline at end of file
diff --git a/src/plugins/globalactivity/common/globalactivity-init.php 
b/src/plugins/globalactivity/common/globalactivity-init.php
new file mode 100644
index 0000000..8429e92
--- /dev/null
+++ b/src/plugins/globalactivity/common/globalactivity-init.php
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ *
+ * 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+global $gfplugins;
+require_once 
$gfplugins.'globalactivity/include/globalactivityPlugin.class.php' ;
+
+$globalactivityPluginObject = new globalactivityPlugin ;
+
+register_plugin ($globalactivityPluginObject) ;
+
+// Local Variables:
+// mode: php
+// c-file-style: "bsd"
+// End:
diff --git a/src/plugins/globalactivity/etc/globalactivity.ini 
b/src/plugins/globalactivity/etc/globalactivity.ini
new file mode 100644
index 0000000..591c0b5
--- /dev/null
+++ b/src/plugins/globalactivity/etc/globalactivity.ini
@@ -0,0 +1,7 @@
+[globalactivity]
+
+; plugin_status is a string.
+; valid means : production ready.
+; Any other strings means it's under work or broken and plugin
+; is available in installation_environment = development only.
+plugin_status = 'valid'
diff --git 
a/src/plugins/globalactivity/include/GlobalactivityPluginDescriptor.class.php 
b/src/plugins/globalactivity/include/GlobalactivityPluginDescriptor.class.php
new file mode 100644
index 0000000..9d0286c
--- /dev/null
+++ 
b/src/plugins/globalactivity/include/GlobalactivityPluginDescriptor.class.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Copyright (c) Xerox Corporation, Codendi Team, 2001-2009. All rights 
reserved
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Portions Copyright 2010 (c) Mélanie Le Bail
+ * Portions Copyright 2011 (c) France Telecom, Coclico project
+ */
+
+require_once 'common/plugin/PluginDescriptor.class.php';
+
+class GlobalactivityPluginDescriptor extends PluginDescriptor {
+
+    function GlobalactivityPluginDescriptor() {
+        $this->PluginDescriptor(_('Globalactivity'), 'v1.0', _('Global 
activity in the forge'));
+    }
+}
diff --git 
a/src/plugins/globalactivity/include/GlobalactivityPluginInfo.class.php 
b/src/plugins/globalactivity/include/GlobalactivityPluginInfo.class.php
new file mode 100644
index 0000000..88f233e
--- /dev/null
+++ b/src/plugins/globalactivity/include/GlobalactivityPluginInfo.class.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Copyright (c) Xerox Corporation, Codendi Team, 2001-2009. All rights 
reserved
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright 2010 (c) Mélanie Le Bail
+ * Copyright 2011 (c) France Telecom, Coclico project
+ */
+require_once 'common/plugin/PluginInfo.class.php';
+require_once 'GlobalactivityPluginDescriptor.class.php';
+
+class GlobalactivityPluginInfo extends PluginInfo {
+
+    function GlobalactivityPluginInfo(&$plugin) {
+        $this->PluginInfo($plugin);
+        $this->setPluginDescriptor(new GlobalactivityPluginDescriptor());
+    }
+
+}
diff --git a/src/plugins/globalactivity/include/globalactivityPlugin.class.php 
b/src/plugins/globalactivity/include/globalactivityPlugin.class.php
new file mode 100644
index 0000000..14ca531
--- /dev/null
+++ b/src/plugins/globalactivity/include/globalactivityPlugin.class.php
@@ -0,0 +1,128 @@
+<?php
+
+/**
+ * globalactivityPlugin Class
+ *
+ *
+ * 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+class globalactivityPlugin extends Plugin {
+       public function __construct($id=0) {
+               $this->Plugin($id) ;
+               $this->name = "globalactivity";
+               $this->text = "HelloWorld!"; // 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("groupmenu");   // To put into the project tabs
+               $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
+       }
+
+       function CallHook ($hookname, &$params) {
+               global $use_helloworldplugin,$G_SESSION,$HTML;
+               if ($hookname == "usermenu") {
+                       $text = $this->text; // this is what shows in the tab
+                       if ($G_SESSION->usesPlugin("helloworld")) {
+                               $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/helloworld/index.php' . $param ));
+
+                       }
+               } elseif ($hookname == "groupmenu") {
+                       $group_id=$params['group'];
+                       $project = group_get_object($group_id);
+                       if (!$project || !is_object($project)) {
+                               return;
+                       }
+                       if ($project->isError()) {
+                               return;
+                       }
+                       if (!$project->isProject()) {
+                               return;
+                       }
+                       if ( $project->usesPlugin ( $this->name ) ) {
+                               $params['TITLES'][]=$this->text;
+                               $params['DIRS'][]=util_make_url 
('/plugins/helloworld/index.php?type=group&id=' . $group_id . "&pluginname=" . 
$this->name) ; // we indicate the part we're calling is the project one
+                       } else {
+                               $params['TITLES'][]=$this->text." is [Off]";
+                               $params['DIRS'][]='';
+                       }
+                       (($params['toptab'] == $this->name) ? 
$params['selected']=(count($params['TITLES'])-1) : '' );
+               } 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 "<tr>";
+                       echo "<td>";
+                       echo ' <input type="checkbox" 
name="use_helloworldplugin" value="1" ';
+                       // checked or unchecked?
+                       if ( $group->usesPlugin ( $this->name ) ) {
+                               echo "checked";
+                       }
+                       echo " /><br/>";
+                       echo "</td>";
+                       echo "<td>";
+                       echo "<strong>Use ".$this->text." Plugin</strong>";
+                       echo "</td>";
+                       echo "</tr>";
+               } 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_helloworldplugin = 
getStringFromRequest('use_helloworldplugin');
+                       if ( $use_helloworldplugin == 1 ) {
+                               $group->setPluginUse ( $this->name );
+                       } else {
+                               $group->setPluginUse ( $this->name, false );
+                       }
+               } elseif ($hookname == "user_personal_links") {
+                       // this displays the link in the user's profile page to 
it's personal HelloWorld (if you want other sto access it, youll have to change 
the permissions in the index.php
+                       $userid = $params['user_id'];
+                       $user = user_get_object($userid);
+                       $text = $params['text'];
+                       //check if the user has the plugin activated
+                       if ($user->usesPlugin($this->name)) {
+                               echo '  <p>' ;
+                               echo util_make_link 
("/plugins/helloworld/index.php?id=$userid&type=user&pluginname=".$this->name,
+                                                    _('View Personal 
HelloWorld')
+                                       );
+                               echo '</p>';
+                       }
+               } elseif ($hookname == "project_admin_plugins") {
+                       // this displays the link in the project admin options 
page to it's  HelloWorld administration
+                       $group_id = $params['group_id'];
+                       $group = group_get_object($group_id);
+                       if ( $group->usesPlugin ( $this->name ) ) {
+                               echo '<p>'.util_make_link 
("/plugins/helloworld/admin/index.php?id=".$group->getID().'&type=admin&pluginname='.$this->name,
+                                                    _('HelloWorld 
Admin')).'</p>' ;
+                       }
+               }
+               elseif ($hookname == "blahblahblah") {
+                       // ...
+               }
+       }
+}
+
+// Local Variables:
+// mode: php
+// c-file-style: "bsd"
+// End:
diff --git a/src/plugins/globalactivity/www/admin/index.php 
b/src/plugins/globalactivity/www/admin/index.php
new file mode 100644
index 0000000..c246739
--- /dev/null
+++ b/src/plugins/globalactivity/www/admin/index.php
@@ -0,0 +1,110 @@
+<?php
+
+/*
+ * HelloWorld plugin
+ *
+ * Daniel Perez <[email protected]>
+ *
+ * This is an example to watch things in action. You can obviously modify 
things and logic as you see fit
+ */
+
+require_once '../../../env.inc.php';
+require_once $gfwww.'include/pre.php';
+require_once $gfconfig.'plugins/helloworld/config.php';
+
+// the header that displays for the user portion of the plugin
+function helloworld_Project_Header($params) {
+       global $DOCUMENT_ROOT,$HTML,$id;
+       $params['toptab']='helloworld';
+       $params['group']=$id;
+       /*
+               Show horizontal links
+       */
+       site_project_header($params);
+}
+
+// the header that displays for the project portion of the plugin
+function helloworld_User_Header($params) {
+       global $DOCUMENT_ROOT,$HTML,$user_id;
+       $params['toptab']='helloworld';
+       $params['user']=$user_id;
+       /*
+        Show horizontal links
+        */
+       site_user_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');
+
+       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 HelloWorld plugin active
+                               exit_error("Error", "First activate the 
$pluginname plugin through the Project's Admin Interface");
+                       }
+                       $userperm = $group->getPermission();//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...
+                       helloworld_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 HelloWorld plugin <br>";
+                       echo "Greetings from planet " . $world; // $world comes 
from the config file in /etc
+               } elseif ($type == 'user') {
+                       $realuser = user_get_object($id);//
+                       if (!($realuser) || 
!($realuser->usesPlugin($pluginname))) {
+                               exit_error("Error", "First activate the User's 
$pluginname plugin through Account Manteinance Page");
+                       }
+                       if ( (!$user) || ($user->getID() != $id)) { // if 
someone else tried to access the private HelloWorld part of this user
+                               exit_error("Access Denied", "You cannot access 
other user's personal $pluginname");
+                       }
+                       helloworld_User_Header(array('title'=>'My 
'.$pluginname,'pagename'=>"$pluginname",'sectionvals'=>array($realuser->getUnixName())));
+                       // DO THE STUFF FOR THE USER PART HERE
+                       echo "We are in the User HelloWorld plugin <br>";
+                       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 HelloWorld plugin active
+                               exit_error("Error", "First activate the 
$pluginname plugin through the Project's Admin Interface");
+                       }
+                       $userperm = $group->getPermission();//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() ) {
+                               
helloworld_Project_Header(array('title'=>$pluginname . ' Project 
Plugin!','pagename'=>"$pluginname",'sectionvals'=>array(group_getname($id))));
+                               // DO THE STUFF FOR THE PROJECT ADMINISTRATION 
PART HERE
+                               echo "We are in the Project HelloWorld plugin 
<font color=\"#ff0000\">ADMINISTRATION</font> <br>";
+                               echo "Greetings from planet " . $world; // 
$world comes from the config file in /etc
+                       } else {
+                               exit_error("Access Denied", "You are not a 
project Admin");
+                       }
+               }
+       }
+
+       site_project_footer();
+
+// Local Variables:
+// mode: php
+// c-file-style: "bsd"
+// End:
diff --git a/src/plugins/globalactivity/www/index.php 
b/src/plugins/globalactivity/www/index.php
new file mode 100644
index 0000000..9663aff
--- /dev/null
+++ b/src/plugins/globalactivity/www/index.php
@@ -0,0 +1,394 @@
+<?php
+/**
+ * Global Activity Page
+ *
+ * Copyright 1999 dtype
+ * Copyright 2006 (c) GForge, LLC
+ * Copyright 2010-2011, Franck Villaume - Capgemini
+ * Copyright 2012-2014, Franck Villaume - TrivialDev
+ * Copyright (C) 2012 Alain Peyrat - Alcatel-Lucent
+ * Copyright 2014, Benoit Debaenst - TrivialDev
+ * Copyright 2016, Roland Mas
+ * http://fusionforge.org/
+ *
+ * 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 Licence, 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+require_once '../../env.inc.php';
+require_once $gfcommon.'include/pre.php';
+
+global $HTML;
+
+$received_begin = getStringFromRequest("start_date");
+$received_end = getStringFromRequest("end_date");
+$show = getArrayFromRequest("show");
+
+$date_format = _('%Y-%m-%d');
+
+if (!$received_begin || $received_begin==0) {
+       $begin = (time()-(30*86400));
+       $rendered_begin = strftime($date_format, $begin);
+} else {
+       $tmp = strptime($received_begin, $date_format);
+       if (!$tmp) {
+               $begin = (time()-(7*86400));
+               $rendered_begin = strftime($date_format, $begin);
+       } else {
+               $begin = mktime(0, 0, 0, $tmp['tm_mon']+1, $tmp['tm_mday'], 
$tmp['tm_year'] + 1900);
+               $rendered_begin = $received_begin;
+       }
+}
+if ($begin < 0) {
+    $begin = 0;
+    $rendered_begin = strftime($date_format, $begin);
+}
+
+if (!$received_end || $received_end == 0) {
+       $end = time();
+       $rendered_end = strftime($date_format, $end);
+} else {
+       $tmp = strptime($received_end, $date_format);
+       if (!$tmp) {
+               $end = time();
+               $rendered_end = strftime($date_format, $end);
+       } else {
+               $end = mktime(23, 59, 59, $tmp['tm_mon']+1, $tmp['tm_mday'], 
$tmp['tm_year'] + 1900);
+               $rendered_end = $received_end;
+       }
+}
+
+if ($begin > $end) {
+       $tmp = $end;
+       $end = $begin;
+       $begin = $tmp;
+       $tmp = $rendered_end;
+       $rendered_end = $rendered_begin;
+       $rendered_begin = $tmp;
+}
+
+if (!forge_get_config('use_activity')) {
+       exit_disabled();
+}
+
+site_header(array('title'=>_('Global activity')));
+
+$ids = array();
+$texts = array();
+
+if (forge_get_config('use_forum')) {
+       $ids[]          = 'forumpost';
+       $texts[]        = _('Forum Post');
+}
+
+if (forge_get_config('use_tracker')) {
+       $ids[]          = 'trackeropen';
+       $texts[]        = _('Tracker Opened');
+       $ids[]          = 'trackerclose';
+       $texts[]        = _('Tracker Closed');
+}
+
+if (forge_get_config('use_news')) {
+       $ids[]          = 'news';
+       $texts[]        = _('News');
+}
+
+if (forge_get_config('use_pm')) {
+       $ids[]          = 'taskopen';
+       $texts[]        = _('Tasks Opened');
+       $ids[]          = 'taskclose';
+       $texts[]        = _('Tasks Closed');
+       $ids[]          = 'taskdelete';
+       $texts[]        = _('Tasks Deleted');
+}
+
+if (forge_get_config('use_frs')) {
+       $ids[]          = 'frsrelease';
+       $texts[]        = _('FRS Release');
+}
+
+if (forge_get_config('use_docman')) {
+       $ids[]          = 'docmannew';
+       $texts[]        = _('New Documents');
+       $ids[]          = 'docmanupdate';
+       $texts[]        = _('Updated Documents');
+       $ids[]          = 'docgroupnew';
+       $texts[]        = _('New Directories');
+}
+
+if (count($show) < 1) {
+       $section = $ids;
+} else {
+       $section = $show;
+}
+
+$res = db_query_params('SELECT * FROM activity_vw WHERE activity_date BETWEEN 
$1 AND $2
+                       AND section = ANY ($3) ORDER BY activity_date DESC',
+                       array($begin,
+                               $end,
+                               db_string_array_to_any_clause($section)));
+
+if (db_error()) {
+       exit_error(db_error(), 'home');
+}
+
+$results = array();
+while ($arr = db_fetch_array($res)) {
+       $results[] = $arr;
+}
+
+$res = db_query_params('SELECT group_id FROM groups WHERE status=$1',
+    array('A'));
+
+if (db_error()) {
+       exit_error(db_error(), 'home');
+}
+
+// If plugins wants to add activities.
+while ($arr = db_fetch_array($res)) {
+       $group_id = $arr['group_id'];
+       $hookParams['group'] = $group_id;
+       $hookParams['results'] = &$results;
+       $hookParams['show'] = &$show;
+       $hookParams['begin'] = $begin;
+       $hookParams['end'] = $end;
+       $hookParams['ids'] = &$ids;
+       $hookParams['texts'] = &$texts;
+       plugin_hook("activity", $hookParams);
+}
+
+if (count($show) < 1) {
+       $show = $ids;
+}
+
+foreach ($show as $showthis) {
+       if (array_search($showthis, $ids) === false) {
+               exit_error(_('Invalid Data Passed to query'), 'home');
+       }
+}
+
+if (count($ids) < 1) {
+       echo $HTML->information(_('No Activity Found'));
+} else {
+?>
+
+<div id="activity">
+<div id="activity_left">
+
+<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
+
+<div id="activity_select" >
+<div id="activity_label"><?php echo _('Activity')._(':'); ?></div>
+<?php echo html_build_multiple_select_box_from_arrays($ids, $texts, 'show[]', 
$show, count($texts), false); ?>
+</div>
+
+<div id="activity_startdate" >
+<div id="activity_label_startdate"><?php echo _('Start Date')._(':'); ?></div>
+<input name="start_date" value="<?php echo $rendered_begin; ?>" size="10" 
maxlength="10" />
+</div>
+
+<div id="activity_enddate" >
+<div id="activity_label_enddate"><?php echo _('End Date')._(':'); ?></div>
+<input name="end_date" value="<?php echo $rendered_end; ?>" size="10" 
maxlength="10" />
+</div>
+
+<div id="activity_submit" >
+<input type="submit" name="submit" value="<?php echo _('Refresh'); ?>" />
+</div>
+
+</form>
+</div>
+
+<div id="activity_right">
+<?php
+       if (count($results) < 1) {
+               echo $HTML->information(_('No Activity Found'));
+       } else {
+
+               function date_compare($a, $b)
+               {
+                       if ($a['activity_date'] == $b['activity_date']) {
+                               return 0;
+                       }
+                       return ($a['activity_date'] > $b['activity_date']) ? -1 
: 1;
+               }
+
+               $cached_perms = array();
+               function check_perm_for_activity($arr) {
+                       global $cached_perms;
+                       $s = $arr['section'];
+                       $ref = $arr['ref_id'];
+                       $group_id = $arr['group_id'];
+
+                       if (!isset($cached_perms[$s][$ref])) {
+                               switch ($s) {
+                                       case 'scm': {
+                                               $cached_perms[$s][$ref] = 
forge_check_perm('scm', $group_id, 'read');
+                                               break;
+                                       }
+                                       case 'trackeropen':
+                                       case 'trackerclose': {
+                                               $cached_perms[$s][$ref] = 
forge_check_perm('tracker', $ref, 'read');
+                                               break;
+                                       }
+                                       case 'frsrelease': {
+                                               $cached_perms[$s][$ref] = 
forge_check_perm('frs', $ref, 'read');
+                                               break;
+                                       }
+                                       case 'forumpost':
+                                       case 'news': {
+                                               $cached_perms[$s][$ref] = 
forge_check_perm('forum', $ref, 'read');
+                                               break;
+                                       }
+                                       case 'taskopen':
+                                       case 'taskclose':
+                                       case 'taskdelete': {
+                                               $cached_perms[$s][$ref] = 
forge_check_perm('pm', $ref, 'read');
+                                               break;
+                                       }
+                                       case 'docmannew':
+                                       case 'docmanupdate':
+                                       case 'docgroupnew': {
+                                               $cached_perms[$s][$ref] = 
forge_check_perm('docman', $group_id, 'read');
+                                               break;
+                                       }
+                                       default: {
+                                               // Must be a bug somewhere, 
we're supposed to handle all types
+                                               $cached_perms[$s][$ref] = false;
+                                       }
+                               }
+                       }
+                       return $cached_perms[$s][$ref];
+               }
+
+               usort($results, 'date_compare');
+
+               $displayTableTop = 0;
+               $j = 0;
+               $last_day = 0;
+               foreach ($results as $arr) {
+
+                       $group_id = $arr['group_id'];
+                       if (!forge_check_perm('project_read', $group_id)) {
+                               continue;
+                       }
+
+                       if (!check_perm_for_activity($arr)) {
+                               continue;
+                       }
+                       if (!$displayTableTop) {
+                               $theader = array();
+                               $theader[] = _('Project');
+                               $theader[] = _('Time');
+                               $theader[] = _('Activity');
+                               $theader[] = _('By');
+
+                               echo $HTML->listTableTop($theader);
+                               $displayTableTop = 1;
+                       }
+                       if ($last_day != strftime($date_format, 
$arr['activity_date'])) {
+                               //      echo $HTML->listTableBottom($theader);
+                               echo '<tr class="tableheading"><td 
colspan="4">'.strftime($date_format, $arr['activity_date']).'</td></tr>';
+                               //      echo $HTML->listTableTop($theader);
+                               $last_day=strftime($date_format, 
$arr['activity_date']);
+                       }
+                       switch (@$arr['section']) {
+                               case 'scm': {
+                                       $icon = 
html_image('ic/cvs16b.png','','',array('alt'=>_('Source Code')));
+                                       $url = 
util_make_link('/scm/'.$arr['ref_id'].$arr['subref_id'],_('scm commit')._(': 
').$arr['description']);
+                                       break;
+                               }
+                               case 'trackeropen': {
+                                       $icon = 
html_image('ic/tracker20g.png','','',array('alt'=>_('Trackers')));
+                                       $url = 
util_make_link('/tracker/?func=detail&atid='.$arr['ref_id'].'&aid='.$arr['subref_id'].'&group_id='.$arr['group_id'],_('Tracker
 Item').' [#'.$arr['subref_id'].'] '.$arr['description'].' '._('Opened'));
+                                       break;
+                               }
+                               case 'trackerclose': {
+                                       $icon = 
html_image('ic/tracker20g.png','','',array('alt'=>_('Trackers')));
+                                       $url = 
util_make_link('/tracker/?func=detail&atid='.$arr['ref_id'].'&aid='.$arr['subref_id'].'&group_id='.$arr['group_id'],_('Tracker
 Item').' [#'.$arr['subref_id'].'] '.$arr['description'].' '._('Closed'));
+                                       break;
+                               }
+                               case 'frsrelease': {
+                                       $icon = 
html_image('ic/cvs16b.png','','',array('alt'=>_('Files')));
+                                       $url = 
util_make_link('/frs/?release_id='.$arr['subref_id'].'&group_id='.$arr['group_id'],_('FRS
 Release').' '.$arr['description']);
+                                       break;
+                               }
+                               case 'forumpost': {
+                                       $icon = 
html_image('ic/forum20g.png','','',array('alt'=>_('Forum')));
+                                       $url = 
util_make_link('/forum/message.php?msg_id='.$arr['subref_id'].'&group_id='.$arr['group_id'],_('Forum
 Post').' '.$arr['description']);
+                                       break;
+                               }
+                               case 'news': {
+                                       $icon = 
html_image('ic/write16w.png','','',array('alt'=>_('News')));
+                                       $url = 
util_make_link('/forum/forum.php?forum_id='.$arr['subref_id'],_('News').' 
'.$arr['description']);
+                                       break;
+                               }
+                               case 'taskopen': {
+                                       $icon = 
html_image('ic/taskman20w.png','','',array('alt'=>_('Tasks')));
+                                       $url = 
util_make_link('/pm/task.php?func=detailtask&project_task_id='.$arr['subref_id'].'&group_id='.$arr['group_id'].'&group_project_id='.$arr['ref_id'],_('Tasks').'
 '.$arr['description']);
+                                       break;
+                               }
+                               case 'taskclose': {
+                                       $icon = 
html_image('ic/taskman20w.png','','',array('alt'=>_('Tasks')));
+                                       $url = 
util_make_link('/pm/task.php?func=detailtask&project_task_id='.$arr['subref_id'].'&group_id='.$arr['group_id'].'&group_project_id='.$arr['ref_id'],_('Tasks').'
 '.$arr['description']);
+                                       break;
+                               }
+
+                               case 'taskdelete': {
+                                       $icon = 
html_image('ic/taskman20w.png','','',array('alt'=>_('Tasks')));
+                                       $url = 
util_make_link('/pm/task.php?func=detailtask&project_task_id='.$arr['subref_id'].'&group_id='.$arr['group_id'].'&group_project_id='.$arr['ref_id'],_('Tasks').'
 '.$arr['description']);
+                                       break;
+                               }
+                               case 'docmannew':
+                               case 'docmanupdate': {
+                                       $icon = html_image('ic/docman16b.png', 
'', '', array('alt'=>_('Documents')));
+                                       $url = 
util_make_link('docman/?group_id='.$arr['group_id'].'&view=listfile&dirid='.$arr['ref_id'],_('Document').'
 '.$arr['description']);
+                                       break;
+                               }
+                               case 'docgroupnew': {
+                                       $icon = html_image('ic/cfolder15.png', 
'', '', array("alt"=>_('Directory')));
+                                       $url = 
util_make_link('docman/?group_id='.$arr['group_id'].'&view=listfile&dirid='.$arr['subref_id'],_('Directory').'
 '.$arr['description']);
+                                       break;
+                               }
+                               default: {
+                                       $icon = isset($arr['icon']) ? 
$arr['icon'] : '';
+                                       $url = '<a 
href="'.$arr['link'].'">'.$arr['title'].'</a>';
+                               }
+                       }
+                       $cells = array();
+                       $cells[][] = 
util_make_link_g(group_get_object($group_id)->getUnixName(),$group_id,group_get_object($group_id)->getPublicName());
+                       $cells[][] = date('H:i:s',$arr['activity_date']);
+                       $cells[][] = $icon .' '.$url;
+                       if (isset($arr['user_name']) && $arr['user_name']) {
+                               $cells[][] = 
util_display_user($arr['user_name'], $arr['user_id'],$arr['realname']);
+                       } else {
+                               $cells[][] = $arr['realname'];
+                       }
+                       echo $HTML->multiTableRow(array('class' => 
$HTML->boxGetAltRowStyle($j++, true)), $cells);
+               }
+               if ($displayTableTop) {
+                       echo $HTML->listTableBottom($theader);
+               }
+               if (!$displayTableTop) {
+                       echo $HTML->information(_('No Activity Found'));
+               }
+       }
+
+       echo '</div>';
+       echo '</div>';
+}
+
+
+site_project_footer();

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=a0bcf394e9020acff0b8739b96004d37a7e1a884

commit a0bcf394e9020acff0b8739b96004d37a7e1a884
Author: Roland Mas <[email protected]>
Date:   Tue May 31 13:47:57 2016 +0200

    Activity: avoid duplicate sections
    
    This change is harmless in the standard case but avoids duplicate
    sections in the globalactivity plugin.

diff --git a/src/plugins/scmgit/common/GitPlugin.class.php 
b/src/plugins/scmgit/common/GitPlugin.class.php
index 31e8f78..30e0c39 100644
--- a/src/plugins/scmgit/common/GitPlugin.class.php
+++ b/src/plugins/scmgit/common/GitPlugin.class.php
@@ -1022,8 +1022,10 @@ control over it to the project's administrator.");
                                }
                        }
                }
-               $params['ids'][] = $this->name;
-               $params['texts'][] = _('Git Commits');
+               if (!in_array($this->name, $params['ids'])) {
+                       $params['ids'][] = $this->name;
+                       $params['texts'][] = _('Git Commits');
+               }
                return true;
        }
 
diff --git a/src/plugins/scmhg/common/HgPlugin.class.php 
b/src/plugins/scmhg/common/HgPlugin.class.php
index 3c626c7..370b933 100644
--- a/src/plugins/scmhg/common/HgPlugin.class.php
+++ b/src/plugins/scmhg/common/HgPlugin.class.php
@@ -635,8 +635,10 @@ Offer DAV or SSH access.");
                                }
                        }
                }
-               $params['ids'][] = $this->name;
-               $params['texts'][] = _('Hg Commits');
+               if (!in_array($this->name, $params['ids'])) {
+                       $params['ids'][] = $this->name;
+                       $params['texts'][] = _('Hg Commits');
+               }
                return true;
        }
 
diff --git a/src/plugins/scmsvn/common/SVNPlugin.class.php 
b/src/plugins/scmsvn/common/SVNPlugin.class.php
index 91b2d4c..d4a0b2f 100644
--- a/src/plugins/scmsvn/common/SVNPlugin.class.php
+++ b/src/plugins/scmsvn/common/SVNPlugin.class.php
@@ -629,8 +629,10 @@ some control over it to the project's administrator.");
                                }
                        }
                }
-               $params['ids'][] = $this->name;
-               $params['texts'][] = _('Subversion Commits');
+               if (!in_array($this->name, $params['ids'])) {
+                       $params['ids'][] = $this->name;
+                       $params['texts'][] = _('Subversion Commits');
+               }
                return true;
        }
 

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=d067e68ed6e761a98c2165fc860802af35688319

commit d067e68ed6e761a98c2165fc860802af35688319
Author: Roland Mas <[email protected]>
Date:   Tue May 31 13:47:57 2016 +0200

    New hook to allow plugins to register SOAP methods

diff --git a/src/www/soap/index.php b/src/www/soap/index.php
index 8ffe50d..99c4e67 100644
--- a/src/www/soap/index.php
+++ b/src/www/soap/index.php
@@ -128,6 +128,11 @@ require_once $gfwww.'soap/frs/frs.php';
 //
 require_once $gfwww.'soap/scm/scm.php';
 
+// Include methods defined by plugins
+$params = array();
+$params['server'] = &$server;
+plugin_hook('register_soap',$params);
+
 $wsdl_data = $server->wsdl->serialize();
 
 if (isset($wsdl)) {

-----------------------------------------------------------------------


hooks/post-receive
-- 
FusionForge

_______________________________________________
Fusionforge-commits mailing list
[email protected]
http://lists.fusionforge.org/cgi-bin/mailman/listinfo/fusionforge-commits

Reply via email to