Commit in PEAR_Server on MAIN
Server/Backend.php+20-11.11 -> 1.12
      /REST.php+157-181.1 -> 1.2
      /mysqlinstall.php+12-11.29 -> 1.30
      /Backend.php+20-11.11 -> 1.12
      /REST.php+157-181.1 -> 1.2
      /mysqlinstall.php+12-11.29 -> 1.30
Server/Backend/DBDataObject.php+2-21.50 -> 1.51
              /DBDataObject.php+2-21.50 -> 1.51
makepackage.php+3-31.5 -> 1.6
package.xml+21-81.41 -> 1.42
+406-55
10 modified files
fully implement REST 1.1
fix Chiara_PEAR_Server_REST bugs
fix PHP 5.0.5-specific bugs in Chiara_PEAR_Server_Backend_DBDataObject
prepare for 0.18.4

PEAR_Server/Server
Backend.php 1.11 -> 1.12
diff -u -r1.11 -r1.12
--- Backend.php	3 Nov 2005 05:42:59 -0000	1.11
+++ Backend.php	12 Nov 2005 17:45:39 -0000	1.12
@@ -1,5 +1,6 @@
 <?php
 require_once 'Chiara/PEAR/Server/Maintainer.php';
+require_once 'Chiara/PEAR/Server/REST.php';
 /**
  * Base class for all backends.
  * @author Gregory Beaver <cellog@php.net>
@@ -16,7 +17,7 @@
     public function __construct($channel, $restdir)
     {
         $this->_channel = $channel;
-        $this->_restdir = $restdir;
+        $this->_rest = new Chiara_PEAR_Server_REST($this, $restdir);
     }
 
     /**
@@ -77,6 +78,19 @@
         return $this->_rest->saveCategoryREST($category);
     }
 
+    public function saveAllCategoriesREST()
+    {
+        return $this->_rest->saveAllCategoriesREST();
+    }
+
+    /**
+     * @param string
+     */
+    public function savePackagesCategoryREST($category)
+    {
+        return $this->_rest->savePackagesCategoryREST($category);
+    }
+
     /**
      * @param string
      */
@@ -116,6 +130,11 @@
         return $this->_rest->deleteReleaseREST($package, $version);
     }
 
+    public function saveAllMaintainersREST()
+    {
+        return $this->_rest->saveAllMaintainersREST();
+    }
+
     public function saveMaintainerREST(Chiara_PEAR_Server_Maintainer $maintainer)
     {
         return $this->_rest->saveMaintainerREST($maintainer);

PEAR_Server/Server
REST.php 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- REST.php	3 Nov 2005 05:42:59 -0000	1.1
+++ REST.php	12 Nov 2005 17:45:39 -0000	1.2
@@ -4,7 +4,7 @@
  * REST implementation class (backend-independent)
  * @author Gregory Beaver <cellog@php.net>
  */
-abstract class Chiara_PEAR_Server_REST
+class Chiara_PEAR_Server_REST
 {
     protected $_channel;
     protected $_restdir;
@@ -79,11 +79,21 @@
             DIRECTORY_SEPARATOR . $version . '.xml', 0666);
         file_put_contents($rdir . DIRECTORY_SEPARATOR . strtolower($release['package']) .
             DIRECTORY_SEPARATOR . 'package.' .
-            $version . '.xml', $this->getPackageXml($release['package'], $version));
+            $version . '.xml', $this->_backend->getPackageXml($release['package'], $version));
         @chmod($rdir . DIRECTORY_SEPARATOR . strtolower($release['package']) .
             DIRECTORY_SEPARATOR . 'package.' . $version . '.xml', 0666);
     }
 
+    function _getAllReleasesRESTProlog($package)
+    {
+        return '<?xml version="1.0" encoding="UTF-8" ?>' . "\n" .
+'<a xmlns="http://pear.php.net/dtd/rest.allreleases"' . "\n" .
+'    xsi:schemaLocation="http://pear.php.net/dtd/rest.allreleases' . "\n" .
+'    http://pear.php.net/dtd/rest.allreleases.xsd">' . "\n" .
+' <p>' . htmlspecialchars($package) . '</p>' . "\n" .
+' <c>' . htmlspecialchars($this->_channel) . '</c>' . "\n";
+    }
+
     /**
      * @param string
      */
@@ -95,17 +105,12 @@
         } else {
             $extra = '/Chiara_PEAR_Server_REST/';
         }
+        $rdir = $this->_restdir . DIRECTORY_SEPARATOR . 'r';
         $releases = $this->_backend->listReleases($package);
         if (!$releases) {
             return;
         }
-        $info = '<?xml version="1.0" encoding="iso-8859-1" ?>
-<a xmlns="http://pear.php.net/dtd/rest.allreleases"
-    xsi:schemaLocation="http://pear.php.net/dtd/rest.allreleases
-    http://pear.php.net/dtd/rest.allreleases.xsd">
- <p>' . $package . '</p>
- <c>' . $this->_channel . '</c>
-';
+        $info = $this->_getAllReleasesRESTProlog($package);
         foreach ($releases as $release) {
             if (!class_exists('PEAR_PackageFile_Parser_v2')) {
                 require_once 'PEAR/PackageFile/Parser/v2.php';
@@ -239,18 +244,14 @@
         } else {
             $deprecated = '';
         }
-        $info = '<?xml version="1.0" encoding="iso-8859-1" ?>
-<p xmlns="http://pear.php.net/dtd/rest.package"
-    xsi:schemaLocation="http://pear.php.net/dtd/rest.package
-    http://pear.php.net/dtd/rest.package.xsd">
+        $info = $this->_getPackageRESTProlog() . '
  <n>' . $package['package'] . '</n>
  <c>' . $package['channel'] . '</c>
  <ca xlink:href="' . $extra . 'c/' . urlencode($catinfo['name']) . '">' .
             htmlspecialchars($catinfo['name']) . '</ca>
  <l>' . $package['license'] . '</l>' . ($package['licenseuri'] ? '
  <lu>' . $package['licenseuri'] . '</lu>
-' : '
-') . '
+' : '') . '
  <s>' . htmlspecialchars($package['summary']) . '</s>
  <d>' . htmlspecialchars($package['description']) . '</d>
  <r xlink:href="' . $extra . 'r/' . $package['package'] . '"/>
@@ -327,6 +328,81 @@
             DIRECTORY_SEPARATOR . 'packages.xml', 0666);
     }
 
+    private function _getPackageRESTProlog()
+    {
+        return "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" .
+"<p xmlns=\"http://pear.php.net/dtd/rest.package\"" .
+"    xsi:schemaLocation=\"http://pear.php.net/dtd/rest.package" .
+'    http://pear.php.net/dtd/rest.package.xsd">';
+    }
+
+    public function savePackagesCategoryREST($category)
+    {
+        $channelinfo = parse_url($this->_channel);
+        if (isset($channelinfo['host'])) {
+            $extra = $channelinfo['path'] . '/Chiara_PEAR_Server_REST/';
+        } else {
+            $extra = '/Chiara_PEAR_Server_REST/';
+        }
+        $cdir = $this->_restdir . DIRECTORY_SEPARATOR . 'c';
+        if (!is_dir($cdir)) {
+            return;
+        }
+        $pdir = $this->_restdir . DIRECTORY_SEPARATOR . 'p';
+        $rdir = $this->_restdir . DIRECTORY_SEPARATOR . 'r';
+        $packages = $this->_backend->listPackagesInCategory($category);
+        $fullpackageinfo = '<?xml version="1.0" encoding="UTF-8" ?>
+<f xmlns="http://pear.php.net/dtd/rest.categorypackageinfo"
+    xsi:schemaLocation="http://pear.php.net/dtd/rest.categorypackageinfo
+    http://pear.php.net/dtd/rest.categorypackageinfo.xsd">
+';
+        clearstatcache();
+        foreach ($packages as $package) {
+            if (!file_exists($pdir . DIRECTORY_SEPARATOR . strtolower($package['package']) .
+                    DIRECTORY_SEPARATOR . 'info.xml')) {
+                continue;
+            }
+            $fullpackageinfo .= '<pi>
+';
+            $fullpackageinfo .= str_replace($this->_getPackageRESTProlog(), '<p>',
+                file_get_contents($pdir . DIRECTORY_SEPARATOR . strtolower($package['package']) .
+                    DIRECTORY_SEPARATOR . 'info.xml'));
+            if (file_exists($rdir . DIRECTORY_SEPARATOR . strtolower($package['package']) .
+                    DIRECTORY_SEPARATOR . 'allreleases.xml')) {
+                $fullpackageinfo .= str_replace(
+                    $this->_getAllReleasesRESTProlog($package['package']), '
+<a>
+',
+                    file_get_contents($rdir . DIRECTORY_SEPARATOR .
+                        strtolower($package['package']) . DIRECTORY_SEPARATOR .
+                        'allreleases.xml'));
+                $dirhandle = opendir($rdir . DIRECTORY_SEPARATOR .
+                    strtolower($package['package']));
+                while (false !== ($entry = readdir($dirhandle))) {
+                    if (strpos($entry, 'deps.') === 0) {
+                        $version = str_replace(array('deps.', '.txt'), array('', ''), $entry);
+                        $fullpackageinfo .= '
+<deps>
+ <v>' . $version . '</v>
+ <d>' . htmlspecialchars(utf8_encode(file_get_contents($rdir . DIRECTORY_SEPARATOR .
+                        strtolower($package['package']) . DIRECTORY_SEPARATOR .
+                        $entry))) . '</d>
+</deps>
+';
+                    }
+                }
+            }
+            $fullpackageinfo .= '</pi>
+';
+        }
+        $fullpackageinfo .= '</f>';
+        // list packages in a category
+        file_put_contents($cdir . DIRECTORY_SEPARATOR . urlencode($category) .
+            DIRECTORY_SEPARATOR . 'packagesinfo.xml', $fullpackageinfo);
+        @chmod($cdir . DIRECTORY_SEPARATOR . urlencode($category) .
+            DIRECTORY_SEPARATOR . 'packagesinfo.xml', 0666);
+    }
+
     /**
      * @param string
      */
@@ -341,6 +417,41 @@
             . DIRECTORY_SEPARATOR . urlencode($category)));
     }
 
+    public function saveAllCategoriesREST()
+    {
+        require_once 'System.php';
+        $channelinfo = parse_url($this->_channel);
+        if (isset($channelinfo['host'])) {
+            $extra = $channelinfo['path'] . '/Chiara_PEAR_Server_REST/';
+        } else {
+            $extra = '/Chiara_PEAR_Server_REST/';
+        }
+        $cdir = $this->_restdir . DIRECTORY_SEPARATOR . 'c';
+        if (!is_dir($cdir)) {
+            System::mkdir(array('-p', $cdir));
+            @chmod($cdir, 0777);
+        }
+
+        $categories = $this->_backend->listCategories();
+        $info = '<?xml version="1.0" encoding="UTF-8" ?>
+<a xmlns="http://pear.php.net/dtd/rest.allcategories"
+    xsi:schemaLocation="http://pear.php.net/dtd/rest.allcategories
+    http://pear.php.net/dtd/rest.allcategories.xsd">
+<ch>' . $this->_channel . '</ch>
+';
+        foreach ($categories as $category)
+        {
+            $info .= ' <c xlink:href="' . $extra . 'c/' .
+                urlencode(urlencode($category['name'])) .
+                '/info.xml">' .
+                htmlspecialchars(utf8_encode($category['name'])) . '</c>
+';
+        }
+        $info .= '</a>';
+        file_put_contents($cdir . DIRECTORY_SEPARATOR . 'categories.xml', $info);
+        @chmod($cdir . DIRECTORY_SEPARATOR . 'categories.xml', 0666);
+    }
+
     /**
      * @param string
      * @param string
@@ -403,7 +514,7 @@
     http://pear.php.net/dtd/rest.allpackages.xsd">
  <c>' . htmlspecialchars($this->_channel) . '</c>
 ';
-        foreach ($this->listPackages(false, false, false) as $package)
+        foreach ($this->_backend->listPackages(false, false, false) as $package)
         {
             $info .= ' <p>' . $package['package'] . '</p>
 ';
@@ -436,8 +547,8 @@
  <c>' . htmlspecialchars($this->_channel) . '</c>
 ';
             foreach ($maintainers as $maintainer) {
-                $info .= ' <m><h>' . $maintainer['handle'] . '</h><a>' .
-                    $maintainers['active'] .
+                $info .= ' <m><h>' . $maintainer->handle . '</h><a>' .
+                    ($maintainer->active ? '1' : '0') .
                     '</a></m>';
             }
             $info .= '</m>';
@@ -451,6 +562,34 @@
         }
     }
 
+    public function saveAllMaintainersREST()
+    {
+        $channelinfo = parse_url($this->_channel);
+        if (isset($channelinfo['host'])) {
+            $extra = $channelinfo['path'] . '/Chiara_PEAR_Server_REST/';
+        } else {
+            $extra = '/Chiara_PEAR_Server_REST/';
+        }
+        $maintainers = $this->_backend->listMaintainers();
+        $info = '<?xml version="1.0" encoding="UTF-8" ?>
+<m xmlns="http://pear.php.net/dtd/rest.allmaintainers"
+    xsi:schemaLocation="http://pear.php.net/dtd/rest.allmaintainers
+    http://pear.php.net/dtd/rest.allmaintainers.xsd">' . "\n";
+        // package information
+        foreach ($maintainers as $maintainer) {
+            $info .= ' <h xlink:href="' . $extra . 'm/' . $maintainer->handle . '">' .
+                $maintainer->handle . '</h>' . "\n";
+        }
+        $info .= '</m>';
+        $mdir = $this->_restdir . DIRECTORY_SEPARATOR . 'm';
+        if (!is_dir($mdir)) {
+            System::mkdir(array('-p', $mdir));
+            @chmod($mdir, 0777);
+        }
+        file_put_contents($mdir . DIRECTORY_SEPARATOR . 'allmaintainers.xml', $info);
+        @chmod($mdir . DIRECTORY_SEPARATOR . 'allmaintainers.xml', 0666);
+    }
+
     public function saveMaintainerREST(Chiara_PEAR_Server_Maintainer $maintainer)
     {
         $channelinfo = parse_url($this->_channel);

PEAR_Server/Server
mysqlinstall.php 1.29 -> 1.30
diff -u -r1.29 -r1.30
--- mysqlinstall.php	5 Oct 2005 04:31:05 -0000	1.29
+++ mysqlinstall.php	12 Nov 2005 17:45:39 -0000	1.30
@@ -720,10 +720,11 @@
         }
         $chan->rest_support = 1;
         $chan->update();
-        $this->_ui->outputData('Adding REST 1.0 to channel.xml');
+        $this->_ui->outputData('Adding REST 1.0 and REST 1.1 to channel.xml');
         $chan = $this->_registry->getChannel($this->channel);
         if (is_a($chan, 'PEAR_ChannelFile')) {
             $chan->setBaseURL('REST1.0', 'http://' . $this->channel . '/Chiara_PEAR_Server_REST/');
+            $chan->setBaseURL('REST1.1', 'http://' . $this->channel . '/Chiara_PEAR_Server_REST/');
             $this->_registry->updateChannel($chan);
             file_put_contents($this->webroot . DIRECTORY_SEPARATOR . 'channel.xml',
                 $chan->toXml());
@@ -754,6 +755,9 @@
             $this->_ui->outputData('  Category ' . $category['name']);
             $backend->saveCategoryREST($category['name']);
         }
+        $backend->saveAllCategoriesREST();
+        $this->_ui->outputData("Saving All Maintainers REST");
+        $backend->saveAllMaintainersREST();
         $this->_ui->outputData('Saving Maintainer REST');
         $maintainers = $backend->listMaintainers();
         foreach ($maintainers as $maintainer) {
@@ -766,9 +770,11 @@
         foreach ($packages as $package) {
             $this->_ui->outputData('  Package ' . $package['package']);
             $backend->savePackageREST($package['package']);
+            $this->_ui->outputData('    Maintainers...');
             $backend->savePackageMaintainersREST($package['package']);
             $releases = $backend->listReleases($package['package']);
             if (count($releases)) {
+                $this->_ui->outputData('    Processing releases');
                 $backend->saveAllReleasesREST($package['package']);
                 foreach ($releases as $version => $release) {
                     $this->_ui->outputData('     Version ' . $version);
@@ -779,6 +785,11 @@
                 }
             }
         }
+        $this->_ui->outputData("Saving Category Package REST");
+        foreach ($backend->listCategories() as $category) {
+            $this->_ui->outputData("  $category[name]");
+            $backend->savePackagesCategoryREST($category['name']);
+        }
     }
 }
 ?>
\ No newline at end of file

PEAR_Server/Server
Backend.php 1.11 -> 1.12
diff -u -r1.11 -r1.12
--- Backend.php	3 Nov 2005 05:42:59 -0000	1.11
+++ Backend.php	12 Nov 2005 17:45:39 -0000	1.12
@@ -1,5 +1,6 @@
 <?php
 require_once 'Chiara/PEAR/Server/Maintainer.php';
+require_once 'Chiara/PEAR/Server/REST.php';
 /**
  * Base class for all backends.
  * @author Gregory Beaver <cellog@php.net>
@@ -16,7 +17,7 @@
     public function __construct($channel, $restdir)
     {
         $this->_channel = $channel;
-        $this->_restdir = $restdir;
+        $this->_rest = new Chiara_PEAR_Server_REST($this, $restdir);
     }
 
     /**
@@ -77,6 +78,19 @@
         return $this->_rest->saveCategoryREST($category);
     }
 
+    public function saveAllCategoriesREST()
+    {
+        return $this->_rest->saveAllCategoriesREST();
+    }
+
+    /**
+     * @param string
+     */
+    public function savePackagesCategoryREST($category)
+    {
+        return $this->_rest->savePackagesCategoryREST($category);
+    }
+
     /**
      * @param string
      */
@@ -116,6 +130,11 @@
         return $this->_rest->deleteReleaseREST($package, $version);
     }
 
+    public function saveAllMaintainersREST()
+    {
+        return $this->_rest->saveAllMaintainersREST();
+    }
+
     public function saveMaintainerREST(Chiara_PEAR_Server_Maintainer $maintainer)
     {
         return $this->_rest->saveMaintainerREST($maintainer);

PEAR_Server/Server
REST.php 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- REST.php	3 Nov 2005 05:42:59 -0000	1.1
+++ REST.php	12 Nov 2005 17:45:39 -0000	1.2
@@ -4,7 +4,7 @@
  * REST implementation class (backend-independent)
  * @author Gregory Beaver <cellog@php.net>
  */
-abstract class Chiara_PEAR_Server_REST
+class Chiara_PEAR_Server_REST
 {
     protected $_channel;
     protected $_restdir;
@@ -79,11 +79,21 @@
             DIRECTORY_SEPARATOR . $version . '.xml', 0666);
         file_put_contents($rdir . DIRECTORY_SEPARATOR . strtolower($release['package']) .
             DIRECTORY_SEPARATOR . 'package.' .
-            $version . '.xml', $this->getPackageXml($release['package'], $version));
+            $version . '.xml', $this->_backend->getPackageXml($release['package'], $version));
         @chmod($rdir . DIRECTORY_SEPARATOR . strtolower($release['package']) .
             DIRECTORY_SEPARATOR . 'package.' . $version . '.xml', 0666);
     }
 
+    function _getAllReleasesRESTProlog($package)
+    {
+        return '<?xml version="1.0" encoding="UTF-8" ?>' . "\n" .
+'<a xmlns="http://pear.php.net/dtd/rest.allreleases"' . "\n" .
+'    xsi:schemaLocation="http://pear.php.net/dtd/rest.allreleases' . "\n" .
+'    http://pear.php.net/dtd/rest.allreleases.xsd">' . "\n" .
+' <p>' . htmlspecialchars($package) . '</p>' . "\n" .
+' <c>' . htmlspecialchars($this->_channel) . '</c>' . "\n";
+    }
+
     /**
      * @param string
      */
@@ -95,17 +105,12 @@
         } else {
             $extra = '/Chiara_PEAR_Server_REST/';
         }
+        $rdir = $this->_restdir . DIRECTORY_SEPARATOR . 'r';
         $releases = $this->_backend->listReleases($package);
         if (!$releases) {
             return;
         }
-        $info = '<?xml version="1.0" encoding="iso-8859-1" ?>
-<a xmlns="http://pear.php.net/dtd/rest.allreleases"
-    xsi:schemaLocation="http://pear.php.net/dtd/rest.allreleases
-    http://pear.php.net/dtd/rest.allreleases.xsd">
- <p>' . $package . '</p>
- <c>' . $this->_channel . '</c>
-';
+        $info = $this->_getAllReleasesRESTProlog($package);
         foreach ($releases as $release) {
             if (!class_exists('PEAR_PackageFile_Parser_v2')) {
                 require_once 'PEAR/PackageFile/Parser/v2.php';
@@ -239,18 +244,14 @@
         } else {
             $deprecated = '';
         }
-        $info = '<?xml version="1.0" encoding="iso-8859-1" ?>
-<p xmlns="http://pear.php.net/dtd/rest.package"
-    xsi:schemaLocation="http://pear.php.net/dtd/rest.package
-    http://pear.php.net/dtd/rest.package.xsd">
+        $info = $this->_getPackageRESTProlog() . '
  <n>' . $package['package'] . '</n>
  <c>' . $package['channel'] . '</c>
  <ca xlink:href="' . $extra . 'c/' . urlencode($catinfo['name']) . '">' .
             htmlspecialchars($catinfo['name']) . '</ca>
  <l>' . $package['license'] . '</l>' . ($package['licenseuri'] ? '
  <lu>' . $package['licenseuri'] . '</lu>
-' : '
-') . '
+' : '') . '
  <s>' . htmlspecialchars($package['summary']) . '</s>
  <d>' . htmlspecialchars($package['description']) . '</d>
  <r xlink:href="' . $extra . 'r/' . $package['package'] . '"/>
@@ -327,6 +328,81 @@
             DIRECTORY_SEPARATOR . 'packages.xml', 0666);
     }
 
+    private function _getPackageRESTProlog()
+    {
+        return "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" .
+"<p xmlns=\"http://pear.php.net/dtd/rest.package\"" .
+"    xsi:schemaLocation=\"http://pear.php.net/dtd/rest.package" .
+'    http://pear.php.net/dtd/rest.package.xsd">';
+    }
+
+    public function savePackagesCategoryREST($category)
+    {
+        $channelinfo = parse_url($this->_channel);
+        if (isset($channelinfo['host'])) {
+            $extra = $channelinfo['path'] . '/Chiara_PEAR_Server_REST/';
+        } else {
+            $extra = '/Chiara_PEAR_Server_REST/';
+        }
+        $cdir = $this->_restdir . DIRECTORY_SEPARATOR . 'c';
+        if (!is_dir($cdir)) {
+            return;
+        }
+        $pdir = $this->_restdir . DIRECTORY_SEPARATOR . 'p';
+        $rdir = $this->_restdir . DIRECTORY_SEPARATOR . 'r';
+        $packages = $this->_backend->listPackagesInCategory($category);
+        $fullpackageinfo = '<?xml version="1.0" encoding="UTF-8" ?>
+<f xmlns="http://pear.php.net/dtd/rest.categorypackageinfo"
+    xsi:schemaLocation="http://pear.php.net/dtd/rest.categorypackageinfo
+    http://pear.php.net/dtd/rest.categorypackageinfo.xsd">
+';
+        clearstatcache();
+        foreach ($packages as $package) {
+            if (!file_exists($pdir . DIRECTORY_SEPARATOR . strtolower($package['package']) .
+                    DIRECTORY_SEPARATOR . 'info.xml')) {
+                continue;
+            }
+            $fullpackageinfo .= '<pi>
+';
+            $fullpackageinfo .= str_replace($this->_getPackageRESTProlog(), '<p>',
+                file_get_contents($pdir . DIRECTORY_SEPARATOR . strtolower($package['package']) .
+                    DIRECTORY_SEPARATOR . 'info.xml'));
+            if (file_exists($rdir . DIRECTORY_SEPARATOR . strtolower($package['package']) .
+                    DIRECTORY_SEPARATOR . 'allreleases.xml')) {
+                $fullpackageinfo .= str_replace(
+                    $this->_getAllReleasesRESTProlog($package['package']), '
+<a>
+',
+                    file_get_contents($rdir . DIRECTORY_SEPARATOR .
+                        strtolower($package['package']) . DIRECTORY_SEPARATOR .
+                        'allreleases.xml'));
+                $dirhandle = opendir($rdir . DIRECTORY_SEPARATOR .
+                    strtolower($package['package']));
+                while (false !== ($entry = readdir($dirhandle))) {
+                    if (strpos($entry, 'deps.') === 0) {
+                        $version = str_replace(array('deps.', '.txt'), array('', ''), $entry);
+                        $fullpackageinfo .= '
+<deps>
+ <v>' . $version . '</v>
+ <d>' . htmlspecialchars(utf8_encode(file_get_contents($rdir . DIRECTORY_SEPARATOR .
+                        strtolower($package['package']) . DIRECTORY_SEPARATOR .
+                        $entry))) . '</d>
+</deps>
+';
+                    }
+                }
+            }
+            $fullpackageinfo .= '</pi>
+';
+        }
+        $fullpackageinfo .= '</f>';
+        // list packages in a category
+        file_put_contents($cdir . DIRECTORY_SEPARATOR . urlencode($category) .
+            DIRECTORY_SEPARATOR . 'packagesinfo.xml', $fullpackageinfo);
+        @chmod($cdir . DIRECTORY_SEPARATOR . urlencode($category) .
+            DIRECTORY_SEPARATOR . 'packagesinfo.xml', 0666);
+    }
+
     /**
      * @param string
      */
@@ -341,6 +417,41 @@
             . DIRECTORY_SEPARATOR . urlencode($category)));
     }
 
+    public function saveAllCategoriesREST()
+    {
+        require_once 'System.php';
+        $channelinfo = parse_url($this->_channel);
+        if (isset($channelinfo['host'])) {
+            $extra = $channelinfo['path'] . '/Chiara_PEAR_Server_REST/';
+        } else {
+            $extra = '/Chiara_PEAR_Server_REST/';
+        }
+        $cdir = $this->_restdir . DIRECTORY_SEPARATOR . 'c';
+        if (!is_dir($cdir)) {
+            System::mkdir(array('-p', $cdir));
+            @chmod($cdir, 0777);
+        }
+
+        $categories = $this->_backend->listCategories();
+        $info = '<?xml version="1.0" encoding="UTF-8" ?>
+<a xmlns="http://pear.php.net/dtd/rest.allcategories"
+    xsi:schemaLocation="http://pear.php.net/dtd/rest.allcategories
+    http://pear.php.net/dtd/rest.allcategories.xsd">
+<ch>' . $this->_channel . '</ch>
+';
+        foreach ($categories as $category)
+        {
+            $info .= ' <c xlink:href="' . $extra . 'c/' .
+                urlencode(urlencode($category['name'])) .
+                '/info.xml">' .
+                htmlspecialchars(utf8_encode($category['name'])) . '</c>
+';
+        }
+        $info .= '</a>';
+        file_put_contents($cdir . DIRECTORY_SEPARATOR . 'categories.xml', $info);
+        @chmod($cdir . DIRECTORY_SEPARATOR . 'categories.xml', 0666);
+    }
+
     /**
      * @param string
      * @param string
@@ -403,7 +514,7 @@
     http://pear.php.net/dtd/rest.allpackages.xsd">
  <c>' . htmlspecialchars($this->_channel) . '</c>
 ';
-        foreach ($this->listPackages(false, false, false) as $package)
+        foreach ($this->_backend->listPackages(false, false, false) as $package)
         {
             $info .= ' <p>' . $package['package'] . '</p>
 ';
@@ -436,8 +547,8 @@
  <c>' . htmlspecialchars($this->_channel) . '</c>
 ';
             foreach ($maintainers as $maintainer) {
-                $info .= ' <m><h>' . $maintainer['handle'] . '</h><a>' .
-                    $maintainers['active'] .
+                $info .= ' <m><h>' . $maintainer->handle . '</h><a>' .
+                    ($maintainer->active ? '1' : '0') .
                     '</a></m>';
             }
             $info .= '</m>';
@@ -451,6 +562,34 @@
         }
     }
 
+    public function saveAllMaintainersREST()
+    {
+        $channelinfo = parse_url($this->_channel);
+        if (isset($channelinfo['host'])) {
+            $extra = $channelinfo['path'] . '/Chiara_PEAR_Server_REST/';
+        } else {
+            $extra = '/Chiara_PEAR_Server_REST/';
+        }
+        $maintainers = $this->_backend->listMaintainers();
+        $info = '<?xml version="1.0" encoding="UTF-8" ?>
+<m xmlns="http://pear.php.net/dtd/rest.allmaintainers"
+    xsi:schemaLocation="http://pear.php.net/dtd/rest.allmaintainers
+    http://pear.php.net/dtd/rest.allmaintainers.xsd">' . "\n";
+        // package information
+        foreach ($maintainers as $maintainer) {
+            $info .= ' <h xlink:href="' . $extra . 'm/' . $maintainer->handle . '">' .
+                $maintainer->handle . '</h>' . "\n";
+        }
+        $info .= '</m>';
+        $mdir = $this->_restdir . DIRECTORY_SEPARATOR . 'm';
+        if (!is_dir($mdir)) {
+            System::mkdir(array('-p', $mdir));
+            @chmod($mdir, 0777);
+        }
+        file_put_contents($mdir . DIRECTORY_SEPARATOR . 'allmaintainers.xml', $info);
+        @chmod($mdir . DIRECTORY_SEPARATOR . 'allmaintainers.xml', 0666);
+    }
+
     public function saveMaintainerREST(Chiara_PEAR_Server_Maintainer $maintainer)
     {
         $channelinfo = parse_url($this->_channel);

PEAR_Server/Server
mysqlinstall.php 1.29 -> 1.30
diff -u -r1.29 -r1.30
--- mysqlinstall.php	5 Oct 2005 04:31:05 -0000	1.29
+++ mysqlinstall.php	12 Nov 2005 17:45:39 -0000	1.30
@@ -720,10 +720,11 @@
         }
         $chan->rest_support = 1;
         $chan->update();
-        $this->_ui->outputData('Adding REST 1.0 to channel.xml');
+        $this->_ui->outputData('Adding REST 1.0 and REST 1.1 to channel.xml');
         $chan = $this->_registry->getChannel($this->channel);
         if (is_a($chan, 'PEAR_ChannelFile')) {
             $chan->setBaseURL('REST1.0', 'http://' . $this->channel . '/Chiara_PEAR_Server_REST/');
+            $chan->setBaseURL('REST1.1', 'http://' . $this->channel . '/Chiara_PEAR_Server_REST/');
             $this->_registry->updateChannel($chan);
             file_put_contents($this->webroot . DIRECTORY_SEPARATOR . 'channel.xml',
                 $chan->toXml());
@@ -754,6 +755,9 @@
             $this->_ui->outputData('  Category ' . $category['name']);
             $backend->saveCategoryREST($category['name']);
         }
+        $backend->saveAllCategoriesREST();
+        $this->_ui->outputData("Saving All Maintainers REST");
+        $backend->saveAllMaintainersREST();
         $this->_ui->outputData('Saving Maintainer REST');
         $maintainers = $backend->listMaintainers();
         foreach ($maintainers as $maintainer) {
@@ -766,9 +770,11 @@
         foreach ($packages as $package) {
             $this->_ui->outputData('  Package ' . $package['package']);
             $backend->savePackageREST($package['package']);
+            $this->_ui->outputData('    Maintainers...');
             $backend->savePackageMaintainersREST($package['package']);
             $releases = $backend->listReleases($package['package']);
             if (count($releases)) {
+                $this->_ui->outputData('    Processing releases');
                 $backend->saveAllReleasesREST($package['package']);
                 foreach ($releases as $version => $release) {
                     $this->_ui->outputData('     Version ' . $version);
@@ -779,6 +785,11 @@
                 }
             }
         }
+        $this->_ui->outputData("Saving Category Package REST");
+        foreach ($backend->listCategories() as $category) {
+            $this->_ui->outputData("  $category[name]");
+            $backend->savePackagesCategoryREST($category['name']);
+        }
     }
 }
 ?>
\ No newline at end of file

PEAR_Server/Server/Backend
DBDataObject.php 1.50 -> 1.51
diff -u -r1.50 -r1.51
--- DBDataObject.php	3 Nov 2005 05:42:59 -0000	1.50
+++ DBDataObject.php	12 Nov 2005 17:45:39 -0000	1.51
@@ -630,7 +630,7 @@
         if (!$package->find(true)) {
             return false;
         }
-        if (isset($package->$key)) {
+        if ($key && isset($package->$key)) {
             return $package->$key;
         }
         if ($key === null) {
@@ -639,7 +639,7 @@
             $ret['category'] = $this->categoryFromId($ret['category_id']);
             $ret['releases'] = $this->listReleases($pkg);
             if (count($ret['releases'])) {
-                $temp = array_shift(array_values($ret['releases']));
+                $temp = array_shift($a = array_values($ret['releases']));
                 // it's not really necessarily stable - this is crap legacy from pearweb
                 $ret['stable'] = $temp['version'];
             } else {

PEAR_Server/Server/Backend
DBDataObject.php 1.50 -> 1.51
diff -u -r1.50 -r1.51
--- DBDataObject.php	3 Nov 2005 05:42:59 -0000	1.50
+++ DBDataObject.php	12 Nov 2005 17:45:39 -0000	1.51
@@ -630,7 +630,7 @@
         if (!$package->find(true)) {
             return false;
         }
-        if (isset($package->$key)) {
+        if ($key && isset($package->$key)) {
             return $package->$key;
         }
         if ($key === null) {
@@ -639,7 +639,7 @@
             $ret['category'] = $this->categoryFromId($ret['category_id']);
             $ret['releases'] = $this->listReleases($pkg);
             if (count($ret['releases'])) {
-                $temp = array_shift(array_values($ret['releases']));
+                $temp = array_shift($a = array_values($ret['releases']));
                 // it's not really necessarily stable - this is crap legacy from pearweb
                 $ret['stable'] = $temp['version'];
             } else {

PEAR_Server
makepackage.php 1.5 -> 1.6
diff -u -r1.5 -r1.6
--- makepackage.php	4 Nov 2005 23:52:16 -0000	1.5
+++ makepackage.php	12 Nov 2005 17:45:39 -0000	1.6
@@ -19,9 +19,9 @@
 'simpleoutput' => true,
 ));
 $pfm->setReleaseStability('alpha');
-$pfm->setReleaseVersion('0.18.3');
-$pfm->setNotes(' * fix missing brace in mysqlinstall.php - now post-install script works
-');
+$pfm->setReleaseVersion('0.18.4');
+$pfm->setNotes(' * Implement REST 1.1
+ * re-factor backend to make more modular');
 $pfm->addMaintainer('cellog', 'lead', 'Greg Beaver', 'cellog@php.net');
 $pfm->setPhpDep('5.0.0');
 $pfm->setPearinstallerDep('1.4.2');

PEAR_Server
package.xml 1.41 -> 1.42
diff -u -r1.41 -r1.42
--- package.xml	4 Nov 2005 23:52:16 -0000	1.41
+++ package.xml	12 Nov 2005 17:45:39 -0000	1.42
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<package packagerversion="1.4.3" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
+<package packagerversion="1.4.4" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
  <name>Chiara_PEAR_Server</name>
  <channel>pear.chiaraquartet.net</channel>
  <summary>A lightweight pearweb-compatible channel server for hosting a PEAR channel</summary>
@@ -28,10 +28,10 @@
   <email>clay@killersoft.com</email>
   <active>yes</active>
  </lead>
- <date>2005-11-04</date>
- <time>17:50:14</time>
+ <date>2005-11-12</date>
+ <time>11:43:01</time>
  <version>
-  <release>0.18.3</release>
+  <release>0.18.4</release>
   <api>0.18.0</api>
  </version>
  <stability>
@@ -39,8 +39,8 @@
   <api>alpha</api>
  </stability>
  <license uri="http://www.php.net/license">PHP License</license>
- <notes> * fix missing brace in mysqlinstall.php - now post-install script works
- </notes>
+ <notes> * Implement REST 1.1
+ * re-factor backend to make more modular</notes>
  <contents>
   <dir baseinstalldir="Chiara/PEAR" name="/">
    <dir name="data">
@@ -540,8 +540,21 @@
    </stability>
    <date>2005-11-04</date>
    <license>PHP License</license>
-   <notes> * fix missing brace in mysqlinstall.php - now post-install script works
-   </notes>
+   <notes>* fix missing brace in mysqlinstall.php - now post-install script works</notes>
+  </release>
+  <release>
+   <version>
+    <release>0.18.4</release>
+    <api>0.18.0</api>
+   </version>
+   <stability>
+    <release>alpha</release>
+    <api>alpha</api>
+   </stability>
+   <date>2005-11-12</date>
+   <license>PHP License</license>
+   <notes> * Implement REST 1.1
+ * re-factor backend to make more modular</notes>
   </release>
  </changelog>
 </package>