No changes between revisions
/WebSVN/languages/czech.inc
87,9 → 87,9
$lang["NORESULTS"] = "Nejsou tu žádné zázanmy odpovídající vašim požadavkům";
$lang["NOMORERESULTS"] = "Nejsou tu žádné další záznamy odpovídající vašim požadavkům";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS feed";
$lang["FILESMODIFIED"] = "soubor(y) změněn(y)";
$lang["RSSFEED"] = "RSS";
$lang["RSSFEEDTITLE"] = "WebSVN RSS feed";
$lang["FILESMODIFIED"] = "soubor(y) změněn(y)";
$lang["RSSFEED"] = "RSS";
 
$lang["LINENO"] = "Číslo řádky";
$lang["BLAMEFOR"] = "Blame information for rev";
114,7 → 114,7
$lang["FILEADDED"] = "Nový soubor";
 
// The following are defined by some languages to stop unwanted line splitting
// in the template files.
// in the template files.
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
/WebSVN/languages/english.inc
86,7 → 86,6
$lang["MORERESULTS"] = "Find more matches...";
$lang["NORESULTS"] = "There are no logs matching your query";
$lang["NOMORERESULTS"] = "There are no more logs matching your query";
$lang['NOPREVREV'] = 'No previous revision';
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS feed";
$lang["FILESMODIFIED"] = "file(s) modified";
/WebSVN/languages/NotUsed/catalan.inc
25,7 → 25,6
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Català-Valencià";
$lang['LANGUAGETAG'] = 'ca';
 
$lang["LOG"] = "Registre";
$lang["DIFF"] = "Diferència";
84,7 → 83,6
$lang["MORERESULTS"] = "Cerca més coincidències...";
$lang["NORESULTS"] = "No hi ha cap registre que coincideixi amb la vostra cerca";
$lang["NOMORERESULTS"] = "No hi ha més registres que coincideixin amb la vostra cerca";
$lang['NOPREVREV'] = 'No hi ha cap revisió anterior.';
 
$lang["RSSFEEDTITLE"] = "Canal RSS del WebSVN";
$lang["FILESMODIFIED"] = "fitxer(s) modificat(s)";
/WebSVN/languages/NotUsed/russian.inc
27,7 → 27,6
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Russian";
$lang['LANGUAGETAG'] = 'ru';
 
$lang["LOG"] = "Журнал";
$lang["DIFF"] = "Различия";
/WebSVN/languages/NotUsed/danish.inc
1,124 → 1,123
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Tim Armes
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// danish.inc
//
// Danish language strings based on TortoiseSVN translation.
// by Jan Normann Nielsen, <span@dubbekarl.dk>
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Dansk";
$lang['LANGUAGETAG'] = 'da';
 
$lang["LOG"] = "Log";
$lang["DIFF"] = "Sammenlign";
 
$lang["NOREP"] = "Der er ikke angivet noget versionarkiv";
$lang["NOPATH"] = "Stien blev ikke fundet";
$lang["NOACCESS"] = "Du har ikke de n&oslash;dvendige rettigheder til at l&aelig;se denne mappe";
$lang["RESTRICTED"] = "Begr&aelig;nset adgang";
$lang["SUPPLYREP"] = "Konfigurer venligst stier til versionsarkiver i include/config.inc ved at bruge \$config->parentPath eller \$config->addRepository<p>. Se installationsguiden for n&aelig;rmere detaljer.";
 
$lang["DIFFREVS"] = "Sammenlign revisionerne";
$lang["AND"] = "og";
$lang["REV"] = "Rev";
$lang["LINE"] = "Linje";
$lang["SHOWENTIREFILE"] = "Vis hele filen";
$lang["SHOWCOMPACT"] = "Vis kun omr&aring;der med forskelle";
 
$lang["DIFFPREV"] = "Sammenlign med forrige";
$lang["BLAME"] = "&aelig;ndringsfordeling";
 
$lang["REVINFO"] = "Informationer om revision";
$lang["GOYOUNGEST"] = "G&aring; til nyeste revision";
$lang["LASTMOD"] = "Sidste &aelig;ndring";
$lang["LOGMSG"] = "Logbesked";
$lang["CHANGES"] = "&aelig;ndringer";
$lang["SHOWCHANGED"] = "Vis &aelig;ndrede filer";
$lang["HIDECHANGED"] = "Skjul &aelig;ndrede filer";
$lang["NEWFILES"] = "Nye filer";
$lang["CHANGEDFILES"] = "&aelig;ndrede filer";
$lang["DELETEDFILES"] = "Slettede filer";
$lang["VIEWLOG"] = "Vis&nbsp;log";
$lang["PATH"] = "Sti";
$lang["AUTHOR"] = "Forfatter";
$lang["AGE"] = "Alder";
$lang["LOG"] = "Log";
$lang["CURDIR"] = "Nuv&aelig;rende mappe";
$lang["TARBALL"] = "Tar-pakke";
 
$lang["PREV"] = "Forrige";
$lang["NEXT"] = "N&aelig;ste";
$lang["SHOWALL"] = "Vis alle";
 
$lang["BADCMD"] = "Fejl ved udf&oslash;relse af kommandoen";
$lang["UNKNOWNREVISION"] = "Revisionen findes ikke";
 
$lang["POWERED"] = "Leveret af <a href=\"http://websvn.tigris.org/\">WebSVN</a>";
$lang["PROJECTS"] = "Subversion-versionsarkiver";
$lang["SERVER"] = "Subversion-server";
 
$lang["FILTER"] = "Filter-indstillinger";
$lang["STARTLOG"] = "Fra rev";
$lang["ENDLOG"] = "Til rev";
$lang["SEARCHLOG"] = "S&oslash;g efter";
$lang["CLEARLOG"] = "Ryd aktuelle filter";
$lang["MORERESULTS"] = "Vis flere resultater...";
$lang["NORESULTS"] = "Der er ingen logbeskeder, der passer p&aring; s&oslash;gningen";
$lang["NOMORERESULTS"] = "Der er ikke flere logbeskeder, som svarer til s&oslash;gningen";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS-feed";
$lang["FILESMODIFIED"] = "fil(er) &aelig;ndret";
$lang["RSSFEED"] = "RSS-feed";
 
$lang["LINENO"] = "Linjenr.";
$lang["BLAMEFOR"] = "&aelig;ndringsfordeling for revision";
 
$lang["DAYLETTER"] = "d";
$lang["HOURLETTER"] = "t";
$lang["MINUTELETTER"] = "m";
$lang["SECONDLETTER"] = "s";
 
$lang["GO"] = "G&aring; til";
 
$lang["PATHCOMPARISON"] = "Sammenligning af stier";
$lang["COMPAREPATHS"] = "Sammenlign stier";
$lang["COMPAREREVS"] = "Sammenlign revisioner";
$lang["PROPCHANGES"] = "&aelig;ndringer i egenskaber:";
$lang["CONVFROM"] = "Denne sammenligning viser de &aelig;ndringer, der skal til for at konvertere stien ";
$lang["TO"] = "til";
$lang["REVCOMP"] = "Omvendt sammenligning";
$lang["COMPPATH"] = "Sammenlign sti:";
$lang["WITHPATH"] = "med sti:";
$lang["FILEDELETED"] = "Fil slettet";
$lang["FILEADDED"] = "Ny fil";
 
// The following are defined by some languages to stop unwanted line splitting
// in the template files.
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
 
// $lang["NOBR"] = "<nobr>";
// $lang["ENDNOBR"] = "</nobr>";
 
 
 
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Tim Armes
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// danish.inc
//
// Danish language strings based on TortoiseSVN translation.
// by Jan Normann Nielsen, <span@dubbekarl.dk>
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Dansk";
 
$lang["LOG"] = "Log";
$lang["DIFF"] = "Sammenlign";
 
$lang["NOREP"] = "Der er ikke angivet noget versionarkiv";
$lang["NOPATH"] = "Stien blev ikke fundet";
$lang["NOACCESS"] = "Du har ikke de n&oslash;dvendige rettigheder til at l&aelig;se denne mappe";
$lang["RESTRICTED"] = "Begr&aelig;nset adgang";
$lang["SUPPLYREP"] = "Konfigurer venligst stier til versionsarkiver i include/config.inc ved at bruge \$config->parentPath eller \$config->addRepository<p>. Se installationsguiden for n&aelig;rmere detaljer.";
 
$lang["DIFFREVS"] = "Sammenlign revisionerne";
$lang["AND"] = "og";
$lang["REV"] = "Rev";
$lang["LINE"] = "Linje";
$lang["SHOWENTIREFILE"] = "Vis hele filen";
$lang["SHOWCOMPACT"] = "Vis kun omr&aring;der med forskelle";
 
$lang["DIFFPREV"] = "Sammenlign med forrige";
$lang["BLAME"] = "&aelig;ndringsfordeling";
 
$lang["REVINFO"] = "Informationer om revision";
$lang["GOYOUNGEST"] = "G&aring; til nyeste revision";
$lang["LASTMOD"] = "Sidste &aelig;ndring";
$lang["LOGMSG"] = "Logbesked";
$lang["CHANGES"] = "&aelig;ndringer";
$lang["SHOWCHANGED"] = "Vis &aelig;ndrede filer";
$lang["HIDECHANGED"] = "Skjul &aelig;ndrede filer";
$lang["NEWFILES"] = "Nye filer";
$lang["CHANGEDFILES"] = "&aelig;ndrede filer";
$lang["DELETEDFILES"] = "Slettede filer";
$lang["VIEWLOG"] = "Vis&nbsp;log";
$lang["PATH"] = "Sti";
$lang["AUTHOR"] = "Forfatter";
$lang["AGE"] = "Alder";
$lang["LOG"] = "Log";
$lang["CURDIR"] = "Nuv&aelig;rende mappe";
$lang["TARBALL"] = "Tar-pakke";
 
$lang["PREV"] = "Forrige";
$lang["NEXT"] = "N&aelig;ste";
$lang["SHOWALL"] = "Vis alle";
 
$lang["BADCMD"] = "Fejl ved udf&oslash;relse af kommandoen";
$lang["UNKNOWNREVISION"] = "Revisionen findes ikke";
 
$lang["POWERED"] = "Leveret af <a href=\"http://websvn.tigris.org/\">WebSVN</a>";
$lang["PROJECTS"] = "Subversion-versionsarkiver";
$lang["SERVER"] = "Subversion-server";
 
$lang["FILTER"] = "Filter-indstillinger";
$lang["STARTLOG"] = "Fra rev";
$lang["ENDLOG"] = "Til rev";
$lang["SEARCHLOG"] = "S&oslash;g efter";
$lang["CLEARLOG"] = "Ryd aktuelle filter";
$lang["MORERESULTS"] = "Vis flere resultater...";
$lang["NORESULTS"] = "Der er ingen logbeskeder, der passer p&aring; s&oslash;gningen";
$lang["NOMORERESULTS"] = "Der er ikke flere logbeskeder, som svarer til s&oslash;gningen";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS-feed";
$lang["FILESMODIFIED"] = "fil(er) &aelig;ndret";
$lang["RSSFEED"] = "RSS-feed";
 
$lang["LINENO"] = "Linjenr.";
$lang["BLAMEFOR"] = "&aelig;ndringsfordeling for revision";
 
$lang["DAYLETTER"] = "d";
$lang["HOURLETTER"] = "t";
$lang["MINUTELETTER"] = "m";
$lang["SECONDLETTER"] = "s";
 
$lang["GO"] = "G&aring; til";
 
$lang["PATHCOMPARISON"] = "Sammenligning af stier";
$lang["COMPAREPATHS"] = "Sammenlign stier";
$lang["COMPAREREVS"] = "Sammenlign revisioner";
$lang["PROPCHANGES"] = "&aelig;ndringer i egenskaber:";
$lang["CONVFROM"] = "Denne sammenligning viser de &aelig;ndringer, der skal til for at konvertere stien ";
$lang["TO"] = "til";
$lang["REVCOMP"] = "Omvendt sammenligning";
$lang["COMPPATH"] = "Sammenlign sti:";
$lang["WITHPATH"] = "med sti:";
$lang["FILEDELETED"] = "Fil slettet";
$lang["FILEADDED"] = "Ny fil";
 
// The following are defined by some languages to stop unwanted line splitting
// in the template files.
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
 
// $lang["NOBR"] = "<nobr>";
// $lang["ENDNOBR"] = "</nobr>";
 
 
 
/WebSVN/languages/NotUsed/dutch.inc
1,119 → 1,118
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Tim Armes
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// dutch.inc
//
// Dutch language strings
//
// By David Gartner david A.T net2ftp D-O-T com
// Comments welcome.
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Dutch";
$lang['LANGUAGETAG'] = 'nl';
 
$lang["LOG"] = "Log";
$lang["DIFF"] = "Diff";
 
$lang["NOREP"] = "Geen repository ingegeven";
$lang["NOPATH"] = "Pad niet gevonden";
$lang["SUPPLYREP"] = "Gelieve een repository pad aan te maken in include/config.inc met behulp van \$config->parentPath of \$config->addRepository<p>Zie de installatiegids voor meer details";
 
$lang["DIFFREVS"] = "Verschil tussen de revisies";
$lang["AND"] = "en";
$lang["REV"] = "Rev";
$lang["LINE"] = "Lijn";
$lang["SHOWENTIREFILE"] = "Toon volledig bestand";
$lang["SHOWCOMPACT"] = "Toon enkel de delen met verschillen";
 
$lang["DIFFPREV"] = "Vergelijk met vorige";
$lang["BLAME"] = "Blame";
 
$lang["REVINFO"] = "Revisie Informatie";
$lang["GOYOUNGEST"] = "Ga naar de meest recente revisie";
$lang["LASTMOD"] = "Laatste wijziging";
$lang["LOGMSG"] = "Log bericht";
$lang["CHANGES"] = "Wijzigingen";
$lang["SHOWCHANGED"] = "Toon gewijzigde bestanden";
$lang["HIDECHANGED"] = "Verberg gewijzigde bestanden";
$lang["NEWFILES"] = "Nieuwe bestanden";
$lang["CHANGEDFILES"] = "Gewijzigde bestanden";
$lang["DELETEDFILES"] = "Gewiste files";
$lang["VIEWLOG"] = "Toon&nbsp;Log";
$lang["PATH"] = "Pad";
$lang["AUTHOR"] = "Auteur";
$lang["AGE"] = "Ouderdom";
$lang["LOG"] = "Log";
$lang["CURDIR"] = "Huidige map";
$lang["TARBALL"] = "Tarball";
 
$lang["PREV"] = "Vorige";
$lang["NEXT"] = "Volgende";
$lang["SHOWALL"] = "Toon alles";
 
$lang["BADCMD"] = "Een fout is opgetreden tijdens het uitvoeren van dit commando";
 
$lang["POWERED"] = "Aangedreven door <a href=\"http://websvn.tigris.org/\">WebSVN</a>";
$lang["PROJECTS"] = "Subversion&nbsp;Projecten";
$lang["SERVER"] = "Subversion&nbsp;Server";
 
$lang["SEARCHLOG"] = "Doorzoek de logs";
$lang["CLEARLOG"] = "Wis deze zoekopdracht";
$lang["MORERESULTS"] = "Vind meer resultaten...";
$lang["NORESULTS"] = "Er zijn geen logs die aan de zoekcriteria voldoen";
$lang["NOMORERESULTS"] = "Er zijn geen logs meer die aan de zoekcriteria voldoen";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS feed";
$lang["FILESMODIFIED"] = "bestand(en) gewijzigd";
$lang["RSSFEED"] = "RSS feed";
 
$lang["LINENO"] = "Lijn Nr.";
$lang["BLAMEFOR"] = "Blame informatie voor revisie";
 
$lang["YEARS"] = "jaren";
$lang["MONTHS"] = "maanden";
$lang["WEEKS"] = "weken";
$lang["DAYS"] = "dagen";
$lang["HOURS"] = "uren";
$lang["MINUTES"] = "minuten";
 
$lang["GO"] = "Ga";
 
$lang["PATHCOMPARISON"] = "Pad vergelijking";
$lang["COMPAREPATHS"] = "Vergelijk paden";
$lang["COMPAREREVS"] = "Vergelijk revisies";
$lang["PROPCHANGES"] = "Eigenschap wijzigingen :";
$lang["CONVFROM"] = "Deze vergelijking geeft de veranderingen weer die nodig zijn om het pad te converteren ";
$lang["TO"] = "TO";
$lang["REVCOMP"] = "Omgekeerde vergelijking";
$lang["COMPPATH"] = "Vergelijk pad:";
$lang["WITHPATH"] = "Met pad:";
$lang["FILEDELETED"] = "Bestand gewist";
$lang["FILEADDED"] = "Nieuw bestand";
 
// The following are defined by some languages to stop unwanted line splitting
// in the template files.
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
 
// $lang["NOBR"] = "<nobr>";
// $lang["ENDNOBR"] = "</nobr>";
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Tim Armes
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// dutch.inc
//
// Dutch language strings
//
// By David Gartner david A.T net2ftp D-O-T com
// Comments welcome.
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Dutch";
 
$lang["LOG"] = "Log";
$lang["DIFF"] = "Diff";
 
$lang["NOREP"] = "Geen repository ingegeven";
$lang["NOPATH"] = "Pad niet gevonden";
$lang["SUPPLYREP"] = "Gelieve een repository pad aan te maken in include/config.inc met behulp van \$config->parentPath of \$config->addRepository<p>Zie de installatiegids voor meer details";
 
$lang["DIFFREVS"] = "Verschil tussen de revisies";
$lang["AND"] = "en";
$lang["REV"] = "Rev";
$lang["LINE"] = "Lijn";
$lang["SHOWENTIREFILE"] = "Toon volledig bestand";
$lang["SHOWCOMPACT"] = "Toon enkel de delen met verschillen";
 
$lang["DIFFPREV"] = "Vergelijk met vorige";
$lang["BLAME"] = "Blame";
 
$lang["REVINFO"] = "Revisie Informatie";
$lang["GOYOUNGEST"] = "Ga naar de meest recente revisie";
$lang["LASTMOD"] = "Laatste wijziging";
$lang["LOGMSG"] = "Log bericht";
$lang["CHANGES"] = "Wijzigingen";
$lang["SHOWCHANGED"] = "Toon gewijzigde bestanden";
$lang["HIDECHANGED"] = "Verberg gewijzigde bestanden";
$lang["NEWFILES"] = "Nieuwe bestanden";
$lang["CHANGEDFILES"] = "Gewijzigde bestanden";
$lang["DELETEDFILES"] = "Gewiste files";
$lang["VIEWLOG"] = "Toon&nbsp;Log";
$lang["PATH"] = "Pad";
$lang["AUTHOR"] = "Auteur";
$lang["AGE"] = "Ouderdom";
$lang["LOG"] = "Log";
$lang["CURDIR"] = "Huidige map";
$lang["TARBALL"] = "Tarball";
 
$lang["PREV"] = "Vorige";
$lang["NEXT"] = "Volgende";
$lang["SHOWALL"] = "Toon alles";
 
$lang["BADCMD"] = "Een fout is opgetreden tijdens het uitvoeren van dit commando";
 
$lang["POWERED"] = "Aangedreven door <a href=\"http://websvn.tigris.org/\">WebSVN</a>";
$lang["PROJECTS"] = "Subversion&nbsp;Projecten";
$lang["SERVER"] = "Subversion&nbsp;Server";
 
$lang["SEARCHLOG"] = "Doorzoek de logs";
$lang["CLEARLOG"] = "Wis deze zoekopdracht";
$lang["MORERESULTS"] = "Vind meer resultaten...";
$lang["NORESULTS"] = "Er zijn geen logs die aan de zoekcriteria voldoen";
$lang["NOMORERESULTS"] = "Er zijn geen logs meer die aan de zoekcriteria voldoen";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS feed";
$lang["FILESMODIFIED"] = "bestand(en) gewijzigd";
$lang["RSSFEED"] = "RSS feed";
 
$lang["LINENO"] = "Lijn Nr.";
$lang["BLAMEFOR"] = "Blame informatie voor revisie";
 
$lang["YEARS"] = "jaren";
$lang["MONTHS"] = "maanden";
$lang["WEEKS"] = "weken";
$lang["DAYS"] = "dagen";
$lang["HOURS"] = "uren";
$lang["MINUTES"] = "minuten";
 
$lang["GO"] = "Ga";
 
$lang["PATHCOMPARISON"] = "Pad vergelijking";
$lang["COMPAREPATHS"] = "Vergelijk paden";
$lang["COMPAREREVS"] = "Vergelijk revisies";
$lang["PROPCHANGES"] = "Eigenschap wijzigingen :";
$lang["CONVFROM"] = "Deze vergelijking geeft de veranderingen weer die nodig zijn om het pad te converteren ";
$lang["TO"] = "TO";
$lang["REVCOMP"] = "Omgekeerde vergelijking";
$lang["COMPPATH"] = "Vergelijk pad:";
$lang["WITHPATH"] = "Met pad:";
$lang["FILEDELETED"] = "Bestand gewist";
$lang["FILEADDED"] = "Nieuw bestand";
 
// The following are defined by some languages to stop unwanted line splitting
// in the template files.
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
 
// $lang["NOBR"] = "<nobr>";
// $lang["ENDNOBR"] = "</nobr>";
/WebSVN/languages/NotUsed/finnish.inc
26,7 → 26,6
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Finnish";
$lang['LANGUAGETAG'] = 'fi';
 
$lang["LOG"] = "Loki";
$lang["DIFF"] = "Diff";
/WebSVN/languages/NotUsed/french.inc
1,94 → 1,93
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Erik Le Blanc
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// french.inc
//
// French language strings
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Francais";
$lang['LANGUAGETAG'] = 'fr';
 
$lang["LOG"] = "Log";
$lang["DIFF"] = "Diff";
 
$lang["NOREP"] = "Pas de repository";
$lang["NOPATH"] = "Fichier ou r&eacute;pertoire non trouv&eacute;";
 
$lang["DIFFREVS"] = "Diff&eacute;rences entre les r&eacute;visions";
$lang["AND"] = "et";
$lang["REV"] = "R&eacute;vision";
$lang["LINE"] = "Ligne";
$lang["SHOWENTIREFILE"] = "Afficher tout le fichier";
$lang["SHOWCOMPACT"] = "Afficher seulement les passages avec des diff&eacute;rences";
 
$lang["DIFFPREV"] = "Diff&eacute;rence avec le pr&eacute;c&eacute;dent";
$lang["BLAME"] = "Responsabilit&eacute;";
 
$lang["REVINFO"] = "Information sur la R&eacute;vision";
$lang["GOYOUNGEST"] = "Aller &agrave; la R&eacute;vision la plus r&eacute;cente";
$lang["LASTMOD"] = "Derni&egrave;re modification";
$lang["LOGMSG"] = "Message de Log";
$lang["CHANGES"] = "Changements";
$lang["SHOWCHANGED"] = "Montrer les fichiers modifi&eacute;s";
$lang["HIDECHANGED"] = "Cacher les fichiers modifi&eacute;s";
$lang["NEWFILES"] = "Nouveaux fichiers";
$lang["CHANGEDFILES"] = "Fichier(s) modifi&eacute;(s)";
$lang["DELETEDFILES"] = "Fichier(s) effac&eacute;(s)";
$lang["VIEWLOG"] = "Afficher&nbsp;le&nbsp;Log";
$lang["PATH"] = "Chemin";
$lang["AUTHOR"] = "Auteur";
$lang["AGE"] = "Anciennet&eacute;";
$lang["LOG"] = "Log";
$lang["CURDIR"] = "R&eacute;pertoire courant";
 
$lang["PREV"] = "Pr&eacute;c&eacute;dent";
$lang["NEXT"] = "Suivant";
$lang["SHOWALL"] = "Tout montrer";
 
$lang["BADCMD"] = "Cette commande a provoqu&eacute; une erreur";
 
$lang["POWERED"] = "Powered by <a href=\"http://websvn.tigris.org/\">WebSVN</a>";
$lang["PROJECTS"] = "Projets&nbsp;Subversion";
$lang["SERVER"] = "Serveur&nbsp;Subversion";
 
$lang["SEARCHLOG"] = "Rechercher dans les Logs";
$lang["CLEARLOG"] = "Effacer la recherche courante";
$lang["MORERESULTS"] = "Trouver plus de r&eacute;ponses...";
$lang["NORESULTS"] = "Il n'y a pas de r&eacute;ponse &agrave; votre recherche dans les Logs";
$lang["NOMORERESULTS"] = "Il n'y a pas plus de r&eacute;ponses &agrave; votre recherche";
 
$lang["RSSFEEDTITLE"] = "Fil RSS de WebSVN";
$lang["FILESMODIFIED"] = "fichier(s) modifi&aecute;(s)";
$lang["RSSFEED"] = "RSS";
 
$lang["LINENO"] = "Ligne num&eacute;ro";
$lang["BLAMEFOR"] = "Dernier responsable";
 
$lang["YEARS"] = "ann&eacute;es";
$lang["MONTHS"] = "mois";
$lang["WEEKS"] = "semaines";
$lang["DAYS"] = "jours";
$lang["HOURS"] = "heures";
$lang["MINUTES"] = "minutes";
 
$lang["GO"] = "Go";
 
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Erik Le Blanc
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// french.inc
//
// French language strings
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Francais";
 
$lang["LOG"] = "Log";
$lang["DIFF"] = "Diff";
 
$lang["NOREP"] = "Pas de repository";
$lang["NOPATH"] = "Fichier ou r&eacute;pertoire non trouv&eacute;";
 
$lang["DIFFREVS"] = "Diff&eacute;rences entre les r&eacute;visions";
$lang["AND"] = "et";
$lang["REV"] = "R&eacute;vision";
$lang["LINE"] = "Ligne";
$lang["SHOWENTIREFILE"] = "Afficher tout le fichier";
$lang["SHOWCOMPACT"] = "Afficher seulement les passages avec des diff&eacute;rences";
 
$lang["DIFFPREV"] = "Diff&eacute;rence avec le pr&eacute;c&eacute;dent";
$lang["BLAME"] = "Responsabilit&eacute;";
 
$lang["REVINFO"] = "Information sur la R&eacute;vision";
$lang["GOYOUNGEST"] = "Aller &agrave; la R&eacute;vision la plus r&eacute;cente";
$lang["LASTMOD"] = "Derni&egrave;re modification";
$lang["LOGMSG"] = "Message de Log";
$lang["CHANGES"] = "Changements";
$lang["SHOWCHANGED"] = "Montrer les fichiers modifi&eacute;s";
$lang["HIDECHANGED"] = "Cacher les fichiers modifi&eacute;s";
$lang["NEWFILES"] = "Nouveaux fichiers";
$lang["CHANGEDFILES"] = "Fichier(s) modifi&eacute;(s)";
$lang["DELETEDFILES"] = "Fichier(s) effac&eacute;(s)";
$lang["VIEWLOG"] = "Afficher&nbsp;le&nbsp;Log";
$lang["PATH"] = "Chemin";
$lang["AUTHOR"] = "Auteur";
$lang["AGE"] = "Anciennet&eacute;";
$lang["LOG"] = "Log";
$lang["CURDIR"] = "R&eacute;pertoire courant";
 
$lang["PREV"] = "Pr&eacute;c&eacute;dent";
$lang["NEXT"] = "Suivant";
$lang["SHOWALL"] = "Tout montrer";
 
$lang["BADCMD"] = "Cette commande a provoqu&eacute; une erreur";
 
$lang["POWERED"] = "Powered by <a href=\"http://websvn.tigris.org/\">WebSVN</a>";
$lang["PROJECTS"] = "Projets&nbsp;Subversion";
$lang["SERVER"] = "Serveur&nbsp;Subversion";
 
$lang["SEARCHLOG"] = "Rechercher dans les Logs";
$lang["CLEARLOG"] = "Effacer la recherche courante";
$lang["MORERESULTS"] = "Trouver plus de r&eacute;ponses...";
$lang["NORESULTS"] = "Il n'y a pas de r&eacute;ponse &agrave; votre recherche dans les Logs";
$lang["NOMORERESULTS"] = "Il n'y a pas plus de r&eacute;ponses &agrave; votre recherche";
 
$lang["RSSFEEDTITLE"] = "Fil RSS de WebSVN";
$lang["FILESMODIFIED"] = "fichier(s) modifi&aecute;(s)";
$lang["RSSFEED"] = "RSS";
 
$lang["LINENO"] = "Ligne num&eacute;ro";
$lang["BLAMEFOR"] = "Dernier responsable";
 
$lang["YEARS"] = "ann&eacute;es";
$lang["MONTHS"] = "mois";
$lang["WEEKS"] = "semaines";
$lang["DAYS"] = "jours";
$lang["HOURS"] = "heures";
$lang["MINUTES"] = "minutes";
 
$lang["GO"] = "Go";
 
/WebSVN/languages/NotUsed/german.inc
1,110 → 1,109
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Stephan Stapel, <stephan.stapel@web.de>
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// germany.inc
//
// German language strings
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "German";
$lang['LANGUAGETAG'] = 'de';
 
$lang["DIFF"] = "Diff";
 
$lang["NOREP"] = "Kein Repository angegeben.";
$lang["NOPATH"] = "Pfad nicht gefunden";
$lang["SUPPLYREP"] = "Bitte den Repository Pfad in include/config.inc mit \$config->parentPath oder \$config->addRepository konfigurieren.<p>Genauere Informationen sind in der Installationsanleitung";
 
$lang["DIFFREVS"] = "Vergleich zwischen Revisionen";
$lang["AND"] = "und";
$lang["REV"] = "Revision";
$lang["LINE"] = "Zeile";
$lang["SHOWENTIREFILE"] = "Ganze Datei anzeigen";
$lang["SHOWCOMPACT"] = "Nur ge&auml;nderte Bereiche";
 
$lang["DIFFPREV"] = "Vergleich mit vorheriger";
$lang["BLAME"] = "Blame";
 
$lang["REVINFO"] = "Revisionsinformation";
$lang["GOYOUNGEST"] = "Zur aktuellen Revision";
$lang["LASTMOD"] = "Letzte &Auml;nderung";
$lang["LOGMSG"] = "Logeintrag";
$lang["CHANGES"] = "&Auml;nderungen";
$lang["SHOWCHANGED"] = "Ge&auml;nderte Dateien anzeigen";
$lang["HIDECHANGED"] = "Ge&auml;nderte Dateien verstecken";
$lang["NEWFILES"] = "Neue Dateien";
$lang["CHANGEDFILES"] = "Ge&auml;nderte Dateien";
$lang["DELETEDFILES"] = "Gel&ouml;schte Dateien";
$lang["VIEWLOG"] = "Log&nbsp;anzeigen";
$lang["PATH"] = "Pfad";
$lang["AUTHOR"] = "Autor";
$lang["AGE"] = "Alter";
$lang["LOG"] = "Log";
$lang["CURDIR"] = "Aktuelles Verzeichnis";
$lang["TARBALL"] = "Archiv Download";
 
$lang["PREV"] = "Zur&uuml;ck";
$lang["NEXT"] = "Weiter";
$lang["SHOWALL"] = "Alles anzeigen";
 
$lang["BADCMD"] = "Fehler beim Ausf&uuml;hren des Befehls";
$lang["POWERED"] = "Powered by <a href=\"http://websvn.tigris.org/\">WebSVN</a>";
$lang["PROJECTS"] = "Subversion-Projekte";
$lang["SERVER"] = "Subversion Server";
 
$lang["SEARCHLOG"] = "Suche im Log nach";
$lang["CLEARLOG"] = "Aktuelle Suche l&ouml;schen";
$lang["MORERESULTS"] = "Weitere Ergebnisse finden...";
$lang["NORESULTS"] = "Es wurden keine Treffer erzielt";
$lang["NOMORERESULTS"] = "Keine weiteren Treffer f&uuml;r diese Suche";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS feed";
$lang["FILESMODIFIED"] = "Ver&auml;nderte Dateien";
$lang["RSSFEED"] = "RSS feed";
$lang["LINENO"] = "Nr.";
$lang["BLAMEFOR"] = "Blame Information f&uuml; Rev.";
 
$lang["GO"] = "Los";
 
$lang["PATHCOMPARISON"] = "Pfadvergleich";
$lang["COMPAREPATHS"] = "Vergleiche Pfade";
$lang["COMPAREREVS"] = "Vergleiche Revisionen";
$lang["PROPCHANGES"] = "Ge&auml;nderte Eigenschaften :";
$lang["CONVFROM"] = "Dieser Vergleich zeigt die &Auml;nderungen zwischen ";
$lang["TO"] = "und";
$lang["REVCOMP"] = "Revisionen vertauschen";
$lang["COMPPATH"] = "Vergleiche Pfad:";
$lang["WITHPATH"] = "Mit Pfad:";
$lang["FILEDELETED"] = "Datei gel&ouml;scht";
$lang["FILEADDED"] = "Neue Datei";
 
$lang["YEARS"] = "Jahre";
$lang["MONTHS"] = "Monate";
$lang["WEEKS"] = "Wochen";
$lang["DAYS"] = "Tage";
$lang["HOURS"] = "Stunden";
$lang["MINUTES"] = "Minuten";
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
 
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Stephan Stapel, <stephan.stapel@web.de>
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// germany.inc
//
// German language strings
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "German";
 
$lang["DIFF"] = "Diff";
 
$lang["NOREP"] = "Kein Repository angegeben.";
$lang["NOPATH"] = "Pfad nicht gefunden";
$lang["SUPPLYREP"] = "Bitte den Repository Pfad in include/config.inc mit \$config->parentPath oder \$config->addRepository konfigurieren.<p>Genauere Informationen sind in der Installationsanleitung";
 
$lang["DIFFREVS"] = "Vergleich zwischen Revisionen";
$lang["AND"] = "und";
$lang["REV"] = "Revision";
$lang["LINE"] = "Zeile";
$lang["SHOWENTIREFILE"] = "Ganze Datei anzeigen";
$lang["SHOWCOMPACT"] = "Nur ge&auml;nderte Bereiche";
 
$lang["DIFFPREV"] = "Vergleich mit vorheriger";
$lang["BLAME"] = "Blame";
 
$lang["REVINFO"] = "Revisionsinformation";
$lang["GOYOUNGEST"] = "Zur aktuellen Revision";
$lang["LASTMOD"] = "Letzte &Auml;nderung";
$lang["LOGMSG"] = "Logeintrag";
$lang["CHANGES"] = "&Auml;nderungen";
$lang["SHOWCHANGED"] = "Ge&auml;nderte Dateien anzeigen";
$lang["HIDECHANGED"] = "Ge&auml;nderte Dateien verstecken";
$lang["NEWFILES"] = "Neue Dateien";
$lang["CHANGEDFILES"] = "Ge&auml;nderte Dateien";
$lang["DELETEDFILES"] = "Gel&ouml;schte Dateien";
$lang["VIEWLOG"] = "Log&nbsp;anzeigen";
$lang["PATH"] = "Pfad";
$lang["AUTHOR"] = "Autor";
$lang["AGE"] = "Alter";
$lang["LOG"] = "Log";
$lang["CURDIR"] = "Aktuelles Verzeichnis";
$lang["TARBALL"] = "Archiv Download";
 
$lang["PREV"] = "Zur&uuml;ck";
$lang["NEXT"] = "Weiter";
$lang["SHOWALL"] = "Alles anzeigen";
 
$lang["BADCMD"] = "Fehler beim Ausf&uuml;hren des Befehls";
$lang["POWERED"] = "Powered by <a href=\"http://websvn.tigris.org/\">WebSVN</a>";
$lang["PROJECTS"] = "Subversion-Projekte";
$lang["SERVER"] = "Subversion Server";
 
$lang["SEARCHLOG"] = "Suche im Log nach";
$lang["CLEARLOG"] = "Aktuelle Suche l&ouml;schen";
$lang["MORERESULTS"] = "Weitere Ergebnisse finden...";
$lang["NORESULTS"] = "Es wurden keine Treffer erzielt";
$lang["NOMORERESULTS"] = "Keine weiteren Treffer f&uuml;r diese Suche";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS feed";
$lang["FILESMODIFIED"] = "Ver&auml;nderte Dateien";
$lang["RSSFEED"] = "RSS feed";
$lang["LINENO"] = "Nr.";
$lang["BLAMEFOR"] = "Blame Information f&uuml; Rev.";
 
$lang["GO"] = "Los";
 
$lang["PATHCOMPARISON"] = "Pfadvergleich";
$lang["COMPAREPATHS"] = "Vergleiche Pfade";
$lang["COMPAREREVS"] = "Vergleiche Revisionen";
$lang["PROPCHANGES"] = "Ge&auml;nderte Eigenschaften :";
$lang["CONVFROM"] = "Dieser Vergleich zeigt die &Auml;nderungen zwischen ";
$lang["TO"] = "und";
$lang["REVCOMP"] = "Revisionen vertauschen";
$lang["COMPPATH"] = "Vergleiche Pfad:";
$lang["WITHPATH"] = "Mit Pfad:";
$lang["FILEDELETED"] = "Datei gel&ouml;scht";
$lang["FILEADDED"] = "Neue Datei";
 
$lang["YEARS"] = "Jahre";
$lang["MONTHS"] = "Monate";
$lang["WEEKS"] = "Wochen";
$lang["DAYS"] = "Tage";
$lang["HOURS"] = "Stunden";
$lang["MINUTES"] = "Minuten";
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
 
/WebSVN/languages/NotUsed/japanese.inc
26,7 → 26,6
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Japanese";
$lang['LANGUAGETAG'] = 'ja';
 
$lang["LOG"] = "ログ";
$lang["DIFF"] = "差分";
/WebSVN/languages/NotUsed/korean.inc
1,114 → 1,113
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Tim Armes
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// korean-utf8.inc
// Translator: Lee Jae-Hong
// Korean(utf8) language strings
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Korean";
$lang['LANGUAGETAG'] = 'ko';
 
$lang["LOG"] = "로그";
$lang["DIFF"] = "비교";
 
$lang["NOREP"] = "저장소가 지정되어 있지 않습니다.";
$lang["NOPATH"] = "경로를 찾을 수 없습니다.";
$lang["SUPPLYREP"] = "include/config.inc 파일의 \$config->parentPath 또는 \$config->addRepository에 저장소의 경로를 지정해 주십시오.<p>설치 설명서를 참조해 주십시오.";
 
$lang["DIFFREVS"] = "리비전간 비교";
$lang["AND"] = "와(과)";
$lang["REV"] = "리비전";
$lang["LINE"] = "행";
$lang["SHOWENTIREFILE"] = "모두 보기";
$lang["SHOWCOMPACT"] = "바뀐 부분만 보기";
 
$lang["DIFFPREV"] = "이전 리비전과 비교";
$lang["BLAME"] = "수정한 사람 보기";
 
$lang["REVINFO"] = "리비전 정보";
$lang["GOYOUNGEST"] = "최신 리비전으로 가기";
$lang["LASTMOD"] = "마지막 변경";
$lang["LOGMSG"] = "로그 메시지";
$lang["CHANGES"] = "변경";
$lang["SHOWCHANGED"] = "변경된 파일 보기";
$lang["HIDECHANGED"] = "변경된 파일 숨기기";
$lang["NEWFILES"] = "새 파일";
$lang["CHANGEDFILES"] = "수정된 파일";
$lang["DELETEDFILES"] = "삭제된 파일";
$lang["VIEWLOG"] = "로그&nbsp;보기";
$lang["PATH"] = "경로";
$lang["AUTHOR"] = "작성자";
$lang["AGE"] = "기간";
$lang["LOG"] = "로그";
$lang["CURDIR"] = "현재 디렉토리";
$lang["TARBALL"] = "Tarball";
 
$lang["PREV"] = "이전";
$lang["NEXT"] = "다음";
$lang["SHOWALL"] = "모두 보기";
 
$lang["BADCMD"] = "명령 실행 에러";
 
$lang["POWERED"] = "Powered by <a href=\"http://websvn.tigris.org/\">WebSVN</a>";
$lang["PROJECTS"] = "Subversion&nbsp;프로젝트";
$lang["SERVER"] = "Subversion&nbsp;서버";
 
$lang["SEARCHLOG"] = "로그 검색";
$lang["CLEARLOG"] = "검색 조건 삭제";
$lang["MORERESULTS"] = "나머지 검색 결과...";
$lang["NORESULTS"] = "검색 조건에 맞는 결과가 없습니다.";
$lang["NOMORERESULTS"] = "더 이상 검색 조건에 맞는 결과가 없습니다.";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS feed";
$lang["FILESMODIFIED"] = "파일 수정됨";
$lang["RSSFEED"] = "RSS feed";
 
$lang["LINENO"] = "행번호";
$lang["BLAMEFOR"] = "수정한 사람 보기, 리비전 ";
 
$lang["YEARS"] = "년";
$lang["MONTHS"] = "개월";
$lang["WEEKS"] = "주일";
$lang["DAYS"] = "일";
$lang["HOURS"] = "시간";
$lang["MINUTES"] = "분";
 
$lang["GO"] = "Go";
 
$lang["PATHCOMPARISON"] = "경로 비교";
$lang["COMPAREPATHS"] = "경로 비교하기";
$lang["COMPAREREVS"] = "리비전 비교하기";
$lang["PROPCHANGES"] = "특성 변경 :";
$lang["CONVFROM"] = "이 비교는 바뀐 경로를 보여 줍니다.";
$lang["TO"] = "에서";
$lang["REVCOMP"] = "역 비교";
$lang["COMPPATH"] = "비교 경로:";
$lang["WITHPATH"] = "경로:";
 
// The following are defined by some languages to stop unwanted line splitting
// in the template files.
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
 
// $lang["NOBR"] = "<nobr>";
// $lang["ENDNOBR"] = "</nobr>";
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Tim Armes
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// korean-utf8.inc
// Translator: Lee Jae-Hong
// Korean(utf8) language strings
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Korean";
 
$lang["LOG"] = "로그";
$lang["DIFF"] = "비교";
 
$lang["NOREP"] = "저장소가 지정되어 있지 않습니다.";
$lang["NOPATH"] = "경로를 찾을 수 없습니다.";
$lang["SUPPLYREP"] = "include/config.inc 파일의 \$config->parentPath 또는 \$config->addRepository에 저장소의 경로를 지정해 주십시오.<p>설치 설명서를 참조해 주십시오.";
 
$lang["DIFFREVS"] = "리비전간 비교";
$lang["AND"] = "와(과)";
$lang["REV"] = "리비전";
$lang["LINE"] = "행";
$lang["SHOWENTIREFILE"] = "모두 보기";
$lang["SHOWCOMPACT"] = "바뀐 부분만 보기";
 
$lang["DIFFPREV"] = "이전 리비전과 비교";
$lang["BLAME"] = "수정한 사람 보기";
 
$lang["REVINFO"] = "리비전 정보";
$lang["GOYOUNGEST"] = "최신 리비전으로 가기";
$lang["LASTMOD"] = "마지막 변경";
$lang["LOGMSG"] = "로그 메시지";
$lang["CHANGES"] = "변경";
$lang["SHOWCHANGED"] = "변경된 파일 보기";
$lang["HIDECHANGED"] = "변경된 파일 숨기기";
$lang["NEWFILES"] = "새 파일";
$lang["CHANGEDFILES"] = "수정된 파일";
$lang["DELETEDFILES"] = "삭제된 파일";
$lang["VIEWLOG"] = "로그&nbsp;보기";
$lang["PATH"] = "경로";
$lang["AUTHOR"] = "작성자";
$lang["AGE"] = "기간";
$lang["LOG"] = "로그";
$lang["CURDIR"] = "현재 디렉토리";
$lang["TARBALL"] = "Tarball";
 
$lang["PREV"] = "이전";
$lang["NEXT"] = "다음";
$lang["SHOWALL"] = "모두 보기";
 
$lang["BADCMD"] = "명령 실행 에러";
 
$lang["POWERED"] = "Powered by <a href=\"http://websvn.tigris.org/\">WebSVN</a>";
$lang["PROJECTS"] = "Subversion&nbsp;프로젝트";
$lang["SERVER"] = "Subversion&nbsp;서버";
 
$lang["SEARCHLOG"] = "로그 검색";
$lang["CLEARLOG"] = "검색 조건 삭제";
$lang["MORERESULTS"] = "나머지 검색 결과...";
$lang["NORESULTS"] = "검색 조건에 맞는 결과가 없습니다.";
$lang["NOMORERESULTS"] = "더 이상 검색 조건에 맞는 결과가 없습니다.";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS feed";
$lang["FILESMODIFIED"] = "파일 수정됨";
$lang["RSSFEED"] = "RSS feed";
 
$lang["LINENO"] = "행번호";
$lang["BLAMEFOR"] = "수정한 사람 보기, 리비전 ";
 
$lang["YEARS"] = "년";
$lang["MONTHS"] = "개월";
$lang["WEEKS"] = "주일";
$lang["DAYS"] = "일";
$lang["HOURS"] = "시간";
$lang["MINUTES"] = "분";
 
$lang["GO"] = "Go";
 
$lang["PATHCOMPARISON"] = "경로 비교";
$lang["COMPAREPATHS"] = "경로 비교하기";
$lang["COMPAREREVS"] = "리비전 비교하기";
$lang["PROPCHANGES"] = "특성 변경 :";
$lang["CONVFROM"] = "이 비교는 바뀐 경로를 보여 줍니다.";
$lang["TO"] = "에서";
$lang["REVCOMP"] = "역 비교";
$lang["COMPPATH"] = "비교 경로:";
$lang["WITHPATH"] = "경로:";
 
// The following are defined by some languages to stop unwanted line splitting
// in the template files.
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
 
// $lang["NOBR"] = "<nobr>";
// $lang["ENDNOBR"] = "</nobr>";
/WebSVN/languages/NotUsed/norwegian.inc
1,122 → 1,121
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Tim Armes
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// norwegian.inc
//
// Norwegian language strings
// by Sigve Indregard <sigve.indregard@gmail.com>.
 
// Translation notes:
// - I've tried to keep with the translations made in the norwegian version
// of "Version control with Subversion"
// - I've kept the abbreviation "diff"
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Norwegian";
$lang['LANGUAGETAG'] = 'no';
 
$lang["LOG"] = "Logg";
$lang["DIFF"] = "Diff";
 
$lang["NOREP"] = "Depot ble ikke angitt";
$lang["NOPATH"] = "Stien ble ikke funnet";
$lang["SUPPLYREP"] = "Vennligst sett opp en depotsti i include/config.inc ved hjelp av \$config->parentPath eller \$config->addRepository.<p>Se installasjonsguiden for detaljer.";
 
$lang["DIFFREVS"] = "Diff mellom revisjoner";
$lang["AND"] = "og";
$lang["REV"] = "Rev";
$lang["LINE"] = "Linje";
$lang["SHOWENTIREFILE"] = "Vis hele filen";
$lang["SHOWCOMPACT"] = "Vis kun omr&aring;der med forskjeller";
 
$lang["DIFFPREV"] = "Sammenlign med forrige";
$lang["BLAME"] = "Ansvarlig";
 
$lang["REVINFO"] = "Revisjonsinformasjon";
$lang["GOYOUNGEST"] = "G&aring; til nyeste revisjon";
$lang["LASTMOD"] = "Siste endring";
$lang["LOGMSG"] = "Loggmelding";
$lang["CHANGES"] = "Endringer";
$lang["SHOWCHANGED"] = "Vis endrede filer";
$lang["HIDECHANGED"] = "Gjem endrede filer";
$lang["NEWFILES"] = "Nye filer";
$lang["CHANGEDFILES"] = "Endrede filer";
$lang["DELETEDFILES"] = "Slettede filer";
$lang["VIEWLOG"] = "Vis&nbsp;logg";
$lang["PATH"] = "Sti";
$lang["AUTHOR"] = "Forfatter";
$lang["AGE"] = "Alder";
$lang["LOG"] = "Logg";
$lang["CURDIR"] = "Gjeldende katalog";
$lang["TARBALL"] = "Tar-ball";
 
$lang["PREV"] = "Forrige";
$lang["NEXT"] = "Neste";
$lang["SHOWALL"] = "Vis alle";
 
$lang["BADCMD"] = "En feil oppstod under utf&oslash;relse av denne kommandoen";
 
$lang["POWERED"] = "Kj&oslash;rer p&aring; <a href=\"http://websvn.tigris.org/\">WebSVN</a>";
$lang["PROJECTS"] = "Subversionprosjekter";
$lang["SERVER"] = "Subversiontjener";
 
$lang["SEARCHLOG"] = "S&oslash;k i loggen etter";
$lang["CLEARLOG"] = "T&oslash;m gjeldende s&oslash;k";
$lang["MORERESULTS"] = "Finn flere treff...";
$lang["NORESULTS"] = "Ingen loggmeldinger passer til ditt s&oslash;k";
$lang["NOMORERESULTS"] = "Ingen flere loggmeldinger passer til ditt s&oslash;k";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS-str&oslash;m";
$lang["FILESMODIFIED"] = "fil(er) endret";
$lang["RSSFEED"] = "RSS-str&oslash;m";
 
$lang["LINENO"] = "Linjenr.";
$lang["BLAMEFOR"] = "Ansvarliginformasjon for rev.";
 
$lang["YEARS"] = "&aring;r";
$lang["MONTHS"] = "m&aring;neder";
$lang["WEEKS"] = "uker";
$lang["DAYS"] = "dager";
$lang["HOURS"] = "timer";
$lang["MINUTES"] = "minutter";
 
$lang["GO"] = "G&aring;";
 
$lang["PATHCOMPARISON"] = "Stisammenligning";
$lang["COMPAREPATHS"] = "Sammenlign stier";
$lang["COMPAREREVS"] = "Sammenlign revisjoner";
$lang["PROPCHANGES"] = "Egenskapsendringer :";
$lang["CONVFROM"] = "Denne sammenligningen viser hva som m&aring; til for &aring; konvertere stien ";
$lang["TO"] = "med";
$lang["REVCOMP"] = "Baklengs sammenligning";
$lang["COMPPATH"] = "Sammenlign sti:";
$lang["WITHPATH"] = "Med sti:";
$lang["FILEDELETED"] = "Fil slettet";
$lang["FILEADDED"] = "Ny fil";
 
// The following are defined by some languages to stop unwanted line splitting
// in the template files.
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
 
// $lang["NOBR"] = "<nobr>";
// $lang["ENDNOBR"] = "</nobr>";
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Tim Armes
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// norwegian.inc
//
// Norwegian language strings
// by Sigve Indregard <sigve.indregard@gmail.com>.
 
// Translation notes:
// - I've tried to keep with the translations made in the norwegian version
// of "Version control with Subversion"
// - I've kept the abbreviation "diff"
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Norwegian";
 
$lang["LOG"] = "Logg";
$lang["DIFF"] = "Diff";
 
$lang["NOREP"] = "Depot ble ikke angitt";
$lang["NOPATH"] = "Stien ble ikke funnet";
$lang["SUPPLYREP"] = "Vennligst sett opp en depotsti i include/config.inc ved hjelp av \$config->parentPath eller \$config->addRepository.<p>Se installasjonsguiden for detaljer.";
 
$lang["DIFFREVS"] = "Diff mellom revisjoner";
$lang["AND"] = "og";
$lang["REV"] = "Rev";
$lang["LINE"] = "Linje";
$lang["SHOWENTIREFILE"] = "Vis hele filen";
$lang["SHOWCOMPACT"] = "Vis kun omr&aring;der med forskjeller";
 
$lang["DIFFPREV"] = "Sammenlign med forrige";
$lang["BLAME"] = "Ansvarlig";
 
$lang["REVINFO"] = "Revisjonsinformasjon";
$lang["GOYOUNGEST"] = "G&aring; til nyeste revisjon";
$lang["LASTMOD"] = "Siste endring";
$lang["LOGMSG"] = "Loggmelding";
$lang["CHANGES"] = "Endringer";
$lang["SHOWCHANGED"] = "Vis endrede filer";
$lang["HIDECHANGED"] = "Gjem endrede filer";
$lang["NEWFILES"] = "Nye filer";
$lang["CHANGEDFILES"] = "Endrede filer";
$lang["DELETEDFILES"] = "Slettede filer";
$lang["VIEWLOG"] = "Vis&nbsp;logg";
$lang["PATH"] = "Sti";
$lang["AUTHOR"] = "Forfatter";
$lang["AGE"] = "Alder";
$lang["LOG"] = "Logg";
$lang["CURDIR"] = "Gjeldende katalog";
$lang["TARBALL"] = "Tar-ball";
 
$lang["PREV"] = "Forrige";
$lang["NEXT"] = "Neste";
$lang["SHOWALL"] = "Vis alle";
 
$lang["BADCMD"] = "En feil oppstod under utf&oslash;relse av denne kommandoen";
 
$lang["POWERED"] = "Kj&oslash;rer p&aring; <a href=\"http://websvn.tigris.org/\">WebSVN</a>";
$lang["PROJECTS"] = "Subversionprosjekter";
$lang["SERVER"] = "Subversiontjener";
 
$lang["SEARCHLOG"] = "S&oslash;k i loggen etter";
$lang["CLEARLOG"] = "T&oslash;m gjeldende s&oslash;k";
$lang["MORERESULTS"] = "Finn flere treff...";
$lang["NORESULTS"] = "Ingen loggmeldinger passer til ditt s&oslash;k";
$lang["NOMORERESULTS"] = "Ingen flere loggmeldinger passer til ditt s&oslash;k";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS-str&oslash;m";
$lang["FILESMODIFIED"] = "fil(er) endret";
$lang["RSSFEED"] = "RSS-str&oslash;m";
 
$lang["LINENO"] = "Linjenr.";
$lang["BLAMEFOR"] = "Ansvarliginformasjon for rev.";
 
$lang["YEARS"] = "&aring;r";
$lang["MONTHS"] = "m&aring;neder";
$lang["WEEKS"] = "uker";
$lang["DAYS"] = "dager";
$lang["HOURS"] = "timer";
$lang["MINUTES"] = "minutter";
 
$lang["GO"] = "G&aring;";
 
$lang["PATHCOMPARISON"] = "Stisammenligning";
$lang["COMPAREPATHS"] = "Sammenlign stier";
$lang["COMPAREREVS"] = "Sammenlign revisjoner";
$lang["PROPCHANGES"] = "Egenskapsendringer :";
$lang["CONVFROM"] = "Denne sammenligningen viser hva som m&aring; til for &aring; konvertere stien ";
$lang["TO"] = "med";
$lang["REVCOMP"] = "Baklengs sammenligning";
$lang["COMPPATH"] = "Sammenlign sti:";
$lang["WITHPATH"] = "Med sti:";
$lang["FILEDELETED"] = "Fil slettet";
$lang["FILEADDED"] = "Ny fil";
 
// The following are defined by some languages to stop unwanted line splitting
// in the template files.
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
 
// $lang["NOBR"] = "<nobr>";
// $lang["ENDNOBR"] = "</nobr>";
/WebSVN/languages/NotUsed/polish.inc
1,122 → 1,121
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Tim Armes
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// polish.inc
//
// Polish language strings in UTF-8 encoding
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Polish";
$lang['LANGUAGETAG'] = 'pl';
 
$lang["LOG"] = "Dziennik zmian";
$lang["DIFF"] = "Różnice";
 
$lang["NOREP"] = "Nie podano żadnego repozytorium";
$lang["NOPATH"] = "Nie odnaleziono ścieżki";
$lang["SUPPLYREP"] = "Proszę ustawić ścieżkę do repozytoriów w
include/config.inc za pomocą \$config->parentPath lub
\$config->addRepository<p>Aby uzyskać więcej szczegółów zapoznaj się z
podręcznikiem instalacyjnym";
 
$lang["DIFFREVS"] = "Różnice pomiędzy wersjami";
$lang["AND"] = "i";
$lang["REV"] = "Wersja";
$lang["LINE"] = "Linia";
$lang["SHOWENTIREFILE"] = "Pokaż cały plik";
$lang["SHOWCOMPACT"] = "Pokaż tylko fragmety w których zaszły zmiany";
 
$lang["DIFFPREV"] = "Porównaj z poprzednią wersją";
$lang["BLAME"] = "Wkład pracy";
 
$lang["REVINFO"] = "Informacje o wersji";
$lang["GOYOUNGEST"] = "Przejdź do najnowszej wersji";
$lang["LASTMOD"] = "Ostatnia zmiana";
$lang["LOGMSG"] = "Wpis z dziennika zmian";
$lang["CHANGES"] = "Zmiany";
$lang["SHOWCHANGED"] = "Pokaż zmienione pliki";
$lang["HIDECHANGED"] = "Ukryj zmienione pliki";
$lang["NEWFILES"] = "Nowe pliki";
$lang["CHANGEDFILES"] = "Zmienione pliki";
$lang["DELETEDFILES"] = "Usunięte pliki";
$lang["VIEWLOG"] = "Pokaż&nbsp;dziennik&nbsp;zmian";
$lang["PATH"] = "Ścieżka";
$lang["AUTHOR"] = "Autor";
$lang["AGE"] = "Wiek";
$lang["LOG"] = "Dziennik&nbsp;zmian";
$lang["CURDIR"] = "Aktualny katalog";
$lang["TARBALL"] = "Archiwum tar";
 
$lang["PREV"] = "Poprzednia strona";
$lang["NEXT"] = "Następna strona";
$lang["SHOWALL"] = "Pokaż wszyskie";
 
$lang["BADCMD"] = "Błąd podczas wykonywania polecenia";
 
$lang["POWERED"] = "Obsługiwane przez <a
href=\"http://websvn.tigris.org/\">WebSVN</a>";
$lang["PROJECTS"] = "Projekty&nbsp;Subversion";
$lang["SERVER"] = "Serwer Subversion";
 
$lang["SEARCHLOG"] = "Przeszukaj dziennik zmian";
$lang["CLEARLOG"] = "Usuń rezulaty wyszukiwania";
$lang["MORERESULTS"] = "Znajdź więcej dopasowań...";
$lang["NORESULTS"] = "Żaden wpis w dzinniku zmian nie pasuje do zapytania";
$lang["NOMORERESULTS"] = "Nie ma już więcej wpisów pasujących do
zadanych kryterów";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS feed";
$lang["FILESMODIFIED"] = "zmienione pliki";
$lang["RSSFEED"] = "RSS feed";
 
$lang["LINENO"] = "Linia nr";
$lang["BLAMEFOR"] = "Wkład pracy dla wersji";
 
$lang["YEARS"] = "lat";
$lang["MONTHS"] = "miesięcy";
$lang["WEEKS"] = "tygodni";
$lang["DAYS"] = "dni";
$lang["HOURS"] = "godzin";
$lang["MINUTES"] = "minut";
 
$lang["GO"] = "Przejdź";
 
$lang["PATHCOMPARISON"] = "Porównywanie katalogów";
$lang["COMPAREPATHS"] = "Porównaj katalogi";
$lang["COMPAREREVS"] = "Porównaj wersje";
$lang["PROPCHANGES"] = "Zmiany właściwości :";
$lang["CONVFROM"] = "Poniższe zestawienie pokazuje zmiany konieczne by
zaktualizować katalog";
$lang["TO"] = "na";
$lang["REVCOMP"] = "Odwróć porównanie";
$lang["COMPPATH"] = "Porównaj katalog:";
$lang["WITHPATH"] = "Z katalogiem:";
$lang["FILEDELETED"] = "Plik usunięty";
$lang["FILEADDED"] = "Nowy plik";
 
// The following are defined by some languages to stop unwanted line splitting
// in the template files.
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
 
// $lang["NOBR"] = "<nobr>";
// $lang["ENDNOBR"] = "</nobr>";
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Tim Armes
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// polish.inc
//
// Polish language strings in UTF-8 encoding
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Polish";
 
$lang["LOG"] = "Dziennik zmian";
$lang["DIFF"] = "Różnice";
 
$lang["NOREP"] = "Nie podano żadnego repozytorium";
$lang["NOPATH"] = "Nie odnaleziono ścieżki";
$lang["SUPPLYREP"] = "Proszę ustawić ścieżkę do repozytoriów w
include/config.inc za pomocą \$config->parentPath lub
\$config->addRepository<p>Aby uzyskać więcej szczegółów zapoznaj się z
podręcznikiem instalacyjnym";
 
$lang["DIFFREVS"] = "Różnice pomiędzy wersjami";
$lang["AND"] = "i";
$lang["REV"] = "Wersja";
$lang["LINE"] = "Linia";
$lang["SHOWENTIREFILE"] = "Pokaż cały plik";
$lang["SHOWCOMPACT"] = "Pokaż tylko fragmety w których zaszły zmiany";
 
$lang["DIFFPREV"] = "Porównaj z poprzednią wersją";
$lang["BLAME"] = "Wkład pracy";
 
$lang["REVINFO"] = "Informacje o wersji";
$lang["GOYOUNGEST"] = "Przejdź do najnowszej wersji";
$lang["LASTMOD"] = "Ostatnia zmiana";
$lang["LOGMSG"] = "Wpis z dziennika zmian";
$lang["CHANGES"] = "Zmiany";
$lang["SHOWCHANGED"] = "Pokaż zmienione pliki";
$lang["HIDECHANGED"] = "Ukryj zmienione pliki";
$lang["NEWFILES"] = "Nowe pliki";
$lang["CHANGEDFILES"] = "Zmienione pliki";
$lang["DELETEDFILES"] = "Usunięte pliki";
$lang["VIEWLOG"] = "Pokaż&nbsp;dziennik&nbsp;zmian";
$lang["PATH"] = "Ścieżka";
$lang["AUTHOR"] = "Autor";
$lang["AGE"] = "Wiek";
$lang["LOG"] = "Dziennik&nbsp;zmian";
$lang["CURDIR"] = "Aktualny katalog";
$lang["TARBALL"] = "Archiwum tar";
 
$lang["PREV"] = "Poprzednia strona";
$lang["NEXT"] = "Następna strona";
$lang["SHOWALL"] = "Pokaż wszyskie";
 
$lang["BADCMD"] = "Błąd podczas wykonywania polecenia";
 
$lang["POWERED"] = "Obsługiwane przez <a
href=\"http://websvn.tigris.org/\">WebSVN</a>";
$lang["PROJECTS"] = "Projekty&nbsp;Subversion";
$lang["SERVER"] = "Serwer Subversion";
 
$lang["SEARCHLOG"] = "Przeszukaj dziennik zmian";
$lang["CLEARLOG"] = "Usuń rezulaty wyszukiwania";
$lang["MORERESULTS"] = "Znajdź więcej dopasowań...";
$lang["NORESULTS"] = "Żaden wpis w dzinniku zmian nie pasuje do zapytania";
$lang["NOMORERESULTS"] = "Nie ma już więcej wpisów pasujących do
zadanych kryterów";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS feed";
$lang["FILESMODIFIED"] = "zmienione pliki";
$lang["RSSFEED"] = "RSS feed";
 
$lang["LINENO"] = "Linia nr";
$lang["BLAMEFOR"] = "Wkład pracy dla wersji";
 
$lang["YEARS"] = "lat";
$lang["MONTHS"] = "miesięcy";
$lang["WEEKS"] = "tygodni";
$lang["DAYS"] = "dni";
$lang["HOURS"] = "godzin";
$lang["MINUTES"] = "minut";
 
$lang["GO"] = "Przejdź";
 
$lang["PATHCOMPARISON"] = "Porównywanie katalogów";
$lang["COMPAREPATHS"] = "Porównaj katalogi";
$lang["COMPAREREVS"] = "Porównaj wersje";
$lang["PROPCHANGES"] = "Zmiany właściwości :";
$lang["CONVFROM"] = "Poniższe zestawienie pokazuje zmiany konieczne by
zaktualizować katalog";
$lang["TO"] = "na";
$lang["REVCOMP"] = "Odwróć porównanie";
$lang["COMPPATH"] = "Porównaj katalog:";
$lang["WITHPATH"] = "Z katalogiem:";
$lang["FILEDELETED"] = "Plik usunięty";
$lang["FILEADDED"] = "Nowy plik";
 
// The following are defined by some languages to stop unwanted line splitting
// in the template files.
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
 
// $lang["NOBR"] = "<nobr>";
// $lang["ENDNOBR"] = "</nobr>";
/WebSVN/languages/NotUsed/portuguese.inc
1,85 → 1,84
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Tim Armes
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// portuguese.inc
//
// Portuguese language strings
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Portuguese";
$lang['LANGUAGETAG'] = 'pt';
 
$lang["LOG"] = "Log";
$lang["DIFF"] = "Diff";
 
$lang["NOREP"] = "N&atilde;o foi indicado um reposit&oacute;rio";
$lang["NOPATH"] = "Path Inv&aacute;lida";
 
$lang["DIFFREVS"] = "Diferen&ccedil;as entre revis&otilde;es";
$lang["AND"] = "e";
$lang["REV"] = "Rev";
$lang["LINE"] = "Linha";
$lang["SHOWENTIREFILE"] = "Mostrar todo o ficheiro";
$lang["SHOWCOMPACT"] = "Mostrar apenas &aacute;reas com diferen&ccedil;as";
 
$lang["DIFFPREV"] = "Diferen&ccedil;as com a anterior";
 
$lang["REVINFO"] = "Notas desta revis&atilde;o";
$lang["GOYOUNGEST"] = "Revis&atilde;o mais recente";
$lang["LASTMOD"] = "&Uacute;ltima altera&ccedil;&atilde;o";
$lang["LOGMSG"] = "Mensagem de Log";
$lang["CHANGES"] = "Altera&ccedil;&otilde;es";
$lang["SHOWCHANGED"] = "Mostrar ficheiros alterados";
$lang["HIDECHANGED"] = "Esconder ficheiros alterados";
$lang["NEWFILES"] = "Novos ficheiros";
$lang["CHANGEDFILES"] = "Ficheiros alterados";
$lang["DELETEDFILES"] = "Ficheiros apagados";
$lang["VIEWLOG"] = "Ver&nbsp;Log";
$lang["PATH"] = "Path";
$lang["AUTHOR"] = "Autor";
$lang["AGE"] = "Idade";
$lang["LOG"] = "Log";
$lang["CURDIR"] = "Directoria Currente";
 
$lang["PREV"] = "Anterior";
$lang["NEXT"] = "Seguinte";
$lang["SHOWALL"] = "Mostrar todos";
 
$lang["BADCMD"] = "Erro ao correr este comando";
 
$lang["POWERED"] = "Powered by <a href=\"http://websvn.tigris.org/\">WebSVN</a>";
$lang["PROJECTS"] = "Subversion&nbsp;Projectos";
$lang["SERVER"] = "Subversion&nbsp;Servidor";
 
$lang["SEARCHLOG"] = "Pesquisar o Search log por";
$lang["CLEARLOG"] = "Limpar pesquisa";
$lang["MORERESULTS"] = "Encontrar mais...";
$lang["NORESULTS"] = "A pesquisa n&atilde;o devolveu nenhum log";
$lang["NOMORERESULTS"] = "N&atilde;o existem mais resultados (logs) para a pesquisa";
 
$lang["YEARS"] = "anos";
$lang["MONTHS"] = "meses";
$lang["WEEKS"] = "semanas";
$lang["DAYS"] = "dias";
$lang["HOURS"] = "horas";
$lang["MINUTES"] = "minutos";
 
$lang["GO"] = "Go";
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Tim Armes
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// portuguese.inc
//
// Portuguese language strings
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Portuguese";
 
$lang["LOG"] = "Log";
$lang["DIFF"] = "Diff";
 
$lang["NOREP"] = "N&atilde;o foi indicado um reposit&oacute;rio";
$lang["NOPATH"] = "Path Inv&aacute;lida";
 
$lang["DIFFREVS"] = "Diferen&ccedil;as entre revis&otilde;es";
$lang["AND"] = "e";
$lang["REV"] = "Rev";
$lang["LINE"] = "Linha";
$lang["SHOWENTIREFILE"] = "Mostrar todo o ficheiro";
$lang["SHOWCOMPACT"] = "Mostrar apenas &aacute;reas com diferen&ccedil;as";
 
$lang["DIFFPREV"] = "Diferen&ccedil;as com a anterior";
 
$lang["REVINFO"] = "Notas desta revis&atilde;o";
$lang["GOYOUNGEST"] = "Revis&atilde;o mais recente";
$lang["LASTMOD"] = "&Uacute;ltima altera&ccedil;&atilde;o";
$lang["LOGMSG"] = "Mensagem de Log";
$lang["CHANGES"] = "Altera&ccedil;&otilde;es";
$lang["SHOWCHANGED"] = "Mostrar ficheiros alterados";
$lang["HIDECHANGED"] = "Esconder ficheiros alterados";
$lang["NEWFILES"] = "Novos ficheiros";
$lang["CHANGEDFILES"] = "Ficheiros alterados";
$lang["DELETEDFILES"] = "Ficheiros apagados";
$lang["VIEWLOG"] = "Ver&nbsp;Log";
$lang["PATH"] = "Path";
$lang["AUTHOR"] = "Autor";
$lang["AGE"] = "Idade";
$lang["LOG"] = "Log";
$lang["CURDIR"] = "Directoria Currente";
 
$lang["PREV"] = "Anterior";
$lang["NEXT"] = "Seguinte";
$lang["SHOWALL"] = "Mostrar todos";
 
$lang["BADCMD"] = "Erro ao correr este comando";
 
$lang["POWERED"] = "Powered by <a href=\"http://websvn.tigris.org/\">WebSVN</a>";
$lang["PROJECTS"] = "Subversion&nbsp;Projectos";
$lang["SERVER"] = "Subversion&nbsp;Servidor";
 
$lang["SEARCHLOG"] = "Pesquisar o Search log por";
$lang["CLEARLOG"] = "Limpar pesquisa";
$lang["MORERESULTS"] = "Encontrar mais...";
$lang["NORESULTS"] = "A pesquisa n&atilde;o devolveu nenhum log";
$lang["NOMORERESULTS"] = "N&atilde;o existem mais resultados (logs) para a pesquisa";
 
$lang["YEARS"] = "anos";
$lang["MONTHS"] = "meses";
$lang["WEEKS"] = "semanas";
$lang["DAYS"] = "dias";
$lang["HOURS"] = "horas";
$lang["MINUTES"] = "minutos";
 
$lang["GO"] = "Go";
/WebSVN/languages/NotUsed/schinese.inc
1,118 → 1,117
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Tim Armes
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// schinese-utf8.inc
//
// Simple Chinese language strings
//
// Author: Liangxu Wang <wlx@mygis.org>
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Simplified Chinese";
$lang['LANGUAGETAG'] = 'zh-CN';
 
$lang["LOG"] = "记录";
$lang["DIFF"] = "差异";
 
$lang["NOREP"] = "没有仓库";
$lang["NOPATH"] = "找不到路径";
$lang["SUPPLYREP"] = "请在include/config.inc中使用\$config->parentPath或\$config->addRepository设置仓库的路径<p>更详细的内容请参考安装手册";
 
$lang["DIFFREVS"] = "修订版本之间的差异";
$lang["AND"] = "和";
$lang["REV"] = "修订";
$lang["LINE"] = "行";
$lang["SHOWENTIREFILE"] = "显示整个文件";
$lang["SHOWCOMPACT"] = "只显示差异处";
 
$lang["DIFFPREV"] = "与前一次版本进行比较";
$lang["BLAME"] = "Blame";
 
$lang["REVINFO"] = "修订版信息";
$lang["GOYOUNGEST"] = "到最新的修订版";
$lang["LASTMOD"] = "最后修改";
$lang["LOGMSG"] = "记录消息";
$lang["CHANGES"] = "变化";
$lang["SHOWCHANGED"] = "显示有变化的文件";
$lang["HIDECHANGED"] = "隐藏有变化的文件";
$lang["NEWFILES"] = "新文件";
$lang["CHANGEDFILES"] = "已修改文件";
$lang["DELETEDFILES"] = "已删除文件";
$lang["VIEWLOG"] = "查看记录";
$lang["PATH"] = "路径";
$lang["AUTHOR"] = "作者";
$lang["AGE"] = "年龄";
$lang["LOG"] = "记录";
$lang["CURDIR"] = "当前目录";
$lang["TARBALL"] = "Tarball格式";
 
$lang["PREV"] = "前";
$lang["NEXT"] = "后";
$lang["SHOWALL"] = "全部显示";
 
$lang["BADCMD"] = "命令执行错误";
 
$lang["POWERED"] = "Powered by <a href=\"http://websvn.tigris.org/\">WebSVN</a>";
$lang["PROJECTS"] = "Subversion&nbsp;Projects";
$lang["SERVER"] = "Subversion&nbsp;Server";
 
$lang["SEARCHLOG"] = "搜索记录内容";
$lang["CLEARLOG"] = "清除当前搜索";
$lang["MORERESULTS"] = "找个更多符合的...";
$lang["NORESULTS"] = "没有符合要求的记录";
$lang["NOMORERESULTS"] = "没有更多记录符合要求";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS feed";
$lang["FILESMODIFIED"] = "个文件被改动";
$lang["RSSFEED"] = "RSS feed";
 
$lang["LINENO"] = "行号";
$lang["BLAMEFOR"] = "Blame information for rev";
 
$lang["YEARS"] = "年";
$lang["MONTHS"] = "月";
$lang["WEEKS"] = "周";
$lang["DAYS"] = "日";
$lang["HOURS"] = "小时";
$lang["MINUTES"] = "分钟";
 
$lang["GO"] = "Go";
 
$lang["PATHCOMPARISON"] = "路径比较";
$lang["COMPAREPATHS"] = "路径比较";
$lang["COMPAREREVS"] = "比较修订版";
$lang["PROPCHANGES"] = "改变属性 :";
$lang["CONVFROM"] = "这个比较必须转换路径,从";
$lang["TO"] = "到";
$lang["REVCOMP"] = "颠倒比较";
$lang["COMPPATH"] = "路径比较:";
$lang["WITHPATH"] = "With Path:";
$lang["FILEDELETED"] = "已删除文件";
$lang["FILEADDED"] = "新文件";
 
// The following are defined by some languages to stop unwanted line splitting
// in the template files.
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
 
// $lang["NOBR"] = "<nobr>";
// $lang["ENDNOBR"] = "</nobr>";
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Tim Armes
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// schinese-utf8.inc
//
// Simple Chinese language strings
//
// Author: Liangxu Wang <wlx@mygis.org>
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Simplified Chinese";
 
$lang["LOG"] = "记录";
$lang["DIFF"] = "差异";
 
$lang["NOREP"] = "没有仓库";
$lang["NOPATH"] = "找不到路径";
$lang["SUPPLYREP"] = "请在include/config.inc中使用\$config->parentPath或\$config->addRepository设置仓库的路径<p>更详细的内容请参考安装手册";
 
$lang["DIFFREVS"] = "修订版本之间的差异";
$lang["AND"] = "和";
$lang["REV"] = "修订";
$lang["LINE"] = "行";
$lang["SHOWENTIREFILE"] = "显示整个文件";
$lang["SHOWCOMPACT"] = "只显示差异处";
 
$lang["DIFFPREV"] = "与前一次版本进行比较";
$lang["BLAME"] = "Blame";
 
$lang["REVINFO"] = "修订版信息";
$lang["GOYOUNGEST"] = "到最新的修订版";
$lang["LASTMOD"] = "最后修改";
$lang["LOGMSG"] = "记录消息";
$lang["CHANGES"] = "变化";
$lang["SHOWCHANGED"] = "显示有变化的文件";
$lang["HIDECHANGED"] = "隐藏有变化的文件";
$lang["NEWFILES"] = "新文件";
$lang["CHANGEDFILES"] = "已修改文件";
$lang["DELETEDFILES"] = "已删除文件";
$lang["VIEWLOG"] = "查看记录";
$lang["PATH"] = "路径";
$lang["AUTHOR"] = "作者";
$lang["AGE"] = "年龄";
$lang["LOG"] = "记录";
$lang["CURDIR"] = "当前目录";
$lang["TARBALL"] = "Tarball格式";
 
$lang["PREV"] = "前";
$lang["NEXT"] = "后";
$lang["SHOWALL"] = "全部显示";
 
$lang["BADCMD"] = "命令执行错误";
 
$lang["POWERED"] = "Powered by <a href=\"http://websvn.tigris.org/\">WebSVN</a>";
$lang["PROJECTS"] = "Subversion&nbsp;Projects";
$lang["SERVER"] = "Subversion&nbsp;Server";
 
$lang["SEARCHLOG"] = "搜索记录内容";
$lang["CLEARLOG"] = "清除当前搜索";
$lang["MORERESULTS"] = "找个更多符合的...";
$lang["NORESULTS"] = "没有符合要求的记录";
$lang["NOMORERESULTS"] = "没有更多记录符合要求";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS feed";
$lang["FILESMODIFIED"] = "个文件被改动";
$lang["RSSFEED"] = "RSS feed";
 
$lang["LINENO"] = "行号";
$lang["BLAMEFOR"] = "Blame information for rev";
 
$lang["YEARS"] = "年";
$lang["MONTHS"] = "月";
$lang["WEEKS"] = "周";
$lang["DAYS"] = "日";
$lang["HOURS"] = "小时";
$lang["MINUTES"] = "分钟";
 
$lang["GO"] = "Go";
 
$lang["PATHCOMPARISON"] = "路径比较";
$lang["COMPAREPATHS"] = "路径比较";
$lang["COMPAREREVS"] = "比较修订版";
$lang["PROPCHANGES"] = "改变属性 :";
$lang["CONVFROM"] = "这个比较必须转换路径,从";
$lang["TO"] = "到";
$lang["REVCOMP"] = "颠倒比较";
$lang["COMPPATH"] = "路径比较:";
$lang["WITHPATH"] = "With Path:";
$lang["FILEDELETED"] = "已删除文件";
$lang["FILEADDED"] = "新文件";
 
// The following are defined by some languages to stop unwanted line splitting
// in the template files.
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
 
// $lang["NOBR"] = "<nobr>";
// $lang["ENDNOBR"] = "</nobr>";
/WebSVN/languages/NotUsed/slovenian.inc
1,130 → 1,129
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Goran Kavrecic
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// slovenian.inc
//
// Slovenian language strings
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Slovenian";
$lang['LANGUAGETAG'] = 'sl';
 
$lang["LOG"] = "Log";
$lang["DIFF"] = "Diff";
 
$lang["NOREP"] = "Skladišče ni določeno";
$lang["NOPATH"] = "Ne najdem poti";
$lang["NOACCESS"] = "Nimate dovolj pravic za branje tega direktorija";
$lang["RESTRICTED"] = "Dostop zavrnjen";
$lang["SUPPLYREP"] = "Prosim nastavi pot do skladišča v include/config.inc z \$config->parentPath ali \$config->addRepository<p>Poglej navodila za detajle";
 
$lang["DIFFREVS"] = "Razlika med različicama";
$lang["AND"] = "in";
$lang["REV"] = "Različica";
$lang["LINE"] = "Vrstica";
$lang["SHOWENTIREFILE"] = "Prikaži celo datoteko";
$lang["SHOWCOMPACT"] = "Prikaži samo področja z razlikami";
 
$lang["DIFFPREV"] = "Primerjaj s prejšno";
$lang["BLAME"] = "Blame";
 
$lang["REVINFO"] = "Informacija o različici";
$lang["GOYOUNGEST"] = "Skoči na zadnjo različico";
$lang["LASTMOD"] = "Zadnje spremembe";
$lang["LOGMSG"] = "Opombe";
$lang["CHANGES"] = "Spremembe";
$lang["SHOWCHANGED"] = "Prikaži spremenjene datoteke";
$lang["HIDECHANGED"] = "Skrij spremenjene datoteke";
$lang["NEWFILES"] = "Nove datoteke";
$lang["CHANGEDFILES"] = "Spremenjene datoteke";
$lang["DELETEDFILES"] = "Pobrisane datoteke";
$lang["VIEWLOG"] = "Poglej&nbsp;Opombe";
$lang["PATH"] = "Pot";
$lang["AUTHOR"] = "Avtor";
$lang["AGE"] = "Starost";
$lang["LOG"] = "Log";
$lang["CURDIR"] = "Trenutni direktorij";
$lang["TARBALL"] = "Tarball";
 
$lang["PREV"] = "Nazaj";
$lang["NEXT"] = "Naprej";
$lang["SHOWALL"] = "Prikaži vse";
 
$lang["BADCMD"] = "Napaka pri izvajanju tega ukaza";
$lang["UNKNOWNREVISION"] = "Ne najdem različice";
 
$lang["POWERED"] = "Powered by <a href=\"http://websvn.tigris.org/\">WebSVN</a>";
$lang["PROJECTS"] = "Subversion&nbsp;Projekti";
$lang["SERVER"] = "Subversion&nbsp;strežnik";
 
 
$lang["FILTER"] = "Možnosti filtriranja";
$lang["STARTLOG"] = "Od različice";
$lang["ENDLOG"] = "Do različice";
$lang["MAXLOG"] = "Max različic";
$lang["SEARCHLOG"] = "Išči po opombah";
$lang["CLEARLOG"] = "Pobriši trenutno iskanje";
$lang["MORERESULTS"] = "Poišči še...";
$lang["NORESULTS"] = "Med zapisi ni opomb z iskalno zahtevo";
$lang["NOMORERESULTS"] = "Med zapisi ni več opomb z iskalno zahtevo";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS feed";
$lang["FILESMODIFIED"] = "datotek spremenjenih";
$lang["RSSFEED"] = "RSS feed";
 
$lang["LINENO"] = "Vrstica št.";
$lang["BLAMEFOR"] = "Blame informacije za različico";
 
//$lang["YEARS"] = "let";
//$lang["MONTHS"] = "mesecev";
//$lang["WEEKS"] = "tednov";
//$lang["DAYS"] = "dni";
//$lang["HOURS"] = "ur";
//$lang["MINUTES"] = "minute";
$lang["DAYLETTER"] = "d";
$lang["HOURLETTER"] = "h";
$lang["MINUTELETTER"] = "m";
$lang["SECONDLETTER"] = "s";
 
$lang["GO"] = "Izvedi";
 
$lang["PATHCOMPARISON"] = "Primerjava poti";
$lang["COMPAREPATHS"] = "Primerjaj poti";
$lang["COMPAREREVS"] = "Primerjaj različici";
$lang["PROPCHANGES"] = "Spremembe lastnosti :";
$lang["CONVFROM"] = "Ta primerjava prikazuje spremembe potrebne za pretvorbo poti ";
$lang["TO"] = "V";
$lang["REVCOMP"] = "Reverzna primerjava";
$lang["COMPPATH"] = "Primerjaj pot:";
$lang["WITHPATH"] = "S potjo:";
$lang["FILEDELETED"] = "Datoteka pobrisana";
$lang["FILEADDED"] = "Nova datoteka";
 
// The following are defined by some languages to stop unwanted line splitting
// in the template files.
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
 
// $lang["NOBR"] = "<nobr>";
// $lang["ENDNOBR"] = "</nobr>";
 
 
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Goran Kavrecic
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// slovenian.inc
//
// Slovenian language strings
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Slovenian";
 
$lang["LOG"] = "Log";
$lang["DIFF"] = "Diff";
 
$lang["NOREP"] = "Skladišče ni določeno";
$lang["NOPATH"] = "Ne najdem poti";
$lang["NOACCESS"] = "Nimate dovolj pravic za branje tega direktorija";
$lang["RESTRICTED"] = "Dostop zavrnjen";
$lang["SUPPLYREP"] = "Prosim nastavi pot do skladišča v include/config.inc z \$config->parentPath ali \$config->addRepository<p>Poglej navodila za detajle";
 
$lang["DIFFREVS"] = "Razlika med različicama";
$lang["AND"] = "in";
$lang["REV"] = "Različica";
$lang["LINE"] = "Vrstica";
$lang["SHOWENTIREFILE"] = "Prikaži celo datoteko";
$lang["SHOWCOMPACT"] = "Prikaži samo področja z razlikami";
 
$lang["DIFFPREV"] = "Primerjaj s prejšno";
$lang["BLAME"] = "Blame";
 
$lang["REVINFO"] = "Informacija o različici";
$lang["GOYOUNGEST"] = "Skoči na zadnjo različico";
$lang["LASTMOD"] = "Zadnje spremembe";
$lang["LOGMSG"] = "Opombe";
$lang["CHANGES"] = "Spremembe";
$lang["SHOWCHANGED"] = "Prikaži spremenjene datoteke";
$lang["HIDECHANGED"] = "Skrij spremenjene datoteke";
$lang["NEWFILES"] = "Nove datoteke";
$lang["CHANGEDFILES"] = "Spremenjene datoteke";
$lang["DELETEDFILES"] = "Pobrisane datoteke";
$lang["VIEWLOG"] = "Poglej&nbsp;Opombe";
$lang["PATH"] = "Pot";
$lang["AUTHOR"] = "Avtor";
$lang["AGE"] = "Starost";
$lang["LOG"] = "Log";
$lang["CURDIR"] = "Trenutni direktorij";
$lang["TARBALL"] = "Tarball";
 
$lang["PREV"] = "Nazaj";
$lang["NEXT"] = "Naprej";
$lang["SHOWALL"] = "Prikaži vse";
 
$lang["BADCMD"] = "Napaka pri izvajanju tega ukaza";
$lang["UNKNOWNREVISION"] = "Ne najdem različice";
 
$lang["POWERED"] = "Powered by <a href=\"http://websvn.tigris.org/\">WebSVN</a>";
$lang["PROJECTS"] = "Subversion&nbsp;Projekti";
$lang["SERVER"] = "Subversion&nbsp;strežnik";
 
 
$lang["FILTER"] = "Možnosti filtriranja";
$lang["STARTLOG"] = "Od različice";
$lang["ENDLOG"] = "Do različice";
$lang["MAXLOG"] = "Max različic";
$lang["SEARCHLOG"] = "Išči po opombah";
$lang["CLEARLOG"] = "Pobriši trenutno iskanje";
$lang["MORERESULTS"] = "Poišči še...";
$lang["NORESULTS"] = "Med zapisi ni opomb z iskalno zahtevo";
$lang["NOMORERESULTS"] = "Med zapisi ni več opomb z iskalno zahtevo";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS feed";
$lang["FILESMODIFIED"] = "datotek spremenjenih";
$lang["RSSFEED"] = "RSS feed";
 
$lang["LINENO"] = "Vrstica št.";
$lang["BLAMEFOR"] = "Blame informacije za različico";
 
//$lang["YEARS"] = "let";
//$lang["MONTHS"] = "mesecev";
//$lang["WEEKS"] = "tednov";
//$lang["DAYS"] = "dni";
//$lang["HOURS"] = "ur";
//$lang["MINUTES"] = "minute";
$lang["DAYLETTER"] = "d";
$lang["HOURLETTER"] = "h";
$lang["MINUTELETTER"] = "m";
$lang["SECONDLETTER"] = "s";
 
$lang["GO"] = "Izvedi";
 
$lang["PATHCOMPARISON"] = "Primerjava poti";
$lang["COMPAREPATHS"] = "Primerjaj poti";
$lang["COMPAREREVS"] = "Primerjaj različici";
$lang["PROPCHANGES"] = "Spremembe lastnosti :";
$lang["CONVFROM"] = "Ta primerjava prikazuje spremembe potrebne za pretvorbo poti ";
$lang["TO"] = "V";
$lang["REVCOMP"] = "Reverzna primerjava";
$lang["COMPPATH"] = "Primerjaj pot:";
$lang["WITHPATH"] = "S potjo:";
$lang["FILEDELETED"] = "Datoteka pobrisana";
$lang["FILEADDED"] = "Nova datoteka";
 
// The following are defined by some languages to stop unwanted line splitting
// in the template files.
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
 
// $lang["NOBR"] = "<nobr>";
// $lang["ENDNOBR"] = "</nobr>";
 
 
/WebSVN/languages/NotUsed/spanish.inc
1,116 → 1,115
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Tim Armes
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// spanish.inc
//
// Spanish language strings
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Spanish";
$lang['LANGUAGETAG'] = 'es';
 
$lang["LOG"] = "Log";
$lang["DIFF"] = "Diff";
 
$lang["NOREP"] = "No se especific&oacute; un repositorio";
$lang["NOPATH"] = "Ruta no encontrada";
$lang["SUPPLYREP"] = "Por Favor, configure una ruta a un repositorio en include/config.inc usando \$config->parentPath o \$config->addRepository<p>Verifique la gu&iacute;a de instalaci&oacute;n para mas detalles";
 
$lang["DIFFREVS"] = "Diff entre versiones";
$lang["AND"] = "y";
$lang["REV"] = "Rev";
$lang["LINE"] = "L&iacute;nea";
$lang["SHOWENTIREFILE"] = "Mostrar el archivo completo";
$lang["SHOWCOMPACT"] = "Solo mostrar &aacute;reas con diferencias";
 
$lang["DIFFPREV"] = "Comparar con el anterior";
$lang["BLAME"] = "Autor&iacute;a";
 
$lang["REVINFO"] = "Informaci&oacute;n sobre la revisi&oacute;n";
$lang["GOYOUNGEST"] = "Ir a la &uacute;ltima revisi&oacute;n";
$lang["LASTMOD"] = "Ultima modificaci&oacute;n";
$lang["LOGMSG"] = "Mensaje de Log";
$lang["CHANGES"] = "Cambios";
$lang["SHOWCHANGED"] = "Mostrar archivos modificados";
$lang["HIDECHANGED"] = "Ocultar archivos modificados";
$lang["NEWFILES"] = "Archivos Nuevos";
$lang["CHANGEDFILES"] = "Archivos modificados";
$lang["DELETEDFILES"] = "Archivos borrados";
$lang["VIEWLOG"] = "Ver&nbsp;Log";
$lang["PATH"] = "Ruta";
$lang["AUTHOR"] = "Autor";
$lang["AGE"] = "Antig&#252;edad";
$lang["LOG"] = "Log";
$lang["CURDIR"] = "Directorio Actual";
$lang["TARBALL"] = "Tarball";
 
$lang["PREV"] = "Ant";
$lang["NEXT"] = "Sig";
$lang["SHOWALL"] = "Mostrar todo";
 
$lang["BADCMD"] = "Error ejecutando ese comando";
 
$lang["POWERED"] = "Powered by <a href=\"http://websvn.tigris.org/\">WebSVN</a>";
$lang["PROJECTS"] = "Proyectos de&nbsp;Subversion";
$lang["SERVER"] = "Servidor de&nbsp;Subversion";
 
$lang["SEARCHLOG"] = "Buscar en el log";
$lang["CLEARLOG"] = "Limpiar la b&uacute;squeda actual";
$lang["MORERESULTS"] = "Buscar mas coincidencias";
$lang["NORESULTS"] = "Ning&uacute;n log coincide con su b&uacute;squeda";
$lang["NOMORERESULTS"] = "No hay mas logs que coincidan con su b&uacute;squeda";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS feed";
$lang["FILESMODIFIED"] = "Archivo(s) modificados";
$lang["RSSFEED"] = "RSS feed";
 
$lang["LINENO"] = "L&iacute;nea Nro.";
$lang["BLAMEFOR"] = "Informaci&oacute;n de culpa para rev";
 
$lang["YEARS"] = "A&ntilde;os";
$lang["MONTHS"] = "meses";
$lang["WEEKS"] = "semanas";
$lang["DAYS"] = "d&iacute;as";
$lang["HOURS"] = "horas";
$lang["MINUTES"] = "minutos";
 
$lang["GO"] = "Ir";
 
$lang["PATHCOMPARISON"] = "Comparaci&oacute;n de rutas";
$lang["COMPAREPATHS"] = "Comparar Rutas";
$lang["COMPAREREVS"] = "Comparar Revisiones";
$lang["PROPCHANGES"] = "Cambios de propiedades :";
$lang["CONVFROM"] = "Esta Comparaci&oacute;n muestra los cambios necesarios para convertir la ruta";
$lang["TO"] = "a";
$lang["REVCOMP"] = "Revertir comparaci&oacute;n";
$lang["COMPPATH"] = "Comparar Ruta:";
$lang["WITHPATH"] = "Con Ruta:";
$lang["FILEDELETED"] = "Archivo Eliminado";
$lang["FILEADDED"] = "Archivo Nuevo";
 
// The following are defined by some languages to stop unwanted line splitting
// in the template files.
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
 
// $lang["NOBR"] = "<nobr>";
// $lang["ENDNOBR"] = "</nobr>";
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Tim Armes
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// spanish.inc
//
// Spanish language strings
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Spanish";
 
$lang["LOG"] = "Log";
$lang["DIFF"] = "Diff";
 
$lang["NOREP"] = "No se especific&oacute; un repositorio";
$lang["NOPATH"] = "Ruta no encontrada";
$lang["SUPPLYREP"] = "Por Favor, configure una ruta a un repositorio en include/config.inc usando \$config->parentPath o \$config->addRepository<p>Verifique la gu&iacute;a de instalaci&oacute;n para mas detalles";
 
$lang["DIFFREVS"] = "Diff entre versiones";
$lang["AND"] = "y";
$lang["REV"] = "Rev";
$lang["LINE"] = "L&iacute;nea";
$lang["SHOWENTIREFILE"] = "Mostrar el archivo completo";
$lang["SHOWCOMPACT"] = "Solo mostrar &aacute;reas con diferencias";
 
$lang["DIFFPREV"] = "Comparar con el anterior";
$lang["BLAME"] = "Autor&iacute;a";
 
$lang["REVINFO"] = "Informaci&oacute;n sobre la revisi&oacute;n";
$lang["GOYOUNGEST"] = "Ir a la &uacute;ltima revisi&oacute;n";
$lang["LASTMOD"] = "Ultima modificaci&oacute;n";
$lang["LOGMSG"] = "Mensaje de Log";
$lang["CHANGES"] = "Cambios";
$lang["SHOWCHANGED"] = "Mostrar archivos modificados";
$lang["HIDECHANGED"] = "Ocultar archivos modificados";
$lang["NEWFILES"] = "Archivos Nuevos";
$lang["CHANGEDFILES"] = "Archivos modificados";
$lang["DELETEDFILES"] = "Archivos borrados";
$lang["VIEWLOG"] = "Ver&nbsp;Log";
$lang["PATH"] = "Ruta";
$lang["AUTHOR"] = "Autor";
$lang["AGE"] = "Antig&#252;edad";
$lang["LOG"] = "Log";
$lang["CURDIR"] = "Directorio Actual";
$lang["TARBALL"] = "Tarball";
 
$lang["PREV"] = "Ant";
$lang["NEXT"] = "Sig";
$lang["SHOWALL"] = "Mostrar todo";
 
$lang["BADCMD"] = "Error ejecutando ese comando";
 
$lang["POWERED"] = "Powered by <a href=\"http://websvn.tigris.org/\">WebSVN</a>";
$lang["PROJECTS"] = "Proyectos de&nbsp;Subversion";
$lang["SERVER"] = "Servidor de&nbsp;Subversion";
 
$lang["SEARCHLOG"] = "Buscar en el log";
$lang["CLEARLOG"] = "Limpiar la b&uacute;squeda actual";
$lang["MORERESULTS"] = "Buscar mas coincidencias";
$lang["NORESULTS"] = "Ning&uacute;n log coincide con su b&uacute;squeda";
$lang["NOMORERESULTS"] = "No hay mas logs que coincidan con su b&uacute;squeda";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS feed";
$lang["FILESMODIFIED"] = "Archivo(s) modificados";
$lang["RSSFEED"] = "RSS feed";
 
$lang["LINENO"] = "L&iacute;nea Nro.";
$lang["BLAMEFOR"] = "Informaci&oacute;n de culpa para rev";
 
$lang["YEARS"] = "A&ntilde;os";
$lang["MONTHS"] = "meses";
$lang["WEEKS"] = "semanas";
$lang["DAYS"] = "d&iacute;as";
$lang["HOURS"] = "horas";
$lang["MINUTES"] = "minutos";
 
$lang["GO"] = "Ir";
 
$lang["PATHCOMPARISON"] = "Comparaci&oacute;n de rutas";
$lang["COMPAREPATHS"] = "Comparar Rutas";
$lang["COMPAREREVS"] = "Comparar Revisiones";
$lang["PROPCHANGES"] = "Cambios de propiedades :";
$lang["CONVFROM"] = "Esta Comparaci&oacute;n muestra los cambios necesarios para convertir la ruta";
$lang["TO"] = "a";
$lang["REVCOMP"] = "Revertir comparaci&oacute;n";
$lang["COMPPATH"] = "Comparar Ruta:";
$lang["WITHPATH"] = "Con Ruta:";
$lang["FILEDELETED"] = "Archivo Eliminado";
$lang["FILEADDED"] = "Archivo Nuevo";
 
// The following are defined by some languages to stop unwanted line splitting
// in the template files.
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
 
// $lang["NOBR"] = "<nobr>";
// $lang["ENDNOBR"] = "</nobr>";
/WebSVN/languages/NotUsed/swedish.inc
1,118 → 1,117
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Tim Armes
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// swedish.inc
//
// Swedish language strings
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Swedish";
$lang['LANGUAGETAG'] = 'sv';
 
$lang["LOG"] = "Logg";
$lang["DIFF"] = "Skillnad";
 
$lang["NOREP"] = "Inget arkiv angivet"; //repository
$lang["NOPATH"] = "S&ouml;kv&auml;gen saknas";
$lang["SUPPLYREP"] = "V&auml;nligen s&auml;tt upp en s&ouml;v&auml;g till arkivet i include/config.inc med \$config->parentPath eller \$config->addRepository<p>Se installationsanvisningen f&ouml;r mer detaljer";
 
$lang["DIFFREVS"] = "Skillnad mellan rev.";
$lang["AND"] = "och";
$lang["REV"] = "Rev";
$lang["LINE"] = "Rad";
$lang["SHOWENTIREFILE"] = "Visa hela filen";
$lang["SHOWCOMPACT"] = "Visa bara omr&aring;den med skillnader";
 
$lang["DIFFPREV"] = "Skillnad mot f&ouml;reg&aring;ende";
$lang["BLAME"] = "Ansvarig";
 
$lang["REVINFO"] = "Revisionsinformation";
$lang["GOYOUNGEST"] = "G&aring; till senaste revision";
$lang["LASTMOD"] = "Senast &auml;ndrad";
$lang["LOGMSG"] = "Loggmeddelande";
$lang["CHANGES"] = "&auml;ndringar";
$lang["SHOWCHANGED"] = "Visa &auml;ndrade filer";
$lang["HIDECHANGED"] = "G&ouml;m &auml;ndrade filer";
$lang["NEWFILES"] = "Nya filer";
$lang["CHANGEDFILES"] = "&Auml;ndrade filer";
$lang["DELETEDFILES"] = "Raderade filer";
$lang["VIEWLOG"] = "Visa&nbsp;Logg";
$lang["PATH"] = "S&ouml;kv&auml;g";
$lang["AUTHOR"] = "F&ouml;rfattare";
$lang["AGE"] = "&Aring;lder";
$lang["LOG"] = "Logg";
$lang["CURDIR"] = "Nuvarande folder";
$lang["TARBALL"] = "Tarball";
 
$lang["PREV"] = "F&ouml;reg.";
$lang["NEXT"] = "N&auml;sta";
$lang["SHOWALL"] = "Visa alla";
 
$lang["BADCMD"] = "Fel vid k&ouml;rning av kommande";
 
$lang["POWERED"] = "Powered by <a href=\"http://websvn.tigris.org/\">WebSVN</a>";
$lang["PROJECTS"] = "Subversion&nbsp;Projekt";
$lang["SERVER"] = "Subversion&nbsp;Server";
 
$lang["SEARCHLOG"] = "S&ouml;k i logg efter";
$lang["CLEARLOG"] = "Rensa nuvarande s&ouml;kning";
$lang["MORERESULTS"] = "Hitta fler tr&auml;ffar...";
$lang["NORESULTS"] = "Det finns ingen logg som motsvarar din s&ouml;kning";
$lang["NOMORERESULTS"] = "Det finns inga fler loggar i din s&ouml;kning";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS feed";
$lang["FILESMODIFIED"] = "fil(er) &auml;ndrade";
$lang["RSSFEED"] = "RSS";
 
$lang["LINENO"] = "Radnr.";
$lang["BLAMEFOR"] = "Ansvariginformation f&ouml;r rev";
 
$lang["YEARS"] = "&aring;r";
$lang["MONTHS"] = "m&aring;nader";
$lang["WEEKS"] = "veckor";
$lang["DAYS"] = "dagar";
$lang["HOURS"] = "timmar";
$lang["MINUTES"] = "minuter";
 
$lang["GO"] = "Utf&ouml;r";
 
$lang["PATHCOMPARISON"] = "S&ouml;kv&auml;gsj&auml;mf&ouml;relse";
$lang["COMPAREPATHS"] = "J&auml;mf&ouml;r s&ouml;kv&auml;gar";
$lang["COMPAREREVS"] = "J&auml;mf&ouml;r revisioner";
$lang["PROPCHANGES"] = "Egenskaps&auml;ndringar :";
$lang["CONVFROM"] = "Denna j&auml;mförelse visar &auml;ndringarna som beh&ouml;vs för att konvertera s&ouml;kv&auml;g ";
$lang["TO"] = "till";
$lang["REVCOMP"] = "V&auml;xla j&auml;mf&ouml;relse";
$lang["COMPPATH"] = "J&auml;mf&ouml;r s&ouml;kv&auml;g:";
$lang["WITHPATH"] = "Med s&ouml;kv&auml;g:";
$lang["FILEDELETED"] = "Filen raderad";
$lang["FILEADDED"] = "Ny fil";
 
// The following are defined by some languages to stop unwanted line splitting
// in the template files.
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
 
// $lang["NOBR"] = "<nobr>";
// $lang["ENDNOBR"] = "</nobr>";
 
 
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Tim Armes
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// swedish.inc
//
// Swedish language strings
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Swedish";
 
$lang["LOG"] = "Logg";
$lang["DIFF"] = "Skillnad";
 
$lang["NOREP"] = "Inget arkiv angivet"; //repository
$lang["NOPATH"] = "S&ouml;kv&auml;gen saknas";
$lang["SUPPLYREP"] = "V&auml;nligen s&auml;tt upp en s&ouml;v&auml;g till arkivet i include/config.inc med \$config->parentPath eller \$config->addRepository<p>Se installationsanvisningen f&ouml;r mer detaljer";
 
$lang["DIFFREVS"] = "Skillnad mellan rev.";
$lang["AND"] = "och";
$lang["REV"] = "Rev";
$lang["LINE"] = "Rad";
$lang["SHOWENTIREFILE"] = "Visa hela filen";
$lang["SHOWCOMPACT"] = "Visa bara omr&aring;den med skillnader";
 
$lang["DIFFPREV"] = "Skillnad mot f&ouml;reg&aring;ende";
$lang["BLAME"] = "Ansvarig";
 
$lang["REVINFO"] = "Revisionsinformation";
$lang["GOYOUNGEST"] = "G&aring; till senaste revision";
$lang["LASTMOD"] = "Senast &auml;ndrad";
$lang["LOGMSG"] = "Loggmeddelande";
$lang["CHANGES"] = "&auml;ndringar";
$lang["SHOWCHANGED"] = "Visa &auml;ndrade filer";
$lang["HIDECHANGED"] = "G&ouml;m &auml;ndrade filer";
$lang["NEWFILES"] = "Nya filer";
$lang["CHANGEDFILES"] = "&Auml;ndrade filer";
$lang["DELETEDFILES"] = "Raderade filer";
$lang["VIEWLOG"] = "Visa&nbsp;Logg";
$lang["PATH"] = "S&ouml;kv&auml;g";
$lang["AUTHOR"] = "F&ouml;rfattare";
$lang["AGE"] = "&Aring;lder";
$lang["LOG"] = "Logg";
$lang["CURDIR"] = "Nuvarande folder";
$lang["TARBALL"] = "Tarball";
 
$lang["PREV"] = "F&ouml;reg.";
$lang["NEXT"] = "N&auml;sta";
$lang["SHOWALL"] = "Visa alla";
 
$lang["BADCMD"] = "Fel vid k&ouml;rning av kommande";
 
$lang["POWERED"] = "Powered by <a href=\"http://websvn.tigris.org/\">WebSVN</a>";
$lang["PROJECTS"] = "Subversion&nbsp;Projekt";
$lang["SERVER"] = "Subversion&nbsp;Server";
 
$lang["SEARCHLOG"] = "S&ouml;k i logg efter";
$lang["CLEARLOG"] = "Rensa nuvarande s&ouml;kning";
$lang["MORERESULTS"] = "Hitta fler tr&auml;ffar...";
$lang["NORESULTS"] = "Det finns ingen logg som motsvarar din s&ouml;kning";
$lang["NOMORERESULTS"] = "Det finns inga fler loggar i din s&ouml;kning";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS feed";
$lang["FILESMODIFIED"] = "fil(er) &auml;ndrade";
$lang["RSSFEED"] = "RSS";
 
$lang["LINENO"] = "Radnr.";
$lang["BLAMEFOR"] = "Ansvariginformation f&ouml;r rev";
 
$lang["YEARS"] = "&aring;r";
$lang["MONTHS"] = "m&aring;nader";
$lang["WEEKS"] = "veckor";
$lang["DAYS"] = "dagar";
$lang["HOURS"] = "timmar";
$lang["MINUTES"] = "minuter";
 
$lang["GO"] = "Utf&ouml;r";
 
$lang["PATHCOMPARISON"] = "S&ouml;kv&auml;gsj&auml;mf&ouml;relse";
$lang["COMPAREPATHS"] = "J&auml;mf&ouml;r s&ouml;kv&auml;gar";
$lang["COMPAREREVS"] = "J&auml;mf&ouml;r revisioner";
$lang["PROPCHANGES"] = "Egenskaps&auml;ndringar :";
$lang["CONVFROM"] = "Denna j&auml;mförelse visar &auml;ndringarna som beh&ouml;vs för att konvertera s&ouml;kv&auml;g ";
$lang["TO"] = "till";
$lang["REVCOMP"] = "V&auml;xla j&auml;mf&ouml;relse";
$lang["COMPPATH"] = "J&auml;mf&ouml;r s&ouml;kv&auml;g:";
$lang["WITHPATH"] = "Med s&ouml;kv&auml;g:";
$lang["FILEDELETED"] = "Filen raderad";
$lang["FILEADDED"] = "Ny fil";
 
// The following are defined by some languages to stop unwanted line splitting
// in the template files.
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
 
// $lang["NOBR"] = "<nobr>";
// $lang["ENDNOBR"] = "</nobr>";
 
 
/WebSVN/languages/NotUsed/tchinese.inc
1,111 → 1,110
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Tim Armes
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// tchinese.inc
//
// Traditional Chinese language strings
//
// Author: Yuan-Chung Hsiao <ychsiao@ychsiao.idv.tw>
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Traditional Chinese";
$lang['LANGUAGETAG'] = 'zh-TW';
 
$lang["LOG"] = "歷史記錄";
$lang["DIFF"] = "比對";
 
$lang["NOREP"] = "沒有檔案庫";
$lang["NOPATH"] = "找不到路徑";
$lang["SUPPLYREP"] = "請在include/config.inc中設定檔案庫位置為 \$config->parentPath 或 \$config->addRepository<p>更詳細的內容請見安裝手冊";
 
$lang["DIFFREVS"] = "不同版本間的差異";
$lang["AND"] = "與";
$lang["REV"] = "修訂版號";
$lang["LINE"] = "行";
$lang["SHOWALL"] = "顯示完整的檔案";
$lang["SHOWCOMPACT"] = "只顯示不同處";
 
$lang["DIFFPREV"] = "與前一版次比較";
$lang["BLAME"] = "譴責";
 
$lang["REVINFO"] = "修訂版次資訊";
$lang["GOYOUNGEST"] = "到最新的修訂";
$lang["LASTMOD"] = "最後更動";
$lang["LOGMSG"] = "訊息記錄";
$lang["CHANGES"] = "改變";
$lang["SHOWCHANGED"] = "顯示已變動檔案";
$lang["HIDECHANGED"] = "隱藏已變動檔案";
$lang["NEWFILES"] = "新檔案";
$lang["CHANGEDFILES"] = "已變動檔案";
$lang["DELETEDFILES"] = "已刪除檔案";
$lang["VIEWLOG"] = "看歷史記錄";
$lang["PATH"] = "路徑";
$lang["AUTHOR"] = "作者";
$lang["AGE"] = "更動時間";
$lang["LOG"] = "歷史記錄";
$lang["CURDIR"] = "目前目錄";
$lang["TARBALL"] = "Tarball 格式";
 
$lang["PREV"] = "上一筆";
$lang["NEXT"] = "下一筆";
$lang["SHOWALL"] = "顯示全部";
 
$lang["BADCMD"] = "執行錯誤";
 
$lang["POWERED"] = "採用 <a href=\"http://websvn.tigris.org/\">WebSVN</a>架設";
$lang["PROJECTS"] = "Subversion&nbsp;專案";
$lang["SERVER"] = "Subversion&nbsp;Server";
 
$lang["SEARCHLOG"] = "搜尋記錄內容";
$lang["CLEARLOG"] = "清除目前搜尋";
$lang["MORERESULTS"] = "找到更多的符合的...";
$lang["NORESULTS"] = "查詢結果並沒有符合的紀錄";
$lang["NOMORERESULTS"] = "沒有更多紀錄符合你的查詢";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS feed";
$lang["FILESMODIFIED"] = "個檔案變動";
$lang["RSSFEED"] = "RSS feed";
 
$lang["LINENO"] = "行";
$lang["BLAMEFOR"] = "版本譴責資訊";
 
$lang["YEARS"] = "年前";
$lang["MONTHS"] = "月前";
$lang["WEEKS"] = "週前";
$lang["DAYS"] = "日前";
$lang["HOURS"] = "小時前";
$lang["MINUTES"] = "分鐘前";
 
$lang["GO"] = "到";
 
$lang["COMPAREPATHS"] = "比對路徑";
$lang["COMPAREREVS"] = "比對修訂版";
$lang["PROPCHANGES"] = "改變屬性 :";
$lang["CONVFROM"] = "這個比對顯示必需改變轉換路徑";
$lang["TO"] = "到";
$lang["REVCOMP"] = "顛倒比對";
 
// The following are defined by some languages to stop unwanted line splitting
// in the template files.
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
 
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Tim Armes
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// tchinese.inc
//
// Traditional Chinese language strings
//
// Author: Yuan-Chung Hsiao <ychsiao@ychsiao.idv.tw>
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Traditional Chinese";
 
$lang["LOG"] = "歷史記錄";
$lang["DIFF"] = "比對";
 
$lang["NOREP"] = "沒有檔案庫";
$lang["NOPATH"] = "找不到路徑";
$lang["SUPPLYREP"] = "請在include/config.inc中設定檔案庫位置為 \$config->parentPath 或 \$config->addRepository<p>更詳細的內容請見安裝手冊";
 
$lang["DIFFREVS"] = "不同版本間的差異";
$lang["AND"] = "與";
$lang["REV"] = "修訂版號";
$lang["LINE"] = "行";
$lang["SHOWALL"] = "顯示完整的檔案";
$lang["SHOWCOMPACT"] = "只顯示不同處";
 
$lang["DIFFPREV"] = "與前一版次比較";
$lang["BLAME"] = "譴責";
 
$lang["REVINFO"] = "修訂版次資訊";
$lang["GOYOUNGEST"] = "到最新的修訂";
$lang["LASTMOD"] = "最後更動";
$lang["LOGMSG"] = "訊息記錄";
$lang["CHANGES"] = "改變";
$lang["SHOWCHANGED"] = "顯示已變動檔案";
$lang["HIDECHANGED"] = "隱藏已變動檔案";
$lang["NEWFILES"] = "新檔案";
$lang["CHANGEDFILES"] = "已變動檔案";
$lang["DELETEDFILES"] = "已刪除檔案";
$lang["VIEWLOG"] = "看歷史記錄";
$lang["PATH"] = "路徑";
$lang["AUTHOR"] = "作者";
$lang["AGE"] = "更動時間";
$lang["LOG"] = "歷史記錄";
$lang["CURDIR"] = "目前目錄";
$lang["TARBALL"] = "Tarball 格式";
 
$lang["PREV"] = "上一筆";
$lang["NEXT"] = "下一筆";
$lang["SHOWALL"] = "顯示全部";
 
$lang["BADCMD"] = "執行錯誤";
 
$lang["POWERED"] = "採用 <a href=\"http://websvn.tigris.org/\">WebSVN</a>架設";
$lang["PROJECTS"] = "Subversion&nbsp;專案";
$lang["SERVER"] = "Subversion&nbsp;Server";
 
$lang["SEARCHLOG"] = "搜尋記錄內容";
$lang["CLEARLOG"] = "清除目前搜尋";
$lang["MORERESULTS"] = "找到更多的符合的...";
$lang["NORESULTS"] = "查詢結果並沒有符合的紀錄";
$lang["NOMORERESULTS"] = "沒有更多紀錄符合你的查詢";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS feed";
$lang["FILESMODIFIED"] = "個檔案變動";
$lang["RSSFEED"] = "RSS feed";
 
$lang["LINENO"] = "行";
$lang["BLAMEFOR"] = "版本譴責資訊";
 
$lang["YEARS"] = "年前";
$lang["MONTHS"] = "月前";
$lang["WEEKS"] = "週前";
$lang["DAYS"] = "日前";
$lang["HOURS"] = "小時前";
$lang["MINUTES"] = "分鐘前";
 
$lang["GO"] = "到";
 
$lang["COMPAREPATHS"] = "比對路徑";
$lang["COMPAREREVS"] = "比對修訂版";
$lang["PROPCHANGES"] = "改變屬性 :";
$lang["CONVFROM"] = "這個比對顯示必需改變轉換路徑";
$lang["TO"] = "到";
$lang["REVCOMP"] = "顛倒比對";
 
// The following are defined by some languages to stop unwanted line splitting
// in the template files.
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
 
/WebSVN/languages/NotUsed/turkish.inc
1,117 → 1,116
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Tim Armes
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// turkish.inc
//
// Turkish language strings
// by Barış Metin <baris@uludag.org.tr>
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Turkish";
$lang['LANGUAGETAG'] = 'tr';
 
$lang["LOG"] = "Kayıt";
$lang["DIFF"] = "Fark";
 
$lang["NOREP"] = "Bir depo tanımlanmadı";
$lang["NOPATH"] = "Patika bulunamadı";
$lang["SUPPLYREP"] = "Lütfen, include/config.inc dosyasında \$config->parentPath ya da \$config->addRepository değerlerini kullanarak bir depo yolu belirtin<p>Daha fazla bilgi için kurulum kılavuzuna bakın";
 
$lang["DIFFREVS"] = "Sürümler arası fark";
$lang["AND"] = "ve";
$lang["REV"] = "Sürüm";
$lang["LINE"] = "Satır";
$lang["SHOWENTIREFILE"] = "Tüm dosyayı göster";
$lang["SHOWCOMPACT"] = "Yalnızca değişen bölümleri göster";
 
$lang["DIFFPREV"] = "Önceki ile karşılaştır";
$lang["BLAME"] = "svn blame";
 
$lang["REVINFO"] = "Sürüm Bilgisi";
$lang["GOYOUNGEST"] = "En güncel sürüme git";
$lang["LASTMOD"] = "Son değişiklik";
$lang["LOGMSG"] = "Kayıt mesajı";
$lang["CHANGES"] = "Değişiklikler";
$lang["SHOWCHANGED"] = "Değişen dosyaları göster";
$lang["HIDECHANGED"] = "Değişen dosyaları gizle";
$lang["NEWFILES"] = "Yeni Dosyalar";
$lang["CHANGEDFILES"] = "Değişen dosyalar";
$lang["DELETEDFILES"] = "Silinen dosyalar";
$lang["VIEWLOG"] = "Kayıt&nbsp;Mesajını&nbsp;Göster";
$lang["PATH"] = "Patika";
$lang["AUTHOR"] = "Yazar";
$lang["AGE"] = "Yaş";
$lang["LOG"] = "Kayıt";
$lang["CURDIR"] = "Şimdiki Dizin";
$lang["TARBALL"] = "Tar dosyası";
 
$lang["PREV"] = "Önceki";
$lang["NEXT"] = "Sonraki";
$lang["SHOWALL"] = "Tümünü Göster";
 
$lang["BADCMD"] = "Bu komut çalıştırılırken hata oluştu";
 
$lang["POWERED"] = "<a href=\"http://websvn.tigris.org/\">WebSVN</a> tarafından çalıştırılmaktadır";
$lang["PROJECTS"] = "Subversion&nbsp;Projeleri";
$lang["SERVER"] = "Subversion&nbsp;Sunucusu";
 
$lang["SEARCHLOG"] = "Kayıtlarda ara";
$lang["CLEARLOG"] = "Mevcut aramayı iptal et";
$lang["MORERESULTS"] = "Daha fazla eşleştirmeyi bul...";
$lang["NORESULTS"] = "Aramaya uyan kayıt mesajı yok";
$lang["NOMORERESULTS"] = "Aramaya uyan başka kayıt mesajı yok";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS kaynağı";
$lang["FILESMODIFIED"] = "dosya değişti";
$lang["RSSFEED"] = "RSS kaynağı";
 
$lang["LINENO"] = "Satır No.";
$lang["BLAMEFOR"] = "svn blame bilgisi alınan sürüm numarası";
 
$lang["YEARS"] = "yıl";
$lang["MONTHS"] = "ay";
$lang["WEEKS"] = "hafta";
$lang["DAYS"] = "gün";
$lang["HOURS"] = "saat";
$lang["MINUTES"] = "dakika";
 
$lang["GO"] = "Git";
 
$lang["PATHCOMPARISON"] = "Patika karşılaştırması";
$lang["COMPAREPATHS"] = "Patikaları karşılaştır";
$lang["COMPAREREVS"] = "Sürümleri karşışaştır";
$lang["PROPCHANGES"] = "Özellik değişiklikleri :";
$lang["CONVFROM"] = "Bu karşılaştırma patikayı dönüştürmek için gerekli olan değişikliği gösterir ";
$lang["TO"] = "TO";
$lang["REVCOMP"] = "Geriye doğru karşılaştır";
$lang["COMPPATH"] = "Patikaları karşılaştır:";
$lang["WITHPATH"] = "Patika ile:";
$lang["FILEDELETED"] = "Dosya silinmiş";
$lang["FILEADDED"] = "Yeni dosya";
 
// The following are defined by some languages to stop unwanted line splitting
// in the template files.
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
 
// $lang["NOBR"] = "<nobr>";
// $lang["ENDNOBR"] = "</nobr>";
<?php
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004 Tim Armes
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// turkish.inc
//
// Turkish language strings
// by Barış Metin <baris@uludag.org.tr>
 
// The language name is displayed in the drop down box. It MUST be encoded as Unicode (no HTML entities).
$lang["LANGUAGENAME"] = "Turkish";
 
$lang["LOG"] = "Kayıt";
$lang["DIFF"] = "Fark";
 
$lang["NOREP"] = "Bir depo tanımlanmadı";
$lang["NOPATH"] = "Patika bulunamadı";
$lang["SUPPLYREP"] = "Lütfen, include/config.inc dosyasında \$config->parentPath ya da \$config->addRepository değerlerini kullanarak bir depo yolu belirtin<p>Daha fazla bilgi için kurulum kılavuzuna bakın";
 
$lang["DIFFREVS"] = "Sürümler arası fark";
$lang["AND"] = "ve";
$lang["REV"] = "Sürüm";
$lang["LINE"] = "Satır";
$lang["SHOWENTIREFILE"] = "Tüm dosyayı göster";
$lang["SHOWCOMPACT"] = "Yalnızca değişen bölümleri göster";
 
$lang["DIFFPREV"] = "Önceki ile karşılaştır";
$lang["BLAME"] = "svn blame";
 
$lang["REVINFO"] = "Sürüm Bilgisi";
$lang["GOYOUNGEST"] = "En güncel sürüme git";
$lang["LASTMOD"] = "Son değişiklik";
$lang["LOGMSG"] = "Kayıt mesajı";
$lang["CHANGES"] = "Değişiklikler";
$lang["SHOWCHANGED"] = "Değişen dosyaları göster";
$lang["HIDECHANGED"] = "Değişen dosyaları gizle";
$lang["NEWFILES"] = "Yeni Dosyalar";
$lang["CHANGEDFILES"] = "Değişen dosyalar";
$lang["DELETEDFILES"] = "Silinen dosyalar";
$lang["VIEWLOG"] = "Kayıt&nbsp;Mesajını&nbsp;Göster";
$lang["PATH"] = "Patika";
$lang["AUTHOR"] = "Yazar";
$lang["AGE"] = "Yaş";
$lang["LOG"] = "Kayıt";
$lang["CURDIR"] = "Şimdiki Dizin";
$lang["TARBALL"] = "Tar dosyası";
 
$lang["PREV"] = "Önceki";
$lang["NEXT"] = "Sonraki";
$lang["SHOWALL"] = "Tümünü Göster";
 
$lang["BADCMD"] = "Bu komut çalıştırılırken hata oluştu";
 
$lang["POWERED"] = "<a href=\"http://websvn.tigris.org/\">WebSVN</a> tarafından çalıştırılmaktadır";
$lang["PROJECTS"] = "Subversion&nbsp;Projeleri";
$lang["SERVER"] = "Subversion&nbsp;Sunucusu";
 
$lang["SEARCHLOG"] = "Kayıtlarda ara";
$lang["CLEARLOG"] = "Mevcut aramayı iptal et";
$lang["MORERESULTS"] = "Daha fazla eşleştirmeyi bul...";
$lang["NORESULTS"] = "Aramaya uyan kayıt mesajı yok";
$lang["NOMORERESULTS"] = "Aramaya uyan başka kayıt mesajı yok";
 
$lang["RSSFEEDTITLE"] = "WebSVN RSS kaynağı";
$lang["FILESMODIFIED"] = "dosya değişti";
$lang["RSSFEED"] = "RSS kaynağı";
 
$lang["LINENO"] = "Satır No.";
$lang["BLAMEFOR"] = "svn blame bilgisi alınan sürüm numarası";
 
$lang["YEARS"] = "yıl";
$lang["MONTHS"] = "ay";
$lang["WEEKS"] = "hafta";
$lang["DAYS"] = "gün";
$lang["HOURS"] = "saat";
$lang["MINUTES"] = "dakika";
 
$lang["GO"] = "Git";
 
$lang["PATHCOMPARISON"] = "Patika karşılaştırması";
$lang["COMPAREPATHS"] = "Patikaları karşılaştır";
$lang["COMPAREREVS"] = "Sürümleri karşışaştır";
$lang["PROPCHANGES"] = "Özellik değişiklikleri :";
$lang["CONVFROM"] = "Bu karşılaştırma patikayı dönüştürmek için gerekli olan değişikliği gösterir ";
$lang["TO"] = "TO";
$lang["REVCOMP"] = "Geriye doğru karşılaştır";
$lang["COMPPATH"] = "Patikaları karşılaştır:";
$lang["WITHPATH"] = "Patika ile:";
$lang["FILEDELETED"] = "Dosya silinmiş";
$lang["FILEADDED"] = "Yeni dosya";
 
// The following are defined by some languages to stop unwanted line splitting
// in the template files.
 
$lang["NOBR"] = "";
$lang["ENDNOBR"] = "";
 
// $lang["NOBR"] = "<nobr>";
// $lang["ENDNOBR"] = "</nobr>";
/WebSVN/include/utils.inc
1,340 → 1,259
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// utils.inc
//
// General utility commands
 
// {{{ createDirLinks
//
// Create a list of links to the current path that'll be available from the template
 
function createDirLinks($rep, $path, $rev, $showchanged)
{
global $vars, $config;
$subs = explode('/', htmlentities($path));
$sofar = "";
$count = count($subs);
$vars["curdirlinks"] = "";
// The number of links depends on the last item. It's empty if
// we're looing at a directory, and full if it's a file
if (empty($subs[$count - 1]))
{
$limit = $count - 2;
$dir = true;
}
else
{
$limit = $count - 1;
$dir = false;
}
for ($n = 0; $n < $limit; $n++)
{
$sofar .= html_entity_decode($subs[$n])."/";
$sofarurl = $config->getURL($rep, $sofar, "dir");
$vars["curdirlinks"] .= "[<a href=\"${sofarurl}rev=$rev&amp;sc=$showchanged\">".$subs[$n]."/]</a> ";
}
if ($dir)
{
$vars["curdirlinks"] .= "[<b>".html_entity_decode($subs[$n])."</b>/]";
}
else
{
$vars["curdirlinks"] .= "[<b>".html_entity_decode($subs[$n])."</b>]";
}
}
 
// }}}
 
// {{{ create_anchors
//
// Create links out of http:// and mailto: tags
 
# TODO: the target="_blank" nonsense should be optional (or specified by the template)
function create_anchors($text)
{
$ret = $text;
 
// Match correctly formed URLs that aren't already links
$ret = preg_replace("#\b(?<!href=\")([a-z]+?)://(\S*)([\w/]+)#i",
"<a href=\"\\1://\\2\\3\" target=\"_blank\">\\1://\\2\\3</a>",
$ret);
// Now match anything beginning with www, as long as it's not //www since they were matched above
$ret = preg_replace("#\b(?<!//)www\.(\S*)([\w/]+)#i",
"<a href=\"http://www.\\1\\2\" target=\"_blank\">www.\\1\\2</a>",
$ret);
 
// Match email addresses
$ret = preg_replace("#\b([\w\-_.]+)@([\w\-.]+)\b#i",
"<a href=\"mailto:\\1@\\2\">\\1@\\2</a>",
$ret);
return ($ret);
}
 
// }}}
 
// {{{ getFullURL
 
function getFullURL($loc)
{
$protocol = 'http';
if (isset($_SERVER["HTTPS"]) && (strtolower($_SERVER["HTTPS"]) != "off"))
{
$protocol = "https";
}
$port = ":".$_SERVER["SERVER_PORT"];
if ((":80" == $port && "http" == $protocol) ||
(":443" == $port && "https" == $protocol))
{
$port = "";
}
if (isset($_SERVER["HTTP_HOST"]))
{
$host = $_SERVER["HTTP_HOST"];
}
else if (isset($_SERVER["SERVER_NAME"]))
{
$host = $_SERVER["SERVER_NAME"].$port;
}
else if (isset($_SERVER["SERVER_ADDR"]))
{
$host = $_SERVER["SERVER_ADDR"].$port;
}
else
{
print "Unable to redirect";
exit;
}
$url = $protocol . "://" . $host . $loc;
 
return $url;
}
 
// }}}
 
// {{{ hardspace
//
// Replace the spaces at the front of a line with hard spaces
 
# XXX: this is an unnecessary function; you can prevent whitespace from being
# trimmed via CSS (use the "white-space: pre;" properties). ~J
# in the meantime, here's an improved function (does nothing)
 
function hardspace($s)
{
return '<code>' . expandTabs($s) . '</code>';
}
 
// }}}
 
// {{{ expandTabs
 
/**
* Expands the tabs in a line that may or may not include HTML.
*
* Enscript generates code with HTML, so we need to take that into account.
*
* @param string $s Line of possibly HTML-encoded text to expand
* @param int $tabwidth Tab width, -1 to use repository's default, 0 to collapse
* all tabs.
* @return string The expanded line.
* @since 2.1
*/
 
function expandTabs($s, $tabwidth = -1)
{
global $rep;
 
if ($tabwidth == -1)
$tabwidth = $rep->getExpandTabsBy();
$pos = 0;
 
// Parse the string into chunks that are either 1 of: HTML tag, tab char, run of any other stuff
$chunks = preg_split("/((?:<.+?>)|(?:&.+?;)|(?:\t))/", $s, -1, PREG_SPLIT_DELIM_CAPTURE);
 
// Count the sizes of the chunks and replace tabs as we go
for ($i = 0; $i < count($chunks); $i++)
{
# make sure we're not dealing with an empty string
if (empty($chunks[$i])) continue;
switch ($chunks[$i]{0})
{
case '<': // HTML tag : ignore its width by doing nothing
break;
 
case '&': // HTML entity: count its width as 1 char
$pos += 1;
break;
 
case "\t": // Tab char: replace it with a run of spaces between length tabwidth and 1
$tabsize = $tabwidth - ($pos % $tabwidth);
$chunks[$i] = str_repeat(' ', $tabsize);
$pos += $tabsize;
break;
 
default: // Anything else: just keep track of its width
$pos += strlen($chunks[$i]);
break;
}
}
 
// Put the chunks back together and we've got the original line, detabbed.
return join('', $chunks);
}
 
// }}}
 
// {{{ datetimeFormatDuration
//
// Formats a duration of seconds for display.
//
// $seconds the number of seconds until something
// $nbsp true if spaces should be replaced by nbsp
// $skipSeconds true if seconds should be omitted
//
// return the formatted duration (e.g. @c "8h 6m 1s")
 
function datetimeFormatDuration($seconds, $nbsp = false, $skipSeconds = false)
{
global $lang;
if ($seconds < 0)
{
$seconds = -$seconds;
$neg = true;
}
else
$neg = false;
 
$qty = array();
 
$qty[] = (int)($seconds / (60 * 60 * 24));
$seconds %= 60 * 60 * 24;
 
$qty[] = (int)($seconds / (60 * 60));
$seconds %= 60 * 60;
 
$qty[] = (int)($seconds / 60);
$qty[] = (int)($seconds % 60);
 
$text = "";
$names = $lang["DAYLETTER"].$lang["HOURLETTER"].$lang["MINUTELETTER"];
if (!$skipSeconds) $names .= $lang["SECONDLETTER"];
 
$any = false;
for ($i = 0; $i < strlen($names); $i++)
// If a "higher valued" time slot had a value or this time slot
// has a value or this is the very last entry (i.e. all values
// are 0 and we still want to print seconds)
if ($any || $qty[$i] || $i == sizeof($qty) - 1)
{
$any = true;
 
if ($i)
$text .= sprintf("%2d", $qty[$i]);
else
$text .= $qty[$i];
 
$text .= "{$names{$i}} ";
}
 
$text = trim($text);
if ($neg)
$text = "-$text";
 
return $nbsp ? str_replace(" ", "&nbsp;", $text) : $text;
}
 
// }}}
 
// {{{ getParameterisedSelfUrl
//
// Get the relative URL (PHP_SELF) with GET and POST data
 
function getParameterisedSelfUrl($params = true)
{
global $config;
 
$url = null;
 
if ($config->multiViews)
{
// Get rid of the file's name
$url = preg_replace('/\.php/', '', $_SERVER['PHP_SELF'], 1);
}
else
{
$url = basename($_SERVER['PHP_SELF']);
 
// Sometimes the .php isn't on the end. Damn strange...
if (strchr($url, '.') === false)
$url .= '.php';
}
 
if ($params)
{
$arr = $_GET + $_POST;
# XXX: the point of HTTP POST is that URIs have a set size limit, so POST
# data is typically too large to bother with; why include it?
$url .= '?'.htmlentities(http_build_query($arr));
}
 
return $url;
}
 
// }}}
 
// {{{ getUserLanguage
 
function getUserLanguage() {
$languages = !empty($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : 'en';
if (strpos($languages, ',') === false) return $languages; # only one specified
# split off the languages into an array of languages and q-values
$qvals = array();
$langs = array();
preg_match_all('#(\S+?)\s*(?:;q=([01](?:\.\d{1,3})?))?\s*,\s*#', $languages, $qvals, PREG_SET_ORDER);
foreach ($qvals as $q) {
$langs[] = array (
$q[1],
floatval(!empty($q[2]) ? $q[2] : 1.0)
);
}
# XXX: now, we should loop through our available languages and choose an
# appropriate one for the user
# note that we shouldn't match the region unless we have a specific region
# to use (e.g. zh-CN vs. zh-TW)
# FIXME: see above; otherwise, this function doesn't really do anything
}
 
// }}}
 
?>
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// utils.inc
//
// General utility commands
 
#require_once 'php5compat.inc';
 
// {{{ createDirLinks
//
// Create a list of links to the current path that'll be available from the template
 
function createDirLinks($rep, $path, $rev, $showchanged)
{
global $vars, $config;
$subs = explode('/', htmlentities($path));
$sofar = "";
$count = count($subs);
$vars["curdirlinks"] = "";
// The number of links depends on the last item. It's empty if
// we're looing at a directory, and full if it's a file
if (empty($subs[$count - 1]))
{
$limit = $count - 2;
$dir = true;
}
else
{
$limit = $count - 1;
$dir = false;
}
for ($n = 0; $n < $limit; $n++)
{
$sofar .= html_entity_decode($subs[$n])."/";
$sofarurl = $config->getURL($rep, $sofar, "dir");
$vars["curdirlinks"] .= "[<a href=\"${sofarurl}rev=$rev&amp;sc=$showchanged\">".$subs[$n]."/]</a> ";
}
if ($dir)
{
$vars["curdirlinks"] .= "[<b>".html_entity_decode($subs[$n])."</b>/]";
}
else
{
$vars["curdirlinks"] .= "[<b>".html_entity_decode($subs[$n])."</b>]";
}
}
 
// }}}
 
// {{{ create_anchors
//
// Create links out of http:// and mailto: tags
 
# TODO: the target="_blank" nonsense should be optional (or specified by the template)
function create_anchors($text)
{
$ret = $text;
 
// Match correctly formed URLs that aren't already links
$ret = preg_replace("#\b(?<!href=\")([a-z]+?)://(\S*)([\w/]+)#i",
"<a href=\"\\1://\\2\\3\" target=\"_blank\">\\1://\\2\\3</a>",
$ret);
// Now match anything beginning with www, as long as it's not //www since they were matched above
$ret = preg_replace("#\b(?<!//)www\.(\S*)([\w/]+)#i",
"<a href=\"http://www.\\1\\2\" target=\"_blank\">www.\\1\\2</a>",
$ret);
 
// Match email addresses
$ret = preg_replace("#\b([\w\-_.]+)@([\w\-.]+)\b#i",
"<a href=\"mailto:\\1@\\2\">\\1@\\2</a>",
$ret);
return ($ret);
}
 
// }}}
 
// {{{ getFullURL
 
function getFullURL($loc)
{
$protocol = 'http';
if (isset($_SERVER["HTTPS"]) && (strtolower($_SERVER["HTTPS"]) != "off"))
{
$protocol = "https";
}
$port = ":".$_SERVER["SERVER_PORT"];
if ((":80" == $port && "http" == $protocol) ||
(":443" == $port && "https" == $protocol))
{
$port = "";
}
if (isset($_SERVER["HTTP_HOST"]))
{
$host = $_SERVER["HTTP_HOST"];
}
else if (isset($_SERVER["SERVER_NAME"]))
{
$host = $_SERVER["SERVER_NAME"].$port;
}
else if (isset($_SERVER["SERVER_ADDR"]))
{
$host = $_SERVER["SERVER_ADDR"].$port;
}
else
{
print "Unable to redirect";
exit;
}
$url = $protocol . "://" . $host . $loc;
 
return $url;
}
 
// }}}
 
// {{{ hardspace
//
// Replace the spaces at the front of a line with hard spaces
 
# XXX: this is an unnecessary function; you can prevent whitespace from being
# trimmed via CSS (use the "white-space: pre;" properties). ~J
# in the meantime, here's an improved function (does nothing)
 
function hardspace($s)
{
return '<code>'.$s.'</code>';
}
 
// }}}
 
// {{{ datetimeFormatDuration
//
// Formats a duration of seconds for display.
//
// $seconds the number of seconds until something
// $nbsp true if spaces should be replaced by nbsp
// $skipSeconds true if seconds should be omitted
//
// return the formatted duration (e.g. @c "8h 6m 1s")
 
function datetimeFormatDuration($seconds, $nbsp = false, $skipSeconds = false)
{
global $lang;
if ($seconds < 0)
{
$seconds = -$seconds;
$neg = true;
}
else
$neg = false;
 
$qty = array();
 
$qty[] = (int)($seconds / (60 * 60 * 24));
$seconds %= 60 * 60 * 24;
 
$qty[] = (int)($seconds / (60 * 60));
$seconds %= 60 * 60;
 
$qty[] = (int)($seconds / 60);
$qty[] = (int)($seconds % 60);
 
$text = "";
$names = $lang["DAYLETTER"].$lang["HOURLETTER"].$lang["MINUTELETTER"];
if (!$skipSeconds) $names .= $lang["SECONDLETTER"];
 
$any = false;
for ($i = 0; $i < strlen($names); $i++)
// If a "higher valued" time slot had a value or this time slot
// has a value or this is the very last entry (i.e. all values
// are 0 and we still want to print seconds)
if ($any || $qty[$i] || $i == sizeof($qty) - 1)
{
$any = true;
 
if ($i)
$text .= sprintf("%2d", $qty[$i]);
else
$text .= $qty[$i];
 
$text .= "{$names{$i}} ";
}
 
$text = trim($text);
if ($neg)
$text = "-$text";
 
return $nbsp ? str_replace(" ", "&nbsp;", $text) : $text;
}
 
// }}}
 
// {{{ getParameterisedSelfUrl
//
// Get the relative URL (PHP_SELF) with GET and POST data
 
function getParameterisedSelfUrl($params = true)
{
$url = null;
 
if ($config->multiViews)
{
// Get rid of the file's name
$url = preg_replace('/\.php/', '', $_SERVER['PHP_SELF'], 1);
}
else
{
$url = basename($_SERVER['PHP_SELF']);
 
// Sometimes the .php isn't on the end. Damn strange...
if (strchr($url, '.') === false)
$url .= '.php';
}
 
if ($params)
{
$arr = $_GET + $_POST;
# XXX: the point of HTTP POST is that URIs have a set size limit, so POST
# data is typically too large to bother with; why include it?
$url .= '?'.htmlentities(http_build_query($arr));
}
 
return $url;
}
 
// }}}
 
?>
/WebSVN/include/distconfig.inc
1,376 → 1,375
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// config.inc
//
// Configuration parameters
 
// --- FOLLOW THE INSTRUCTIONS BELOW TO CONFIGURE YOUR SETUP ---
 
// {{{ PLATFORM CONFIGURATION ---
 
// Uncomment the next line if your running a windows server
//
// $config->setServerIsWindows();
 
// Configure these lines if your commands aren't on your path.
//
// $config->setSVNCommandPath('Path/to/svn and svnlook/ e.g. c:\\program files\\subversion\\bin');
// $config->setDiffPath('Path/to/diff/command/');
 
// For syntax colouring, if option enabled...
// $config->setEnscriptPath('Path/to/enscript/command/');
// $config->setSedPath('Path/to/sed/command/');
 
// For delivered tarballs, if option enabled...
// $config->setTarPath('Path/to/tar/command/');
 
// For delivered GZIP'd files and tarballs, if option enabled...
// $config->setGZipPath('Path/to/gzip/command/');
 
// }}}
 
// {{{ REPOSITORY SETUP ---
 
// There are 2 methods for defining the repositiories available on the system. Either you list
// them by hand, in which case you can give each one the name of your choice, or you use the
// parent path function, in which case the name of the directory is used as the repository name.
//
// In all cases, you may optionally supply a group name to the repositories. This is useful in the
// case that you need to separate your projects. Grouped Repositories are referred to using the
// convention GroupName.RepositoryName
//
// Performance is much better on local repositories (e.g. accessed by file:///). However, you
// can also provide an interface onto a remote repository. In this case you should supply the
// username and password needed to access it.
//
// To configure the repositories by hand, copy the appropriate line below, uncomment it and
// replace the name and URL of your repository.
 
// Local repositories (without and with optional group):
//
// $config->addRepository('NameToDisplay', 'URL to repository (e.g. file:///c:/svn/proj)');
// $config->addRepository('NameToDisplay', 'URL to repository (e.g. file:///c:/svn/proj)', 'group');
//
// Remote repositories (without and with optional group):
//
// $config->addRepository('NameToDisplay', 'URL (e.g. http://path/to/rep)', NULL, 'username', 'password');
// $config->addRepository('NameToDisplay', 'URL (e.g. http://path/to/rep)', 'group', 'username', 'password');
//
// To use the parent path method, uncomment the newt line and and replace the path with your one. You
// can call the function several times if you have several parent paths. Note that in this case the
// path is a filesystem path
//
// $config->parentPath('Path/to/parent (e.g. c:\\svn)');
 
// }}}
 
// {{{ LOOK AND FEEL ---
//
// Uncomment ONLY the template file that you want.
 
$config->setTemplatePath("$locwebsvnreal/templates/Standard/");
// $config->setTemplatePath("$locwebsvnreal/templates/BlueGrey/");
// $config->setTemplatePath("$locwebsvnreal/templates/Zinn/");
 
// You may also specify a per repository template file by uncommenting and changing the following
// line as necessary. Use the convention "groupname.myrep" if your repository is in a group.
 
// $config->setTemplatePath('$locwebsvnreal/templates/Standard/', 'myrep'); // Access file for myrep
 
// The index page containing the projects may either be displayed as a flat view (the default),
// where grouped repositories are displayed as "GroupName.RepName" or as a tree view.
// In the case of a tree view, you may choose whether the entire tree is open by default.
 
// $config->useTreeIndex(false); // Tree index, closed by default
// $config->useTreeIndex(true); // Tree index, open by default
 
// By default, WebSVN displays a tree view onto the current directory. You can however
// choose to display a flat view of the current directory only, which may make the display
// load faster. Uncomment this line if you want that.
 
// $config->useFlatView();
 
// }}}
 
// {{{ LANGUAGE SETUP ---
 
// WebSVN uses the iconv module to convert messages from your system's character set to the
// UTF-8 output encoding. If you find that your log messages aren't displayed correctly then
// you'll need to change the value here.
//
// You may also specify the character encoding of the repository contents if different from
// the system encoding. This is typically the case for windows users, whereby the command
// line returns, for example, CP850 encoded strings, whereas the source files are encoded
// as iso-8859-1 by Windows based text editors. When display text file, WebSVN will convert
// them from the content encoding to the output encoding (UTF-8).
//
// WebSVN does its best to automate all this, so only use the following if it doesn't work
// "out of the box". Uncomment and change one of the examples below.
//
// $config->setInputEncoding('CP850'); // Encoding of result returned by svn command line, etc.
// $config->setContentEncoding('iso-8859-1'); // Content encoding of all your repositories // repositories
 
// You may also specify a content encoding on a per repository basis. Uncomment and copy this
// line as necessary.
//
// $config->setContentEncoding('iso-8859-1', 'MyEnc');
 
// Note for Windows users: To enable iconv you'll need to enable the extension in your php.ini file
// AND copy iconv.dll (not php_iconv.dll) to your Windows system folder. In most cases the correct
// encoding is set when you call $config->setServerIsWindows();.
 
// Note for *nix users. You'll need to have iconv compiled into your binary. The default input and
// output encodings are taken from your locale informations. Override these if they aren't correct.
 
// Uncomment the default language. If you want English then don't do anything here.
//
// include 'languages/catalan.inc';
// include 'languages/czech.inc';
// include 'languages/danish.inc';
// include 'languages/dutch.inc';
// include 'languages/finnish.inc';
// include 'languages/french.inc';
// include 'languages/german.inc';
// include 'languages/japanese.inc';
// include 'languages/korean.inc';
// include 'languages/norwegian.inc';
// include 'languages/polish.inc';
// include 'languages/portuguese.inc';
// include 'languages/russian.inc';
// include 'languages/schinese.inc';
// include 'languages/slovenian.inc';
// include 'languages/spanish.inc';
// include 'languages/swedish.inc';
// include 'languages/tchinese.inc';
// include 'languages/turkish.inc';
 
// }}}
 
// {{{ MULTIVIEWS ---
 
// Uncomment this line if you want to use MultiView to access the repository by, for example:
//
// http://servername/wsvn/repname/path/in/repository
//
// Note: The websvn directory will need to have Multiviews turned on in Apache, and you'll need to configure
// wsvn.php
 
// $config->useMultiViews();
 
// }}}
 
// {{{ ACCESS RIGHTS ---
 
// Uncomment this line if you want to use your Subversion access file to control access
// rights via WebSVN. For this to work, you'll need to set up the same Apache based authentication
// to the WebSVN (or wsvn) directory as you have for Subversion itself. More information can be
// found in install.txt
 
// $config->useAuthenticationFile('/path/to/accessfile'); // Global access file
 
// You may also specify a per repository access file by uncommenting and copying the following
// line as necessary. Use the convention 'groupname.myrep' if your repository is in a group.
 
// $config->useAuthenticationFile('/path/to/accessfile', 'myrep'); // Access file for myrep
 
// }}}
 
// {{{ FILE CONTENT ---
//
// You may wish certain file types to be GZIP'd and delieved to the user when clicked apon.
// This is useful for binary files and the like that don't display well in a browser window!
// Copy, uncomment and modify this line for each extension to which this rule should apply.
// (Don't forget the . before the extension. You don't need an index between the []'s).
// If you'd rather that the files were delivered uncompressed with the associated MIME type,
// then read below.
//
// $zipped[] = '.dll';
 
// Subversion controlled files have an svn:mime-type property that can
// be set on a file indicating its mime type. By default binary files
// are set to the generic appcliation/octet-stream, and other files
// don't have it set at all. WebSVN also has a built-in list of
// associations from file extension to MIME content type. (You can
// view this list in setup.inc).
//
// Determining the content-type: By default, if the svn:mime-type
// property exists and is different from application/octet-stream, it
// is used. Otherwise, if the built-in list has a contentType entry
// for the extension of the file, that is used. Otherwise, if the
// svn:mime-type property exists has the generic binary value of
// application/octet-stream, the file will be served as a binary
// file. Otherwise, the file will be brought up as ASCII text in the
// browser window (although this text may optionally be colourised.
// See below).
//
// Uncomment this if you want to ignore any svn:mime-type property on your
// files.
//
// $config->ignoreSvnMimeTypes();
//
// Uncomment this if you want skip WebSVN's custom mime-type handling
//
// $config->ignoreWebSVNContentTypes();
//
// Following the examples below, you can add new associations, modify
// the default ones or even delete them entirely (to show them in
// ASCII via WebSVN).
 
// $contentType['.c'] = 'plain/text'; // Create a new association
// $contentType['.doc'] = 'plain/text'; // Modify an existing one
// unset($contentType['.m'] // Remove a default association
 
// }}}
 
// {{{ TARBALLS ---
 
// You need tar and gzip installed on your system. Set the paths above if necessary
//
// Uncomment the line below to offer a tarball download option across all your
// repositories.
//
// $config->allowDownload();
//
// To change the global option for individual repositories, uncomment and replicate
// the required line below (replacing 'myrep' for the name of the repository to be changed).
// Use the convention 'groupname.myrep' if your repository is in a group.
 
// $config->allowDownload('myrep'); // Specifically allow downloading for 'myrep'
// $config->disallowDownload('myrep'); // Specifically disallow downloading for 'myrep'
 
// You can also choose the minimum directory level from which you'll allow downloading.
// A value of zero will allow downloading from the root. 1 will allow downloding of directories
// in the root, etc.
//
// If your project is arranged with trunk, tags and branches at the root level, then a value of 2
// would allow the downloading of directories within branches/tags while disallowing the download
// of the entire branches or tags directories. This would also stop downloading of the trunk, but
// see after for path exceptions.
//
// Change the line below to set the download level across all your repositories.
 
$config->setMinDownloadLevel(2);
 
// To change the level for individual repositories, uncomment and replicate
// the required line below (replacing 'myrep' for the name of the repository to be changed).
// Use the convention 'groupname.myrep' if your repository is in a group.
 
// $config->setMinDownloadLevel(2, 'myrep');
 
// Finally, you may add or remove certain directories (and their contents) either globally
// or on a per repository basis. Uncomment and copy the following lines as necessary. Note
// that the these are searched in the order than you give them until a match is made (with the
// exception that all the per repository exceptions are tested before the global ones). This means
// that you must disallow /a/b/c/ before you allow /a/b/ otherwise the allowed match on /a/b/ will
// stop any further searching, thereby allowing downloads on /a/b/c/.
 
// Global exceptions possibilties:
//
// $config->addAllowedDownloadException('/path/to/allowed/directory/');
// $config->addDisAllowedDownloadException('/path/to/disallowed/directory/');
//
// Per repository exception possibilties:
// Use the convention 'groupname.myrep' if your repository is in a group.
//
// $config->addAllowedDownloadException('/path/to/allowed/directory/', 'myrep');
// $config->addDisAllowedDownloadException('/path/to/disallowed/directory/', 'myrep');
 
// }}}
 
// {{{ COLOURISATION ---
 
// Uncomment this line if you want to use Enscript to colourise your file listings
//
// You'll need Enscript version 1.6 or higher AND Sed installed to use this feature.
// Set the path above.
//
// $config->useEnscript();
 
// Enscript need to be told what the contents of a file are so that it can be colourised
// correctly. WebSVN includes a predefined list of mappings from file extension to Enscript
// file type (viewable in setup.inc).
//
// Here you should add and other extensions not already listed or redefine the default ones. eg:
//
// $extEnscript['.pas'] = 'pascal';
//
// Note that extensions are case sensitive.
 
// }}}
 
// {{{ RSSFEED ---
 
// Uncomment this line if you wish to hide the RSS feed links across all repositories
//
// $config->hideRSS();
//
// To change the global option for individual repositories, uncomment and replicate
// the required line below (replacing 'myrep' for the name of the repository to be changed).
// Use the convention 'groupname.myrep' if your repository is in a group.
 
// $config->hideRSS('myrep'); // Specifically hide RSS links for 'myrep'
// $config->showRSS('myrep'); // Specifically show RSS links for 'myrep'
 
// }}}
 
// {{{ BUGTRAQ ---
 
// Uncomment this line if you wish to use bugtraq: properties to show links to your BugTracker
// from the log messages.
//
// $config->useBugtraqProperties();
//
// To change the global option for individual repositories, uncomment and replicate
// the required line below (replacing 'myrep' for the name of the repository to be changed).
// Use the convention 'groupname.myrep' if your repository is in a group.
 
// $config->useBugtraqProperties('myrep'); // Specifically use bugtraq properties for 'myrep'
// $config->ignoreBugtraqProperties('myrep'); // Specifically ignore bugtraq properties for 'myrep'
 
// }}}
 
// {{{ MISCELLANEOUS ---
 
// Comment out this if you don't have the right to use it. Be warned that you may need it however!
set_time_limit(0);
 
// Comment this line to turn off caching of repo information. This will slow down your browsing.
$config->setCachingOn();
 
// Number of spaces to expand tabs to in diff/listing view across all repositories
 
$config->expandTabsBy(8);
 
// To change the global option for individual repositories, uncomment and replicate
// the required line below (replacing 'myrep' for the name of the repository to be changed).
// Use the convention 'groupname.myrep' if your repository is in a group.
 
// $config->expandTabsBy(3, 'myrep'); // Expand Tabs by 3 for repository 'myrep'
 
// For installations without PHP5, a copy of PEAR's PHP Compat library is included.
// If you have your own version of Compat you wish to use, go ahead and specify here.
 
// $config->setPHPCompatPath('/usr/share/php/PHP/');
 
// }}}
?>
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// config.inc
//
// Configuration parameters
 
// --- FOLLOW THE INSTRUCTIONS BELOW TO CONFIGURE YOUR SETUP ---
 
// {{{ PLATFORM CONFIGURATION ---
 
// Uncomment the next line if your running a windows server
//
// $config->setServerIsWindows();
 
// Configure these lines if your commands aren't on your path.
//
// $config->setSVNCommandPath('Path/to/svn and svnlook/ e.g. c:\\program files\\subversion\\bin');
// $config->setDiffPath('Path/to/diff/command/');
 
// For syntax colouring, if option enabled...
// $config->setEnscriptPath('Path/to/enscript/command/');
// $config->setSedPath('Path/to/sed/command/');
 
// For delivered tarballs, if option enabled...
// $config->setTarPath('Path/to/tar/command/');
 
// For delivered GZIP'd files and tarballs, if option enabled...
// $config->setGZipPath('Path/to/gzip/command/');
 
// }}}
 
// {{{ REPOSITORY SETUP ---
 
// There are 2 methods for defining the repositiories available on the system. Either you list
// them by hand, in which case you can give each one the name of your choice, or you use the
// parent path function, in which case the name of the directory is used as the repository name.
//
// In all cases, you may optionally supply a group name to the repositories. This is useful in the
// case that you need to separate your projects. Grouped Repositories are referred to using the
// convention GroupName.RepositoryName
//
// Performance is much better on local repositories (e.g. accessed by file:///). However, you
// can also provide an interface onto a remote repository. In this case you should supply the
// username and password needed to access it.
//
// To configure the repositories by hand, copy the appropriate line below, uncomment it and
// replace the name and URL of your repository.
 
// Local repositories (without and with optional group):
//
// $config->addRepository('NameToDisplay', 'URL to repository (e.g. file:///c:/svn/proj)');
// $config->addRepository('NameToDisplay', 'URL to repository (e.g. file:///c:/svn/proj)', 'group');
//
// Remote repositories (without and with optional group):
//
// $config->addRepository('NameToDisplay', 'URL (e.g. http://path/to/rep)', NULL, 'username', 'password');
// $config->addRepository('NameToDisplay', 'URL (e.g. http://path/to/rep)', 'group', 'username', 'password');
//
// To use the parent path method, uncomment the newt line and and replace the path with your one. You
// can call the function several times if you have several parent paths. Note that in this case the
// path is a filesystem path
//
// $config->parentPath('Path/to/parent (e.g. c:\\svn)');
 
// }}}
 
// {{{ LOOK AND FEEL ---
//
// Uncomment ONLY the template file that you want.
 
$config->setTemplatePath("$locwebsvnreal/templates/Standard/");
// $config->setTemplatePath("$locwebsvnreal/templates/BlueGrey/");
// $config->setTemplatePath("$locwebsvnreal/templates/Zinn/");
 
// You may also specify a per repository template file by uncommenting and changing the following
// line as necessary. Use the convention "groupname.myrep" if your repository is in a group.
 
// $config->setTemplatePath('$locwebsvnreal/templates/Standard/', 'myrep'); // Access file for myrep
 
// The index page containing the projects may either be displayed as a flat view (the default),
// where grouped repositories are displayed as "GroupName.RepName" or as a tree view.
// In the case of a tree view, you may choose whether the entire tree is open by default.
 
// $config->useTreeIndex(false); // Tree index, closed by default
// $config->useTreeIndex(true); // Tree index, open by default
 
// By default, WebSVN displays a tree view onto the current directory. You can however
// choose to display a flat view of the current directory only, which may make the display
// load faster. Uncomment this line if you want that.
 
// $config->useFlatView();
 
// }}}
 
// {{{ LANGUAGE SETUP ---
 
// WebSVN uses the iconv module to convert messages from your system's character set to the
// UTF-8 output encoding. If you find that your log messages aren't displayed correctly then
// you'll need to change the value here.
//
// You may also specify the character encoding of the repository contents if different from
// the system encoding. This is typically the case for windows users, whereby the command
// line returns, for example, CP850 encoded strings, whereas the source files are encoded
// as iso-8859-1 by Windows based text editors. When display text file, WebSVN will convert
// them from the content encoding to the output encoding (UTF-8).
//
// WebSVN does its best to automate all this, so only use the following if it doesn't work
// "out of the box". Uncomment and change one of the examples below.
//
// $config->setInputEncoding('CP850'); // Encoding of result returned by svn command line, etc.
// $config->setContentEncoding('iso-8859-1'); // Content encoding of all your repositories // repositories
 
// You may also specify a content encoding on a per repository basis. Uncomment and copy this
// line as necessary.
//
// $config->setContentEncoding('iso-8859-1', 'MyEnc');
 
// Note for Windows users: To enable iconv you'll need to enable the extension in your php.ini file
// AND copy iconv.dll (not php_iconv.dll) to your Windows system folder. In most cases the correct
// encoding is set when you call $config->setServerIsWindows();.
 
// Note for *nix users. You'll need to have iconv compiled into your binary. The default input and
// output encodings are taken from your locale informations. Override these if they aren't correct.
 
// Uncomment the default language. If you want English then don't do anything here.
//
// include 'languages/catalan.inc';
// include 'languages/danish.inc';
// include 'languages/dutch.inc';
// include 'languages/finnish.inc';
// include 'languages/french.inc';
// include 'languages/german.inc';
// include 'languages/japanese.inc';
// include 'languages/korean.inc';
// include 'languages/norwegian.inc';
// include 'languages/polish.inc';
// include 'languages/portuguese.inc';
// include 'languages/russian.inc';
// include 'languages/schinese.inc';
// include 'languages/slovenian.inc';
// include 'languages/spanish.inc';
// include 'languages/swedish.inc';
// include 'languages/tchinese.inc';
// include 'languages/turkish.inc';
 
// }}}
 
// {{{ MULTIVIEWS ---
 
// Uncomment this line if you want to use MultiView to access the repository by, for example:
//
// http://servername/wsvn/repname/path/in/repository
//
// Note: The websvn directory will need to have Multiviews turned on in Apache, and you'll need to configure
// wsvn.php
 
// $config->useMultiViews();
 
// }}}
 
// {{{ ACCESS RIGHTS ---
 
// Uncomment this line if you want to use your Subversion access file to control access
// rights via WebSVN. For this to work, you'll need to set up the same Apache based authentication
// to the WebSVN (or wsvn) directory as you have for Subversion itself. More information can be
// found in install.txt
 
// $config->useAuthenticationFile('/path/to/accessfile'); // Global access file
 
// You may also specify a per repository access file by uncommenting and copying the following
// line as necessary. Use the convention 'groupname.myrep' if your repository is in a group.
 
// $config->useAuthenticationFile('/path/to/accessfile', 'myrep'); // Access file for myrep
 
// }}}
 
// {{{ FILE CONTENT ---
//
// You may wish certain file types to be GZIP'd and delieved to the user when clicked apon.
// This is useful for binary files and the like that don't display well in a browser window!
// Copy, uncomment and modify this line for each extension to which this rule should apply.
// (Don't forget the . before the extension. You don't need an index between the []'s).
// If you'd rather that the files were delivered uncompressed with the associated MIME type,
// then read below.
//
// $zipped[] = '.dll';
 
// Subversion controlled files have an svn:mime-type property that can
// be set on a file indicating its mime type. By default binary files
// are set to the generic appcliation/octet-stream, and other files
// don't have it set at all. WebSVN also has a built-in list of
// associations from file extension to MIME content type. (You can
// view this list in setup.inc).
//
// Determining the content-type: By default, if the svn:mime-type
// property exists and is different from application/octet-stream, it
// is used. Otherwise, if the built-in list has a contentType entry
// for the extension of the file, that is used. Otherwise, if the
// svn:mime-type property exists has the generic binary value of
// application/octet-stream, the file will be served as a binary
// file. Otherwise, the file will be brought up as ASCII text in the
// browser window (although this text may optionally be colourised.
// See below).
//
// Uncomment this if you want to ignore any svn:mime-type property on your
// files.
//
// $config->ignoreSvnMimeTypes();
//
// Uncomment this if you want skip WebSVN's custom mime-type handling
//
// $config->ignoreWebSVNContentTypes();
//
// Following the examples below, you can add new associations, modify
// the default ones or even delete them entirely (to show them in
// ASCII via WebSVN).
 
// $contentType['.c'] = 'plain/text'; // Create a new association
// $contentType['.doc'] = 'plain/text'; // Modify an existing one
// unset($contentType['.m'] // Remove a default association
 
// }}}
 
// {{{ TARBALLS ---
 
// You need tar and gzip installed on your system. Set the paths above if necessary
//
// Uncomment the line below to offer a tarball download option across all your
// repositories.
//
// $config->allowDownload();
//
// To change the global option for individual repositories, uncomment and replicate
// the required line below (replacing 'myrep' for the name of the repository to be changed).
// Use the convention 'groupname.myrep' if your repository is in a group.
 
// $config->allowDownload('myrep'); // Specifically allow downloading for 'myrep'
// $config->disallowDownload('myrep'); // Specifically disallow downloading for 'myrep'
 
// You can also choose the minimum directory level from which you'll allow downloading.
// A value of zero will allow downloading from the root. 1 will allow downloding of directories
// in the root, etc.
//
// If your project is arranged with trunk, tags and branches at the root level, then a value of 2
// would allow the downloading of directories within branches/tags while disallowing the download
// of the entire branches or tags directories. This would also stop downloading of the trunk, but
// see after for path exceptions.
//
// Change the line below to set the download level across all your repositories.
 
$config->setMinDownloadLevel(2);
 
// To change the level for individual repositories, uncomment and replicate
// the required line below (replacing 'myrep' for the name of the repository to be changed).
// Use the convention 'groupname.myrep' if your repository is in a group.
 
// $config->setMinDownloadLevel(2, 'myrep');
 
// Finally, you may add or remove certain directories (and their contents) either globally
// or on a per repository basis. Uncomment and copy the following lines as necessary. Note
// that the these are searched in the order than you give them until a match is made (with the
// exception that all the per repository exceptions are tested before the global ones). This means
// that you must disallow /a/b/c/ before you allow /a/b/ otherwise the allowed match on /a/b/ will
// stop any further searching, thereby allowing downloads on /a/b/c/.
 
// Global exceptions possibilties:
//
// $config->addAllowedDownloadException('/path/to/allowed/directory/');
// $config->addDisAllowedDownloadException('/path/to/disallowed/directory/');
//
// Per repository exception possibilties:
// Use the convention 'groupname.myrep' if your repository is in a group.
//
// $config->addAllowedDownloadException('/path/to/allowed/directory/', 'myrep');
// $config->addDisAllowedDownloadException('/path/to/disallowed/directory/', 'myrep');
 
// }}}
 
// {{{ COLOURISATION ---
 
// Uncomment this line if you want to use Enscript to colourise your file listings
//
// You'll need Enscript version 1.6 or higher AND Sed installed to use this feature.
// Set the path above.
//
// $config->useEnscript();
 
// Enscript need to be told what the contents of a file are so that it can be colourised
// correctly. WebSVN includes a predefined list of mappings from file extension to Enscript
// file type (viewable in setup.inc).
//
// Here you should add and other extensions not already listed or redefine the default ones. eg:
//
// $extEnscript['.pas'] = 'pascal';
//
// Note that extensions are case sensitive.
 
// }}}
 
// {{{ RSSFEED ---
 
// Uncomment this line if you wish to hide the RSS feed links across all repositories
//
// $config->hideRSS();
//
// To change the global option for individual repositories, uncomment and replicate
// the required line below (replacing 'myrep' for the name of the repository to be changed).
// Use the convention 'groupname.myrep' if your repository is in a group.
 
// $config->hideRSS('myrep'); // Specifically hide RSS links for 'myrep'
// $config->showRSS('myrep'); // Specifically show RSS links for 'myrep'
 
// }}}
 
// {{{ BUGTRAQ ---
 
// Uncomment this line if you wish to use bugtraq: properties to show links to your BugTracker
// from the log messages.
//
// $config->useBugtraqProperties();
//
// To change the global option for individual repositories, uncomment and replicate
// the required line below (replacing 'myrep' for the name of the repository to be changed).
// Use the convention 'groupname.myrep' if your repository is in a group.
 
// $config->useBugtraqProperties('myrep'); // Specifically use bugtraq properties for 'myrep'
// $config->ignoreBugtraqProperties('myrep'); // Specifically ignore bugtraq properties for 'myrep'
 
// }}}
 
// {{{ MISCELLANEOUS ---
 
// Comment out this if you don't have the right to use it. Be warned that you may need it however!
set_time_limit(0);
 
// Comment this line to turn off caching of repo information. This will slow down your browsing.
$config->setCachingOn();
 
// Number of spaces to expand tabs to in diff/listing view across all repositories
 
$config->expandTabsBy(8);
 
// To change the global option for individual repositories, uncomment and replicate
// the required line below (replacing 'myrep' for the name of the repository to be changed).
// Use the convention 'groupname.myrep' if your repository is in a group.
 
// $config->expandTabsBy(3, 'myrep'); // Expand Tabs by 3 for repository 'myrep'
 
// For installations without PHP5, a copy of PEAR's PHP Compat library is included.
// If you have your own version of Compat you wish to use, go ahead and specify here.
 
// $config->setPHPCompatPath('/usr/share/php/PHP/');
 
// }}}
?>
/WebSVN/include/configclass.inc
1,1269 → 1,1251
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// configclass.inc4
//
// General class for handling configuration options
 
require_once("include/command.inc");
require_once("include/auth.inc");
require_once("include/version.inc");
 
// Auxillary functions used to sort repositories by name/group
 
// {{{ cmpReps($a, $b)
 
function cmpReps($a, $b)
{
// First, sort by group
$g = strcasecmp($a->group, $b->group);
if ($g)
return $g;
// Same group? Sort by name
return strcasecmp($a->name, $b->name);
}
 
// }}}
 
// {{{ cmpGroups($a, $b)
 
function cmpGroups($a, $b)
{
$g = strcasecmp($a->group, $b->group);
if ($g)
return $g;
return 0;
}
 
// }}}
 
// {{{ mergesort(&$array, [$cmp_function])
 
function mergesort(&$array, $cmp_function = 'strcmp')
{
// Arrays of size < 2 require no action
if (count($array) < 2)
return;
// Split the array in half
$halfway = count($array) / 2;
$array1 = array_slice($array, 0, $halfway);
$array2 = array_slice($array, $halfway);
// Recurse to sort the two halves
mergesort($array1, $cmp_function);
mergesort($array2, $cmp_function);
// If all of $array1 is <= all of $array2, just append them.
if (call_user_func($cmp_function, end($array1), $array2[0]) < 1)
{
$array = array_merge($array1, $array2);
return;
}
// Merge the two sorted arrays into a single sorted array
$array = array();
$ptr1 = $ptr2 = 0;
while ($ptr1 < count($array1) && $ptr2 < count($array2))
{
if (call_user_func($cmp_function, $array1[$ptr1], $array2[$ptr2]) < 1)
{
$array[] = $array1[$ptr1++];
}
else
{
$array[] = $array2[$ptr2++];
}
}
// Merge the remainder
while ($ptr1 < count($array1)) $array[] = $array1[$ptr1++];
while ($ptr2 < count($array2)) $array[] = $array2[$ptr2++];
return;
}
 
// }}}
 
// A Repository configuration class
 
Class Repository
{
// {{{ Properties
 
var $name;
var $svnName;
var $path;
var $group;
var $username;
var $password;
// Local configuration options must start off unset
var $allowDownload;
var $minDownloadLevel;
var $allowedExceptions = array();
var $disallowedExceptions = array();
var $rss;
var $spaces;
var $ignoreSvnMimeTypes;
var $ignoreWebSVNContentTypes;
var $bugtraq;
var $auth;
var $contentEnc;
var $templatePath;
 
// }}}
 
// {{{ __construct($name, $svnName, $path, [$group, [$username, [$password]]])
 
function Repository($name, $svnName, $path, $group = NULL, $username = NULL, $password = NULL)
{
$this->name = $name;
$this->svnName = $svnName;
$this->path = $path;
$this->group = $group;
$this->username = $username;
$this->password = $password;
}
 
// }}}
 
// {{{ getDisplayName()
 
function getDisplayName()
{
if(!empty($this->group))
return $this->group.".".$this->name;
else
return $this->name;
}
 
// }}}
 
// {{{ svnParams
 
function svnParams()
{
if (!empty($this->username))
return " --username ".$this->username." --password ".$this->password." ";
else
return " ";
}
 
// }}}
 
// Local configuration accessors
// {{{ RSS Feed
function hideRSS()
{
$this->rss = false;
}
 
function showRSS()
{
$this->rss = true;
}
 
function getHideRSS()
{
global $config;
 
if (isset($this->rss))
return $this->rss;
return $config->getHideRSS();
}
 
// }}}
// {{{ Download
function allowDownload()
{
$this->allowDownload = true;
}
 
function disallowDownload()
{
$this->allowDownload = false;
}
function getAllowDownload()
{
global $config;
 
if (isset($this->allowDownload))
return $this->allowDownload;
return $config->getAllowDownload();
}
 
function setMinDownloadLevel($level)
{
$this->minDownloadLevel = $level;
}
 
function getMinDownloadLevel()
{
global $config;
 
if (isset($this->minDownloadLevel))
return $this->minDownloadLevel;
return $config->getMinDownloadLevel();
}
function addAllowedDownloadException($path)
{
if ($path{strlen($path) - 1} != "/")
$path .= "/";
$this->allowedExceptions[] = $path;
}
function addDisallowedDownloadException($path)
{
if ($path{strlen($path) - 1} != "/")
$path .= "/";
$this->disallowedExceptions[] = $path;
}
 
function isDownloadAllowed($path)
{
global $config;
// Check global download option
if (!$this->getAllowDownload())
return false;
// Check with access module
if (!$this->hasUnrestrictedReadAccess($path))
return false;
$subs = explode("/", $path);
$level = count($subs) - 2;
if ($level >= $this->getMinDownloadLevel())
{
// Level OK, search for disallowed exceptions
if ($config->findException($path, $this->disallowedExceptions))
return false;
if ($config->findException($path, $config->disallowedExceptions))
return false;
return true;
}
else
{
// Level not OK, search for disallowed exceptions
 
if ($config->findException($path, $this->allowedExceptions))
return true;
if ($config->findException($path, $config->allowedExceptions))
return true;
return false;
}
}
 
// }}}
 
// {{{ Templates
 
function setTemplatePath($path)
{
$lastchar = substr($path, -1, 1);
if (!($lastchar == DIRECTORY_SEPARATOR ||
$lastchar == '/' ||
$lastchar == '\\'))
$path .= DIRECTORY_SEPARATOR;
 
$this->templatePath = $path;
}
 
function getTemplatePath()
{
global $config;
if (!empty($this->templatePath))
return $this->templatePath;
else
return $config->getTemplatePath();
}
 
// }}}
 
// {{{ Tab expansion
function expandTabsBy($sp)
{
$this->spaces = $sp;
}
function getExpandTabsBy()
{
global $config;
 
if (isset($this->spaces))
return $this->spaces;
return $config->getExpandTabsBy();
}
 
// }}}
 
// {{{ MIME-Type Handing
function ignoreSvnMimeTypes()
{
$this->ignoreSvnMimeTypes = true;
}
 
function useSvnMimeTypes()
{
$this->ignoreSvnMimeTypes = false;
}
 
function getIgnoreSvnMimeTypes()
{
global $config;
 
if (isset($this->ignoreSvnMimeTypes))
return $this->ignoreSvnMimeTypes;
return $config->getIgnoreSvnMimeTypes();
}
 
function ignoreWebSVNContentTypes()
{
$this->ignoreWebSVNContentTypes = true;
}
 
function useWebSVNContentTypes()
{
$this->ignoreWebSVNContentTypes = false;
}
 
function getIgnoreWebSVNContentTypes()
{
global $config;
 
if (isset($this->ignoreWebSVNContentTypes))
return $this->ignoreWebSVNContentTypes;
return $config->getIgnoreWebSVNContentTypes();
}
 
// }}}
// {{{ Issue Tracking
function useBugtraqProperties()
{
$this->bugtraq = true;
}
 
function ignoreBugtraqProperties()
{
$this->bugtraq = false;
}
 
function getBugtraq()
{
global $config;
 
if (isset($this->bugtraq))
return $this->bugtraq;
return $config->getBugtraq();
}
 
// }}}
// {{{ Encodings
function setContentEncoding($contentEnc)
{
$this->contentEnc = $contentEnc;
}
 
function getContentEncoding()
{
global $config;
 
if (isset($this->contentEnc))
return $this->contentEnc;
return $config->getContentEncoding();
}
 
// }}}
 
// {{{ Authentication
function useAuthenticationFile($file)
{
if (is_readable($file))
$this->auth =& new Authentication($file);
else
die('Unable to read authentication file "'.$file.'"');
}
 
function hasReadAccess($path, $checkSubFolders = false)
{
global $config;
 
$a = null;
if (isset($this->auth))
$a =& $this->auth;
else
$a =& $config->getAuth();
if (!empty($a))
return $a->hasReadAccess($this->svnName, $path, $checkSubFolders);
// No auth file - free access...
return true;
}
 
function hasUnrestrictedReadAccess($path)
{
global $config;
 
$a = null;
if (isset($this->auth))
$a =& $this->auth;
else
$a =& $config->getAuth();
if (!empty($a))
return $a->hasUnrestrictedReadAccess($this->svnName, $path);
// No auth file - free access...
return true;
}
 
// }}}
 
}
 
// The general configuration class
 
Class Config
{
// {{{ Properties
 
// Tool path locations
 
var $svnlook = "svnlook";
var $svn = "svn --non-interactive --config-dir /tmp";
var $svn_noparams = "svn --config-dir /tmp";
var $diff = "diff";
var $enscript ="enscript";
var $sed = "sed";
var $gzip = "gzip";
var $tar = "tar";
// Other configuration items
var $treeView = true;
var $flatIndex = true;
var $openTree = false;
var $serverIsWindows = false;
var $phpCompatEnabled = false;
var $cacheResults = false;
var $multiViews = false;
var $useEnscript = false;
var $allowDownload = false;
var $minDownloadLevel = 0;
var $allowedExceptions = array();
var $disallowedExceptions = array();
var $rss = true;
var $spaces = 8;
var $bugtraq = false;
var $auth = "";
var $templatePath = "./templates/Standard/";
var $phpCompatPath = './include/PHP/Compat.php';
 
var $ignoreSvnMimeTypes = false;
var $ignoreWebSVNContentTypes = false;
 
var $subversionMajorVersion = "";
var $subversionMinorVersion = "";
 
// Default character encodings
var $inputEnc = ""; // Encoding of output returned from command line
var $contentEnc = ""; // Encoding of repository content
var $outputEnc = "UTF-8"; // Encoding of web page. Now forced to UTF-8
 
var $quote = "'";
var $pathSeparator = ":";
 
var $_repositories;
 
// }}}
 
// {{{ __construct()
 
function Config()
{
}
 
// }}}
 
// {{{ Repository configuration
function addRepository($name, $url, $group = NULL, $username = NULL, $password = NULL)
{
$url = str_replace(DIRECTORY_SEPARATOR, "/", $url);
if ($url{strlen($url) - 1} == "/")
$url = substr($url, 0, -1);
$svnName = substr($url, strrpos($url, "/") + 1);
$this->_repositories[] = new Repository($name, $svnName, $url, $group, $username, $password);
}
 
function getRepositories()
{
return $this->_repositories;
}
 
function &findRepository($name)
{
foreach ($this->_repositories as $index => $rep)
{
if (strcmp($rep->getDisplayName(), $name) == 0)
{
$repref =& $this->_repositories[$index];
return $repref;
}
}
print "ERROR: Unable to find repository '$name'";
exit;
}
 
// }}}
 
// {{{ setServerIsWindows
//
// The server is running on Windows
function setServerIsWindows()
{
$this->serverIsWindows = true;
// Try to set the input encoding intelligently
$cp = 0;
if ($cp = @shell_exec("CHCP"))
{
$cp = trim(substr($cp, strpos($cp, ":") + 1));
settype($cp, "integer");
}
// Use the most sensible default value if that failed
if ($cp == 0) $cp = 850;
// We assume, as a default, that the encoding of the repository contents is
// in iso-8859-1, to be compatible with compilers and the like.
$this->setInputEncoding("CP$cp", "iso-8859-1");
// On Windows machines, use double quotes around command line parameters
$this->quote = '"';
// On Windows, semicolon separates path entries in a list rather than colon.
$this->pathSeparator = ";";
}
// }}}
// {{{ setPHPCompatEnabled
//
// Used for PHP4
 
function setPHPCompatEnabled() {
$this->phpCompatEnabled = true;
}
function isPHPCompatEnabled() {
return $this->phpCompatEnabled;
}
 
// }}}
 
// {{{ Caching
 
// setCachingOn
//
// Set result caching on
function setCachingOn()
{
$this->cacheResults = true;
}
 
function isCachingOn()
{
return $this->cacheResults;
}
 
// }}}
 
// {{{ MultiViews
 
// useMultiViews
//
// Use MultiViews to access the repository
function useMultiViews()
{
$this->multiViews = true;
}
 
function getUseMultiViews()
{
return $this->multiViews;
}
 
// }}}
 
// {{{ Enscript
 
// useEnscript
//
// Use Enscript to colourise listings
function useEnscript()
{
$this->useEnscript = true;
}
 
function getUseEnscript()
{
return $this->useEnscript;
}
 
// }}}
 
// {{{ RSS
 
// offerRSS
//
// Use Enscript to colourise listings
function hideRSS($myrep = 0)
{
if (empty($myrep))
$this->rss = false;
else
{
$repo =& $this->findRepository($myrep);
$repo->hideRSS();
}
}
 
function getHideRSS()
{
return $this->rss;
}
 
// }}}
 
// {{{ Downloads
 
// allowDownload
//
// Allow download of tarballs
function allowDownload($myrep = 0)
{
if (empty($myrep))
$this->allowDownload = true;
else
{
$repo =& $this->findRepository($myrep);
$repo->allowDownload();
}
}
 
function disallowDownload($myrep = 0)
{
if (empty($myrep))
$this->allowDownload = false;
else
{
$repo =& $this->findRepository($myrep);
$repo->disallowDownload();
}
}
 
function getAllowDownload()
{
return $this->allowDownload;
}
 
function setMinDownloadLevel($level, $myrep = 0)
{
if (empty($myrep))
$this->minDownloadLevel = $level;
else
{
$repo =& $this->findRepository($myrep);
$repo->setMinDownloadLevel($level);
}
}
 
function getMinDownloadLevel()
{
return $this->minDownloadLevel;
}
 
function addAllowedDownloadException($path, $myrep = 0)
{
if ($path{strlen($path) - 1} != "/")
$path .= "/";
if (empty($myrep))
$this->allowedExceptions[] = $path;
else
{
$repo =& $this->findRepository($myrep);
$repo->addAllowedDownloadException($path);
}
}
 
function addDisallowedDownloadException($path, $myrep = 0)
{
if ($path{strlen($path) - 1} != "/")
$path .= "/";
if (empty($myrep))
$this->disallowedExceptions[] = $path;
else
{
$repo =& $this->findRepository($myrep);
$repo->addDisallowedDownloadException($path);
}
}
function findException($path, $exceptions)
{
foreach ($exceptions As $key => $exc)
{
if (strncmp($exc, $path, strlen($exc)) == 0)
return true;
}
return false;
}
// }}}
 
// {{{ getURL
//
// Get the URL to a path name based on the current config
function getURL($rep, $path, $op)
{
$base = $_SERVER["SCRIPT_NAME"];
if ($this->multiViews)
{
// Remove the .php
if (eregi(".php$", $base))
{
// Remove the .php
$base = substr($base, 0, -4);
}
if ($path && $path{0} != "/") $path = "/".$path;
$url = $base;
if (is_object($rep))
{
$url .= "/".$rep->getDisplayName().str_replace('%2F', '/', urlencode($path));
if ($op != "dir" && $op != "file")
$url .= "?op=$op&amp;";
else
$url .= "?";
}
return $url;
}
else
{
switch ($op)
{
case "dir":
$fname = "listing.php";
break;
case "file":
$fname = "filedetails.php";
break;
 
case "log":
$fname = "log.php";
break;
 
case "diff":
$fname = "diff.php";
break;
 
case "blame":
$fname = "blame.php";
break;
 
case "form":
$fname = "form.php";
break;
 
case "rss":
$fname = "rss.php";
break;
 
case "dl":
$fname = "dl.php";
break;
 
case "comp":
$fname = "comp.php";
break;
}
 
if ($rep == -1)
return $fname."?path=".urlencode($path)."&amp;";
else
return $fname."?repname=".urlencode($rep->getDisplayName())."&amp;path=".urlencode($path)."&amp;";
}
}
 
// }}}
 
// {{{ Paths and Commands
 
// setPath
//
// Set the location of the given path
function setPath(&$var, $path, $name, $params = "")
{
$lastchar = substr($path, -1, 1);
$isDir = ($lastchar == DIRECTORY_SEPARATOR ||
$lastchar == "/" ||
$lastchar == "\\");
if (!$isDir)
{
$path .= DIRECTORY_SEPARATOR;
}
 
// On a windows machine we need to put spaces around the entire command
// to allow for spaces in the path
if ($this->serverIsWindows)
$var = "\"$path$name\"";
else
$var = "$path$name";
$var .= " ".$params;
}
 
// setSVNCommandPath
//
// Define the location of the svn and svnlook commands
function setSVNCommandPath($path)
{
$this->setPath($this->svn, $path, "svn", "--non-interactive --config-dir /tmp");
$this->setPath($this->svn_noparams, $path, "svn", " --config-dir /tmp");
$this->setPath($this->svnlook, $path, "svnlook");
}
function getSvnCommand()
{
return $this->svn;
}
 
function getCleanSvnCommand()
{
return $this->svn_noparams;
}
 
function getSvnlookCommand()
{
return $this->svnlook;
}
// setDiffPath
//
// Define the location of the diff command
function setDiffPath($path)
{
$this->setPath($this->diff, $path, "diff");
}
 
function getDiffCommand()
{
return $this->diff;
}
 
// setEnscriptPath
//
// Define the location of the enscript command
function setEnscriptPath($path)
{
$this->setPath($this->enscript, $path, "enscript");
}
 
function getEnscriptCommand()
{
return $this->enscript;
}
 
// setSedPath
//
// Define the location of the sed command
function setSedPath($path)
{
$this->setPath($this->sed, $path, "sed");
}
function getSedCommand()
{
return $this->sed;
}
 
// setTarPath
//
// Define the location of the tar command
function setTarPath($path)
{
$this->setPath($this->tar, $path, "tar");
}
function getTarCommand()
{
return $this->tar;
}
 
// setGzipPath
//
// Define the location of the GZip command
function setGzipPath($path)
{
$this->setPath($this->gzip, $path, "gzip");
}
function getGzipCommand()
{
return $this->gzip;
}
 
// Templates
function setTemplatePath($path, $myrep = 0)
{
if (empty($myrep))
{
$lastchar = substr($path, -1, 1);
if (!($lastchar == DIRECTORY_SEPARATOR ||
$lastchar == '/' ||
$lastchar == '\\'))
$path .= DIRECTORY_SEPARATOR;
 
$this->templatePath = $path;
}
else
{
$repo =& $this->findRepository($myrep);
$repo->setTemplatePath($path);
}
}
 
function getTemplatePath()
{
return $this->templatePath;
}
 
// PHP Compat file (from PEAR)
 
function setPHPCompatPath($path)
{
$this->setPath($this->phpCompatPath, $path, 'Compat.php');
}
 
function getPHPCompatFile()
{
return trim($this->phpCompatPath);
}
 
// }}}
 
// {{{ parentPath
//
// Automatically set up the repositories based on a parent path
function parentPath($path, $group = NULL)
{
if ($handle = @opendir($path))
{
// For each file...
while (false !== ($file = readdir($handle)))
{
// That's also a non hidden directory
if (is_dir($path.DIRECTORY_SEPARATOR.$file) && $file{0} != ".")
{
// And that contains a db directory (in an attempt to not include
// non svn repositories.
if (is_dir($path.DIRECTORY_SEPARATOR.$file.DIRECTORY_SEPARATOR."db"))
{
// We add the repository to the list
$this->addRepository($file, "file:///".$path.DIRECTORY_SEPARATOR.$file, $group);
}
}
}
closedir($handle);
}
 
// Sort the repositories into alphabetical order
if (!empty($this->_repositories))
usort($this->_repositories, "cmpReps");
}
 
// }}}
// {{{ Encoding functions
function setInputEncoding($systemEnc)
{
$this->inputEnc = $systemEnc;
if (!isset($this->contentEnc))
$this->contentEnc = $systemEnc;
}
function getInputEncoding()
{
return $this->inputEnc;
}
 
function setContentEncoding($contentEnc, $myrep = 0)
{
if (empty($myrep))
$this->contentEnc = $contentEnc;
else
{
$repo =& $this->findRepository($myrep);
$repo->setContentEncoding($contentEnc);
}
}
function getContentEncoding()
{
return $this->contentEnc;
}
 
// }}}
 
// {{{ Tab expansion functions
function expandTabsBy($sp, $myrep = 0)
{
if (empty($myrep))
$this->spaces = $sp;
else
{
$repo =& $this->findRepository($myrep);
$repo->expandTabsBy($sp);
}
}
function getExpandTabsBy()
{
return $this->spaces;
}
 
// }}}
 
// {{{ Misc settings
function ignoreSvnMimeTypes()
{
$this->ignoreSvnMimeTypes = true;
}
 
function getIgnoreSvnMimeTypes()
{
return $this->ignoreSvnMimeTypes;
}
 
function ignoreWebSVNContentTypes()
{
$this->ignoreWebSVNContentTypes = true;
}
 
function getIgnoreWebSVNContentTypes()
{
return $this->ignoreWebSVNContentTypes;
}
 
function useBugtraqProperties($myrep = 0)
{
if (empty($myrep))
$this->bugtraq = true;
else
{
$repo =& $this->findRepository($myrep);
$repo->useBugtraqProperties();
}
}
function getBugtraq()
{
return $this->bugtraq;
}
 
function useAuthenticationFile($file, $myrep = 0)
{
if (empty($myrep))
{
if (is_readable($file))
$this->auth = new Authentication($file);
else
{
echo "Unable to read authentication file '$file'";
exit;
}
}
else
{
$repo =& $this->findRepository($myrep);
$repo->useAuthenticationFile($file);
}
}
function &getAuth()
{
return $this->auth;
}
 
function useTreeView()
{
$this->treeView = true;
}
function getUseTreeView()
{
return $this->treeView;
}
 
function useFlatView()
{
$this->treeView = false;
}
 
function useTreeIndex($open)
{
$this->flatIndex = false;
$this->openTree = $open;
}
 
function getUseFlatIndex()
{
return $this->flatIndex;
}
 
function getOpenTree()
{
return $this->openTree;
}
 
// setSubversionMajorVersion
//
// Set subversion major version
function setSubversionMajorVersion($subversionMajorVersion)
{
$this->subversionMajorVersion = $subversionMajorVersion;
}
 
function getSubversionMajorVersion()
{
return $this->subversionMajorVersion;
}
 
// setSubversionMinorVersion
//
// Set subversion minor version
function setSubversionMinorVersion($subversionMinorVersion)
{
$this->subversionMinorVersion = $subversionMinorVersion;
}
function getSubversionMinorVersion()
{
return $this->subversionMinorVersion;
}
 
// }}}
 
// {{{ Sort the repostories
//
// This function sorts the repositories by group name. The contents of the
// group are left in there original order, which will either be sorted if the
// group was added using the parentPath function, or defined for the order in
// which the repositories were included in the user's config file.
//
// Note that as of PHP 4.0.6 the usort command no longer preserves the order
// of items that are considered equal (in our case, part of the same group).
// The mergesort function preserves this order.
function sortByGroup()
{
if (!empty($this->_repositories))
mergesort($this->_repositories, "cmpGroups");
}
 
// }}}
}
?>
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// configclass.inc4
//
// General class for handling configuration options
 
require_once("include/command.inc");
require_once("include/auth.inc");
require_once("include/version.inc");
 
// Auxillary functions used to sort repositories by name/group
 
// {{{ cmpReps($a, $b)
 
function cmpReps($a, $b)
{
// First, sort by group
$g = strcasecmp($a->group, $b->group);
if ($g)
return $g;
// Same group? Sort by name
return strcasecmp($a->name, $b->name);
}
 
// }}}
 
// {{{ cmpGroups($a, $b)
 
function cmpGroups($a, $b)
{
$g = strcasecmp($a->group, $b->group);
if ($g)
return $g;
return 0;
}
 
// }}}
 
// {{{ mergesort(&$array, [$cmp_function])
 
function mergesort(&$array, $cmp_function = 'strcmp')
{
// Arrays of size < 2 require no action
if (count($array) < 2)
return;
// Split the array in half
$halfway = count($array) / 2;
$array1 = array_slice($array, 0, $halfway);
$array2 = array_slice($array, $halfway);
// Recurse to sort the two halves
mergesort($array1, $cmp_function);
mergesort($array2, $cmp_function);
// If all of $array1 is <= all of $array2, just append them.
if (call_user_func($cmp_function, end($array1), $array2[0]) < 1)
{
$array = array_merge($array1, $array2);
return;
}
// Merge the two sorted arrays into a single sorted array
$array = array();
$ptr1 = $ptr2 = 0;
while ($ptr1 < count($array1) && $ptr2 < count($array2))
{
if (call_user_func($cmp_function, $array1[$ptr1], $array2[$ptr2]) < 1)
{
$array[] = $array1[$ptr1++];
}
else
{
$array[] = $array2[$ptr2++];
}
}
// Merge the remainder
while ($ptr1 < count($array1)) $array[] = $array1[$ptr1++];
while ($ptr2 < count($array2)) $array[] = $array2[$ptr2++];
return;
}
 
// }}}
 
// A Repository configuration class
 
Class Repository
{
// {{{ Properties
 
var $name;
var $svnName;
var $path;
var $group;
var $username;
var $password;
// Local configuration options must start off unset
var $allowDownload;
var $minDownloadLevel;
var $allowedExceptions = array();
var $disallowedExceptions = array();
var $rss;
var $spaces;
var $ignoreSvnMimeTypes;
var $ignoreWebSVNContentTypes;
var $bugtraq;
var $auth;
var $contentEnc;
var $templatePath;
 
// }}}
 
// {{{ __construct($name, $svnName, $path, [$group, [$username, [$password]]])
 
function Repository($name, $svnName, $path, $group = NULL, $username = NULL, $password = NULL)
{
$this->name = $name;
$this->svnName = $svnName;
$this->path = $path;
$this->group = $group;
$this->username = $username;
$this->password = $password;
}
 
// }}}
 
// {{{ getDisplayName()
 
function getDisplayName()
{
if(!empty($this->group))
return $this->group.".".$this->name;
else
return $this->name;
}
 
// }}}
 
// {{{ svnParams
 
function svnParams()
{
if (!empty($this->username))
return " --username ".$this->username." --password ".$this->password." ";
else
return " ";
}
 
// }}}
 
// Local configuration accessors
// {{{ RSS Feed
function hideRSS()
{
$this->rss = false;
}
 
function showRSS()
{
$this->rss = true;
}
 
function getHideRSS()
{
global $config;
 
if (isset($this->rss))
return $this->rss;
return $config->getHideRSS();
}
 
// }}}
// {{{ Download
function allowDownload()
{
$this->allowDownload = true;
}
 
function disallowDownload()
{
$this->allowDownload = false;
}
function getAllowDownload()
{
global $config;
 
if (isset($this->allowDownload))
return $this->allowDownload;
return $config->getAllowDownload();
}
 
function setMinDownloadLevel($level)
{
$this->minDownloadLevel = $level;
}
 
function getMinDownloadLevel()
{
global $config;
 
if (isset($this->minDownloadLevel))
return $this->minDownloadLevel;
return $config->getMinDownloadLevel();
}
function addAllowedDownloadException($path)
{
if ($path{strlen($path) - 1} != "/")
$path .= "/";
$this->allowedExceptions[] = $path;
}
function addDisallowedDownloadException($path)
{
if ($path{strlen($path) - 1} != "/")
$path .= "/";
$this->disallowedExceptions[] = $path;
}
 
function isDownloadAllowed($path)
{
global $config;
// Check global download option
if (!$this->getAllowDownload())
return false;
// Check with access module
if (!$this->hasUnrestrictedReadAccess($path))
return false;
$subs = explode("/", $path);
$level = count($subs) - 2;
if ($level >= $this->getMinDownloadLevel())
{
// Level OK, search for disallowed exceptions
if ($config->findException($path, $this->disallowedExceptions))
return false;
if ($config->findException($path, $config->disallowedExceptions))
return false;
return true;
}
else
{
// Level not OK, search for disallowed exceptions
 
if ($config->findException($path, $this->allowedExceptions))
return true;
if ($config->findException($path, $config->allowedExceptions))
return true;
return false;
}
}
 
// }}}
 
// {{{ Templates
 
function setTemplatePath($path)
{
$lastchar = substr($path, -1, 1);
if (!($lastchar == DIRECTORY_SEPARATOR ||
$lastchar == '/' ||
$lastchar == '\\'))
$path .= DIRECTORY_SEPARATOR;
 
$this->templatePath = $path;
}
 
function getTemplatePath()
{
global $config;
if (!empty($this->templatePath))
return $this->templatePath;
else
return $config->getTemplatePath();
}
 
// }}}
 
// {{{ Tab expansion
function expandTabsBy($sp)
{
$this->spaces = $sp;
}
function getExpandTabsBy()
{
global $config;
 
if (isset($this->spaces))
return $this->spaces;
return $config->getExpandTabsBy();
}
 
// }}}
 
// {{{ MIME-Type Handing
function ignoreSvnMimeTypes()
{
$this->ignoreSvnMimeTypes = true;
}
 
function useSvnMimeTypes()
{
$this->ignoreSvnMimeTypes = false;
}
 
function getIgnoreSvnMimeTypes()
{
global $config;
 
if (isset($this->ignoreSvnMimeTypes))
return $this->ignoreSvnMimeTypes;
return $config->getIgnoreSvnMimeTypes();
}
 
function ignoreWebSVNContentTypes()
{
$this->ignoreWebSVNContentTypes = true;
}
 
function useWebSVNContentTypes()
{
$this->ignoreWebSVNContentTypes = false;
}
 
function getIgnoreWebSVNContentTypes()
{
global $config;
 
if (isset($this->ignoreWebSVNContentTypes))
return $this->ignoreWebSVNContentTypes;
return $config->getIgnoreWebSVNContentTypes();
}
 
// }}}
// {{{ Issue Tracking
function useBugtraqProperties()
{
$this->bugtraq = true;
}
 
function ignoreBugtraqProperties()
{
$this->bugtraq = false;
}
 
function getBugtraq()
{
global $config;
 
if (isset($this->bugtraq))
return $this->bugtraq;
return $config->getBugtraq();
}
 
// }}}
// {{{ Encodings
function setContentEncoding($contentEnc)
{
$this->contentEnc = $contentEnc;
}
 
function getContentEncoding()
{
global $config;
 
if (isset($this->contentEnc))
return $this->contentEnc;
return $config->getContentEncoding();
}
 
// }}}
 
// {{{ Authentication
function useAuthenticationFile($file)
{
if (is_readable($file))
$this->auth =& new Authentication($file);
else
die('Unable to read authentication file "'.$file.'"');
}
 
function hasReadAccess($path, $checkSubFolders = false)
{
global $config;
 
$a = null;
if (isset($this->auth))
$a =& $this->auth;
else
$a =& $config->getAuth();
if (!empty($a))
return $a->hasReadAccess($this->svnName, $path, $checkSubFolders);
// No auth file - free access...
return true;
}
 
function hasUnrestrictedReadAccess($path)
{
global $config;
 
$a = null;
if (isset($this->auth))
$a =& $this->auth;
else
$a =& $config->getAuth();
if (!empty($a))
return $a->hasUnrestrictedReadAccess($this->svnName, $path);
// No auth file - free access...
return true;
}
 
// }}}
 
}
 
// The general configuration class
 
Class Config
{
// {{{ Properties
 
// Tool path locations
 
var $svnlook = "svnlook";
var $svn = "svn --non-interactive --config-dir /tmp";
var $svn_noparams = "svn --config-dir /tmp";
var $diff = "diff";
var $enscript ="enscript";
var $sed = "sed";
var $gzip = "gzip";
var $tar = "tar";
// Other configuration items
var $treeView = true;
var $flatIndex = true;
var $openTree = false;
var $serverIsWindows = false;
var $cacheResults = false;
var $multiViews = false;
var $useEnscript = false;
var $allowDownload = false;
var $minDownloadLevel = 0;
var $allowedExceptions = array();
var $disallowedExceptions = array();
var $rss = true;
var $spaces = 8;
var $bugtraq = false;
var $auth = "";
var $templatePath = "./templates/Standard/";
var $phpCompatPath = './include/PHP/Compat.php';
 
var $ignoreSvnMimeTypes = false;
var $ignoreWebSVNContentTypes = false;
 
var $subversionMajorVersion = "";
var $subversionMinorVersion = "";
 
// Default character encodings
var $inputEnc = ""; // Encoding of output returned from command line
var $contentEnc = ""; // Encoding of repository content
var $outputEnc = "UTF-8"; // Encoding of web page. Now forced to UTF-8
 
var $quote = "'";
 
var $_repositories;
 
// }}}
 
// {{{ __construct()
 
function Config()
{
}
 
// }}}
 
// {{{ Repository configuration
function addRepository($name, $url, $group = NULL, $username = NULL, $password = NULL)
{
$url = str_replace(DIRECTORY_SEPARATOR, "/", $url);
if ($url{strlen($url) - 1} == "/")
$url = substr($url, 0, -1);
$svnName = substr($url, strrpos($url, "/") + 1);
$this->_repositories[] = new Repository($name, $svnName, $url, $group, $username, $password);
}
 
function getRepositories()
{
return $this->_repositories;
}
 
function &findRepository($name)
{
foreach ($this->_repositories as $index => $rep)
{
if (strcmp($rep->getDisplayName(), $name) == 0)
{
$repref =& $this->_repositories[$index];
return $repref;
}
}
print "ERROR: Unable to find repository '$name'";
exit;
}
 
// }}}
 
// {{{ setServerIsWindows
//
// The server is running on Windows
function setServerIsWindows()
{
$this->serverIsWindows = true;
// Try to set the input encoding intelligently
$cp = 0;
if ($cp = @shell_exec("CHCP"))
{
$cp = trim(substr($cp, strpos($cp, ":") + 1));
settype($cp, "integer");
}
// Use the most sensible default value if that failed
if ($cp == 0) $cp = 850;
// We assume, as a default, that the encoding of the repository contents is
// in iso-8859-1, to be compatible with compilers and the like.
$this->setInputEncoding("CP$cp", "iso-8859-1");
// On Windows machines, use double quotes around command line parameters
$this->quote = '"';
}
 
// }}}
 
// {{{ Caching
 
// setCachingOn
//
// Set result caching on
function setCachingOn()
{
$this->cacheResults = true;
}
 
function isCachingOn()
{
return $this->cacheResults;
}
 
// }}}
 
// {{{ MultiViews
 
// useMultiViews
//
// Use MultiViews to access the repository
function useMultiViews()
{
$this->multiViews = true;
}
 
function getUseMultiViews()
{
return $this->multiViews;
}
 
// }}}
 
// {{{ Enscript
 
// useEnscript
//
// Use Enscript to colourise listings
function useEnscript()
{
$this->useEnscript = true;
}
 
function getUseEnscript()
{
return $this->useEnscript;
}
 
// }}}
 
// {{{ RSS
 
// offerRSS
//
// Use Enscript to colourise listings
function hideRSS($myrep = 0)
{
if (empty($myrep))
$this->rss = false;
else
{
$repo =& $this->findRepository($myrep);
$repo->hideRSS();
}
}
 
function getHideRSS()
{
return $this->rss;
}
 
// }}}
 
// {{{ Downloads
 
// allowDownload
//
// Allow download of tarballs
function allowDownload($myrep = 0)
{
if (empty($myrep))
$this->allowDownload = true;
else
{
$repo =& $this->findRepository($myrep);
$repo->allowDownload();
}
}
 
function disallowDownload($myrep = 0)
{
if (empty($myrep))
$this->allowDownload = false;
else
{
$repo =& $this->findRepository($myrep);
$repo->disallowDownload();
}
}
 
function getAllowDownload()
{
return $this->allowDownload;
}
 
function setMinDownloadLevel($level, $myrep = 0)
{
if (empty($myrep))
$this->minDownloadLevel = $level;
else
{
$repo =& $this->findRepository($myrep);
$repo->setMinDownloadLevel($level);
}
}
 
function getMinDownloadLevel()
{
return $this->minDownloadLevel;
}
 
function addAllowedDownloadException($path, $myrep = 0)
{
if ($path{strlen($path) - 1} != "/")
$path .= "/";
if (empty($myrep))
$this->allowedExceptions[] = $path;
else
{
$repo =& $this->findRepository($myrep);
$repo->addAllowedDownloadException($path);
}
}
 
function addDisallowedDownloadException($path, $myrep = 0)
{
if ($path{strlen($path) - 1} != "/")
$path .= "/";
if (empty($myrep))
$this->disallowedExceptions[] = $path;
else
{
$repo =& $this->findRepository($myrep);
$repo->addDisallowedDownloadException($path);
}
}
function findException($path, $exceptions)
{
foreach ($exceptions As $key => $exc)
{
if (strncmp($exc, $path, strlen($exc)) == 0)
return true;
}
return false;
}
// }}}
 
// {{{ getURL
//
// Get the URL to a path name based on the current config
function getURL($rep, $path, $op)
{
$base = $_SERVER["SCRIPT_NAME"];
if ($this->multiViews)
{
// Remove the .php
if (eregi(".php$", $base))
{
// Remove the .php
$base = substr($base, 0, -4);
}
if ($path && $path{0} != "/") $path = "/".$path;
$url = $base;
if (is_object($rep))
{
$url .= "/".$rep->getDisplayName().str_replace('%2F', '/', urlencode($path));
if ($op != "dir" && $op != "file")
$url .= "?op=$op&amp;";
else
$url .= "?";
}
return $url;
}
else
{
switch ($op)
{
case "dir":
$fname = "listing.php";
break;
case "file":
$fname = "filedetails.php";
break;
 
case "log":
$fname = "log.php";
break;
 
case "diff":
$fname = "diff.php";
break;
 
case "blame":
$fname = "blame.php";
break;
 
case "form":
$fname = "form.php";
break;
 
case "rss":
$fname = "rss.php";
break;
 
case "dl":
$fname = "dl.php";
break;
 
case "comp":
$fname = "comp.php";
break;
}
 
if ($rep == -1)
return $fname."?path=".urlencode($path)."&amp;";
else
return $fname."?repname=".urlencode($rep->getDisplayName())."&amp;path=".urlencode($path)."&amp;";
}
}
 
// }}}
 
// {{{ Paths and Commands
 
// setPath
//
// Set the location of the given path
function setPath(&$var, $path, $name, $params = "")
{
$lastchar = substr($path, -1, 1);
$isDir = ($lastchar == DIRECTORY_SEPARATOR ||
$lastchar == "/" ||
$lastchar == "\\");
if (!$isDir)
{
$path .= DIRECTORY_SEPARATOR;
}
 
// On a windows machine we need to put spaces around the entire command
// to allow for spaces in the path
if ($this->serverIsWindows)
$var = "\"$path$name\"";
else
$var = "$path$name";
$var .= " ".$params;
}
 
// setSVNCommandPath
//
// Define the location of the svn and svnlook commands
function setSVNCommandPath($path)
{
$this->setPath($this->svn, $path, "svn", "--non-interactive --config-dir /tmp");
$this->setPath($this->svn_noparams, $path, "svn", " --config-dir /tmp");
$this->setPath($this->svnlook, $path, "svnlook");
}
function getSvnCommand()
{
return $this->svn;
}
 
function getCleanSvnCommand()
{
return $this->svn_noparams;
}
 
function getSvnlookCommand()
{
return $this->svnlook;
}
// setDiffPath
//
// Define the location of the diff command
function setDiffPath($path)
{
$this->setPath($this->diff, $path, "diff");
}
 
function getDiffCommand()
{
return $this->diff;
}
 
// setEnscriptPath
//
// Define the location of the enscript command
function setEnscriptPath($path)
{
$this->setPath($this->enscript, $path, "enscript");
}
 
function getEnscriptCommand()
{
return $this->enscript;
}
 
// setSedPath
//
// Define the location of the sed command
function setSedPath($path)
{
$this->setPath($this->sed, $path, "sed");
}
function getSedCommand()
{
return $this->sed;
}
 
// setTarPath
//
// Define the location of the tar command
function setTarPath($path)
{
$this->setPath($this->tar, $path, "tar");
}
function getTarCommand()
{
return $this->tar;
}
 
// setGzipPath
//
// Define the location of the GZip command
function setGzipPath($path)
{
$this->setPath($this->gzip, $path, "gzip");
}
function getGzipCommand()
{
return $this->gzip;
}
 
// Templates
function setTemplatePath($path, $myrep = 0)
{
if (empty($myrep))
{
$lastchar = substr($path, -1, 1);
if (!($lastchar == DIRECTORY_SEPARATOR ||
$lastchar == '/' ||
$lastchar == '\\'))
$path .= DIRECTORY_SEPARATOR;
 
$this->templatePath = $path;
}
else
{
$repo =& $this->findRepository($myrep);
$repo->setTemplatePath($path);
}
}
 
function getTemplatePath()
{
return $this->templatePath;
}
 
// PHP Compat file (from PEAR)
 
function setPHPCompatPath($path)
{
$this->setPath($this->phpCompatPath, $path, 'Compat.php');
}
 
function getPHPCompatFile()
{
return trim($this->phpCompatPath);
}
 
// }}}
 
// {{{ parentPath
//
// Automatically set up the repositories based on a parent path
function parentPath($path, $group = NULL)
{
if ($handle = @opendir($path))
{
// For each file...
while (false !== ($file = readdir($handle)))
{
// That's also a non hidden directory
if (is_dir($path.DIRECTORY_SEPARATOR.$file) && $file{0} != ".")
{
// And that contains a db directory (in an attempt to not include
// non svn repositories.
if (is_dir($path.DIRECTORY_SEPARATOR.$file.DIRECTORY_SEPARATOR."db"))
{
// We add the repository to the list
$this->addRepository($file, "file:///".$path.DIRECTORY_SEPARATOR.$file, $group);
}
}
}
closedir($handle);
}
 
// Sort the repositories into alphabetical order
if (!empty($this->_repositories))
usort($this->_repositories, "cmpReps");
}
 
// }}}
// {{{ Encoding functions
function setInputEncoding($systemEnc)
{
$this->inputEnc = $systemEnc;
if (!isset($this->contentEnc))
$this->contentEnc = $systemEnc;
}
function getInputEncoding()
{
return $this->inputEnc;
}
 
function setContentEncoding($contentEnc, $myrep = 0)
{
if (empty($myrep))
$this->contentEnc = $contentEnc;
else
{
$repo =& $this->findRepository($myrep);
$repo->setContentEncoding($contentEnc);
}
}
function getContentEncoding()
{
return $this->contentEnc;
}
 
// }}}
 
// {{{ Tab expansion functions
function expandTabsBy($sp, $myrep = 0)
{
if (empty($myrep))
$this->spaces = $sp;
else
{
$repo =& $this->findRepository($myrep);
$repo->expandTabsBy($sp);
}
}
function getExpandTabsBy()
{
return $this->spaces;
}
 
// }}}
 
// {{{ Misc settings
function ignoreSvnMimeTypes()
{
$this->ignoreSvnMimeTypes = true;
}
 
function getIgnoreSvnMimeTypes()
{
return $this->ignoreSvnMimeTypes;
}
 
function ignoreWebSVNContentTypes()
{
$this->ignoreWebSVNContentTypes = true;
}
 
function getIgnoreWebSVNContentTypes()
{
return $this->ignoreWebSVNContentTypes;
}
 
function useBugtraqProperties($myrep = 0)
{
if (empty($myrep))
$this->bugtraq = true;
else
{
$repo =& $this->findRepository($myrep);
$repo->useBugtraqProperties();
}
}
function getBugtraq()
{
return $this->bugtraq;
}
 
function useAuthenticationFile($file, $myrep = 0)
{
if (empty($myrep))
{
if (is_readable($file))
$this->auth = new Authentication($file);
else
{
echo "Unable to read authentication file '$file'";
exit;
}
}
else
{
$repo =& $this->findRepository($myrep);
$repo->useAuthenticationFile($file);
}
}
function &getAuth()
{
return $this->auth;
}
 
function useTreeView()
{
$this->treeView = true;
}
function getUseTreeView()
{
return $this->treeView;
}
 
function useFlatView()
{
$this->treeView = false;
}
 
function useTreeIndex($open)
{
$this->flatIndex = false;
$this->openTree = $open;
}
 
function getUseFlatIndex()
{
return $this->flatIndex;
}
 
function getOpenTree()
{
return $this->openTree;
}
 
// setSubversionMajorVersion
//
// Set subversion major version
function setSubversionMajorVersion($subversionMajorVersion)
{
$this->subversionMajorVersion = $subversionMajorVersion;
}
 
function getSubversionMajorVersion()
{
return $this->subversionMajorVersion;
}
 
// setSubversionMinorVersion
//
// Set subversion minor version
function setSubversionMinorVersion($subversionMinorVersion)
{
$this->subversionMinorVersion = $subversionMinorVersion;
}
function getSubversionMinorVersion()
{
return $this->subversionMinorVersion;
}
 
// }}}
 
// {{{ Sort the repostories
//
// This function sorts the repositories by group name. The contents of the
// group are left in there original order, which will either be sorted if the
// group was added using the parentPath function, or defined for the order in
// which the repositories were included in the user's config file.
//
// Note that as of PHP 4.0.6 the usort command no longer preserves the order
// of items that are considered equal (in our case, part of the same group).
// The mergesort function preserves this order.
function sortByGroup()
{
if (!empty($this->_repositories))
mergesort($this->_repositories, "cmpGroups");
}
 
// }}}
}
?>
/WebSVN/include/php5compat.inc
2,6 → 2,12
 
if (version_compare(phpversion(), '5.0.0', 'lt')) {
 
# XXX: these includes shouldn't be necessary!
require_once 'include/configclass.inc';
$config = new Config;
require_once 'include/config.inc';
require_once($config->getPHPCompatFile());
 
// Configure necessary functions here
$funcs = array(
'stripos',
10,13 → 16,6
 
// End configuration
 
// JB: PHP_Compat expects to be able to find functions by including
// 'PHP/Compat/Functions/functionname.php', but that hardcoded path
// isn't relative to the standard include path '.' (it's instead relative
// to './include'). So rather than hack PHP_Compat to work, just add
// './include' to our include path.
ini_set("include_path", ini_get("include_path").$config->pathSeparator."./include");
 
foreach ($funcs as $fn) {
if (PHP_Compat::loadFunction($fn) != true)
error_log('Could not load function `'.$fn.'\' as required by PHP Compat.');
/WebSVN/include/svnlook.inc
1,769 → 1,770
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// svn-look.inc
//
// Svn bindings
//
// These binding currently use the svn command line to achieve their goal. Once a proper
// SWIG binding has been produced for PHP, there'll be an option to use that instead.
 
require_once("include/utils.inc");
 
// {{{ Classes for retaining log information ---
 
$debugxml = false;
 
Class SVNMod
{
var $action = '';
var $copyfrom = '';
var $copyrev = '';
var $path = '';
}
 
Class SVNLogEntry
{
var $rev = 1;
var $author = '';
var $date = '';
var $committime;
var $age = '';
var $msg = '';
var $path = '';
var $mods;
var $curMod;
}
 
Class SVNLog
{
var $entries; // Array of entries
var $curEntry; // Current entry
var $path = ''; // Temporary variable used to trace path history
// findEntry
//
// Return the entry for a given revision
function findEntry($rev)
{
foreach ($this->entries as $index => $entry)
{
if ($entry->rev == $rev)
return $index;
 
}
}
}
 
// }}}
 
// {{{ XML parsing functions---
 
$curLog = 0;
$curTag = '';
 
// {{{ startElement
 
function startElement($parser, $name, $attrs)
{
global $curLog, $curTag, $debugxml;
 
switch ($name)
{
case "LOGENTRY":
if ($debugxml) print "Creating new log entry\n";
$curLog->curEntry = new SVNLogEntry;
$curLog->curEntry->mods = array();
$curLog->curEntry->path = $curLog->path;
if (sizeof($attrs))
{
while (list($k, $v) = each($attrs))
{
switch ($k)
{
case "REVISION":
if ($debugxml) print "Revision $v\n";
$curLog->curEntry->rev = $v;
break;
}
}
}
break;
case "PATH":
if ($debugxml) print "Creating new path\n";
$curLog->curEntry->curMod = new SVNMod;
if (sizeof($attrs))
{
while (list($k, $v) = each($attrs))
{
switch ($k)
{
case "ACTION":
if ($debugxml) print "Action $v\n";
$curLog->curEntry->curMod->action = $v;
break;
 
case "COPYFROM-PATH":
if ($debugxml) print "Copy from: $v\n";
$curLog->curEntry->curMod->copyfrom = $v;
break;
 
case "COPYFROM-REV":
$curLog->curEntry->curMod->copyrev = $v;
break;
}
}
}
$curTag = $name;
break;
default:
$curTag = $name;
break;
}
}
 
// }}}
 
// {{{ endElement
 
function endElement($parser, $name)
{
global $curLog, $debugxml, $curTag;
 
switch ($name)
{
case "LOGENTRY":
if ($debugxml) print "Ending new log entry\n";
$curLog->entries[] = $curLog->curEntry;
break;
 
case "PATH":
if ($debugxml) print "Ending path\n";
$curLog->curEntry->mods[] = $curLog->curEntry->curMod;
break;
 
case "MSG":
$curLog->curEntry->msg = trim($curLog->curEntry->msg);
if ($debugxml) print "Completed msg = '".$curLog->curEntry->msg."'\n";
break;
}
$curTag = "";
}
 
// }}}
 
// {{{ characterData
 
function characterData($parser, $data)
{
global $curLog, $curTag, $lang, $debugxml;
 
switch ($curTag)
{
case "AUTHOR":
if ($debugxml) print "Author: $data\n";
if (empty($data)) return;
$curLog->curEntry->author .= htmlentities($data, ENT_COMPAT, "UTF-8");
break;
 
case "DATE":
if ($debugxml) print "Date: $data\n";
$data = trim($data);
if (empty($data)) return;
sscanf($data, "%d-%d-%dT%d:%d:%d.", $y, $mo, $d, $h, $m, $s);
$mo = substr("00".$mo, -2);
$d = substr("00".$d, -2);
$h = substr("00".$h, -2);
$m = substr("00".$m, -2);
$s = substr("00".$s, -2);
$curLog->curEntry->date = "$y-$mo-$d $h:$m:$s GMT";
$committime = strtotime($curLog->curEntry->date);
$curLog->curEntry->committime = $committime;
$curtime = time();
// Get the number of seconds since the commit
$agesecs = $curtime - $committime;
if ($agesecs < 0) $agesecs = 0;
$curLog->curEntry->age = datetimeFormatDuration($agesecs, true, true);
break;
 
case "MSG":
if ($debugxml) print "Msg: '$data'\n";
$curLog->curEntry->msg .= htmlentities($data, ENT_COMPAT, "UTF-8");
break;
case "PATH":
if ($debugxml) print "Path name: '$data'\n";
$data = trim($data);
if (empty($data)) return;
 
$curLog->curEntry->curMod->path .= $data;
// The XML returned when a file is renamed/branched in inconsistant. In the case
// of a branch, the path information doesn't include the leafname. In the case of
// a rename, it does. Ludicrous.
if (!empty($curLog->path))
{
$pos = strrpos($curLog->path, "/");
$curpath = substr($curLog->path, 0, $pos);
$leafname = substr($curLog->path, $pos + 1);
}
else
{
$curpath = "";
$leafname = "";
}
if ($curLog->curEntry->curMod->action == "A")
{
if ($debugxml) print "Examining added path '".$curLog->curEntry->curMod->copyfrom."' - Current path = '$curpath', leafname = '$leafname'\n";
if ($data == $curLog->path) // For directories and renames
{
if ($debugxml) print "New path for comparison: '".$curLog->curEntry->curMod->copyfrom."'\n";
$curLog->path = $curLog->curEntry->curMod->copyfrom;
}
else if ($data == $curpath || $data == $curpath."/") // Logs of files that have moved due to branching
{
if ($debugxml) print "New path for comparison: '".$curLog->curEntry->curMod->copyfrom."/$leafname'\n";
$curLog->path = $curLog->curEntry->curMod->copyfrom."/$leafname";
}
}
break;
}
}
 
// }}}
 
// }}}
 
// Function returns true if the give entry in a directory tree is at the top level
 
function _topLevel($entry)
{
// To be at top level, there must be one space before the entry
return (strlen($entry) > 1 && $entry{0} == " " && $entry{1} != " ");
}
 
// Function to sort two given directory entries. Directories go at the top
 
function _dirSort($e1, $e2)
{
$isDir1 = $e1{strlen($e1) - 1} == "/";
$isDir2 = $e2{strlen($e2) - 1} == "/";
if ($isDir1 && !$isDir2) return -1;
if ($isDir2 && !$isDir1) return 1;
return strnatcasecmp($e1, $e2);
}
 
// Return the revision string to pass to a command
 
function _revStr($rev)
{
if ($rev > 0)
return "-r $rev";
else
return "";
}
 
// {{{ encodePath
 
// Function to encode a URL without encoding the /'s
 
function encodePath($uri)
{
global $config;
 
$uri = str_replace(DIRECTORY_SEPARATOR, "/", $uri);
 
$parts = explode('/', $uri);
for ($i = 0; $i < count($parts); $i++)
{
if ( function_exists("mb_detect_encoding") && function_exists("mb_convert_encoding"))
{
$parts[$i] = mb_convert_encoding($parts[$i], "UTF-8", mb_detect_encoding($parts[$i]));
}
$parts[$i] = rawurlencode($parts[$i]);
}
$uri = implode('/', $parts);
// Quick hack. Subversion seems to have a bug surrounding the use of %3A instead of :
$uri = str_replace("%3A" ,":", $uri);
// Correct for Window share names
if ( $config->serverIsWindows==true )
{
if ( substr($uri, 0,2)=="//" )
$uri="\\".substr($uri, 2, strlen($uri));
}
 
return $uri;
}
 
// }}}
 
// The SVNRepository Class
 
Class SVNRepository
{
var $repConfig;
function SVNRepository($repConfig)
{
$this->repConfig = $repConfig;
}
// {{{ dirContents
 
function dirContents($path, $rev = 0)
{
global $config, $locwebsvnreal;
$revstr = _revStr($rev);
$tree = array();
if ($rev == 0)
{
$headlog = $this->getLog("/", "", "", true, 1);
$rev = $headlog->entries[0]->rev;
}
$path = encodepath($this->repConfig->path.$path);
$output = runCommand($config->svn." list $revstr ".$this->repConfig->svnParams().quote($path), true);
foreach ($output as $entry)
{
if ($entry != "")
$tree[] = $entry;
}
// Sort the entries into alphabetical order with the directories at the top of the list
usort($tree, "_dirSort");
return $tree;
}
 
// }}}
// {{{ highlightLine
//
// Distill line-spanning syntax highlighting so that each line can stand alone
// (when invoking on the first line, $attributes should be an empty array)
// Invoked to make sure all open syntax highlighting tags (<font>, <i>, <b>, etc.)
// are closed at the end of each line and re-opened on the next line
function highlightLine($line, &$attributes)
{
$hline = "";
// Apply any highlighting in effect from the previous line
foreach($attributes as $attr)
{
$hline.=$attr['text'];
}
 
// append the new line
$hline.=$line;
 
// update attributes
for ($line = strstr($line, "<"); $line; $line = strstr(substr($line,1), "<"))
{
// if this closes a tag, remove most recent corresponding opener
if (substr($line,1,1) == "/")
{
$tagNamLen = strcspn($line, "> \t", 2);
$tagNam = substr($line,2,$tagNamLen);
foreach(array_reverse(array_keys($attributes)) as $k)
{
if ($attributes[$k]['tag'] == $tagNam)
{
unset($attributes[$k]);
break;
}
}
}
else
// if this opens a tag, add it to the list
{
$tagNamLen = strcspn($line, "> \t", 1);
$tagNam = substr($line,1,$tagNamLen);
$tagLen = strcspn($line, ">") + 1;
$attributes[] = array('tag' => $tagNam, 'text' => substr($line,0,$tagLen));
}
}
 
// close any still-open tags
foreach(array_reverse($attributes) as $attr)
{
$hline.="</".$attr['tag'].">";
}
 
return($hline);
}
 
// }}}
 
// {{{ getFileContents
//
// Dump the content of a file to the given filename
function getFileContents($path, $filename, $rev = 0, $pipe = "", $perLineHighlighting = false)
{
global $config, $extEnscript;
$revstr = _revStr($rev);
// If there's no filename, we'll just deliver the contents as it is to the user
if ($filename == "")
{
$path = encodepath($this->repConfig->path.$path);
passthru(quoteCommand($config->svn." cat $revstr ".$this->repConfig->svnParams().quote($path)." $pipe", false));
return;
}
// Get the file contents info
$ext = strrchr($path, ".");
$l = @$extEnscript[$ext];
if ($l == "php")
{
// Output the file to the filename
$path = encodepath($this->repConfig->path.$path);
$cmd = quoteCommand($config->svn." cat $revstr ".$this->repConfig->svnParams().quote($path)." > $filename", false);
@exec($cmd);
// Get the file as a string (memory hogging, but we have no other options)
$content = highlight_file($filename, true);
// Destroy the previous version, and replace it with the highlighted version
$f = fopen($filename, "w");
if ($f)
{
// The highlight file function doesn't deal with line endings very nicely at all. We'll have to do it
// by hand.
// Remove the first line generated by highlight()
$pos = strpos($content, "\n");
$content = substr($content, $pos+1);
$content = explode("<br />", $content);
if ($perLineHighlighting)
{
// If we need each line independently highlighted (e.g. for diff or blame)
// hen we'll need to filter the output of the highlighter
// to make sure tags like <font>, <i> or <b> don't span lines
// $attributes is used to remember what highlighting attributes
// are in effect from one line to the next
$attributes = array(); // start with no attributes in effect
foreach ($content as $line)
{
fputs($f, $this->highlightLine(rtrim($line),$attributes)."\n");
}
}
else
{
foreach ($content as $line)
{
fputs($f, rtrim($line)."\n");
}
}
 
fclose($f);
}
}
else
{
if ($config->useEnscript)
{
// Get the files, feed it through enscript, then remove the enscript headers using sed
//
// Note that the sec command returns only the part of the file between <PRE> and </PRE>.
// It's complicated because it's designed not to return those lines themselves.
$path = encodepath($this->repConfig->path.$path);
$cmd = quoteCommand($config->svn." cat $revstr ".$this->repConfig->svnParams().quote($path)." | ".
$config->enscript." --language=html ".
($l ? "--color --pretty-print=$l" : "")." -o - | ".
$config->sed." -n ".$config->quote."1,/^<PRE.$/!{/^<\\/PRE.$/,/^<PRE.$/!p;}".$config->quote." > $filename", false);
@exec($cmd);
}
else
{
$path = encodepath(str_replace(DIRECTORY_SEPARATOR, "/", $this->repConfig->path.$path));
$cmd = quoteCommand($config->svn." cat $revstr ".$this->repConfig->svnParams().quote($path)." > $filename", false);
@exec($cmd);
}
}
}
 
// }}}
 
// {{{ listFileContents
//
// Print the contents of a file without filling up Apache's memory
function listFileContents($path, $rev = 0)
{
global $config, $extEnscript;
$revstr = _revStr($rev);
$pre = false;
// Get the file contents info
$ext = strrchr($path, ".");
$l = @$extEnscript[$ext];
// Deal with php highlighting internally
if ($l == "php")
{
$tmp = tempnam("temp", "wsvn");
// Output the file to a temporary file
$path = encodepath($this->repConfig->path.$path);
$cmd = quoteCommand($config->svn." cat $revstr ".$this->repConfig->svnParams().quote($path)." > $tmp", false);
@exec($cmd);
highlight_file($tmp);
unlink($tmp);
}
else
{
if ($config->useEnscript)
{
$path = encodepath($this->repConfig->path.$path);
$cmd = quoteCommand($config->svn." cat $revstr ".$this->repConfig->svnParams().quote($path)." | ".
$config->enscript." --language=html ".
($l ? "--color --pretty-print=$l" : "")." -o - | ".
$config->sed." -n ".$config->quote."/^<PRE.$/,/^<\\/PRE.$/p".$config->quote." 2>&1", false);
if (!($result = popen($cmd, "r")))
return;
}
else
{
$path = encodepath($this->repConfig->path.$path);
$cmd = quoteCommand($config->svn." cat $revstr ".$this->repConfig->svnParams().quote($path)." 2>&1", false);
if (!($result = popen($cmd, "r")))
return;
$pre = true;
}
if ($pre)
echo "<PRE>";
while (!feof($result))
{
$line = fgets($result, 1024);
if ($pre) $line = replaceEntities($line, $this->repConfig);
print hardspace($line);
}
if ($pre)
echo "</PRE>";
pclose($result);
}
}
 
// }}}
 
// {{{ getBlameDetails
//
// Dump the blame content of a file to the given filename
function getBlameDetails($path, $filename, $rev = 0)
{
global $config;
$revstr = _revStr($rev);
$path = encodepath($this->repConfig->path.$path);
$cmd = quoteCommand($config->svn." blame $revstr ".$this->repConfig->svnParams().quote($path)." > $filename", false);
@exec($cmd);
}
 
// }}}
 
// {{{ getProperty
 
function getProperty($path, $property, $rev = 0)
{
global $config;
$revstr = _revStr($rev);
$path = encodepath($this->repConfig->path.$path);
$ret = runCommand($config->svn." propget $property $revstr ".$this->repConfig->svnParams().quote($path), true);
// Remove the surplus newline
if (count($ret))
unset($ret[count($ret) - 1]);
return implode("\n", $ret);
}
 
// }}}
 
// {{{ exportDirectory
//
// Exports the directory to the given location
function exportDirectory($path, $filename, $rev = 0)
{
global $config;
$revstr = _revStr($rev);
$path = encodepath($this->repConfig->path.$path);
$cmd = quoteCommand($config->svn." export $revstr ".$this->repConfig->svnParams().quote($path)." ".quote($filename), false);
 
@exec($cmd);
}
 
// }}}
 
// {{{ getLog
function getLog($path, $brev = "", $erev = 1, $quiet = false, $limit = 2)
{
global $config, $curLog, $vars, $lang;
$xml_parser = xml_parser_create("UTF-8");
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, true);
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");
 
// Since directories returned by svn log don't have trailing slashes (:-(), we need to remove
// the trailing slash from the path for comparison purposes
if ($path{strlen($path) - 1} == "/" && $path != "/")
$path = substr($path, 0, -1);
$curLog = new SVNLog;
$curLog->entries = array();
$curLog->path = $path;
$revStr = "";
if ($brev && $erev)
$revStr = "-r$brev:$erev";
else if ($brev)
$revStr = "-r$brev:1";
 
if (($config->subversionMajorVersion > 1 || $config->subversionMinorVersion >=2) && $limit != 0)
$revStr .= " --limit $limit";
// Get the log info
$path = encodepath($this->repConfig->path.$path);
$info = "--verbose";
if ($quiet)
$info = "--quiet";
$cmd = quoteCommand($config->svn." log --xml $info $revStr ".$this->repConfig->svnParams().quote($path), false);
 
if ($handle = popen($cmd, "r"))
{
$firstline = true;
while (!feof($handle))
{
$line = fgets($handle);
if (!xml_parse($xml_parser, $line, feof($handle)))
{
if (xml_get_error_code($xml_parser) != 5)
{
die(sprintf("XML error: %s (%d) at line %d column %d byte %d<br>cmd: %s<nr>",
xml_error_string(xml_get_error_code($xml_parser)),
xml_get_error_code($xml_parser),
xml_get_current_line_number($xml_parser),
xml_get_current_column_number($xml_parser),
xml_get_current_byte_index($xml_parser),
$cmd));
}
else
{
$vars["error"] = $lang["UNKNOWNREVISION"];
return 0;
}
}
}
pclose($handle);
}
 
xml_parser_free($xml_parser);
return $curLog;
}
 
// }}}
 
}
 
// {{{ initSvnVersion
 
function initSvnVersion(&$major, &$minor)
{
global $config;
$ret = runCommand($config->svn_noparams." --version", false);
 
if (preg_match("~([0-9]?)\.([0-9]?)\.([0-9]?)~",$ret[0],$matches))
{
$major = $matches[1];
$minor = $matches[2];
}
$config->setSubversionMajorVersion($major);
$config->setSubversionMinorVersion($minor);
}
 
// }}}
 
?>
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// svn-look.inc
//
// Svn bindings
//
// These binding currently use the svn command line to achieve their goal. Once a proper
// SWIG binding has been produced for PHP, there'll be an option to use that instead.
 
require_once("include/utils.inc");
 
// {{{ Classes for retaining log information ---
 
$debugxml = false;
 
Class SVNMod
{
var $action = '';
var $copyfrom = '';
var $copyrev = '';
var $path = '';
}
 
Class SVNLogEntry
{
var $rev = 1;
var $author = '';
var $date = '';
var $committime;
var $age = '';
var $msg = '';
var $path = '';
var $mods;
var $curMod;
}
 
Class SVNLog
{
var $entries; // Array of entries
var $curEntry; // Current entry
var $path = ''; // Temporary variable used to trace path history
// findEntry
//
// Return the entry for a given revision
function findEntry($rev)
{
foreach ($this->entries as $index => $entry)
{
if ($entry->rev == $rev)
return $index;
 
}
}
}
 
// }}}
 
// {{{ XML parsing functions---
 
$curLog = 0;
$curTag = '';
 
// {{{ startElement
 
function startElement($parser, $name, $attrs)
{
global $curLog, $curTag, $debugxml;
 
switch ($name)
{
case "LOGENTRY":
if ($debugxml) print "Creating new log entry\n";
$curLog->curEntry = new SVNLogEntry;
$curLog->curEntry->mods = array();
$curLog->curEntry->path = $curLog->path;
if (sizeof($attrs))
{
while (list($k, $v) = each($attrs))
{
switch ($k)
{
case "REVISION":
if ($debugxml) print "Revision $v\n";
$curLog->curEntry->rev = $v;
break;
}
}
}
break;
case "PATH":
if ($debugxml) print "Creating new path\n";
$curLog->curEntry->curMod = new SVNMod;
if (sizeof($attrs))
{
while (list($k, $v) = each($attrs))
{
switch ($k)
{
case "ACTION":
if ($debugxml) print "Action $v\n";
$curLog->curEntry->curMod->action = $v;
break;
 
case "COPYFROM-PATH":
if ($debugxml) print "Copy from: $v\n";
$curLog->curEntry->curMod->copyfrom = $v;
break;
 
case "COPYFROM-REV":
$curLog->curEntry->curMod->copyrev = $v;
break;
}
}
}
$curTag = $name;
break;
default:
$curTag = $name;
break;
}
}
 
// }}}
 
// {{{ endElement
 
function endElement($parser, $name)
{
global $curLog, $debugxml, $curTag;
 
switch ($name)
{
case "LOGENTRY":
if ($debugxml) print "Ending new log entry\n";
$curLog->entries[] = $curLog->curEntry;
break;
 
case "PATH":
if ($debugxml) print "Ending path\n";
$curLog->curEntry->mods[] = $curLog->curEntry->curMod;
break;
 
case "MSG":
$curLog->curEntry->msg = trim($curLog->curEntry->msg);
if ($debugxml) print "Completed msg = '".$curLog->curEntry->msg."'\n";
break;
}
$curTag = "";
}
 
// }}}
 
// {{{ characterData
 
function characterData($parser, $data)
{
global $curLog, $curTag, $lang, $debugxml;
 
switch ($curTag)
{
case "AUTHOR":
if ($debugxml) print "Author: $data\n";
if (empty($data)) return;
$curLog->curEntry->author .= htmlentities($data, ENT_COMPAT, "UTF-8");
break;
 
case "DATE":
if ($debugxml) print "Date: $data\n";
$data = trim($data);
if (empty($data)) return;
sscanf($data, "%d-%d-%dT%d:%d:%d.", $y, $mo, $d, $h, $m, $s);
$mo = substr("00".$mo, -2);
$d = substr("00".$d, -2);
$h = substr("00".$h, -2);
$m = substr("00".$m, -2);
$s = substr("00".$s, -2);
$curLog->curEntry->date = "$y-$mo-$d $h:$m:$s GMT";
$committime = strtotime($curLog->curEntry->date);
$curLog->curEntry->committime = $committime;
$curtime = time();
// Get the number of seconds since the commit
$agesecs = $curtime - $committime;
if ($agesecs < 0) $agesecs = 0;
$curLog->curEntry->age = datetimeFormatDuration($agesecs, true, true);
break;
 
case "MSG":
if ($debugxml) print "Msg: '$data'\n";
$curLog->curEntry->msg .= htmlentities($data, ENT_COMPAT, "UTF-8");
break;
case "PATH":
if ($debugxml) print "Path name: '$data'\n";
$data = trim($data);
if (empty($data)) return;
 
$curLog->curEntry->curMod->path .= $data;
// The XML returned when a file is renamed/branched in inconsistant. In the case
// of a branch, the path information doesn't include the leafname. In the case of
// a rename, it does. Ludicrous.
if (!empty($curLog->path))
{
$pos = strrpos($curLog->path, "/");
$curpath = substr($curLog->path, 0, $pos);
$leafname = substr($curLog->path, $pos + 1);
}
else
{
$curpath = "";
$leafname = "";
}
if ($curLog->curEntry->curMod->action == "A")
{
if ($debugxml) print "Examining added path '".$curLog->curEntry->curMod->copyfrom."' - Current path = '$curpath', leafname = '$leafname'\n";
if ($data == $curLog->path) // For directories and renames
{
if ($debugxml) print "New path for comparison: '".$curLog->curEntry->curMod->copyfrom."'\n";
$curLog->path = $curLog->curEntry->curMod->copyfrom;
}
else if ($data == $curpath || $data == $curpath."/") // Logs of files that have moved due to branching
{
if ($debugxml) print "New path for comparison: '".$curLog->curEntry->curMod->copyfrom."/$leafname'\n";
$curLog->path = $curLog->curEntry->curMod->copyfrom."/$leafname";
}
}
break;
}
}
 
// }}}
 
// }}}
 
// Function returns true if the give entry in a directory tree is at the top level
 
function _topLevel($entry)
{
// To be at top level, there must be one space before the entry
return (strlen($entry) > 1 && $entry{0} == " " && $entry{1} != " ");
}
 
// Function to sort two given directory entries. Directories go at the top
 
function _dirSort($e1, $e2)
{
$isDir1 = $e1{strlen($e1) - 1} == "/";
$isDir2 = $e2{strlen($e2) - 1} == "/";
if ($isDir1 && !$isDir2) return -1;
if ($isDir2 && !$isDir1) return 1;
return strnatcasecmp($e1, $e2);
}
 
// Return the revision string to pass to a command
 
function _revStr($rev)
{
if ($rev > 0)
return "-r $rev";
else
return "";
}
 
// {{{ encodePath
 
// Function to encode a URL without encoding the /'s
 
function encodePath($uri)
{
global $config;
 
$uri = str_replace(DIRECTORY_SEPARATOR, "/", $uri);
 
$parts = explode('/', $uri);
for ($i = 0; $i < count($parts); $i++)
+
+ if ( function_exists("mb_detect_encoding") && function_exists("mb_convert_encoding"))
+ {
+ $parts[$i] = mb_convert_encoding($parts[$i], "UTF-8", mb_detect_encoding($parts[$i]));
+ }
+
+ $parts[$i] = rawurlencode($parts[$i]);
+ }
+
+ $uri = implode('/', $parts);
+
+ // Quick hack. Subversion seems to have a bug surrounding the use of %3A instead of :
+
+ $uri = str_replace("%3A" ,":", $uri);
+
+ // Correct for Window share names
+ if ( $config->serverIsWindows==true )
+ {
+ if ( substr($uri, 0,2)=="//" )
+ $uri="\\".substr($uri, 2, strlen($uri));
+ }
+
+ return $uri;
+}
+
+// }}}
+
+// The SVNRepository Class
+
+Class SVNRepository
+{
+ var $repConfig;
+
+ function SVNRepository($repConfig)
+ {
+ $this->repConfig = $repConfig;
+ }
+
+ // {{{ dirContents
+
+ function dirContents($path, $rev = 0)
+ {
+ global $config, $locwebsvnreal;
+
+ $revstr = _revStr($rev);
+
+ $tree = array();
+
+ if ($rev == 0)
+ {
+ $headlog = $this->getLog("/", "", "", true, 1);
+ $rev = $headlog->entries[0]->rev;
+ }
+
+ $path = encodepath($this->repConfig->path.$path);
+ $output = runCommand($config->svn." list $revstr ".$this->repConfig->svnParams().quote($path), true);
+
+ foreach ($output as $entry)
+ {
+ if ($entry != "")
+ $tree[] = $entry;
+ }
+
+ // Sort the entries into alphabetical order with the directories at the top of the list
+ usort($tree, "_dirSort");
+
+ return $tree;
+ }
+
+ // }}}
+
+ // {{{ highlightLine
+ //
+ // Distill line-spanning syntax highlighting so that each line can stand alone
+ // (when invoking on the first line, $attributes should be an empty array)
+ // Invoked to make sure all open syntax highlighting tags (<font>, <i>, <b>, etc.)
+ // are closed at the end of each line and re-opened on the next line
+
+ function highlightLine($line, &$attributes)
+ {
+ $hline = "";
+
+ // Apply any highlighting in effect from the previous line
+ foreach($attributes as $attr)
+ {
+ $hline.=$attr['text'];
+ }
+
+ // append the new line
+ $hline.=$line;
+
+ // update attributes
+ for ($line = strstr($line, "<"); $line; $line = strstr(substr($line,1), "<"))
+ {
+ // if this closes a tag, remove most recent corresponding opener
+ if (substr($line,1,1) == "/")
+ {
+ $tagNamLen = strcspn($line, "> \t", 2);
+ $tagNam = substr($line,2,$tagNamLen);
+ foreach(array_reverse(array_keys($attributes)) as $k)
+ {
+ if ($attributes[$k]['tag'] == $tagNam)
+ {
+ unset($attributes[$k]);
+ break;
+ }
+ }
+ }
+ else
+ // if this opens a tag, add it to the list
+ {
+ $tagNamLen = strcspn($line, "> \t", 1);
+ $tagNam = substr($line,1,$tagNamLen);
+ $tagLen = strcspn($line, ">") + 1;
+ $attributes[] = array('tag' => $tagNam, 'text' => substr($line,0,$tagLen));
+ }
+ }
+
+ // close any still-open tags
+ foreach(array_reverse($attributes) as $attr)
+ {
+ $hline.="</".$attr['tag'].">";
+ }
+
+ return($hline);
+ }
+
+ // }}}
+
+ // {{{ getFileContents
+ //
+ // Dump the content of a file to the given filename
+
+ function getFileContents($path, $filename, $rev = 0, $pipe = "", $perLineHighlighting = false)
+ {
+ global $config, $extEnscript;
+
+ $revstr = _revStr($rev);
+
+ // If there's no filename, we'll just deliver the contents as it is to the user
+ if ($filename == "")
+ {
+ $path = encodepath($this->repConfig->path.$path);
+ passthru(quoteCommand($config->svn." cat $revstr ".$this->repConfig->svnParams().quote($path)." $pipe", false));
+ return;
+ }
+
+ // Get the file contents info
+
+ $ext = strrchr($path, ".");
+ $l = @$extEnscript[$ext];
+
+ if ($l == "php")
+ {
+ // Output the file to the filename
+ $path = encodepath($this->repConfig->path.$path);
+ $cmd = quoteCommand($config->svn." cat $revstr ".$this->repConfig->svnParams().quote($path)." > $filename", false);
+ @exec($cmd);
+
+ // Get the file as a string (memory hogging, but we have no other options)
+ $content = highlight_file($filename, true);
+
+ // Destroy the previous version, and replace it with the highlighted version
+ $f = fopen($filename, "w");
+ if ($f)
+ {
+ // The highlight file function doesn't deal with line endings very nicely at all. We'll have to do it
+ // by hand.
+
+ // Remove the first line generated by highlight()
+ $pos = strpos($content, "\n");
+ $content = substr($content, $pos+1);
+
+ $content = explode("<br />", $content);
+
+ if ($perLineHighlighting)
+ {
+ // If we need each line independently highlighted (e.g. for diff or blame)
+ // hen we'll need to filter the output of the highlighter
+ // to make sure tags like <font>, <i> or <b> don't span lines
+
+ // $attributes is used to remember what highlighting attributes
+ // are in effect from one line to the next
+ $attributes = array(); // start with no attributes in effect
+
+ foreach ($content as $line)
+ {
+ fputs($f, $this->highlightLine(rtrim($line),$attributes)."\n");
+ }
+ }
+ else
+ {
+ foreach ($content as $line)
+ {
+ fputs($f, rtrim($line)."\n");
+ }
+ }
+
+ fclose($f);
+ }
+ }
+ else
+ {
+ if ($config->useEnscript)
+ {
+ // Get the files, feed it through enscript, then remove the enscript headers using sed
+ //
+ // Note that the sec command returns only the part of the file between <PRE> and </PRE>.
+ // It's complicated because it's designed not to return those lines themselves.
+
+ $path = encodepath($this->repConfig->path.$path);
+ $cmd = quoteCommand($config->svn." cat $revstr ".$this->repConfig->svnParams().quote($path)." | ".
+ $config->enscript." --language=html ".
+ ($l ? "--color --pretty-print=$l" : "")." -o - | ".
+ $config->sed." -n ".$config->quote."1,/^<PRE.$/!{/^<\\/PRE.$/,/^<PRE.$/!p;}".$config->quote." > $filename", false);
+ @exec($cmd);
+ }
+ else
+ {
+ $path = encodepath(str_replace(DIRECTORY_SEPARATOR, "/", $this->repConfig->path.$path));
+ $cmd = quoteCommand($config->svn." cat $revstr ".$this->repConfig->svnParams().quote($path)." > $filename", false);
+ @exec($cmd);
+ }
+ }
+ }
+
+ // }}}
+
+ // {{{ listFileContents
+ //
+ // Print the contents of a file without filling up Apache's memory
+
+ function listFileContents($path, $rev = 0)
+ {
+ global $config, $extEnscript;
+
+ $revstr = _revStr($rev);
+ $pre = false;
+
+ // Get the file contents info
+
+ $ext = strrchr($path, ".");
+ $l = @$extEnscript[$ext];
+
+ // Deal with php highlighting internally
+ if ($l == "php")
+ {
+ $tmp = tempnam("temp", "wsvn");
+
+ // Output the file to a temporary file
+ $path = encodepath($this->repConfig->path.$path);
+ $cmd = quoteCommand($config->svn." cat $revstr ".$this->repConfig->svnParams().quote($path)." > $tmp", false);
+ @exec($cmd);
+ highlight_file($tmp);
+ unlink($tmp);
+ }
+ else
+ {
+ if ($config->useEnscript)
+ {
+ $path = encodepath($this->repConfig->path.$path);
+ $cmd = quoteCommand($config->svn." cat $revstr ".$this->repConfig->svnParams().quote($path)." | ".
+ $config->enscript." --language=html ".
+ ($l ? "--color --pretty-print=$l" : "")." -o - | ".
+ $config->sed." -n ".$config->quote."/^<PRE.$/,/^<\\/PRE.$/p".$config->quote." 2>&1", false);
+
+ if (!($result = popen($cmd, "r")))
+ return;
+ }
+ else
+ {
+ $path = encodepath($this->repConfig->path.$path);
+ $cmd = quoteCommand($config->svn." cat $revstr ".$this->repConfig->svnParams().quote($path)." 2>&1", false);
+
+ if (!($result = popen($cmd, "r")))
+ return;
+
+ $pre = true;
+ }
+
+ if ($pre)
+ echo "<PRE>";
+
+ while (!feof($result))
+ {
+ $line = fgets($result, 1024);
+ if ($pre) $line = replaceEntities($line, $this->repConfig);
+
+ print hardspace($line);
+ }
+
+ if ($pre)
+ echo "</PRE>";
+
+ pclose($result);
+ }
+ }
+
+ // }}}
+
+ // {{{ getBlameDetails
+ //
+ // Dump the blame content of a file to the given filename
+
+ function getBlameDetails($path, $filename, $rev = 0)
+ {
+ global $config;
+
+ $revstr = _revStr($rev);
+
+ $path = encodepath($this->repConfig->path.$path);
+ $cmd = quoteCommand($config->svn." blame $revstr ".$this->repConfig->svnParams().quote($path)." > $filename", false);
+
+ @exec($cmd);
+ }
+
+ // }}}
+
+ // {{{ getProperty
+
+ function getProperty($path, $property, $rev = 0)
+ {
+ global $config;
+
+ $revstr = _revStr($rev);
+
+ $path = encodepath($this->repConfig->path.$path);
+ $ret = runCommand($config->svn." propget $property $revstr ".$this->repConfig->svnParams().quote($path), true);
+
+ // Remove the surplus newline
+ if (count($ret))
+ unset($ret[count($ret) - 1]);
+
+ return implode("\n", $ret);
+ }
+
+ // }}}
+
+ // {{{ exportDirectory
+ //
+ // Exports the directory to the given location
+
+ function exportDirectory($path, $filename, $rev = 0)
+ {
+ global $config;
+
+ $revstr = _revStr($rev);
+
+ $path = encodepath($this->repConfig->path.$path);
+ $cmd = quoteCommand($config->svn." export $revstr ".$this->repConfig->svnParams().quote($path)." ".quote($filename), false);
+
+ @exec($cmd);
+ }
+
+ // }}}
+
+ // {{{ getLog
+
+ function getLog($path, $brev = "", $erev = 1, $quiet = false, $limit = 2)
+ {
+ global $config, $curLog, $vars, $lang;
+
+ $xml_parser = xml_parser_create("UTF-8");
+ xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, true);
+ xml_set_element_handler($xml_parser, "startElement", "endElement");
+ xml_set_character_data_handler($xml_parser, "characterData");
+
+ // Since directories returned by svn log don't have trailing slashes (:-(), we need to remove
+ // the trailing slash from the path for comparison purposes
+
+ if ($path{strlen($path) - 1} == "/" && $path != "/")
+ $path = substr($path, 0, -1);
+
+ $curLog = new SVNLog;
+ $curLog->entries = array();
+ $curLog->path = $path;
+
+ $revStr = "";
+
+ if ($brev && $erev)
+ $revStr = "-r$brev:$erev";
+ else if ($brev)
+ $revStr = "-r$brev:1";
+
+ if (($config->subversionMajorVersion > 1 || $config->subversionMinorVersion >=2) && $limit != 0)
+ $revStr .= " --limit $limit";
+
+ // Get the log info
+ $path = encodepath($this->repConfig->path.$path);
+ $info = "--verbose";
+ if ($quiet)
+ $info = "--quiet";
+
+ $cmd = quoteCommand($config->svn." log --xml $info $revStr ".$this->repConfig->svnParams().quote($path), false);
+
+ if ($handle = popen($cmd, "r"))
+ {
+ $firstline = true;
+ while (!feof($handle))
+ {
+ $line = fgets($handle);
+ if (!xml_parse($xml_parser, $line, feof($handle)))
+ {
+ if (xml_get_error_code($xml_parser) != 5)
+ {
+ die(sprintf("XML error: %s (%d) at line %d column %d byte %d<br>cmd: %s<nr>",
+ xml_error_string(xml_get_error_code($xml_parser)),
+ xml_get_error_code($xml_parser),
+ xml_get_current_line_number($xml_parser),
+ xml_get_current_column_number($xml_parser),
+ xml_get_current_byte_index($xml_parser),
+ $cmd));
+ }
+ else
+ {
+ $vars["error"] = $lang["UNKNOWNREVISION"];
+ return 0;
+ }
+ }
+ }
+ pclose($handle);
+ }
+
+ xml_parser_free($xml_parser);
+ return $curLog;
+ }
+
+ // }}}
+
+}
+
+// {{{ initSvnVersion
+
+function initSvnVersion(&$major, &$minor)
+{
+ global $config;
+
+ $ret = runCommand($config->svn_noparams." --version", false);
+
+ if (preg_match("~([0-9]?)\.([0-9]?)\.([0-9]?)~",$ret[0],$matches))
+ {
+ $major = $matches[1];
+ $minor = $matches[2];
+ }
+
+ $config->setSubversionMajorVersion($major);
+ $config->setSubversionMinorVersion($minor);
+}
+
+// }}}
+
+?>
/WebSVN/include/auth.inc
1,242 → 1,242
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// auth.inc
//
// Handle reading and interpretation of an SVN auth file
 
require_once("include/accessfile.inc");
 
define("UNDEFINED", 0);
define("ALLOW", 1);
define("DENY", 2);
 
class Authentication
{
var $rights;
var $user;
var $usersGroups = array();
// {{{ __construct
 
function Authentication($accessfile)
{
$this->rights = new IniFile();
$this->rights->readIniFile($accessfile);
$this->setUsername("");
$this->identifyGroups();
}
 
// }}}
// {{{ setUsername($username)
//
// Set the username if it is given, or
// get the user of the current http session
 
function setUsername($username)
{
if ($username == "") // Use the current user
{
$this->user = @$_SERVER["REMOTE_USER"];
}
else
{
$this->user = $username;
}
}
 
// }}}
 
// {{{ identifyGroups()
//
// Checks to see which groups the user belongs to
 
function identifyGroups()
{
$this->usersGroups[] = "*";
 
if (is_array($this->rights->getValues("groups")))
{
foreach ($this->rights->getValues("groups") as $group => $names)
{
if (in_array(strtolower($this->user), preg_split('/\s*,\s*/', $names)))
$this->usersGroups[] = "@" . $group;
}
}
}
 
// }}}
 
// {{{ inList
//
// Check if the user is in the given list and return their read status
// if they are (UNDEFINED, ALLOW or DENY)
function inList($accessors, $user)
{
$output = UNDEFINED;
foreach($accessors As $key => $rights)
{
$keymatch = false;
if (in_array($key, $this->usersGroups) || !strcmp($key, strtolower($user)))
$keymatch = true;
if ($keymatch)
{
if (strpos($rights, "r") !== false)
return ALLOW;
else
$output = DENY;
}
}
return $output;
}
 
// }}}
// {{{ hasReadAccess
//
// Returns true if the user has read access to the given path
function hasReadAccess($repos, $path, $checkSubFolders = false)
{
$access = UNDEFINED;
if ($path{0} != "/")
$path = "/$path";
// If were told to, we should check sub folders of the path to see if there's
// a read access below this level. This is used to display the folders needed
// to get to the folder to which read access is granted.
if ($checkSubFolders)
{
$sections = $this->rights->getSections();
foreach($sections As $section => $accessers)
{
$qualified = $repos.":".$path;
$len = strlen($qualified);
if ($len < strlen($section) && strncmp($section, $qualified, strlen($qualified)) == 0)
{
$access = $this->inList($accessers, $this->user);
}
 
if ($access != ALLOW)
{
$len = strlen($path);
if ($len < strlen($section) && strncmp($section, $path, strlen($path)) == 0)
{
$access = $this->inList($accessers, $this->user);
}
}
if ($access == ALLOW)
break;
}
}
// If we still don't have access, check each subpath of the path until we find an
// access level...
if ($access != ALLOW)
{
$access = UNDEFINED;
do
{
$accessers = $this->rights->getValues($repos.":".$path);
if (!empty($accessers))
$access = $this->inList($accessers, $this->user);
if ($access == UNDEFINED)
{
$accessers = $this->rights->getValues($path);
if (!empty($accessers))
$access = $this->inList($accessers, $this->user);
}
// If we've not got a match, remove the sub directory and start again
if ($access == UNDEFINED)
{
if ($path == "/") break;
$path = substr($path, 0, strrpos(substr($path, 0, -1), "/") + 1);
}
} while ($access == UNDEFINED && $path != "");
}
return $access == ALLOW;
}
 
// }}}
// {{{ hasUnrestrictedReadAccess
//
// Returns true if the user has read access to the given path and too
// all subfolders
function hasUnrestrictedReadAccess($repos, $path)
{
// First make sure that we have full read access at this level
if (!$this->hasReadAccess($repos, $path, false))
return false;
// Now check to see if there is a sub folder that's protected
$sections = $this->rights->getSections();
foreach($sections As $section => $accessers)
{
$qualified = $repos.":".$path;
$len = strlen($qualified);
$access = UNDEFINED;
if ($len < strlen($section) && strncmp($section, $qualified, strlen($qualified)) == 0)
{
$access = $this->inList($accessers, $this->user);
}
 
if ($access != DENY)
{
$len = strlen($path);
if ($len < strlen($section) && strncmp($section, $path, strlen($qualified)) == 0)
{
$access = $this->inList($accessers, $this->user);
}
}
if ($access == DENY)
return false;
}
return true;
}
 
// }}}
 
}
?>
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// auth.inc
//
// Handle reading and interpretation of an SVN auth file
 
require_once("include/accessfile.inc");
 
define("UNDEFINED", 0);
define("ALLOW", 1);
define("DENY", 2);
 
class Authentication
{
var $rights;
var $user;
var $usersGroups = array();
// {{{ __construct
 
function Authentication($accessfile)
{
$this->rights = new IniFile();
$this->rights->readIniFile($accessfile);
$this->setUsername("");
$this->identifyGroups();
}
 
// }}}
// {{{ setUsername($username)
//
// Set the username if it is given, or
// get the user of the current http session
 
function setUsername($username)
{
if ($username == "") // Use the current user
{
$this->user = @$_SERVER["REMOTE_USER"];
}
else
{
$this->user = $username;
}
}
 
// }}}
 
// {{{ identifyGroups()
//
// Checks to see which groups the user belongs to
 
function identifyGroups()
{
$this->usersGroups[] = "*";
 
if (is_array($this->rights->getValues("groups")))
{
foreach ($this->rights->getValues("groups") as $group => $names)
{
if (in_array(strtolower($this->user), preg_split('/\s*,\s*/', $names)))
$this->usersGroups[] = "@" . $group;
}
}
}
 
// }}}
 
// {{{ inList
//
// Check if the user is in the given list and return their read status
// if they are (UNDEFINED, ALLOW or DENY)
function inList($accessors, $user)
{
$output = UNDEFINED;
foreach($accessors As $key => $rights)
{
$keymatch = false;
if (in_array($key, $this->usersGroups) || !strcmp($key, strtolower($user)))
$keymatch = true;
if ($keymatch)
{
if (strpos($rights, "r") !== false)
return ALLOW;
else
$output = DENY;
}
}
return $output;
}
 
// }}}
// {{{ hasReadAccess
//
// Returns true if the user has read access to the given path
function hasReadAccess($repos, $path, $checkSubFolders = false)
{
$access = UNDEFINED;
if ($path{0} != "/")
$path = "/$path";
// If were told to, we should check sub folders of the path to see if there's
// a read access below this level. This is used to display the folders needed
// to get to the folder to which read access is granted.
if ($checkSubFolders)
{
$sections = $this->rights->getSections();
foreach($sections As $section => $accessers)
{
$qualified = $repos.":".$path;
$len = strlen($qualified);
if ($len < strlen($section) && strncmp($section, $qualified, strlen($qualified)) == 0)
{
$access = $this->inList($accessers, $this->user);
}
 
if ($access != ALLOW)
{
$len = strlen($path);
if ($len < strlen($section) && strncmp($section, $path, strlen($path)) == 0)
{
$access = $this->inList($accessers, $this->user);
}
}
if ($access == ALLOW)
break;
}
}
// If we still don't have access, check each subpath of the path until we find an
// access level...
if ($access != ALLOW)
{
$access = UNDEFINED;
do
{
$accessers = $this->rights->getValues($repos.":".$path);
if (!empty($accessers))
$access = $this->inList($accessers, $this->user);
if ($access == UNDEFINED)
{
$accessers = $this->rights->getValues($path);
if (!empty($accessers))
$access = $this->inList($accessers, $this->user);
}
// If we've not got a match, remove the sub directory and start again
if ($access == UNDEFINED)
{
if ($path == "/") break;
$path = substr($path, 0, strrpos(substr($path, 0, -1), "/") + 1);
}
} while ($access == UNDEFINED && $path != "");
}
return $access == ALLOW;
}
 
// }}}
// {{{ hasUnrestrictedReadAccess
//
// Returns true if the user has read access to the given path and too
// all subfolders
function hasUnrestrictedReadAccess($repos, $path)
{
// First make sure that we have full read access at this level
if (!$this->hasReadAccess($repos, $path, false))
return false;
// Now check to see if there is a sub folder that's protected
$sections = $this->rights->getSections();
foreach($sections As $section => $accessers)
{
$qualified = $repos.":".$path;
$len = strlen($qualified);
$access = UNDEFINED;
if ($len < strlen($section) && strncmp($section, $qualified, strlen($qualified)) == 0)
{
$access = $this->inList($accessers, $this->user);
}
 
if ($access != DENY)
{
$len = strlen($path);
if ($len < strlen($section) && strncmp($section, $path, strlen($qualified)) == 0)
{
$access = $this->inList($accessers, $this->user);
}
}
if ($access == DENY)
return false;
}
return true;
}
 
// }}}
 
}
?>
/WebSVN/include/bugtraq.inc
1,390 → 1,390
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// bugtraq.inc
//
// Functions for accessing the bugtraq properties and replacing issue IDs
// with URLs.
//
// For more information about bugtraq, see
// http://svn.collab.net/repos/tortoisesvn/trunk/doc/issuetrackers.txt
 
class Bugtraq
{
// {{{ Properties
 
var $msgstring;
var $urlstring;
var $logregex;
var $append;
 
var $firstPart;
var $firstPartLen;
var $lastPart;
var $lastPartLen;
 
var $propsfound = false;
 
// }}}
 
// {{{ __construct($rep, $svnrep, $path)
 
function Bugtraq($rep, $svnrep, $path)
{
global $config;
if ($rep->getBugtraq())
{
$pos = strrpos($path, "/");
$parent = substr($path, 0, $pos + 1);
$this->append = true;
$enoughdata = false;
while(!$enoughdata && (strpos($parent, "/") !== false))
{
if (empty($this->msgstring)) $this->msgstring = $svnrep->getProperty($parent, 'bugtraq:message');
if (empty($this->logregex)) $this->logregex = $svnrep->getProperty($parent, 'bugtraq:logregex');
if (empty($this->urlstring)) $this->urlstring = $svnrep->getProperty($parent, 'bugtraq:url');
if (empty($this->append)) $this->append = ($svnrep->getProperty($parent, 'bugtraq:append') == "true");
$parent = substr($parent, 0, -1); // Remove the trailing slash
$pos = strrpos($parent, "/"); // Find the last trailing slash
$parent = substr($parent, 0, $pos + 1); // Find the previous parent directory
$enoughdata = ((!empty($this->msgstring) || !empty($this->logregex)) && !empty($this->urlstring));
}
$this->msgstring = trim(@$this->msgstring);
$this->urlstring = trim(@$this->urlstring);
if ($enoughdata && !empty($this->msgstring))
$this->initPartInfo();
if ($enoughdata)
$this->propsfound = true;
}
}
 
// }}}
 
// {{{ initPartInfo()
function initPartInfo()
{
if (($bugidpos = strpos($this->msgstring, "%BUGID%")) !== false && strpos($this->urlstring, "%BUGID%") !== false)
{
// Get the textual parts of the message string for comparison purposes
$this->firstPart = substr($this->msgstring, 0, $bugidpos);
$this->firstPartLen = strlen($this->firstPart);
$this->lastPart = substr($this->msgstring, $bugidpos + 7);
$this->lastPartLen = strlen($this->lastPart);
}
}
 
// }}}
 
// {{{ replaceIDs($message)
 
function replaceIDs($message)
{
if ($this->propsfound)
{
// First we search for the message string
$logmsg = "";
$message = rtrim($message);
if ($this->append)
{
// Just compare the last line
if (($offset = strrpos($message, "\n")) !== false)
{
$logmsg = substr($message, 0, $offset + 1);
$bugLine = substr($message, $offset + 1);
}
else
$bugLine = $message;
}
else
{
if (($offset = strpos($message, "\n")) !== false)
{
$bugLine = substr($message, 0, $offset);
$logmsg = substr($message, $offset);
}
else
$bugLine = $message;
}
 
// Make sure that our line really is an issue tracker message
 
if (((strncmp($bugLine, $this->firstPart, $this->firstPartLen) == 0)) &&
strcmp(substr($bugLine, -$this->lastPartLen, $this->lastPartLen), $this->lastPart) == 0)
{
// Get the issues list
if ($this->lastPartLen > 0)
$issues = substr($bugLine, $this->firstPartLen, -$this->lastPartLen);
else
$issues = substr($bugLine, $this->firstPartLen);
// Add each reference to the first part of the line
$line = $this->firstPart;
while ($pos = strpos($issues, ","))
{
$issue = trim(substr($issues, 0, $pos));
$issues = substr($issues, $pos + 1);
$line .= "<a href=\"".str_replace("%BUGID%", $issue, $this->urlstring)."\">$issue</a>, ";
}
$line .= "<a href=\"".str_replace("%BUGID%", trim($issues), $this->urlstring)."\">".trim($issues)."</a>".$this->lastPart;
if ($this->append)
$message = $logmsg.$line;
else
$message = $line.$logmsg;
}
// Now replace all other instances of bug IDs that match the regex
 
if ($this->logregex)
{
$message = rtrim($message);
$line = "";
$allissues = "";
$lines = split("\n", $this->logregex);
$regex_all = "~".$lines[0]."~";
$regex_single = @$lines[1];
if (empty($regex_single))
{
// If the property only contains one line, then the pattern is only designed
// to find one issue number at a time. e.g. [Ii]ssue #?(\d+). In this case
// we need to replace the matched issue ID with the link.
if ($numMatches = preg_match_all($regex_all, $message, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
{
$addedOffset = 0;
for ($match = 0; $match < $numMatches; $match++)
{
$issue = $matches[$match][1][0];
$issueOffset = $matches[$match][1][1];
$issueLink = "<a href=\"".str_replace("%BUGID%", $issue, $this->urlstring)."\">".$issue."</a>";
$message = substr_replace($message, $issueLink, $issueOffset + $addedOffset, strlen($issue));
$addedOffset += strlen($issueLink) - strlen($issue);
}
}
}
else
{
// It the property contains two lines, then the first is a pattern for extracting
// multiple issue numbers, and the second is a pattern extracting each issue
// number from the multiple match. e.g. [Ii]ssue #?(\d+)(,? ?#?(\d+))+ and (\d+)
while (preg_match($regex_all, $message, $matches, PREG_OFFSET_CAPTURE))
{
$completeMatch = $matches[0][0];
$completeMatchOffset = $matches[0][1];
$replacement = $completeMatch;
if ($numMatches = preg_match_all("~".$regex_single."~", $replacement, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
{
$addedOffset = 0;
for ($match = 0; $match < $numMatches; $match++)
{
$issue = $matches[$match][1][0];
$issueOffset = $matches[$match][1][1];
 
$issueLink = "<a href=\"".str_replace("%BUGID%", $issue, $this->urlstring)."\">".$issue."</a>";
$replacement = substr_replace($replacement, $issueLink, $issueOffset + $addedOffset, strlen($issue));
$addedOffset += strlen($issueLink) - strlen($issue);
}
}
$message = substr_replace($message, $replacement, $completeMatchOffset, strlen($completeMatch));
}
}
}
}
 
return $message;
}
 
// }}}
 
}
 
// The BugtraqTestable class is a derived class that is used to test the matching
// abilities of the Bugtraq class. In particular, it allows for the initialisation of the
// class without the need for a repository.
 
class BugtraqTestable extends Bugtraq
{
// {{{ __construct()
 
function BugtraqTestable()
{
// This constructor serves to assure that the parent constructor is not
// called.
}
 
// }}}
 
// {{{ setUpVars($message, $url, $regex, $append)
 
function setUpVars($message, $url, $regex, $append)
{
$this->msgstring = $message;
$this->urlstring = $url;
$this->logregex = $regex;
$this->append = $append;
$this->propsfound = true;
 
$this->initPartInfo();
}
 
// }}}
 
// {{{ setMessage($message)
function setMessage($message)
{
$this->msgstring = $message;
}
 
// }}}
 
// {{{ setUrl($url)
 
function setUrl($url)
{
$this->urlstring = $url;
}
 
// }}}
 
// {{{ setRegex($regex)
 
function setRegEx($regex)
{
$this->logregex = $regex;
}
 
// }}}
 
// {{{ setAppend($append)
 
function setAppend($append)
{
$this->append = $append;
}
 
// }}}
 
// {{{ printVars()
function printVars()
{
echo "msgstring = ".$this->msgstring."\n";
echo "urlstring = ".$this->urlstring."\n";
echo "logregex = ".$this->logregex."\n";
echo "append = ".$this->append."\n";
echo "firstPart = ".$this->firstPart."\n";
echo "firstPartLen = ".$this->firstPartLen."\n";
echo "lastPart = ".$this->lastPart."\n";
echo "lastPartLen = ".$this->lastPartLen."\n";
}
 
// }}}
}
 
// {{{ test_bugtraq()
 
function test_bugtraq()
{
$tester = new BugtraqTestable;
$tester->setUpVars("BugID: %BUGID%",
"http://bugtracker/?id=%BUGID%",
"[Ii]ssue #?(\d+)",
true);
//$tester->printVars();
$res = $tester->replaceIDs("BugID: 789\n".
"This is a test message that refers to issue #123 and\n".
"issue #456.\n".
"BugID: 789");
echo nl2br($res)."<p>";
$res = $tester->replaceIDs("BugID: 789, 101112\n".
"This is a test message that refers to issue #123 and\n".
"issue #456.\n".
"BugID: 789, 101112");
 
echo nl2br($res)."<p>";
$tester->setAppend(false);
$res = $tester->replaceIDs("BugID: 789\n".
"This is a test message that refers to issue #123 and\n".
"issue #456.\n".
"BugID: 789");
echo nl2br($res)."<p>";
$res = $tester->replaceIDs("BugID: 789, 101112\n".
"This is a test message that refers to issue #123 and\n".
"issue #456.\n".
"BugID: 789, 101112");
 
echo nl2br($res)."<p>";
$tester->setUpVars("BugID: %BUGID%",
"http://bugtracker/?id=%BUGID%",
"[Ii]ssues?:?(\s*(,|and)?\s*#\d+)+\n(\d+)",
true);
$res = $tester->replaceIDs("BugID: 789, 101112\n".
"This is a test message that refers to issue #123 and\n".
"issues #456, #654 and #321.\n".
"BugID: 789, 101112");
 
echo nl2br($res)."<p>";
 
$tester->setUpVars("Test: %BUGID%",
"http://bugtracker/?id=%BUGID%",
"\s*[Cc]ases*\s*[IDs]*\s*[#: ]+((\d+[ ,:;#]*)+)\n(\d+)",
true);
$res = $tester->replaceIDs("Cosmetic change\n".
"CaseIDs: 48");
 
echo nl2br($res)."<p>";
}
 
// }}}
 
?>
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// bugtraq.inc
//
// Functions for accessing the bugtraq properties and replacing issue IDs
// with URLs.
//
// For more information about bugtraq, see
// http://svn.collab.net/repos/tortoisesvn/trunk/doc/issuetrackers.txt
 
class Bugtraq
{
// {{{ Properties
 
var $msgstring;
var $urlstring;
var $logregex;
var $append;
 
var $firstPart;
var $firstPartLen;
var $lastPart;
var $lastPartLen;
 
var $propsfound = false;
 
// }}}
 
// {{{ __construct($rep, $svnrep, $path)
 
function Bugtraq($rep, $svnrep, $path)
{
global $config;
if ($rep->getBugtraq())
{
$pos = strrpos($path, "/");
$parent = substr($path, 0, $pos + 1);
$this->append = true;
$enoughdata = false;
while(!$enoughdata && (strpos($parent, "/") !== false))
{
if (empty($this->msgstring)) $this->msgstring = $svnrep->getProperty($parent, 'bugtraq:message');
if (empty($this->logregex)) $this->logregex = $svnrep->getProperty($parent, 'bugtraq:logregex');
if (empty($this->urlstring)) $this->urlstring = $svnrep->getProperty($parent, 'bugtraq:url');
if (empty($this->append)) $this->append = ($svnrep->getProperty($parent, 'bugtraq:append') == "true");
$parent = substr($parent, 0, -1); // Remove the trailing slash
$pos = strrpos($parent, "/"); // Find the last trailing slash
$parent = substr($parent, 0, $pos + 1); // Find the previous parent directory
$enoughdata = ((!empty($this->msgstring) || !empty($this->logregex)) && !empty($this->urlstring));
}
$this->msgstring = trim(@$this->msgstring);
$this->urlstring = trim(@$this->urlstring);
if ($enoughdata && !empty($this->msgstring))
$this->initPartInfo();
if ($enoughdata)
$this->propsfound = true;
}
}
 
// }}}
 
// {{{ initPartInfo()
function initPartInfo()
{
if (($bugidpos = strpos($this->msgstring, "%BUGID%")) !== false && strpos($this->urlstring, "%BUGID%") !== false)
{
// Get the textual parts of the message string for comparison purposes
$this->firstPart = substr($this->msgstring, 0, $bugidpos);
$this->firstPartLen = strlen($this->firstPart);
$this->lastPart = substr($this->msgstring, $bugidpos + 7);
$this->lastPartLen = strlen($this->lastPart);
}
}
 
// }}}
 
// {{{ replaceIDs($message)
 
function replaceIDs($message)
{
if ($this->propsfound)
{
// First we search for the message string
$logmsg = "";
$message = rtrim($message);
if ($this->append)
{
// Just compare the last line
if (($offset = strrpos($message, "\n")) !== false)
{
$logmsg = substr($message, 0, $offset + 1);
$bugLine = substr($message, $offset + 1);
}
else
$bugLine = $message;
}
else
{
if (($offset = strpos($message, "\n")) !== false)
{
$bugLine = substr($message, 0, $offset);
$logmsg = substr($message, $offset);
}
else
$bugLine = $message;
}
 
// Make sure that our line really is an issue tracker message
 
if (((strncmp($bugLine, $this->firstPart, $this->firstPartLen) == 0)) &&
strcmp(substr($bugLine, -$this->lastPartLen, $this->lastPartLen), $this->lastPart) == 0)
{
// Get the issues list
if ($this->lastPartLen > 0)
$issues = substr($bugLine, $this->firstPartLen, -$this->lastPartLen);
else
$issues = substr($bugLine, $this->firstPartLen);
// Add each reference to the first part of the line
$line = $this->firstPart;
while ($pos = strpos($issues, ","))
{
$issue = trim(substr($issues, 0, $pos));
$issues = substr($issues, $pos + 1);
$line .= "<a href=\"".str_replace("%BUGID%", $issue, $this->urlstring)."\">$issue</a>, ";
}
$line .= "<a href=\"".str_replace("%BUGID%", trim($issues), $this->urlstring)."\">".trim($issues)."</a>".$this->lastPart;
if ($this->append)
$message = $logmsg.$line;
else
$message = $line.$logmsg;
}
// Now replace all other instances of bug IDs that match the regex
 
if ($this->logregex)
{
$message = rtrim($message);
$line = "";
$allissues = "";
$lines = split("\n", $this->logregex);
$regex_all = "~".$lines[0]."~";
$regex_single = @$lines[1];
if (empty($regex_single))
{
// If the property only contains one line, then the pattern is only designed
// to find one issue number at a time. e.g. [Ii]ssue #?(\d+). In this case
// we need to replace the matched issue ID with the link.
if ($numMatches = preg_match_all($regex_all, $message, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
{
$addedOffset = 0;
for ($match = 0; $match < $numMatches; $match++)
{
$issue = $matches[$match][1][0];
$issueOffset = $matches[$match][1][1];
$issueLink = "<a href=\"".str_replace("%BUGID%", $issue, $this->urlstring)."\">".$issue."</a>";
$message = substr_replace($message, $issueLink, $issueOffset + $addedOffset, strlen($issue));
$addedOffset += strlen($issueLink) - strlen($issue);
}
}
}
else
{
// It the property contains two lines, then the first is a pattern for extracting
// multiple issue numbers, and the second is a pattern extracting each issue
// number from the multiple match. e.g. [Ii]ssue #?(\d+)(,? ?#?(\d+))+ and (\d+)
while (preg_match($regex_all, $message, $matches, PREG_OFFSET_CAPTURE))
{
$completeMatch = $matches[0][0];
$completeMatchOffset = $matches[0][1];
$replacement = $completeMatch;
if ($numMatches = preg_match_all("~".$regex_single."~", $replacement, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
{
$addedOffset = 0;
for ($match = 0; $match < $numMatches; $match++)
{
$issue = $matches[$match][1][0];
$issueOffset = $matches[$match][1][1];
 
$issueLink = "<a href=\"".str_replace("%BUGID%", $issue, $this->urlstring)."\">".$issue."</a>";
$replacement = substr_replace($replacement, $issueLink, $issueOffset + $addedOffset, strlen($issue));
$addedOffset += strlen($issueLink) - strlen($issue);
}
}
$message = substr_replace($message, $replacement, $completeMatchOffset, strlen($completeMatch));
}
}
}
}
 
return $message;
}
 
// }}}
 
}
 
// The BugtraqTestable class is a derived class that is used to test the matching
// abilities of the Bugtraq class. In particular, it allows for the initialisation of the
// class without the need for a repository.
 
class BugtraqTestable extends Bugtraq
{
// {{{ __construct()
 
function BugtraqTestable()
{
// This constructor serves to assure that the parent constructor is not
// called.
}
 
// }}}
 
// {{{ setUpVars($message, $url, $regex, $append)
 
function setUpVars($message, $url, $regex, $append)
{
$this->msgstring = $message;
$this->urlstring = $url;
$this->logregex = $regex;
$this->append = $append;
$this->propsfound = true;
 
$this->initPartInfo();
}
 
// }}}
 
// {{{ setMessage($message)
function setMessage($message)
{
$this->msgstring = $message;
}
 
// }}}
 
// {{{ setUrl($url)
 
function setUrl($url)
{
$this->urlstring = $url;
}
 
// }}}
 
// {{{ setRegex($regex)
 
function setRegEx($regex)
{
$this->logregex = $regex;
}
 
// }}}
 
// {{{ setAppend($append)
 
function setAppend($append)
{
$this->append = $append;
}
 
// }}}
 
// {{{ printVars()
function printVars()
{
echo "msgstring = ".$this->msgstring."\n";
echo "urlstring = ".$this->urlstring."\n";
echo "logregex = ".$this->logregex."\n";
echo "append = ".$this->append."\n";
echo "firstPart = ".$this->firstPart."\n";
echo "firstPartLen = ".$this->firstPartLen."\n";
echo "lastPart = ".$this->lastPart."\n";
echo "lastPartLen = ".$this->lastPartLen."\n";
}
 
// }}}
}
 
// {{{ test_bugtraq()
 
function test_bugtraq()
{
$tester = new BugtraqTestable;
$tester->setUpVars("BugID: %BUGID%",
"http://bugtracker/?id=%BUGID%",
"[Ii]ssue #?(\d+)",
true);
//$tester->printVars();
$res = $tester->replaceIDs("BugID: 789\n".
"This is a test message that refers to issue #123 and\n".
"issue #456.\n".
"BugID: 789");
echo nl2br($res)."<p>";
$res = $tester->replaceIDs("BugID: 789, 101112\n".
"This is a test message that refers to issue #123 and\n".
"issue #456.\n".
"BugID: 789, 101112");
 
echo nl2br($res)."<p>";
$tester->setAppend(false);
$res = $tester->replaceIDs("BugID: 789\n".
"This is a test message that refers to issue #123 and\n".
"issue #456.\n".
"BugID: 789");
echo nl2br($res)."<p>";
$res = $tester->replaceIDs("BugID: 789, 101112\n".
"This is a test message that refers to issue #123 and\n".
"issue #456.\n".
"BugID: 789, 101112");
 
echo nl2br($res)."<p>";
$tester->setUpVars("BugID: %BUGID%",
"http://bugtracker/?id=%BUGID%",
"[Ii]ssues?:?(\s*(,|and)?\s*#\d+)+\n(\d+)",
true);
$res = $tester->replaceIDs("BugID: 789, 101112\n".
"This is a test message that refers to issue #123 and\n".
"issues #456, #654 and #321.\n".
"BugID: 789, 101112");
 
echo nl2br($res)."<p>";
 
$tester->setUpVars("Test: %BUGID%",
"http://bugtracker/?id=%BUGID%",
"\s*[Cc]ases*\s*[IDs]*\s*[#: ]+((\d+[ ,:;#]*)+)\n(\d+)",
true);
$res = $tester->replaceIDs("Cosmetic change\n".
"CaseIDs: 48");
 
echo nl2br($res)."<p>";
}
 
// }}}
 
?>
/WebSVN/include/command.inc
1,171 → 1,171
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// command.inc
//
// External command handling
 
// {{{ replaceEntities
//
// Replace character codes with HTML entities for display purposes.
// This routine assumes that the character encoding of the string is
// that of the local system (i.e., it's a string returned from a command
// line command).
 
function replaceEntities($str, $rep)
{
global $config;
// Ideally, we'd do this:
//
// $str = htmlentities($str, ENT_COMPAT, $config->inputEnc);
//
// However, htmlentities is very limited in it's ability to process
// character encodings. We have to rely on something more powerful.
if (version_compare(phpversion(), "4.1.0", "<"))
{
// In this case, we can't do any better than assume that the
// input encoding is ISO-8859-1.
$str = htmlentities($str);
}
else
{
$str = toOutputEncoding($str, $rep->getContentEncoding());
 
// $str is now encoded as UTF-8.
$str = htmlentities($str, ENT_COMPAT, $config->outputEnc);
}
return $str;
}
 
// }}}
 
// {{{ toOutputEncoding
 
function toOutputEncoding($str, $inputEncoding = "")
{
global $config;
if (empty($inputEncoding))
$inputEncoding = $config->inputEnc;
// Try to convert the messages based on the locale information
if ($config->inputEnc && $config->outputEnc)
{
if (function_exists("iconv"))
{
$output = @iconv($inputEncoding, $config->outputEnc, $str);
if (!empty($output))
$str = $output;
}
}
 
return $str;
}
 
// }}}
 
// {{{ quoteCommand
 
function quoteCommand($cmd, $redirecterr)
{
global $config;
if ($redirecterr)
$cmd .= " 2>&1";
// On Windows machines, the whole line needs quotes round it so that it's
// passed to cmd.exe correctly
 
if ($config->serverIsWindows)
$cmd = "\"$cmd\"";
return $cmd;
}
 
// }}}
 
// {{{ runCommand
 
function runCommand($cmd, $mayReturnNothing = false)
{
global $lang;
$output = array ();
$err = false;
 
$c = quoteCommand($cmd, false);
// Try to run the command normally
if ($handle = popen($c, 'r'))
{
$firstline = true;
while (!feof($handle))
{
$line = fgets($handle);
if ($firstline && empty($line) && !$mayReturnNothing)
{
$err = true;
}
$firstline = false;
$output[] = toOutputEncoding(rtrim($line));
}
pclose($handle);
if (!$err)
return $output;
}
 
echo '<p>',$lang['BADCMD'],': <code>',$cmd,'</code></p>';
// Rerun the command, this time grabbing the error information
 
$c = quoteCommand($cmd, true);
 
$output = toOutputEncoding(shell_exec($c));
if (!empty($output))
echo '<p>',nl2br($output),'</p>';
exit;
}
 
// }}}
 
// {{{ quote
//
// Quote a string to send to the command line
 
function quote($str)
{
global $config;
 
if ($config->serverIsWindows)
return "\"$str\"";
else
return escapeshellarg($str);
}
 
// }}}
 
?>
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// command.inc
//
// External command handling
 
// {{{ replaceEntities
//
// Replace character codes with HTML entities for display purposes.
// This routine assumes that the character encoding of the string is
// that of the local system (i.e., it's a string returned from a command
// line command).
 
function replaceEntities($str, $rep)
{
global $config;
// Ideally, we'd do this:
//
// $str = htmlentities($str, ENT_COMPAT, $config->inputEnc);
//
// However, htmlentities is very limited in it's ability to process
// character encodings. We have to rely on something more powerful.
if (version_compare(phpversion(), "4.1.0", "<"))
{
// In this case, we can't do any better than assume that the
// input encoding is ISO-8859-1.
$str = htmlentities($str);
}
else
{
$str = toOutputEncoding($str, $rep->getContentEncoding());
 
// $str is now encoded as UTF-8.
$str = htmlentities($str, ENT_COMPAT, $config->outputEnc);
}
return $str;
}
 
// }}}
 
// {{{ toOutputEncoding
 
function toOutputEncoding($str, $inputEncoding = "")
{
global $config;
if (empty($inputEncoding))
$inputEncoding = $config->inputEnc;
// Try to convert the messages based on the locale information
if ($config->inputEnc && $config->outputEnc)
{
if (function_exists("iconv"))
{
$output = @iconv($inputEncoding, $config->outputEnc, $str);
if (!empty($output))
$str = $output;
}
}
 
return $str;
}
 
// }}}
 
// {{{ quoteCommand
 
function quoteCommand($cmd, $redirecterr)
{
global $config;
if ($redirecterr)
$cmd .= " 2>&1";
// On Windows machines, the whole line needs quotes round it so that it's
// passed to cmd.exe correctly
 
if ($config->serverIsWindows)
$cmd = "\"$cmd\"";
return $cmd;
}
 
// }}}
 
// {{{ runCommand
 
function runCommand($cmd, $mayReturnNothing = false)
{
global $lang;
$output = array ();
$err = false;
 
$c = quoteCommand($cmd, false);
// Try to run the command normally
if ($handle = popen($c, 'r'))
{
$firstline = true;
while (!feof($handle))
{
$line = fgets($handle);
if ($firstline && empty($line) && !$mayReturnNothing)
{
$err = true;
}
$firstline = false;
$output[] = toOutputEncoding(rtrim($line));
}
pclose($handle);
if (!$err)
return $output;
}
 
echo '<p>',$lang['BADCMD'],': <code>',$cmd,'</code></p>';
// Rerun the command, this time grabbing the error information
 
$c = quoteCommand($cmd, true);
 
$output = toOutputEncoding(shell_exec($c));
if (!empty($output))
echo '<p>',nl2br($output),'</p>';
exit;
}
 
// }}}
 
// {{{ quote
//
// Quote a string to send to the command line
 
function quote($str)
{
global $config;
 
if ($config->serverIsWindows)
return "\"$str\"";
else
return escapeshellarg($str);
}
 
// }}}
 
?>
/WebSVN/include/feedcreator.class.php
1,1153 → 1,1153
<?php
# vim:et:ts=4:sts=4:sw=4:fdm=marker:
# {{{ Info
/***************************************************************************
 
FeedCreator class v1.6
originally (c) Kai Blankenhorn
www.bitfolge.de
kaib@bitfolge.de
v1.3 work by Scott Reynen (scott@randomchaos.com) and Kai Blankenhorn
v1.5 OPML support by Dirk Clemens
 
This program 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.
 
This program 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: <http://www.gnu.org/licenses/gpl.txt>
 
****************************************************************************
 
 
Changelog:
 
Modifications for WebSVN:
The main description link wasn't put through htmlspecialcharacters
Output encoding now defined by $config
Remove hardcoded time zone
 
v1.6 05-10-04
added stylesheet to RSS 1.0 feeds
fixed generator comment (thanks Kevin L. Papendick and Tanguy Pruvot)
fixed RFC822 date bug (thanks Tanguy Pruvot)
added TimeZone customization for RFC8601 (thanks Tanguy Pruvot)
fixed Content-type could be empty (thanks Tanguy Pruvot)
fixed author/creator in RSS1.0 (thanks Tanguy Pruvot)
 
 
v1.6 beta 02-28-04
added Atom 0.3 support (not all features, though)
improved OPML 1.0 support (hopefully - added more elements)
added support for arbitrary additional elements (use with caution)
code beautification :-)
considered beta due to some internal changes
 
v1.5.1 01-27-04
fixed some RSS 1.0 glitches (thanks to Stéphane Vanpoperynghe)
fixed some inconsistencies between documentation and code (thanks to Timothy Martin)
 
v1.5 01-06-04
added support for OPML 1.0
added more documentation
 
v1.4 11-11-03
optional feed saving and caching
improved documentation
minor improvements
 
v1.3 10-02-03
renamed to FeedCreator, as it not only creates RSS anymore
added support for mbox
tentative support for echo/necho/atom/pie/???
v1.2 07-20-03
intelligent auto-truncating of RSS 0.91 attributes
don't create some attributes when they're not set
documentation improved
fixed a real and a possible bug with date conversions
code cleanup
 
v1.1 06-29-03
added images to feeds
now includes most RSS 0.91 attributes
added RSS 2.0 feeds
 
v1.0 06-24-03
initial release
 
 
 
***************************************************************************/
 
/*** GENERAL USAGE *********************************************************
 
include("feedcreator.class.php");
 
$rss = new UniversalFeedCreator();
$rss->useCached(); // use cached version if age<1 hour
$rss->title = "PHP news";
$rss->description = "daily news from the PHP scripting world";
$rss->link = "http://www.dailyphp.net/news";
$rss->syndicationURL = "http://www.dailyphp.net/".$_SERVER["PHP_SELF"];
 
$image = new FeedImage();
$image->title = "dailyphp.net logo";
$image->url = "http://www.dailyphp.net/images/logo.gif";
$image->link = "http://www.dailyphp.net";
$image->description = "Feed provided by dailyphp.net. Click to visit.";
$rss->image = $image;
 
// get your news items from somewhere, e.g. your database:
mysql_select_db($dbHost, $dbUser, $dbPass);
$res = mysql_query("SELECT * FROM news ORDER BY newsdate DESC");
while ($data = mysql_fetch_object($res)) {
$item = new FeedItem();
$item->title = $data->title;
$item->link = $data->url;
$item->description = $data->short;
$item->date = $data->newsdate;
$item->source = "http://www.dailyphp.net";
$item->author = "John Doe";
$rss->addItem($item);
}
 
// valid format strings are: RSS0.91, RSS1.0, RSS2.0, PIE0.1 (deprecated),
// MBOX, OPML, ATOM0.3
echo $rss->saveFeed("RSS1.0", "news/feed.xml");
 
# }}}
 
***************************************************************************
* A little setup *
**************************************************************************/
 
/**
* Version string.
**/
define("FEEDCREATOR_VERSION", "FeedCreator 1.6");
 
 
 
/**
* A FeedItem is a part of a FeedCreator feed.
*
* @author Kai Blankenhorn <kaib@bitfolge.de>
* @since 1.3
*/
class FeedItem {
# {{{ Properties
 
/**
* Mandatory attributes of an item.
*/
var $title, $description, $link;
/**
* Optional attributes of an item.
*/
var $author, $authorEmail, $image, $category, $comments, $guid, $source, $creator;
/**
* Publishing date of an item. May be in one of the following formats:
*
* RFC 822:
* "Mon, 20 Jan 03 18:05:41 +0400"
* "20 Jan 03 18:05:41 +0000"
*
* ISO 8601:
* "2003-01-20T18:05:41+04:00"
*
* Unix:
* 1043082341
*/
var $date;
/**
* Any additional elements to include as an assiciated array. All $key => $value pairs
* will be included unencoded in the feed item in the form
* <$key>$value</$key>
* Again: No encoding will be used! This means you can invalidate or enhance the feed
* if $value contains markup. This may be abused to embed tags not implemented by
* the FeedCreator class used.
*/
var $additionalElements = Array();
 
// on hold
// var $source;
 
# }}}
}
 
 
 
/**
* An FeedImage may be added to a FeedCreator feed.
* @author Kai Blankenhorn <kaib@bitfolge.de>
* @since 1.3
*/
class FeedImage {
# {{{ Properties
 
/**
* Mandatory attributes of an image.
*/
var $title, $url, $link;
/**
* Optional attributes of an image.
*/
var $width, $height, $description;
 
# }}}
}
 
 
/**
* UniversalFeedCreator lets you choose during runtime which
* format to build.
* For general usage of a feed class, see the FeedCreator class
* below or the example above.
*
* @since 1.3
* @author Kai Blankenhorn <kaib@bitfolge.de>
*/
class UniversalFeedCreator extends FeedCreator {
var $_feed;
# {{{ _setFormat
function _setFormat($format) {
switch (strtoupper($format)) {
case "2.0":
// fall through
case "RSS2.0":
$this->_feed = new RSSCreator20();
break;
case "1.0":
// fall through
case "RSS1.0":
$this->_feed = new RSSCreator10();
break;
case "0.91":
// fall through
case "RSS0.91":
$this->_feed = new RSSCreator091();
break;
case "PIE0.1":
$this->_feed = new PIECreator01();
break;
case "MBOX":
$this->_feed = new MBOXCreator();
break;
case "OPML":
$this->_feed = new OPMLCreator();
break;
case "ATOM0.3":
$this->_feed = new AtomCreator03();
break;
default:
$this->_feed = new RSSCreator091();
break;
}
$vars = get_object_vars($this);
foreach ($vars as $key => $value) {
if ($key!="feed") {
$this->_feed->{$key} = $this->{$key};
}
}
}
# }}}
# {{{ createFeed
/**
* Creates a syndication feed based on the items previously added.
*
* @see FeedCreator::addItem()
* @param string format format the feed should comply to. Valid values are:
* "PIE0.1", "mbox", "RSS0.91", "RSS1.0", "RSS2.0", "OPML".
* @return string the contents of the feed.
*/
function createFeed($format = "RSS0.91") {
$this->_setFormat($format);
return $this->_feed->createFeed();
}
# }}}
 
# {{{ saveFeed
/**
* Saves this feed as a file on the local disk. After the file is saved, an HTTP redirect
* header may be sent to redirect the use to the newly created file.
* @since 1.4
*
* @param string format format the feed should comply to. Valid values are:
* "PIE0.1" (deprecated), "mbox", "RSS0.91", "RSS1.0", "RSS2.0", "OPML", "ATOM0.3".
* @param string filename optional the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()).
* @param boolean displayContents optional send the content of the file or not. If true, the file will be sent in the body of the response.
*/
function saveFeed($format="RSS0.91", $filename="", $displayContents=true) {
$this->_setFormat($format);
$this->_feed->saveFeed($filename, $displayContents);
}
# }}}
 
}
 
 
/**
* FeedCreator is the abstract base implementation for concrete
* implementations that implement a specific format of syndication.
*
* @abstract
* @author Kai Blankenhorn <kaib@bitfolge.de>
* @since 1.4
*/
class FeedCreator {
# {{{ Properties
 
/**
* Mandatory attributes of a feed.
*/
var $title, $description, $link;
 
 
/**
* Optional attributes of a feed.
*/
var $syndicationURL, $image, $language, $copyright, $pubDate, $lastBuildDate, $editor, $editorEmail, $webmaster, $category, $docs, $ttl, $rating, $skipHours, $skipDays;
 
 
/**
* @access private
*/
var $items = Array();
 
 
/**
* This feed's MIME content type.
* @since 1.4
* @access private
*/
var $contentType = "text/xml";
 
 
/**
* Any additional elements to include as an assiciated array. All $key => $value pairs
* will be included unencoded in the feed in the form
* <$key>$value</$key>
* Again: No encoding will be used! This means you can invalidate or enhance the feed
* if $value contains markup. This may be abused to embed tags not implemented by
* the FeedCreator class used.
*/
var $additionalElements = Array();
 
# }}}
# {{{ addItem
/**
* Adds an FeedItem to the feed.
*
* @param object FeedItem $item The FeedItem to add to the feed.
* @access public
*/
function addItem($item) {
$this->items[] = $item;
}
# }}}
 
# {{{ iTrunc
/**
* Truncates a string to a certain length at the most sensible point.
* First, if there's a '.' character near the end of the string, the string is truncated after this character.
* If there is no '.', the string is truncated after the last ' ' character.
* If the string is truncated, " ..." is appended.
* If the string is already shorter than $length, it is returned unchanged.
*
* @static
* @param string string A string to be truncated.
* @param int length the maximum length the string should be truncated to
* @return string the truncated string
*/
function iTrunc($string, $length) {
if (strlen($string)<=$length) {
return $string;
}
$pos = strrpos($string,".");
if ($pos>=$length-4) {
$string = substr($string,0,$length-4);
$pos = strrpos($string,".");
}
if ($pos>=$length*0.4) {
return substr($string,0,$pos+1)." ...";
}
$pos = strrpos($string," ");
if ($pos>=$length-4) {
$string = substr($string,0,$length-4);
$pos = strrpos($string," ");
}
if ($pos>=$length*0.4) {
return substr($string,0,$pos)." ...";
}
return substr($string,0,$length-4)." ...";
}
# }}}
 
# {{{ _createGeneratorComment
/**
* Creates a comment indicating the generator of this feed.
* The format of this comment seems to be recognized by
* Syndic8.com.
*/
function _createGeneratorComment() {
return "<!-- generator=\"".FEEDCREATOR_VERSION."\" -->\n";
}
# }}}
 
# {{{ _createAdditionalElements
/**
* Creates a string containing all additional elements specified in
* $additionalElements.
* @param elements array an associative array containing key => value pairs
* @param indentString string a string that will be inserted before every generated line
* @return string the XML tags corresponding to $additionalElements
*/
function _createAdditionalElements($elements, $indentString="") {
$ae = "";
if (is_array($elements)) {
foreach($elements AS $key => $value) {
$ae.= $indentString."<$key>$value</$key>\n";
}
}
return $ae;
}
# }}}
 
# {{{ createFeed
/**
* Builds the feed's text.
* @abstract
* @return string the feed's complete text
*/
function createFeed() {
}
# }}}
 
# {{{ _generateFilename
/**
* Generate a filename for the feed cache file. The result will be $_SERVER["PHP_SELF"] with the extension changed to .xml.
* For example:
*
* echo $_SERVER["PHP_SELF"]."\n";
* echo FeedCreator::_generateFilename();
*
* would produce:
*
* /rss/latestnews.php
* latestnews.xml
*
* @return string the feed cache filename
* @since 1.4
* @access private
*/
function _generateFilename() {
$fileInfo = pathinfo($_SERVER["PHP_SELF"]);
return substr($fileInfo["basename"],0,-(strlen($fileInfo["extension"])+1)).".xml";
}
# }}}
 
# {{{ _redirect
/**
* @since 1.4
* @access private
*/
function _redirect($filename) {
// attention, heavily-commented-out-area
// maybe use this in addition to file time checking
//Header("Expires: ".date("r",time()+$this->_timeout));
/* no caching at all, doesn't seem to work as good:
Header("Cache-Control: no-cache");
Header("Pragma: no-cache");
*/
// HTTP redirect, some feed readers' simple HTTP implementations don't follow it
//Header("Location: ".$filename);
 
Header("Content-Type: ".$this->contentType."; filename=".basename($filename));
Header("Content-Disposition: inline; filename=".basename($filename));
readfile($filename, "r");
die();
}
# }}}
 
# {{{ useCached
/**
* Turns on caching and checks if there is a recent version of this feed in the cache.
* If there is, an HTTP redirect header is sent.
* To effectively use caching, you should create the FeedCreator object and call this method
* before anything else, especially before you do the time consuming task to build the feed
* (web fetching, for example).
* @since 1.4
* @param filename string optional the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()).
* @param timeout int optional the timeout in seconds before a cached version is refreshed (defaults to 3600 = 1 hour)
*/
function useCached($filename="", $timeout=3600) {
$this->_timeout = $timeout;
if ($filename=="") {
$filename = $this->_generateFilename();
}
if (file_exists($filename) AND (time()-filemtime($filename) < $timeout)) {
$this->_redirect($filename);
}
}
# }}}
 
# {{{ saveFeed
/**
* Saves this feed as a file on the local disk. After the file is saved, a redirect
* header may be sent to redirect the user to the newly created file.
* @since 1.4
*
* @param filename string optional the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()).
* @param redirect boolean optional send an HTTP redirect header or not. If true, the user will be automatically redirected to the created file.
*/
function saveFeed($filename="", $displayContents=true) {
if ($filename=="") {
$filename = $this->_generateFilename();
}
$feedFile = fopen($filename, "w+");
if ($feedFile) {
fputs($feedFile,$this->createFeed());
fclose($feedFile);
if ($displayContents) {
$this->_redirect($filename);
}
} else {
echo "<br /><b>Error creating feed file, please check write permissions.</b><br />";
}
}
# }}}
}
 
 
/**
* FeedDate is an internal class that stores a date for a feed or feed item.
* Usually, you won't need to use this.
*/
class FeedDate {
var $unix;
 
# {{{ __construct
/**
* Creates a new instance of FeedDate representing a given date.
* Accepts RFC 822, ISO 8601 date formats as well as unix time stamps.
* @param mixed $dateString optional the date this FeedDate will represent. If not specified, the current date and time is used.
*/
function FeedDate($dateString="") {
if ($dateString=="") $dateString = date("r");
if (is_integer($dateString)) {
$this->unix = $dateString;
return;
}
if (preg_match("~(?:(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),\\s+)?(\\d{1,2})\\s+([a-zA-Z]{3})\\s+(\\d{4})\\s+(\\d{2}):(\\d{2}):(\\d{2})\\s+(.*)~",$dateString,$matches)) {
$months = Array("Jan"=>1,"Feb"=>2,"Mar"=>3,"Apr"=>4,"May"=>5,"Jun"=>6,"Jul"=>7,"Aug"=>8,"Sep"=>9,"Oct"=>10,"Nov"=>11,"Dec"=>12);
$this->unix = mktime($matches[4],$matches[5],$matches[6],$months[$matches[2]],$matches[1],$matches[3]);
if (substr($matches[7],0,1)=='+' OR substr($matches[7],0,1)=='-') {
$tzOffset = (substr($matches[7],0,3) * 60 + substr($matches[7],-2)) * 60;
} else {
if (strlen($matches[7])==1) {
$oneHour = 3600;
$ord = ord($matches[7]);
if ($ord < ord("M")) {
$tzOffset = (ord("A") - $ord - 1) * $oneHour;
} elseif ($ord >= ord("M") AND $matches[7]!="Z") {
$tzOffset = ($ord - ord("M")) * $oneHour;
} elseif ($matches[7]=="Z") {
$tzOffset = 0;
}
}
switch ($matches[7]) {
case "UT":
case "GMT": $tzOffset = 0;
}
}
$this->unix += $tzOffset;
return;
}
if (preg_match("~(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(.*)~",$dateString,$matches)) {
$this->unix = mktime($matches[4],$matches[5],$matches[6],$matches[2],$matches[3],$matches[1]);
if (substr($matches[7],0,1)=='+' OR substr($matches[7],0,1)=='-') {
$tzOffset = (substr($matches[7],0,3) * 60 + substr($matches[7],-2)) * 60;
} else {
if ($matches[7]=="Z") {
$tzOffset = 0;
}
}
$this->unix += $tzOffset;
return;
}
$this->unix = 0;
}
# }}}
 
# {{{ rfc822
/**
* Gets the date stored in this FeedDate as an RFC 822 date.
*
* @return a date in RFC 822 format
*/
function rfc822() {
return gmdate("r",$this->unix);
}
# }}}
 
# {{{ iso8601
/**
* Gets the date stored in this FeedDate as an ISO 8601 date.
*
* @return a date in ISO 8601 format
*/
function iso8601() {
$date = gmdate("Y-m-d\TH:i:sO",$this->unix);
$date = substr($date,0,22) . ':' . substr($date,-2);
return $date;
}
# }}}
 
# {{{ unix
/**
* Gets the date stored in this FeedDate as unix time stamp.
*
* @return a date as a unix time stamp
*/
function unix() {
return $this->unix;
}
# }}}
}
 
 
/**
* RSSCreator10 is a FeedCreator that implements RDF Site Summary (RSS) 1.0.
*
* @see http://www.purl.org/rss/1.0/
* @since 1.3
* @author Kai Blankenhorn <kaib@bitfolge.de>
*/
class RSSCreator10 extends FeedCreator {
 
# {{{ createFeed
/**
* Builds the RSS feed's text. The feed will be compliant to RDF Site Summary (RSS) 1.0.
* The feed will contain all items previously added in the same order.
* @return string the feed's complete text
*/
function createFeed() {
global $config;
$feed = "<?xml version=\"1.0\" encoding=\"".$config->outputEnc."\"?>\n";
$feed.= "<?xml-stylesheet href=\"http://www.w3.org/2000/08/w3c-synd/style.css\" type=\"text/css\"?>\n";
$feed.= $this->_createGeneratorComment();
$feed.= "<rdf:RDF\n";
$feed.= " xmlns=\"http://purl.org/rss/1.0/\"\n";
$feed.= " xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n";
$feed.= " xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n";
$feed.= " <channel rdf:about=\"".htmlspecialchars($this->syndicationURL)."\">\n";
$feed.= " <title>".htmlspecialchars($this->title)."</title>\n";
$feed.= " <description>".htmlspecialchars($this->description)."</description>\n";
$feed.= " <link>".htmlspecialchars($this->link)."</link>\n";
if ($this->image!=null) {
$feed.= " <image rdf:resource=\"".$this->image->url."\" />\n";
}
$now = new FeedDate();
$feed.= " <dc:date>".htmlspecialchars($now->iso8601())."</dc:date>\n";
$feed.= " <items>\n";
$feed.= " <rdf:Seq>\n";
for ($i=0;$i<count($this->items);$i++) {
$feed.= " <rdf:li rdf:resource=\"".htmlspecialchars($this->items[$i]->link)."\"/>\n";
}
$feed.= " </rdf:Seq>\n";
$feed.= " </items>\n";
$feed.= " </channel>\n";
if ($this->image!=null) {
$feed.= " <image rdf:about=\"".$this->image->url."\">\n";
$feed.= " <title>".$this->image->title."</title>\n";
$feed.= " <link>".$this->image->link."</link>\n";
$feed.= " <url>".$this->image->url."</url>\n";
$feed.= " </image>\n";
}
//$feed.= $this->_createAdditionalElements($this->items[$i]->additionalElements, " ");
for ($i=0;$i<count($this->items);$i++) {
$feed.= " <item rdf:about=\"".htmlspecialchars($this->items[$i]->link)."\">\n";
//$feed.= " <dc:type>Posting</dc:type>\n";
$feed.= " <dc:format>text/html</dc:format>\n";
if ($this->items[$i]->date!=null) {
$itemDate = new FeedDate($this->items[$i]->date);
$feed.= " <dc:date>".htmlspecialchars($itemDate->iso8601())."</dc:date>\n";
}
if ($this->items[$i]->source!="") {
$feed.= " <dc:source>".htmlspecialchars($this->items[$i]->source)."</dc:source>\n";
}
if ($this->items[$i]->author!="") {
$feed.= " <dc:creator>".htmlspecialchars($this->items[$i]->author)."</dc:creator>\n";
}
$feed.= " <title>".htmlspecialchars(strip_tags(strtr($this->items[$i]->title,"\n\r"," ")))."</title>\n";
$feed.= " <link>".htmlspecialchars($this->items[$i]->link)."</link>\n";
$feed.= " <description>".htmlspecialchars($this->items[$i]->description)."</description>\n";
$feed.= $this->_createAdditionalElements($this->items[$i]->additionalElements, " ");
$feed.= " </item>\n";
}
$feed.= "</rdf:RDF>\n";
return $feed;
}
# }}}
}
 
 
 
/**
* RSSCreator091 is a FeedCreator that implements RSS 0.91 Spec, revision 3.
*
* @see http://my.netscape.com/publish/formats/rss-spec-0.91.html
* @since 1.3
* @author Kai Blankenhorn <kaib@bitfolge.de>
*/
class RSSCreator091 extends FeedCreator {
 
/**
* Stores this RSS feed's version number.
* @access private
*/
var $RSSVersion;
 
# {{{ __construct
function RSSCreator091() {
$this->_setRSSVersion("0.91");
$this->contentType = "application/rss+xml";
}
# }}}
 
# {{{ _setRSSVersion
/**
* Sets this RSS feed's version number.
* @access private
*/
function _setRSSVersion($version) {
$this->RSSVersion = $version;
}
# }}}
 
# {{{ createFeed
/**
* Builds the RSS feed's text. The feed will be compliant to RDF Site Summary (RSS) 1.0.
* The feed will contain all items previously added in the same order.
* @return string the feed's complete text
*/
function createFeed() {
global $config;
$feed = "<?xml version=\"1.0\" encoding=\"".$config->outputEnc."\"?>\n";
$feed.= $this->_createGeneratorComment();
$feed.= "<rss version=\"".$this->RSSVersion."\">\n";
$feed.= " <channel>\n";
$feed.= " <title>".FeedCreator::iTrunc(htmlspecialchars($this->title),100)."</title>\n";
$feed.= " <description>".FeedCreator::iTrunc(htmlspecialchars($this->description),500)."</description>\n";
$feed.= " <link>".htmlspecialchars($this->link)."</link>\n";
$now = new FeedDate();
$feed.= " <lastBuildDate>".htmlspecialchars($now->rfc822())."</lastBuildDate>\n";
$feed.= " <generator>".FEEDCREATOR_VERSION."</generator>\n";
 
if ($this->image!=null) {
$feed.= " <image>\n";
$feed.= " <url>".$this->image->url."</url>\n";
$feed.= " <title>".FeedCreator::iTrunc(htmlspecialchars($this->image->title),100)."</title>\n";
$feed.= " <link>".$this->image->link."</link>\n";
if ($this->image->width!="") {
$feed.= " <width>".$this->image->width."</width>\n";
}
if ($this->image->height!="") {
$feed.= " <height>".$this->image->height."</height>\n";
}
if ($this->image->description!="") {
$feed.= " <description>".htmlspecialchars($this->image->description)."</description>\n";
}
$feed.= " </image>\n";
}
if ($this->language!="") {
$feed.= " <language>".$this->language."</language>\n";
}
if ($this->copyright!="") {
$feed.= " <copyright>".FeedCreator::iTrunc(htmlspecialchars($this->copyright),100)."</copyright>\n";
}
if ($this->editor!="") {
$feed.= " <managingEditor>".FeedCreator::iTrunc(htmlspecialchars($this->editor),100)."</managingEditor>\n";
}
if ($this->webmaster!="") {
$feed.= " <webMaster>".FeedCreator::iTrunc(htmlspecialchars($this->webmaster),100)."</webMaster>\n";
}
if ($this->pubDate!="") {
$pubDate = new FeedDate($this->pubDate);
$feed.= " <pubDate>".htmlspecialchars($pubDate->rfc822())."</pubDate>\n";
}
if ($this->category!="") {
$feed.= " <category>".htmlspecialchars($this->category)."</category>\n";
}
if ($this->docs!="") {
$feed.= " <docs>".FeedCreator::iTrunc(htmlspecialchars($this->docs),500)."</docs>\n";
}
if ($this->ttl!="") {
$feed.= " <ttl>".htmlspecialchars($this->ttl)."</ttl>\n";
}
if ($this->rating!="") {
$feed.= " <rating>".FeedCreator::iTrunc(htmlspecialchars($this->rating),500)."</rating>\n";
}
if ($this->skipHours!="") {
$feed.= " <skipHours>".htmlspecialchars($this->skipHours)."</skipHours>\n";
}
if ($this->skipDays!="") {
$feed.= " <skipDays>".htmlspecialchars($this->skipDays)."</skipDays>\n";
}
$feed.= $this->_createAdditionalElements($this->additionalElements, " ");
 
for ($i=0;$i<count($this->items);$i++) {
$feed.= " <item>\n";
$feed.= " <title>".FeedCreator::iTrunc(htmlspecialchars(strip_tags($this->items[$i]->title)),100)."</title>\n";
$feed.= " <link>".htmlspecialchars($this->items[$i]->link)."</link>\n";
$feed.= " <description>".htmlspecialchars($this->items[$i]->description)."</description>\n";
if ($this->items[$i]->author!="") {
$feed.= " <author>".htmlspecialchars($this->items[$i]->author)."</author>\n";
}
/*
// on hold
if ($this->items[$i]->source!="") {
$feed.= " <source>".htmlspecialchars($this->items[$i]->source)."</source>\n";
}
*/
if ($this->items[$i]->category!="") {
$feed.= " <category>".htmlspecialchars($this->items[$i]->category)."</category>\n";
}
if ($this->items[$i]->comments!="") {
$feed.= " <comments>".$this->items[$i]->comments."</comments>\n";
}
if ($this->items[$i]->date!="") {
$itemDate = new FeedDate($this->items[$i]->date);
$feed.= " <pubDate>".htmlspecialchars($itemDate->rfc822())."</pubDate>\n";
}
if ($this->items[$i]->guid!="") {
$feed.= " <guid>".$this->items[$i]->guid."</guid>\n";
}
$feed.= $this->_createAdditionalElements($this->items[$i]->additionalElements, " ");
$feed.= " </item>\n";
}
$feed.= " </channel>\n";
$feed.= "</rss>\n";
return $feed;
}
# }}}
}
 
 
 
/**
* RSSCreator20 is a FeedCreator that implements RDF Site Summary (RSS) 2.0.
*
* @see http://backend.userland.com/rss
* @since 1.3
* @author Kai Blankenhorn <kaib@bitfolge.de>
*/
class RSSCreator20 extends RSSCreator091 {
 
# {{{ __construct
function RSSCreator20() {
parent::_setRSSVersion("2.0");
}
# }}}
 
}
 
 
/**
* PIECreator01 is a FeedCreator that implements the emerging PIE specification,
* as in http://intertwingly.net/wiki/pie/Syntax.
*
* @deprecated
* @since 1.3
* @author Scott Reynen <scott@randomchaos.com> and Kai Blankenhorn <kaib@bitfolge.de>
*/
class PIECreator01 extends FeedCreator {
 
# {{{ createFeed
function createFeed() {
$feed = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
$feed.= "<feed version=\"0.1\" xmlns=\"http://example.com/newformat#\">\n";
$feed.= " <title>".FeedCreator::iTrunc(htmlspecialchars($this->title),100)."</title>\n";
$feed.= " <subtitle>".FeedCreator::iTrunc(htmlspecialchars($this->description),500)."</subtitle>\n";
$feed.= " <link>".$this->link."</link>\n";
for ($i=0;$i<count($this->items);$i++) {
$feed.= " <entry>\n";
$feed.= " <title>".FeedCreator::iTrunc(htmlspecialchars(strip_tags($this->items[$i]->title)),100)."</title>\n";
$feed.= " <link>".htmlspecialchars($this->items[$i]->link)."</link>\n";
$itemDate = new FeedDate($this->items[$i]->date);
$feed.= " <created>".htmlspecialchars($itemDate->iso8601())."</created>\n";
$feed.= " <issued>".htmlspecialchars($itemDate->iso8601())."</issued>\n";
$feed.= " <modified>".htmlspecialchars($itemDate->iso8601())."</modified>\n";
$feed.= " <id>".$this->items[$i]->guid."</id>\n";
if ($this->items[$i]->author!="") {
$feed.= " <author>\n";
$feed.= " <name>".htmlspecialchars($this->items[$i]->author)."</name>\n";
if ($this->items[$i]->authorEmail!="") {
$feed.= " <email>".$this->items[$i]->authorEmail."</email>\n";
}
$feed.=" </author>\n";
}
$feed.= " <content type=\"text/html\" xml:lang=\"en-us\">\n";
$feed.= " <div xmlns=\"http://www.w3.org/1999/xhtml\">".$this->items[$i]->description."</div>\n";
$feed.= " </content>\n";
$feed.= " </entry>\n";
}
$feed.= "</feed>\n";
return $feed;
}
# }}}
}
 
 
/**
* AtomCreator03 is a FeedCreator that implements the atom specification,
* as in http://www.intertwingly.net/wiki/pie/FrontPage.
* Please note that just by using AtomCreator03 you won't automatically
* produce valid atom files. For example, you have to specify either an editor
* for the feed or an author for every single feed item.
*
* Some elements have not been implemented yet. These are (incomplete list):
* author URL, item author's email and URL, item contents, alternate links,
* other link content types than text/html. Some of them may be created with
* AtomCreator03::additionalElements.
*
* @see FeedCreator#additionalElements
* @since 1.6
* @author Kai Blankenhorn <kaib@bitfolge.de>, Scott Reynen <scott@randomchaos.com>
*/
class AtomCreator03 extends FeedCreator {
 
# {{{ __construct
function AtomCreator03() {
$this->contentType = "application/atom+xml";
}
# }}}
 
# {{{ createFeed
function createFeed() {
$feed = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
$feed.= $this->_createGeneratorComment();
$feed.= "<feed version=\"0.3\" xmlns=\"http://purl.org/atom/ns#\"";
if ($this->language!="") {
$feed.= " xml:lang:\"".$this->language."\"";
}
$feed.= ">\n";
$feed.= " <title>".htmlspecialchars($this->title)."</title>\n";
$feed.= " <tagline>".htmlspecialchars($this->description)."</tagline>\n";
$feed.= " <link rel=\"alternate\" type=\"text/html\" href=\"".htmlspecialchars($this->link)."\"/>\n";
$feed.= " <id>".$this->link."</id>\n";
$now = new FeedDate();
$feed.= " <modified>".htmlspecialchars($now->iso8601())."</modified>\n";
if ($this->editor!="") {
$feed.= " <author>\n";
$feed.= " <name>".$this->editor."</name>\n";
if ($this->editorEmail!="") {
$feed.= " <email>".$this->editorEmail."</email>\n";
}
$feed.= " </author>\n";
}
$feed.= " <generator>".FEEDCREATOR_VERSION."</generator>\n";
$feed.= $this->_createAdditionalElements($this->additionalElements, " ");
for ($i=0;$i<count($this->items);$i++) {
$feed.= " <entry>\n";
$feed.= " <title>".htmlspecialchars(strip_tags($this->items[$i]->title))."</title>\n";
$feed.= " <link rel=\"alternate\" type=\"text/html\" href=\"".htmlspecialchars($this->items[$i]->link)."\"/>\n";
if ($this->items[$i]->date=="") {
$this->items[$i]->date = time();
}
$itemDate = new FeedDate($this->items[$i]->date);
$feed.= " <created>".htmlspecialchars($itemDate->iso8601())."</created>\n";
$feed.= " <issued>".htmlspecialchars($itemDate->iso8601())."</issued>\n";
$feed.= " <modified>".htmlspecialchars($itemDate->iso8601())."</modified>\n";
$feed.= " <id>".$this->items[$i]->link."</id>\n";
$feed.= $this->_createAdditionalElements($this->items[$i]->additionalElements, " ");
if ($this->items[$i]->author!="") {
$feed.= " <author>\n";
$feed.= " <name>".htmlspecialchars($this->items[$i]->author)."</name>\n";
$feed.= " </author>\n";
}
if ($this->items[$i]->description!="") {
$feed.= " <summary>".htmlspecialchars($this->items[$i]->description)."</summary>\n";
}
$feed.= " </entry>\n";
}
$feed.= "</feed>\n";
return $feed;
}
# }}}
}
 
 
/**
* MBOXCreator is a FeedCreator that implements the mbox format
* as described in http://www.qmail.org/man/man5/mbox.html
*
* @since 1.3
* @author Kai Blankenhorn <kaib@bitfolge.de>
*/
class MBOXCreator extends FeedCreator {
 
# {{{ __construct
function MBOXCreator() {
$this->contentType = "text/plain";
}
# }}}
 
# {{{ qp_enc
function qp_enc($input = "", $line_max = 76) {
$hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
$lines = preg_split("/(?:\r\n|\r|\n)/", $input);
$eol = "\r\n";
$escape = "=";
$output = "";
while( list(, $line) = each($lines) ) {
//$line = rtrim($line); // remove trailing white space -> no =20\r\n necessary
$linlen = strlen($line);
$newline = "";
for($i = 0; $i < $linlen; $i++) {
$c = substr($line, $i, 1);
$dec = ord($c);
if ( ($dec == 32) && ($i == ($linlen - 1)) ) { // convert space at eol only
$c = "=20";
} elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) { // always encode "\t", which is *not* required
$h2 = floor($dec/16); $h1 = floor($dec%16);
$c = $escape.$hex["$h2"].$hex["$h1"];
}
if ( (strlen($newline) + strlen($c)) >= $line_max ) { // CRLF is not counted
$output .= $newline.$escape.$eol; // soft line break; " =\r\n" is okay
$newline = "";
}
$newline .= $c;
} // end of for
$output .= $newline.$eol;
}
return trim($output);
}
# }}}
 
# {{{ createFeed
/**
* Builds the MBOX contents.
* @return string the feed's complete text
*/
function createFeed() {
global $config;
for ($i=0;$i<count($this->items);$i++) {
if ($this->items[$i]->author!="") {
$from = $this->items[$i]->author;
} else {
$from = $this->title;
}
$itemDate = new FeedDate($this->items[$i]->date);
$feed.= "From ".strtr(MBOXCreator::qp_enc($from)," ","_")." ".date("D M d H:i:s Y",$itemDate->unix())."\n";
$feed.= "Content-Type: text/plain;\n";
$feed.= " charset=\"".$config->outputEnc."\"\n";
$feed.= "Content-Transfer-Encoding: quoted-printable\n";
$feed.= "Content-Type: text/plain\n";
$feed.= "From: \"".MBOXCreator::qp_enc($from)."\"\n";
$feed.= "Date: ".$itemDate->rfc822()."\n";
$feed.= "Subject: ".MBOXCreator::qp_enc(FeedCreator::iTrunc($this->items[$i]->title,100))."\n";
$feed.= "\n";
$body = chunk_split(MBOXCreator::qp_enc($this->items[$i]->description));
$feed.= preg_replace("~\nFrom ([^\n]*)(\n?)~","\n>From $1$2\n",$body);
$feed.= "\n";
$feed.= "\n";
}
return $feed;
}
# }}}
 
# {{{ _generateFilename
/**
* Generate a filename for the feed cache file. Overridden from FeedCreator to prevent XML data types.
* @return string the feed cache filename
* @since 1.4
* @access private
*/
function _generateFilename() {
$fileInfo = pathinfo($_SERVER["PHP_SELF"]);
return substr($fileInfo["basename"],0,-(strlen($fileInfo["extension"])+1)).".mbox";
}
# }}}
}
 
 
/**
* OPMLCreator is a FeedCreator that implements OPML 1.0.
*
* @see http://opml.scripting.com/spec
* @author Dirk Clemens, Kai Blankenhorn
* @since 1.5
*/
class OPMLCreator extends FeedCreator {
# {{{ createFeed
function createFeed() {
$feed = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
$feed.= $this->_createGeneratorComment();
$feed.= "<opml xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n";
$feed.= " <head>\n";
$feed.= " <title>".htmlspecialchars($this->title)."</title>\n";
if ($this->pubDate!="") {
$date = new FeedDate($this->pubDate);
$feed.= " <dateCreated>".$date->rfc822()."</dateCreated>\n";
}
if ($this->lastBuildDate!="") {
$date = new FeedDate($this->lastBuildDate);
$feed.= " <dateModified>".$date->rfc822()."</dateModified>\n";
}
if ($this->editor!="") {
$feed.= " <ownerName>".$this->editor."</ownerName>\n";
}
if ($this->editorEmail!="") {
$feed.= " <ownerEmail>".$this->editorEmail."</ownerEmail>\n";
}
$feed.= " </head>\n";
$feed.= " <body>\n";
for ($i=0;$i<count($this->items);$i++) {
$feed.= " <outline type=\"rss\" ";
$title = htmlspecialchars(strip_tags(strtr($this->items[$i]->title,"\n\r"," ")));
$feed.= " title=\"".$title."\"";
$feed.= " text=\"".$title."\"";
//$feed.= " description=\"".htmlspecialchars($this->items[$i]->description)."\"";
$feed.= " url=\"".htmlspecialchars($this->items[$i]->link)."\"";
$feed.= "/>\n";
}
$feed.= " </body>\n";
$feed.= "</opml>\n";
return $feed;
}
# }}}
}
 
?>
<?php
# vim:et:ts=4:sts=4:sw=4:fdm=marker:
# {{{ Info
/***************************************************************************
 
FeedCreator class v1.6
originally (c) Kai Blankenhorn
www.bitfolge.de
kaib@bitfolge.de
v1.3 work by Scott Reynen (scott@randomchaos.com) and Kai Blankenhorn
v1.5 OPML support by Dirk Clemens
 
This program 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.
 
This program 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: <http://www.gnu.org/licenses/gpl.txt>
 
****************************************************************************
 
 
Changelog:
 
Modifications for WebSVN:
The main description link wasn't put through htmlspecialcharacters
Output encoding now defined by $config
Remove hardcoded time zone
 
v1.6 05-10-04
added stylesheet to RSS 1.0 feeds
fixed generator comment (thanks Kevin L. Papendick and Tanguy Pruvot)
fixed RFC822 date bug (thanks Tanguy Pruvot)
added TimeZone customization for RFC8601 (thanks Tanguy Pruvot)
fixed Content-type could be empty (thanks Tanguy Pruvot)
fixed author/creator in RSS1.0 (thanks Tanguy Pruvot)
 
 
v1.6 beta 02-28-04
added Atom 0.3 support (not all features, though)
improved OPML 1.0 support (hopefully - added more elements)
added support for arbitrary additional elements (use with caution)
code beautification :-)
considered beta due to some internal changes
 
v1.5.1 01-27-04
fixed some RSS 1.0 glitches (thanks to Stéphane Vanpoperynghe)
fixed some inconsistencies between documentation and code (thanks to Timothy Martin)
 
v1.5 01-06-04
added support for OPML 1.0
added more documentation
 
v1.4 11-11-03
optional feed saving and caching
improved documentation
minor improvements
 
v1.3 10-02-03
renamed to FeedCreator, as it not only creates RSS anymore
added support for mbox
tentative support for echo/necho/atom/pie/???
v1.2 07-20-03
intelligent auto-truncating of RSS 0.91 attributes
don't create some attributes when they're not set
documentation improved
fixed a real and a possible bug with date conversions
code cleanup
 
v1.1 06-29-03
added images to feeds
now includes most RSS 0.91 attributes
added RSS 2.0 feeds
 
v1.0 06-24-03
initial release
 
 
 
***************************************************************************/
 
/*** GENERAL USAGE *********************************************************
 
include("feedcreator.class.php");
 
$rss = new UniversalFeedCreator();
$rss->useCached(); // use cached version if age<1 hour
$rss->title = "PHP news";
$rss->description = "daily news from the PHP scripting world";
$rss->link = "http://www.dailyphp.net/news";
$rss->syndicationURL = "http://www.dailyphp.net/".$_SERVER["PHP_SELF"];
 
$image = new FeedImage();
$image->title = "dailyphp.net logo";
$image->url = "http://www.dailyphp.net/images/logo.gif";
$image->link = "http://www.dailyphp.net";
$image->description = "Feed provided by dailyphp.net. Click to visit.";
$rss->image = $image;
 
// get your news items from somewhere, e.g. your database:
mysql_select_db($dbHost, $dbUser, $dbPass);
$res = mysql_query("SELECT * FROM news ORDER BY newsdate DESC");
while ($data = mysql_fetch_object($res)) {
$item = new FeedItem();
$item->title = $data->title;
$item->link = $data->url;
$item->description = $data->short;
$item->date = $data->newsdate;
$item->source = "http://www.dailyphp.net";
$item->author = "John Doe";
$rss->addItem($item);
}
 
// valid format strings are: RSS0.91, RSS1.0, RSS2.0, PIE0.1 (deprecated),
// MBOX, OPML, ATOM0.3
echo $rss->saveFeed("RSS1.0", "news/feed.xml");
 
# }}}
 
***************************************************************************
* A little setup *
**************************************************************************/
 
/**
* Version string.
**/
define("FEEDCREATOR_VERSION", "FeedCreator 1.6");
 
 
 
/**
* A FeedItem is a part of a FeedCreator feed.
*
* @author Kai Blankenhorn <kaib@bitfolge.de>
* @since 1.3
*/
class FeedItem {
# {{{ Properties
 
/**
* Mandatory attributes of an item.
*/
var $title, $description, $link;
/**
* Optional attributes of an item.
*/
var $author, $authorEmail, $image, $category, $comments, $guid, $source, $creator;
/**
* Publishing date of an item. May be in one of the following formats:
*
* RFC 822:
* "Mon, 20 Jan 03 18:05:41 +0400"
* "20 Jan 03 18:05:41 +0000"
*
* ISO 8601:
* "2003-01-20T18:05:41+04:00"
*
* Unix:
* 1043082341
*/
var $date;
/**
* Any additional elements to include as an assiciated array. All $key => $value pairs
* will be included unencoded in the feed item in the form
* <$key>$value</$key>
* Again: No encoding will be used! This means you can invalidate or enhance the feed
* if $value contains markup. This may be abused to embed tags not implemented by
* the FeedCreator class used.
*/
var $additionalElements = Array();
 
// on hold
// var $source;
 
# }}}
}
 
 
 
/**
* An FeedImage may be added to a FeedCreator feed.
* @author Kai Blankenhorn <kaib@bitfolge.de>
* @since 1.3
*/
class FeedImage {
# {{{ Properties
 
/**
* Mandatory attributes of an image.
*/
var $title, $url, $link;
/**
* Optional attributes of an image.
*/
var $width, $height, $description;
 
# }}}
}
 
 
/**
* UniversalFeedCreator lets you choose during runtime which
* format to build.
* For general usage of a feed class, see the FeedCreator class
* below or the example above.
*
* @since 1.3
* @author Kai Blankenhorn <kaib@bitfolge.de>
*/
class UniversalFeedCreator extends FeedCreator {
var $_feed;
# {{{ _setFormat
function _setFormat($format) {
switch (strtoupper($format)) {
case "2.0":
// fall through
case "RSS2.0":
$this->_feed = new RSSCreator20();
break;
case "1.0":
// fall through
case "RSS1.0":
$this->_feed = new RSSCreator10();
break;
case "0.91":
// fall through
case "RSS0.91":
$this->_feed = new RSSCreator091();
break;
case "PIE0.1":
$this->_feed = new PIECreator01();
break;
case "MBOX":
$this->_feed = new MBOXCreator();
break;
case "OPML":
$this->_feed = new OPMLCreator();
break;
case "ATOM0.3":
$this->_feed = new AtomCreator03();
break;
default:
$this->_feed = new RSSCreator091();
break;
}
$vars = get_object_vars($this);
foreach ($vars as $key => $value) {
if ($key!="feed") {
$this->_feed->{$key} = $this->{$key};
}
}
}
# }}}
# {{{ createFeed
/**
* Creates a syndication feed based on the items previously added.
*
* @see FeedCreator::addItem()
* @param string format format the feed should comply to. Valid values are:
* "PIE0.1", "mbox", "RSS0.91", "RSS1.0", "RSS2.0", "OPML".
* @return string the contents of the feed.
*/
function createFeed($format = "RSS0.91") {
$this->_setFormat($format);
return $this->_feed->createFeed();
}
# }}}
 
# {{{ saveFeed
/**
* Saves this feed as a file on the local disk. After the file is saved, an HTTP redirect
* header may be sent to redirect the use to the newly created file.
* @since 1.4
*
* @param string format format the feed should comply to. Valid values are:
* "PIE0.1" (deprecated), "mbox", "RSS0.91", "RSS1.0", "RSS2.0", "OPML", "ATOM0.3".
* @param string filename optional the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()).
* @param boolean displayContents optional send the content of the file or not. If true, the file will be sent in the body of the response.
*/
function saveFeed($format="RSS0.91", $filename="", $displayContents=true) {
$this->_setFormat($format);
$this->_feed->saveFeed($filename, $displayContents);
}
# }}}
 
}
 
 
/**
* FeedCreator is the abstract base implementation for concrete
* implementations that implement a specific format of syndication.
*
* @abstract
* @author Kai Blankenhorn <kaib@bitfolge.de>
* @since 1.4
*/
class FeedCreator {
# {{{ Properties
 
/**
* Mandatory attributes of a feed.
*/
var $title, $description, $link;
 
 
/**
* Optional attributes of a feed.
*/
var $syndicationURL, $image, $language, $copyright, $pubDate, $lastBuildDate, $editor, $editorEmail, $webmaster, $category, $docs, $ttl, $rating, $skipHours, $skipDays;
 
 
/**
* @access private
*/
var $items = Array();
 
 
/**
* This feed's MIME content type.
* @since 1.4
* @access private
*/
var $contentType = "text/xml";
 
 
/**
* Any additional elements to include as an assiciated array. All $key => $value pairs
* will be included unencoded in the feed in the form
* <$key>$value</$key>
* Again: No encoding will be used! This means you can invalidate or enhance the feed
* if $value contains markup. This may be abused to embed tags not implemented by
* the FeedCreator class used.
*/
var $additionalElements = Array();
 
# }}}
# {{{ addItem
/**
* Adds an FeedItem to the feed.
*
* @param object FeedItem $item The FeedItem to add to the feed.
* @access public
*/
function addItem($item) {
$this->items[] = $item;
}
# }}}
 
# {{{ iTrunc
/**
* Truncates a string to a certain length at the most sensible point.
* First, if there's a '.' character near the end of the string, the string is truncated after this character.
* If there is no '.', the string is truncated after the last ' ' character.
* If the string is truncated, " ..." is appended.
* If the string is already shorter than $length, it is returned unchanged.
*
* @static
* @param string string A string to be truncated.
* @param int length the maximum length the string should be truncated to
* @return string the truncated string
*/
function iTrunc($string, $length) {
if (strlen($string)<=$length) {
return $string;
}
$pos = strrpos($string,".");
if ($pos>=$length-4) {
$string = substr($string,0,$length-4);
$pos = strrpos($string,".");
}
if ($pos>=$length*0.4) {
return substr($string,0,$pos+1)." ...";
}
$pos = strrpos($string," ");
if ($pos>=$length-4) {
$string = substr($string,0,$length-4);
$pos = strrpos($string," ");
}
if ($pos>=$length*0.4) {
return substr($string,0,$pos)." ...";
}
return substr($string,0,$length-4)." ...";
}
# }}}
 
# {{{ _createGeneratorComment
/**
* Creates a comment indicating the generator of this feed.
* The format of this comment seems to be recognized by
* Syndic8.com.
*/
function _createGeneratorComment() {
return "<!-- generator=\"".FEEDCREATOR_VERSION."\" -->\n";
}
# }}}
 
# {{{ _createAdditionalElements
/**
* Creates a string containing all additional elements specified in
* $additionalElements.
* @param elements array an associative array containing key => value pairs
* @param indentString string a string that will be inserted before every generated line
* @return string the XML tags corresponding to $additionalElements
*/
function _createAdditionalElements($elements, $indentString="") {
$ae = "";
if (is_array($elements)) {
foreach($elements AS $key => $value) {
$ae.= $indentString."<$key>$value</$key>\n";
}
}
return $ae;
}
# }}}
 
# {{{ createFeed
/**
* Builds the feed's text.
* @abstract
* @return string the feed's complete text
*/
function createFeed() {
}
# }}}
 
# {{{ _generateFilename
/**
* Generate a filename for the feed cache file. The result will be $_SERVER["PHP_SELF"] with the extension changed to .xml.
* For example:
*
* echo $_SERVER["PHP_SELF"]."\n";
* echo FeedCreator::_generateFilename();
*
* would produce:
*
* /rss/latestnews.php
* latestnews.xml
*
* @return string the feed cache filename
* @since 1.4
* @access private
*/
function _generateFilename() {
$fileInfo = pathinfo($_SERVER["PHP_SELF"]);
return substr($fileInfo["basename"],0,-(strlen($fileInfo["extension"])+1)).".xml";
}
# }}}
 
# {{{ _redirect
/**
* @since 1.4
* @access private
*/
function _redirect($filename) {
// attention, heavily-commented-out-area
// maybe use this in addition to file time checking
//Header("Expires: ".date("r",time()+$this->_timeout));
/* no caching at all, doesn't seem to work as good:
Header("Cache-Control: no-cache");
Header("Pragma: no-cache");
*/
// HTTP redirect, some feed readers' simple HTTP implementations don't follow it
//Header("Location: ".$filename);
 
Header("Content-Type: ".$this->contentType."; filename=".basename($filename));
Header("Content-Disposition: inline; filename=".basename($filename));
readfile($filename, "r");
die();
}
# }}}
 
# {{{ useCached
/**
* Turns on caching and checks if there is a recent version of this feed in the cache.
* If there is, an HTTP redirect header is sent.
* To effectively use caching, you should create the FeedCreator object and call this method
* before anything else, especially before you do the time consuming task to build the feed
* (web fetching, for example).
* @since 1.4
* @param filename string optional the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()).
* @param timeout int optional the timeout in seconds before a cached version is refreshed (defaults to 3600 = 1 hour)
*/
function useCached($filename="", $timeout=3600) {
$this->_timeout = $timeout;
if ($filename=="") {
$filename = $this->_generateFilename();
}
if (file_exists($filename) AND (time()-filemtime($filename) < $timeout)) {
$this->_redirect($filename);
}
}
# }}}
 
# {{{ saveFeed
/**
* Saves this feed as a file on the local disk. After the file is saved, a redirect
* header may be sent to redirect the user to the newly created file.
* @since 1.4
*
* @param filename string optional the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()).
* @param redirect boolean optional send an HTTP redirect header or not. If true, the user will be automatically redirected to the created file.
*/
function saveFeed($filename="", $displayContents=true) {
if ($filename=="") {
$filename = $this->_generateFilename();
}
$feedFile = fopen($filename, "w+");
if ($feedFile) {
fputs($feedFile,$this->createFeed());
fclose($feedFile);
if ($displayContents) {
$this->_redirect($filename);
}
} else {
echo "<br /><b>Error creating feed file, please check write permissions.</b><br />";
}
}
# }}}
}
 
 
/**
* FeedDate is an internal class that stores a date for a feed or feed item.
* Usually, you won't need to use this.
*/
class FeedDate {
var $unix;
 
# {{{ __construct
/**
* Creates a new instance of FeedDate representing a given date.
* Accepts RFC 822, ISO 8601 date formats as well as unix time stamps.
* @param mixed $dateString optional the date this FeedDate will represent. If not specified, the current date and time is used.
*/
function FeedDate($dateString="") {
if ($dateString=="") $dateString = date("r");
if (is_integer($dateString)) {
$this->unix = $dateString;
return;
}
if (preg_match("~(?:(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),\\s+)?(\\d{1,2})\\s+([a-zA-Z]{3})\\s+(\\d{4})\\s+(\\d{2}):(\\d{2}):(\\d{2})\\s+(.*)~",$dateString,$matches)) {
$months = Array("Jan"=>1,"Feb"=>2,"Mar"=>3,"Apr"=>4,"May"=>5,"Jun"=>6,"Jul"=>7,"Aug"=>8,"Sep"=>9,"Oct"=>10,"Nov"=>11,"Dec"=>12);
$this->unix = mktime($matches[4],$matches[5],$matches[6],$months[$matches[2]],$matches[1],$matches[3]);
if (substr($matches[7],0,1)=='+' OR substr($matches[7],0,1)=='-') {
$tzOffset = (substr($matches[7],0,3) * 60 + substr($matches[7],-2)) * 60;
} else {
if (strlen($matches[7])==1) {
$oneHour = 3600;
$ord = ord($matches[7]);
if ($ord < ord("M")) {
$tzOffset = (ord("A") - $ord - 1) * $oneHour;
} elseif ($ord >= ord("M") AND $matches[7]!="Z") {
$tzOffset = ($ord - ord("M")) * $oneHour;
} elseif ($matches[7]=="Z") {
$tzOffset = 0;
}
}
switch ($matches[7]) {
case "UT":
case "GMT": $tzOffset = 0;
}
}
$this->unix += $tzOffset;
return;
}
if (preg_match("~(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(.*)~",$dateString,$matches)) {
$this->unix = mktime($matches[4],$matches[5],$matches[6],$matches[2],$matches[3],$matches[1]);
if (substr($matches[7],0,1)=='+' OR substr($matches[7],0,1)=='-') {
$tzOffset = (substr($matches[7],0,3) * 60 + substr($matches[7],-2)) * 60;
} else {
if ($matches[7]=="Z") {
$tzOffset = 0;
}
}
$this->unix += $tzOffset;
return;
}
$this->unix = 0;
}
# }}}
 
# {{{ rfc822
/**
* Gets the date stored in this FeedDate as an RFC 822 date.
*
* @return a date in RFC 822 format
*/
function rfc822() {
return gmdate("r",$this->unix);
}
# }}}
 
# {{{ iso8601
/**
* Gets the date stored in this FeedDate as an ISO 8601 date.
*
* @return a date in ISO 8601 format
*/
function iso8601() {
$date = gmdate("Y-m-d\TH:i:sO",$this->unix);
$date = substr($date,0,22) . ':' . substr($date,-2);
return $date;
}
# }}}
 
# {{{ unix
/**
* Gets the date stored in this FeedDate as unix time stamp.
*
* @return a date as a unix time stamp
*/
function unix() {
return $this->unix;
}
# }}}
}
 
 
/**
* RSSCreator10 is a FeedCreator that implements RDF Site Summary (RSS) 1.0.
*
* @see http://www.purl.org/rss/1.0/
* @since 1.3
* @author Kai Blankenhorn <kaib@bitfolge.de>
*/
class RSSCreator10 extends FeedCreator {
 
# {{{ createFeed
/**
* Builds the RSS feed's text. The feed will be compliant to RDF Site Summary (RSS) 1.0.
* The feed will contain all items previously added in the same order.
* @return string the feed's complete text
*/
function createFeed() {
global $config;
$feed = "<?xml version=\"1.0\" encoding=\"".$config->outputEnc."\"?>\n";
$feed.= "<?xml-stylesheet href=\"http://www.w3.org/2000/08/w3c-synd/style.css\" type=\"text/css\"?>\n";
$feed.= $this->_createGeneratorComment();
$feed.= "<rdf:RDF\n";
$feed.= " xmlns=\"http://purl.org/rss/1.0/\"\n";
$feed.= " xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n";
$feed.= " xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n";
$feed.= " <channel rdf:about=\"".htmlspecialchars($this->syndicationURL)."\">\n";
$feed.= " <title>".htmlspecialchars($this->title)."</title>\n";
$feed.= " <description>".htmlspecialchars($this->description)."</description>\n";
$feed.= " <link>".htmlspecialchars($this->link)."</link>\n";
if ($this->image!=null) {
$feed.= " <image rdf:resource=\"".$this->image->url."\" />\n";
}
$now = new FeedDate();
$feed.= " <dc:date>".htmlspecialchars($now->iso8601())."</dc:date>\n";
$feed.= " <items>\n";
$feed.= " <rdf:Seq>\n";
for ($i=0;$i<count($this->items);$i++) {
$feed.= " <rdf:li rdf:resource=\"".htmlspecialchars($this->items[$i]->link)."\"/>\n";
}
$feed.= " </rdf:Seq>\n";
$feed.= " </items>\n";
$feed.= " </channel>\n";
if ($this->image!=null) {
$feed.= " <image rdf:about=\"".$this->image->url."\">\n";
$feed.= " <title>".$this->image->title."</title>\n";
$feed.= " <link>".$this->image->link."</link>\n";
$feed.= " <url>".$this->image->url."</url>\n";
$feed.= " </image>\n";
}
//$feed.= $this->_createAdditionalElements($this->items[$i]->additionalElements, " ");
for ($i=0;$i<count($this->items);$i++) {
$feed.= " <item rdf:about=\"".htmlspecialchars($this->items[$i]->link)."\">\n";
//$feed.= " <dc:type>Posting</dc:type>\n";
$feed.= " <dc:format>text/html</dc:format>\n";
if ($this->items[$i]->date!=null) {
$itemDate = new FeedDate($this->items[$i]->date);
$feed.= " <dc:date>".htmlspecialchars($itemDate->iso8601())."</dc:date>\n";
}
if ($this->items[$i]->source!="") {
$feed.= " <dc:source>".htmlspecialchars($this->items[$i]->source)."</dc:source>\n";
}
if ($this->items[$i]->author!="") {
$feed.= " <dc:creator>".htmlspecialchars($this->items[$i]->author)."</dc:creator>\n";
}
$feed.= " <title>".htmlspecialchars(strip_tags(strtr($this->items[$i]->title,"\n\r"," ")))."</title>\n";
$feed.= " <link>".htmlspecialchars($this->items[$i]->link)."</link>\n";
$feed.= " <description>".htmlspecialchars($this->items[$i]->description)."</description>\n";
$feed.= $this->_createAdditionalElements($this->items[$i]->additionalElements, " ");
$feed.= " </item>\n";
}
$feed.= "</rdf:RDF>\n";
return $feed;
}
# }}}
}
 
 
 
/**
* RSSCreator091 is a FeedCreator that implements RSS 0.91 Spec, revision 3.
*
* @see http://my.netscape.com/publish/formats/rss-spec-0.91.html
* @since 1.3
* @author Kai Blankenhorn <kaib@bitfolge.de>
*/
class RSSCreator091 extends FeedCreator {
 
/**
* Stores this RSS feed's version number.
* @access private
*/
var $RSSVersion;
 
# {{{ __construct
function RSSCreator091() {
$this->_setRSSVersion("0.91");
$this->contentType = "application/rss+xml";
}
# }}}
 
# {{{ _setRSSVersion
/**
* Sets this RSS feed's version number.
* @access private
*/
function _setRSSVersion($version) {
$this->RSSVersion = $version;
}
# }}}
 
# {{{ createFeed
/**
* Builds the RSS feed's text. The feed will be compliant to RDF Site Summary (RSS) 1.0.
* The feed will contain all items previously added in the same order.
* @return string the feed's complete text
*/
function createFeed() {
global $config;
$feed = "<?xml version=\"1.0\" encoding=\"".$config->outputEnc."\"?>\n";
$feed.= $this->_createGeneratorComment();
$feed.= "<rss version=\"".$this->RSSVersion."\">\n";
$feed.= " <channel>\n";
$feed.= " <title>".FeedCreator::iTrunc(htmlspecialchars($this->title),100)."</title>\n";
$feed.= " <description>".FeedCreator::iTrunc(htmlspecialchars($this->description),500)."</description>\n";
$feed.= " <link>".htmlspecialchars($this->link)."</link>\n";
$now = new FeedDate();
$feed.= " <lastBuildDate>".htmlspecialchars($now->rfc822())."</lastBuildDate>\n";
$feed.= " <generator>".FEEDCREATOR_VERSION."</generator>\n";
 
if ($this->image!=null) {
$feed.= " <image>\n";
$feed.= " <url>".$this->image->url."</url>\n";
$feed.= " <title>".FeedCreator::iTrunc(htmlspecialchars($this->image->title),100)."</title>\n";
$feed.= " <link>".$this->image->link."</link>\n";
if ($this->image->width!="") {
$feed.= " <width>".$this->image->width."</width>\n";
}
if ($this->image->height!="") {
$feed.= " <height>".$this->image->height."</height>\n";
}
if ($this->image->description!="") {
$feed.= " <description>".htmlspecialchars($this->image->description)."</description>\n";
}
$feed.= " </image>\n";
}
if ($this->language!="") {
$feed.= " <language>".$this->language."</language>\n";
}
if ($this->copyright!="") {
$feed.= " <copyright>".FeedCreator::iTrunc(htmlspecialchars($this->copyright),100)."</copyright>\n";
}
if ($this->editor!="") {
$feed.= " <managingEditor>".FeedCreator::iTrunc(htmlspecialchars($this->editor),100)."</managingEditor>\n";
}
if ($this->webmaster!="") {
$feed.= " <webMaster>".FeedCreator::iTrunc(htmlspecialchars($this->webmaster),100)."</webMaster>\n";
}
if ($this->pubDate!="") {
$pubDate = new FeedDate($this->pubDate);
$feed.= " <pubDate>".htmlspecialchars($pubDate->rfc822())."</pubDate>\n";
}
if ($this->category!="") {
$feed.= " <category>".htmlspecialchars($this->category)."</category>\n";
}
if ($this->docs!="") {
$feed.= " <docs>".FeedCreator::iTrunc(htmlspecialchars($this->docs),500)."</docs>\n";
}
if ($this->ttl!="") {
$feed.= " <ttl>".htmlspecialchars($this->ttl)."</ttl>\n";
}
if ($this->rating!="") {
$feed.= " <rating>".FeedCreator::iTrunc(htmlspecialchars($this->rating),500)."</rating>\n";
}
if ($this->skipHours!="") {
$feed.= " <skipHours>".htmlspecialchars($this->skipHours)."</skipHours>\n";
}
if ($this->skipDays!="") {
$feed.= " <skipDays>".htmlspecialchars($this->skipDays)."</skipDays>\n";
}
$feed.= $this->_createAdditionalElements($this->additionalElements, " ");
 
for ($i=0;$i<count($this->items);$i++) {
$feed.= " <item>\n";
$feed.= " <title>".FeedCreator::iTrunc(htmlspecialchars(strip_tags($this->items[$i]->title)),100)."</title>\n";
$feed.= " <link>".htmlspecialchars($this->items[$i]->link)."</link>\n";
$feed.= " <description>".htmlspecialchars($this->items[$i]->description)."</description>\n";
if ($this->items[$i]->author!="") {
$feed.= " <author>".htmlspecialchars($this->items[$i]->author)."</author>\n";
}
/*
// on hold
if ($this->items[$i]->source!="") {
$feed.= " <source>".htmlspecialchars($this->items[$i]->source)."</source>\n";
}
*/
if ($this->items[$i]->category!="") {
$feed.= " <category>".htmlspecialchars($this->items[$i]->category)."</category>\n";
}
if ($this->items[$i]->comments!="") {
$feed.= " <comments>".$this->items[$i]->comments."</comments>\n";
}
if ($this->items[$i]->date!="") {
$itemDate = new FeedDate($this->items[$i]->date);
$feed.= " <pubDate>".htmlspecialchars($itemDate->rfc822())."</pubDate>\n";
}
if ($this->items[$i]->guid!="") {
$feed.= " <guid>".$this->items[$i]->guid."</guid>\n";
}
$feed.= $this->_createAdditionalElements($this->items[$i]->additionalElements, " ");
$feed.= " </item>\n";
}
$feed.= " </channel>\n";
$feed.= "</rss>\n";
return $feed;
}
# }}}
}
 
 
 
/**
* RSSCreator20 is a FeedCreator that implements RDF Site Summary (RSS) 2.0.
*
* @see http://backend.userland.com/rss
* @since 1.3
* @author Kai Blankenhorn <kaib@bitfolge.de>
*/
class RSSCreator20 extends RSSCreator091 {
 
# {{{ __construct
function RSSCreator20() {
parent::_setRSSVersion("2.0");
}
# }}}
 
}
 
 
/**
* PIECreator01 is a FeedCreator that implements the emerging PIE specification,
* as in http://intertwingly.net/wiki/pie/Syntax.
*
* @deprecated
* @since 1.3
* @author Scott Reynen <scott@randomchaos.com> and Kai Blankenhorn <kaib@bitfolge.de>
*/
class PIECreator01 extends FeedCreator {
 
# {{{ createFeed
function createFeed() {
$feed = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
$feed.= "<feed version=\"0.1\" xmlns=\"http://example.com/newformat#\">\n";
$feed.= " <title>".FeedCreator::iTrunc(htmlspecialchars($this->title),100)."</title>\n";
$feed.= " <subtitle>".FeedCreator::iTrunc(htmlspecialchars($this->description),500)."</subtitle>\n";
$feed.= " <link>".$this->link."</link>\n";
for ($i=0;$i<count($this->items);$i++) {
$feed.= " <entry>\n";
$feed.= " <title>".FeedCreator::iTrunc(htmlspecialchars(strip_tags($this->items[$i]->title)),100)."</title>\n";
$feed.= " <link>".htmlspecialchars($this->items[$i]->link)."</link>\n";
$itemDate = new FeedDate($this->items[$i]->date);
$feed.= " <created>".htmlspecialchars($itemDate->iso8601())."</created>\n";
$feed.= " <issued>".htmlspecialchars($itemDate->iso8601())."</issued>\n";
$feed.= " <modified>".htmlspecialchars($itemDate->iso8601())."</modified>\n";
$feed.= " <id>".$this->items[$i]->guid."</id>\n";
if ($this->items[$i]->author!="") {
$feed.= " <author>\n";
$feed.= " <name>".htmlspecialchars($this->items[$i]->author)."</name>\n";
if ($this->items[$i]->authorEmail!="") {
$feed.= " <email>".$this->items[$i]->authorEmail."</email>\n";
}
$feed.=" </author>\n";
}
$feed.= " <content type=\"text/html\" xml:lang=\"en-us\">\n";
$feed.= " <div xmlns=\"http://www.w3.org/1999/xhtml\">".$this->items[$i]->description."</div>\n";
$feed.= " </content>\n";
$feed.= " </entry>\n";
}
$feed.= "</feed>\n";
return $feed;
}
# }}}
}
 
 
/**
* AtomCreator03 is a FeedCreator that implements the atom specification,
* as in http://www.intertwingly.net/wiki/pie/FrontPage.
* Please note that just by using AtomCreator03 you won't automatically
* produce valid atom files. For example, you have to specify either an editor
* for the feed or an author for every single feed item.
*
* Some elements have not been implemented yet. These are (incomplete list):
* author URL, item author's email and URL, item contents, alternate links,
* other link content types than text/html. Some of them may be created with
* AtomCreator03::additionalElements.
*
* @see FeedCreator#additionalElements
* @since 1.6
* @author Kai Blankenhorn <kaib@bitfolge.de>, Scott Reynen <scott@randomchaos.com>
*/
class AtomCreator03 extends FeedCreator {
 
# {{{ __construct
function AtomCreator03() {
$this->contentType = "application/atom+xml";
}
# }}}
 
# {{{ createFeed
function createFeed() {
$feed = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
$feed.= $this->_createGeneratorComment();
$feed.= "<feed version=\"0.3\" xmlns=\"http://purl.org/atom/ns#\"";
if ($this->language!="") {
$feed.= " xml:lang:\"".$this->language."\"";
}
$feed.= ">\n";
$feed.= " <title>".htmlspecialchars($this->title)."</title>\n";
$feed.= " <tagline>".htmlspecialchars($this->description)."</tagline>\n";
$feed.= " <link rel=\"alternate\" type=\"text/html\" href=\"".htmlspecialchars($this->link)."\"/>\n";
$feed.= " <id>".$this->link."</id>\n";
$now = new FeedDate();
$feed.= " <modified>".htmlspecialchars($now->iso8601())."</modified>\n";
if ($this->editor!="") {
$feed.= " <author>\n";
$feed.= " <name>".$this->editor."</name>\n";
if ($this->editorEmail!="") {
$feed.= " <email>".$this->editorEmail."</email>\n";
}
$feed.= " </author>\n";
}
$feed.= " <generator>".FEEDCREATOR_VERSION."</generator>\n";
$feed.= $this->_createAdditionalElements($this->additionalElements, " ");
for ($i=0;$i<count($this->items);$i++) {
$feed.= " <entry>\n";
$feed.= " <title>".htmlspecialchars(strip_tags($this->items[$i]->title))."</title>\n";
$feed.= " <link rel=\"alternate\" type=\"text/html\" href=\"".htmlspecialchars($this->items[$i]->link)."\"/>\n";
if ($this->items[$i]->date=="") {
$this->items[$i]->date = time();
}
$itemDate = new FeedDate($this->items[$i]->date);
$feed.= " <created>".htmlspecialchars($itemDate->iso8601())."</created>\n";
$feed.= " <issued>".htmlspecialchars($itemDate->iso8601())."</issued>\n";
$feed.= " <modified>".htmlspecialchars($itemDate->iso8601())."</modified>\n";
$feed.= " <id>".$this->items[$i]->link."</id>\n";
$feed.= $this->_createAdditionalElements($this->items[$i]->additionalElements, " ");
if ($this->items[$i]->author!="") {
$feed.= " <author>\n";
$feed.= " <name>".htmlspecialchars($this->items[$i]->author)."</name>\n";
$feed.= " </author>\n";
}
if ($this->items[$i]->description!="") {
$feed.= " <summary>".htmlspecialchars($this->items[$i]->description)."</summary>\n";
}
$feed.= " </entry>\n";
}
$feed.= "</feed>\n";
return $feed;
}
# }}}
}
 
 
/**
* MBOXCreator is a FeedCreator that implements the mbox format
* as described in http://www.qmail.org/man/man5/mbox.html
*
* @since 1.3
* @author Kai Blankenhorn <kaib@bitfolge.de>
*/
class MBOXCreator extends FeedCreator {
 
# {{{ __construct
function MBOXCreator() {
$this->contentType = "text/plain";
}
# }}}
 
# {{{ qp_enc
function qp_enc($input = "", $line_max = 76) {
$hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
$lines = preg_split("/(?:\r\n|\r|\n)/", $input);
$eol = "\r\n";
$escape = "=";
$output = "";
while( list(, $line) = each($lines) ) {
//$line = rtrim($line); // remove trailing white space -> no =20\r\n necessary
$linlen = strlen($line);
$newline = "";
for($i = 0; $i < $linlen; $i++) {
$c = substr($line, $i, 1);
$dec = ord($c);
if ( ($dec == 32) && ($i == ($linlen - 1)) ) { // convert space at eol only
$c = "=20";
} elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) { // always encode "\t", which is *not* required
$h2 = floor($dec/16); $h1 = floor($dec%16);
$c = $escape.$hex["$h2"].$hex["$h1"];
}
if ( (strlen($newline) + strlen($c)) >= $line_max ) { // CRLF is not counted
$output .= $newline.$escape.$eol; // soft line break; " =\r\n" is okay
$newline = "";
}
$newline .= $c;
} // end of for
$output .= $newline.$eol;
}
return trim($output);
}
# }}}
 
# {{{ createFeed
/**
* Builds the MBOX contents.
* @return string the feed's complete text
*/
function createFeed() {
global $config;
for ($i=0;$i<count($this->items);$i++) {
if ($this->items[$i]->author!="") {
$from = $this->items[$i]->author;
} else {
$from = $this->title;
}
$itemDate = new FeedDate($this->items[$i]->date);
$feed.= "From ".strtr(MBOXCreator::qp_enc($from)," ","_")." ".date("D M d H:i:s Y",$itemDate->unix())."\n";
$feed.= "Content-Type: text/plain;\n";
$feed.= " charset=\"".$config->outputEnc."\"\n";
$feed.= "Content-Transfer-Encoding: quoted-printable\n";
$feed.= "Content-Type: text/plain\n";
$feed.= "From: \"".MBOXCreator::qp_enc($from)."\"\n";
$feed.= "Date: ".$itemDate->rfc822()."\n";
$feed.= "Subject: ".MBOXCreator::qp_enc(FeedCreator::iTrunc($this->items[$i]->title,100))."\n";
$feed.= "\n";
$body = chunk_split(MBOXCreator::qp_enc($this->items[$i]->description));
$feed.= preg_replace("~\nFrom ([^\n]*)(\n?)~","\n>From $1$2\n",$body);
$feed.= "\n";
$feed.= "\n";
}
return $feed;
}
# }}}
 
# {{{ _generateFilename
/**
* Generate a filename for the feed cache file. Overridden from FeedCreator to prevent XML data types.
* @return string the feed cache filename
* @since 1.4
* @access private
*/
function _generateFilename() {
$fileInfo = pathinfo($_SERVER["PHP_SELF"]);
return substr($fileInfo["basename"],0,-(strlen($fileInfo["extension"])+1)).".mbox";
}
# }}}
}
 
 
/**
* OPMLCreator is a FeedCreator that implements OPML 1.0.
*
* @see http://opml.scripting.com/spec
* @author Dirk Clemens, Kai Blankenhorn
* @since 1.5
*/
class OPMLCreator extends FeedCreator {
# {{{ createFeed
function createFeed() {
$feed = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
$feed.= $this->_createGeneratorComment();
$feed.= "<opml xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n";
$feed.= " <head>\n";
$feed.= " <title>".htmlspecialchars($this->title)."</title>\n";
if ($this->pubDate!="") {
$date = new FeedDate($this->pubDate);
$feed.= " <dateCreated>".$date->rfc822()."</dateCreated>\n";
}
if ($this->lastBuildDate!="") {
$date = new FeedDate($this->lastBuildDate);
$feed.= " <dateModified>".$date->rfc822()."</dateModified>\n";
}
if ($this->editor!="") {
$feed.= " <ownerName>".$this->editor."</ownerName>\n";
}
if ($this->editorEmail!="") {
$feed.= " <ownerEmail>".$this->editorEmail."</ownerEmail>\n";
}
$feed.= " </head>\n";
$feed.= " <body>\n";
for ($i=0;$i<count($this->items);$i++) {
$feed.= " <outline type=\"rss\" ";
$title = htmlspecialchars(strip_tags(strtr($this->items[$i]->title,"\n\r"," ")));
$feed.= " title=\"".$title."\"";
$feed.= " text=\"".$title."\"";
//$feed.= " description=\"".htmlspecialchars($this->items[$i]->description)."\"";
$feed.= " url=\"".htmlspecialchars($this->items[$i]->link)."\"";
$feed.= "/>\n";
}
$feed.= " </body>\n";
$feed.= "</opml>\n";
return $feed;
}
# }}}
}
 
?>
/WebSVN/include/setup.inc
1,454 → 1,430
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// setup.inc
//
// Global setup
 
// --- DON'T CHANGE THIS FILE ---
//
// User changes should be done in config.ini
 
// Include the configuration class
require_once 'include/configclass.inc';
 
// Create the config
$config = new Config;
 
// Set up the default character encodings
if (function_exists('iconv_get_encoding'))
{
$config->setInputEncoding(iconv_get_encoding('input_encoding'));
}
 
// Define the language array
$lang = array();
$langNames = array();
 
// Set up locwebsvnhttp
// Note: we will use nothing in MultiViews mode so that the URLs use the root
// directory by default.
if (empty($locwebsvnhttp))
$locwebsvnhttp = defined('WSVN_MULTIVIEWS') ? '' : '.';
 
if (empty($locwebsvnreal))
$locwebsvnreal = '.';
 
$vars['locwebsvnhttp'] = $locwebsvnhttp;
 
// Include a default language file (must go before config.inc)
require 'languages/english.inc';
 
// Get the user's personalised config (requires the locwebsvnhttp stuff above)
require_once 'config.inc';
 
// Load PHP_Compat if we're going to use it. This needs to be done after including config.inc (which contains
// the setting) but before svnlook.inc (which requires util.inc, which contains PHP4-incompatible functions)
if ($config->isPHPCompatEnabled()) {
require_once($config->getPHPCompatFile());
require_once 'include/php5compat.inc';
}
 
require_once 'include/svnlook.inc';
 
// Make sure that the input locale is set up correctly
setlocale(LC_ALL, '');
 
// {{{ Content-Type's
// Set up the default content-type extension handling
 
$contentType = array (
 
'.dwg' => 'application/acad', // AutoCAD Drawing files
'.DWG' => 'application/acad', // AutoCAD Drawing files
'.arj' => 'application/arj', //  
'.ccAD' => 'application/clariscad', // ClarisCAD files
'.DRW' => 'application/drafting', // MATRA Prelude drafting
'.dxf' => 'application/dxf', // DXF (AutoCAD)
'.DXF' => 'application/dxf', // DXF (AutoCAD)
'.xl' => 'application/excel', // Microsoft Excel
'.unv' => 'application/i-deas', //SDRC I-DEAS files
'.UNV' => 'application/i-deas', //SDRC I-DEAS files
'.igs' => 'application/iges', // IGES graphics format
'.iges' => 'application/iges', // IGES graphics format
'.IGS' => 'application/iges', // IGES graphics format
'.IGES' => 'application/iges', // IGES graphics format
'.hqx' => 'application/mac-binhex40', // Macintosh BinHex format
'.word' => 'application/msword', // Microsoft Word
'.w6w' => 'application/msword', // Microsoft Word
'.doc' => 'application/msword', // Microsoft Word
'.wri' => 'application/mswrite', // Microsoft Write
'.bin' => 'application/octet-stream', // Uninterpreted binary
'.exe' => 'application/x-msdownload', // Windows EXE
'.EXE' => 'application/x-msdownload', // Windows EXE
'.oda' => 'application/oda', //  
'.pdf' => 'application/pdf', // PDF (Adobe Acrobat)
'.ai' => 'application/postscript', // PostScript
'.PS' => 'application/postscript', // PostScript
'.ps' => 'application/postscript', // PostScript
'.eps' => 'application/postscript', // PostScript
'.prt' => 'application/pro_eng', // PTC Pro/ENGINEER
'.PRT' => 'application/pro_eng', // PTC Pro/ENGINEER
'.part' => 'application/pro_eng', // PTC Pro/ENGINEER
'.rtf' => 'application/rtf', // Rich Text Format
'.set' => 'application/set', // SET (French CAD standard)
'.SET' => 'application/set', // SET (French CAD standard)
'.stl' => 'application/sla', // Stereolithography
'.STL' => 'application/sla', // Stereolithography
'.SOL' => 'application/solids', // MATRA Prelude Solids
'.stp' => 'application/STEP', // ISO-10303 STEP data files
'.STP' => 'application/STEP', // ISO-10303 STEP data files
'.step' => 'application/STEP', // ISO-10303 STEP data files
'.STEP' => 'application/STEP', // ISO-10303 STEP data files
'.vda' => 'application/vda', // VDA-FS Surface data
'.VDA' => 'application/vda', // VDA-FS Surface data
'.dir' => 'application/x-director', // Macromedia Director
'.dcr' => 'application/x-director', // Macromedia Director
'.dxr' => 'application/x-director', // Macromedia Director
'.mif' => 'application/x-mif', // FrameMaker MIF Format
'.csh' => 'application/x-csh', // C-shell script
'.dvi' => 'application/x-dvi', // TeX DVI
'.gz' => 'application/x-gzip', // GNU Zip
'.gzip' => 'application/x-gzip', // GNU Zip
'.hdf' => 'application/x-hdf', // ncSA HDF Data File
'.latex' => 'application/x-latex', // LaTeX source
'.nc' => 'application/x-netcdf', // Unidata netCDF
'.cdf' => 'application/x-netcdf', // Unidata netCDF
'.sit' => 'application/x-stuffit', // Stiffut Archive
'.tcl' => 'application/x-tcl', // TCL script
'.texinfo' => 'application/x-texinfo', // Texinfo (Emacs)
'.texi' => 'application/x-texinfo', // Texinfo (Emacs)
'.t' => 'application/x-troff', // Troff
'.tr' => 'application/x-troff', // Troff
'.roff' => 'application/x-troff', // Troff
'.man' => 'application/x-troff-man', // Troff with MAN macros
'.me' => 'application/x-troff-me', // Troff with ME macros
'.ms' => 'application/x-troff-ms', // Troff with MS macros
'.src' => 'application/x-wais-source', // WAIS source
'.bcpio' => 'application/x-bcpio', // Old binary CPIO
'.cpio' => 'application/x-cpio', // POSIX CPIO
'.gtar' => 'application/x-gtar', // GNU tar
'.shar' => 'application/x-shar', // Shell archive
'.sv4cpio' => 'application/x-sv4cpio', // SVR4 CPIO
'.sv4crc' => 'application/x-sv4crc', // SVR4 CPIO with CRC
'.tar' => 'application/x-tar', // 4.3BSD tar format
'.ustar' => 'application/x-ustar', // POSIX tar format
'.hlp' => 'application/x-winhelp', // Windows Help
'.zip' => 'application/zip', // ZIP archive
'.au' => 'audio/basic', // Basic audio (usually m-law)
'.snd' => 'audio/basic', // Basic audio (usually m-law)
'.aif' => 'audio/x-aiff', // AIFF audio
'.aiff' => 'audio/x-aiff', // AIFF audio
'.aifc' => 'audio/x-aiff', // AIFF audio
'.ra' => 'audio/x-pn-realaudio', // RealAudio
'.ram' => 'audio/x-pn-realaudio', // RealAudio
'.rpm' => 'audio/x-pn-realaudio-plugin', // RealAudio (plug-in)
'.wav' => 'audio/x-wav', // Windows WAVE audio
'.mp3' => 'audio/x-mp3', // MP3 files
'.gif' => 'image/gif', // gif image
'.ief' => 'image/ief', // Image Exchange Format
'.jpg' => 'image/jpeg', // JPEG image
'.JPG' => 'image/jpeg', // JPEG image
'.JPE' => 'image/jpeg', // JPEG image
'.jpe' => 'image/jpeg', // JPEG image
'.JPEG' => 'image/jpeg', // JPEG image
'.jpeg' => 'image/jpeg', // JPEG image
'.pict' => 'image/pict', // Macintosh PICT
'.tiff' => 'image/tiff', // TIFF image
'.tif' => 'image/tiff', // TIFF image
'.ras' => 'image/x-cmu-raster', // CMU raster
'.pnm' => 'image/x-portable-anymap', // PBM Anymap format
'.pbm' => 'image/x-portable-bitmap', // PBM Bitmap format
'.pgm' => 'image/x-portable-graymap', // PBM Graymap format
'.ppm' => 'image/x-portable-pixmap', // PBM Pixmap format
'.rgb' => 'image/x-rgb', // RGB Image
'.xbm' => 'image/x-xbitmap', // X Bitmap
'.xpm' => 'image/x-xpixmap', // X Pixmap
'.xwd' => 'image/x-xwindowdump', // X Windows dump (xwd) format
'.zip' => 'multipart/x-zip', // PKZIP Archive
'.gzip' => 'multipart/x-gzip', // GNU ZIP Archive
'.mpeg' => 'video/mpeg', // MPEG video
'.mpg' => 'video/mpeg', // MPEG video
'.MPG' => 'video/mpeg', // MPEG video
'.MPE' => 'video/mpeg', // MPEG video
'.mpe' => 'video/mpeg', // MPEG video
'.MPEG' => 'video/mpeg', // MPEG video
'.mpeg' => 'video/mpeg', // MPEG video
'.qt' => 'video/quicktime', // QuickTime Video
'.mov' => 'video/quicktime', // QuickTime Video
'.avi' => 'video/msvideo', // Microsoft Windows Video
'.movie' => 'video/x-sgi-movie', // SGI Movieplayer format
'.wrl' => 'x-world/x-vrml', // VRML Worlds
'.odt' => 'application/vnd.oasis.opendocument.text', // OpenDocument Text
'.ott' => 'application/vnd.oasis.opendocument.text-template', // OpenDocument Text Template
'.ods' => 'application/vnd.oasis.opendocument.spreadsheet', // OpenDocument Spreadsheet
'.ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', // OpenDocument Spreadsheet Template
'.odp' => 'application/vnd.oasis.opendocument.presentation', // OpenDocument Presentation
'.otp' => 'application/vnd.oasis.opendocument.presentation-template', // OpenDocument Presentation Template
'.odg' => 'application/vnd.oasis.opendocument.graphics', // OpenDocument Drawing
'.otg' => 'application/vnd.oasis.opendocument.graphics-template', // OpenDocument Drawing Template
'.odc' => 'application/vnd.oasis.opendocument.chart', // OpenDocument Chart
'.otc' => 'application/vnd.oasis.opendocument.chart-template', // OpenDocument Chart Template
'.odf' => 'application/vnd.oasis.opendocument.formula', // OpenDocument Formula
'.otf' => 'application/vnd.oasis.opendocument.formula-template', // OpenDocument Formula Template
'.odi' => 'application/vnd.oasis.opendocument.image', // OpenDocument Image
'.oti' => 'application/vnd.oasis.opendocument.image-template', // OpenDocument Image Template
'.odm' => 'application/vnd.oasis.opendocument.text-master', // OpenDocument Master Document
'.oth' => 'application/vnd.oasis.opendocument.text-web', // HTML Document Template
'.odb' => 'application/vnd.oasis.opendocument.database', // OpenDocument Database
 
);
 
// }}}
 
// {{{ Enscript file extensions
 
// List of extensions recognised by enscript.
 
$extEnscript = array
(
'.ada' => 'ada',
'.adb' => 'ada',
'.ads' => 'ada',
'.awk' => 'awk',
'.c' => 'c',
'.c++' => 'cpp',
'.cc' => 'cpp',
'.cpp' => 'cpp',
'.csh' => 'csh',
'.cxx' => 'cpp',
'.diff' => 'diffu',
'.dpr' => 'delphi',
'.el' => 'elisp',
'.eps' => 'postscript',
'.f' => 'fortran',
'.for' => 'fortran',
'.gs' => 'haskell',
'.h' => 'c',
'.hpp' => 'cpp',
'.hs' => 'haskell',
'.htm' => 'html',
'.html' => 'html',
'.idl' => 'idl',
'.java' => 'java',
'.js' => 'javascript',
'.lgs' => 'haskell',
'.lhs' => 'haskell',
'.m' => 'objc',
'.m4' => 'm4',
'.man' => 'nroff',
'.nr' => 'nroff',
'.p' => 'pascal',
'.pas' => 'delphi',
'.patch' => 'diffu',
'.pkg' => 'sql',
'.pl' => 'perl',
'.pm' => 'perl',
'.pp' => 'pascal',
'.ps' => 'postscript',
'.s' => 'asm',
'.scheme' => 'scheme',
'.scm' => 'scheme',
'.scr' => 'synopsys',
'.sh' => 'sh',
'.shtml' => 'html',
'.sql' => 'sql',
'.st' => 'states',
'.syn' => 'synopsys',
'.synth' => 'synopsys',
'.tcl' => 'tcl',
'.tex' => 'tex',
'.texi' => 'tex',
'.texinfo' => 'tex',
'.v' => 'verilog',
'.vba' => 'vba',
'.vh' => 'verilog',
'.vhd' => 'vhdl',
'.vhdl' => 'vhdl',
'.py' => 'python',
// The following are handled internally by WebSVN, since there's no
// support for them in Enscript
'.php' => 'php',
'.phtml' => 'php',
'.php3' => 'php',
'.inc' => 'php'
);
 
// }}}
 
// Default 'zipped' array
 
$zipped = array ();
 
// Set up the version info
 
initSvnVersion($major,$minor);
 
// Get the language choice as defained as the default by config.inc
$user_defaultLang = $lang['LANGUAGENAME'];
 
// Override this with the user choice if there is one, and memorise the setting
// as a cookie (since we don't have user accounts, we can't store the setting
// anywhere else). We try to memorise a permanant cookie and a per session cookie
// in case the user's disabled permanant ones.
 
if (!empty($_REQUEST['langchoice']))
{
$user_defaultLang = $_REQUEST['langchoice'];
setcookie('storedlang', $_REQUEST['langchoice'], time()+(3600*24*356*10), '/');
setcookie('storedsesslang', $_REQUEST['langchoice']);
}
else // Try to read an existing cookie if there is one
{
if (!empty($_COOKIE['storedlang'])) $user_defaultLang = $_COOKIE['storedlang'];
else if (!empty($_COOKIE['storedsesslang'])) $user_defaultLang = $_COOKIE['storedsesslang'];
}
$user_defaultFile = '';
if ($handle = opendir('languages'))
{
// Read the language name for each language.
while (false !== ($file = readdir($handle)))
{
if ($file{0} != '.' && !is_dir('languages'.DIRECTORY_SEPARATOR.$file))
{
$lang['LANGUAGENAME'] = '';
require 'languages/'.$file;
if ($lang['LANGUAGENAME'] != '')
{
$langNames[] = $lang['LANGUAGENAME'];
if ($lang['LANGUAGENAME'] == $user_defaultLang)
$user_defaultFile = $file;
}
}
}
 
closedir($handle);
// XXX: this shouldn't be necessary
// ^ i.e. just require english.inc, then the desired language
// Reload english to get untranslated strings
require 'languages/english.inc';
// Reload the default language
if (!empty($user_defaultFile))
require 'languages/'.$user_defaultFile;
$url = getParameterisedSelfUrl(true);
$vars["lang_form"] = "<form action=\"$url\" method=\"post\" id=\"langform\">";
$vars["lang_select"] = "<select name=\"langchoice\" onchange=\"javascript:this.form.submit();\">";
reset($langNames);
foreach ($langNames as $name)
{
$sel = "";
if ($name == $user_defaultLang) $sel = "selected";
$vars["lang_select"] .= "<option value=\"$name\" $sel>$name</option>";
}
$vars["lang_select"] .= "</select>";
$vars["lang_submit"] = "<input type=\"submit\" value=\"${lang["GO"]}\">";
$vars["lang_endform"] = "</form>";
}
 
// Set up headers
 
header("Content-type: text/html; charset=".$config->outputEnc);
 
// Make sure that the user has set up a repository
 
$reps = $config->getRepositories();
if (empty($reps[0]))
{
echo $lang["SUPPLYREP"];
exit;
}
 
// Override the rep parameter with the repository name if it's available
$repname = @$_REQUEST["repname"];
if (isset($repname))
{
$rep = $config->findRepository($repname);
}
else
$rep = $reps[0];
// Retrieve other standard parameters
 
# due to possible XSS exploit, we need to clean up path first
$path = !empty($_REQUEST['path']) ? $_REQUEST['path'] : null;
$vars['safepath'] = htmlentities($path);
$rev = (int)@$_REQUEST["rev"];
$showchanged = (@$_REQUEST["sc"] == 1)?1:0;
 
// Function to create the project selection HTML form
function createProjectSelectionForm()
{
global $config, $vars, $rep, $lang, $showchanged;
$url = $config->getURL(-1, "", "form");
$vars["projects_form"] = "<form action=\"$url\" method=\"post\" id=\"projectform\">";
$reps = $config->getRepositories();
$vars["projects_select"] = "<select name=\"repname\" onchange=\"javascript:this.form.submit();\">";
foreach ($reps as $trep)
{
if ($trep->hasReadAccess("/", true))
{
if ($rep->getDisplayName() == $trep->getDisplayName())
$sel = "selected";
else
$sel = "";
$vars["projects_select"] .= "<option value=\"".$trep->getDisplayName()."\" $sel>".$trep->getDisplayName()."</option>";
}
}
$vars["projects_select"] .= "</select>";
$vars["projects_submit"] = "<input type=\"submit\" value=\"${lang["GO"]}\" />";
$vars["projects_endform"] = "<input type=\"hidden\" name=\"selectproj\" value=\"1\" /><input type=\"hidden\" name=\"op\" value=\"form\" /><input type=\"hidden\" name=\"sc\" value=\"$showchanged\" /></form>";
}
 
// Create the form if we're not in MultiViews. Otherwise wsvn must create the form once the current project has
// been found
 
if (!$config->multiViews)
{
createProjectSelectionForm();
}
 
if ($rep)
{
$vars["allowdownload"] = $rep->getAllowDownload();
$vars["repname"] = $rep->getDisplayName();
}
 
// As of version 1.70 the output encoding is forced to be UTF-8, since this is the output
// encoding returned by svn log --xml. This is good, since we are no longer reliant on PHP's
// rudimentary conversions.
 
$vars["charset"] = "UTF-8";
?>
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// setup.inc
//
// Global setup
 
// --- DON'T CHANGE THIS FILE ---
//
// User changes should be done in config.ini
 
// Include the configuration class
require_once 'include/configclass.inc';
require_once 'include/svnlook.inc';
 
// Define the language array
$lang = array();
$langNames = array();
 
// Include a default language file.
require 'languages/english.inc';
 
// Set up locwebsvnhttp
// Note: we will use nothing in MultiViews mode so that the URLs use the root
// directory by default.
if (empty($locwebsvnhttp))
$locwebsvnhttp = defined('WSVN_MULTIVIEWS') ? '' : '.';
 
if (empty($locwebsvnreal))
$locwebsvnreal = '.';
 
$vars['locwebsvnhttp'] = $locwebsvnhttp;
 
// Make sure that the input locale is set up correctly
setlocale(LC_ALL, '');
 
// Create the config
$config = new Config;
 
// Set up the default character encodings
if (function_exists('iconv_get_encoding'))
{
$config->setInputEncoding(iconv_get_encoding('input_encoding'));
}
 
// {{{ Content-Type's
// Set up the default content-type extension handling
 
$contentType = array (
 
'.dwg' => 'application/acad', // AutoCAD Drawing files
'.DWG' => 'application/acad', // AutoCAD Drawing files
'.arj' => 'application/arj', //  
'.ccAD' => 'application/clariscad', // ClarisCAD files
'.DRW' => 'application/drafting', // MATRA Prelude drafting
'.dxf' => 'application/dxf', // DXF (AutoCAD)
'.DXF' => 'application/dxf', // DXF (AutoCAD)
'.xl' => 'application/excel', // Microsoft Excel
'.unv' => 'application/i-deas', //SDRC I-DEAS files
'.UNV' => 'application/i-deas', //SDRC I-DEAS files
'.igs' => 'application/iges', // IGES graphics format
'.iges' => 'application/iges', // IGES graphics format
'.IGS' => 'application/iges', // IGES graphics format
'.IGES' => 'application/iges', // IGES graphics format
'.hqx' => 'application/mac-binhex40', // Macintosh BinHex format
'.word' => 'application/msword', // Microsoft Word
'.w6w' => 'application/msword', // Microsoft Word
'.doc' => 'application/msword', // Microsoft Word
'.wri' => 'application/mswrite', // Microsoft Write
'.bin' => 'application/octet-stream', // Uninterpreted binary
'.exe' => 'application/x-msdownload', // Windows EXE
'.EXE' => 'application/x-msdownload', // Windows EXE
'.oda' => 'application/oda', //  
'.pdf' => 'application/pdf', // PDF (Adobe Acrobat)
'.ai' => 'application/postscript', // PostScript
'.PS' => 'application/postscript', // PostScript
'.ps' => 'application/postscript', // PostScript
'.eps' => 'application/postscript', // PostScript
'.prt' => 'application/pro_eng', // PTC Pro/ENGINEER
'.PRT' => 'application/pro_eng', // PTC Pro/ENGINEER
'.part' => 'application/pro_eng', // PTC Pro/ENGINEER
'.rtf' => 'application/rtf', // Rich Text Format
'.set' => 'application/set', // SET (French CAD standard)
'.SET' => 'application/set', // SET (French CAD standard)
'.stl' => 'application/sla', // Stereolithography
'.STL' => 'application/sla', // Stereolithography
'.SOL' => 'application/solids', // MATRA Prelude Solids
'.stp' => 'application/STEP', // ISO-10303 STEP data files
'.STP' => 'application/STEP', // ISO-10303 STEP data files
'.step' => 'application/STEP', // ISO-10303 STEP data files
'.STEP' => 'application/STEP', // ISO-10303 STEP data files
'.vda' => 'application/vda', // VDA-FS Surface data
'.VDA' => 'application/vda', // VDA-FS Surface data
'.dir' => 'application/x-director', // Macromedia Director
'.dcr' => 'application/x-director', // Macromedia Director
'.dxr' => 'application/x-director', // Macromedia Director
'.mif' => 'application/x-mif', // FrameMaker MIF Format
'.csh' => 'application/x-csh', // C-shell script
'.dvi' => 'application/x-dvi', // TeX DVI
'.gz' => 'application/x-gzip', // GNU Zip
'.gzip' => 'application/x-gzip', // GNU Zip
'.hdf' => 'application/x-hdf', // ncSA HDF Data File
'.latex' => 'application/x-latex', // LaTeX source
'.nc' => 'application/x-netcdf', // Unidata netCDF
'.cdf' => 'application/x-netcdf', // Unidata netCDF
'.sit' => 'application/x-stuffit', // Stiffut Archive
'.tcl' => 'application/x-tcl', // TCL script
'.texinfo' => 'application/x-texinfo', // Texinfo (Emacs)
'.texi' => 'application/x-texinfo', // Texinfo (Emacs)
'.t' => 'application/x-troff', // Troff
'.tr' => 'application/x-troff', // Troff
'.roff' => 'application/x-troff', // Troff
'.man' => 'application/x-troff-man', // Troff with MAN macros
'.me' => 'application/x-troff-me', // Troff with ME macros
'.ms' => 'application/x-troff-ms', // Troff with MS macros
'.src' => 'application/x-wais-source', // WAIS source
'.bcpio' => 'application/x-bcpio', // Old binary CPIO
'.cpio' => 'application/x-cpio', // POSIX CPIO
'.gtar' => 'application/x-gtar', // GNU tar
'.shar' => 'application/x-shar', // Shell archive
'.sv4cpio' => 'application/x-sv4cpio', // SVR4 CPIO
'.sv4crc' => 'application/x-sv4crc', // SVR4 CPIO with CRC
'.tar' => 'application/x-tar', // 4.3BSD tar format
'.ustar' => 'application/x-ustar', // POSIX tar format
'.hlp' => 'application/x-winhelp', // Windows Help
'.zip' => 'application/zip', // ZIP archive
'.au' => 'audio/basic', // Basic audio (usually m-law)
'.snd' => 'audio/basic', // Basic audio (usually m-law)
'.aif' => 'audio/x-aiff', // AIFF audio
'.aiff' => 'audio/x-aiff', // AIFF audio
'.aifc' => 'audio/x-aiff', // AIFF audio
'.ra' => 'audio/x-pn-realaudio', // RealAudio
'.ram' => 'audio/x-pn-realaudio', // RealAudio
'.rpm' => 'audio/x-pn-realaudio-plugin', // RealAudio (plug-in)
'.wav' => 'audio/x-wav', // Windows WAVE audio
'.mp3' => 'audio/x-mp3', // MP3 files
'.gif' => 'image/gif', // gif image
'.ief' => 'image/ief', // Image Exchange Format
'.jpg' => 'image/jpeg', // JPEG image
'.JPG' => 'image/jpeg', // JPEG image
'.JPE' => 'image/jpeg', // JPEG image
'.jpe' => 'image/jpeg', // JPEG image
'.JPEG' => 'image/jpeg', // JPEG image
'.jpeg' => 'image/jpeg', // JPEG image
'.pict' => 'image/pict', // Macintosh PICT
'.tiff' => 'image/tiff', // TIFF image
'.tif' => 'image/tiff', // TIFF image
'.ras' => 'image/x-cmu-raster', // CMU raster
'.pnm' => 'image/x-portable-anymap', // PBM Anymap format
'.pbm' => 'image/x-portable-bitmap', // PBM Bitmap format
'.pgm' => 'image/x-portable-graymap', // PBM Graymap format
'.ppm' => 'image/x-portable-pixmap', // PBM Pixmap format
'.rgb' => 'image/x-rgb', // RGB Image
'.xbm' => 'image/x-xbitmap', // X Bitmap
'.xpm' => 'image/x-xpixmap', // X Pixmap
'.xwd' => 'image/x-xwindowdump', // X Windows dump (xwd) format
'.zip' => 'multipart/x-zip', // PKZIP Archive
'.gzip' => 'multipart/x-gzip', // GNU ZIP Archive
'.mpeg' => 'video/mpeg', // MPEG video
'.mpg' => 'video/mpeg', // MPEG video
'.MPG' => 'video/mpeg', // MPEG video
'.MPE' => 'video/mpeg', // MPEG video
'.mpe' => 'video/mpeg', // MPEG video
'.MPEG' => 'video/mpeg', // MPEG video
'.mpeg' => 'video/mpeg', // MPEG video
'.qt' => 'video/quicktime', // QuickTime Video
'.mov' => 'video/quicktime', // QuickTime Video
'.avi' => 'video/msvideo', // Microsoft Windows Video
'.movie' => 'video/x-sgi-movie', // SGI Movieplayer format
'.wrl' => 'x-world/x-vrml' // VRML Worlds
 
);
 
// }}}
 
// {{{ Enscript file extensions
 
// List of extensions recognised by enscript.
 
$extEnscript = array
(
'.ada' => 'ada',
'.adb' => 'ada',
'.ads' => 'ada',
'.awk' => 'awk',
'.c' => 'c',
'.c++' => 'cpp',
'.cc' => 'cpp',
'.cpp' => 'cpp',
'.csh' => 'csh',
'.cxx' => 'cpp',
'.diff' => 'diffu',
'.dpr' => 'delphi',
'.el' => 'elisp',
'.eps' => 'postscript',
'.f' => 'fortran',
'.for' => 'fortran',
'.gs' => 'haskell',
'.h' => 'c',
'.hpp' => 'cpp',
'.hs' => 'haskell',
'.htm' => 'html',
'.html' => 'html',
'.idl' => 'idl',
'.java' => 'java',
'.js' => 'javascript',
'.lgs' => 'haskell',
'.lhs' => 'haskell',
'.m' => 'objc',
'.m4' => 'm4',
'.man' => 'nroff',
'.nr' => 'nroff',
'.p' => 'pascal',
'.pas' => 'delphi',
'.patch' => 'diffu',
'.pkg' => 'sql',
'.pl' => 'perl',
'.pm' => 'perl',
'.pp' => 'pascal',
'.ps' => 'postscript',
'.s' => 'asm',
'.scheme' => 'scheme',
'.scm' => 'scheme',
'.scr' => 'synopsys',
'.sh' => 'sh',
'.shtml' => 'html',
'.sql' => 'sql',
'.st' => 'states',
'.syn' => 'synopsys',
'.synth' => 'synopsys',
'.tcl' => 'tcl',
'.tex' => 'tex',
'.texi' => 'tex',
'.texinfo' => 'tex',
'.v' => 'verilog',
'.vba' => 'vba',
'.vh' => 'verilog',
'.vhd' => 'vhdl',
'.vhdl' => 'vhdl',
'.py' => 'python',
// The following are handled internally by WebSVN, since there's no
// support for them in Enscript
'.php' => 'php',
'.phtml' => 'php',
'.php3' => 'php',
'.inc' => 'php'
);
 
// }}}
 
// Default 'zipped' array
 
$zipped = array ();
 
// Get the user's personalised config
 
require_once 'config.inc';
 
// Set up the version info
 
initSvnVersion($major,$minor);
 
// Get the language choice as defained as the default by config.inc
$user_defaultLang = $lang['LANGUAGENAME'];
 
// Override this with the user choice if there is one, and memorise the setting
// as a cookie (since we don't have user accounts, we can't store the setting
// anywhere else). We try to memorise a permanant cookie and a per session cookie
// in case the user's disabled permanant ones.
 
if (!empty($_REQUEST['langchoice']))
{
$user_defaultLang = $_REQUEST['langchoice'];
setcookie('storedlang', $_REQUEST['langchoice'], time()+(3600*24*356*10), '/');
setcookie('storedsesslang', $_REQUEST['langchoice']);
}
else // Try to read an existing cookie if there is one
{
if (!empty($_COOKIE['storedlang'])) $user_defaultLang = $_COOKIE['storedlang'];
else if (!empty($_COOKIE['storedsesslang'])) $user_defaultLang = $_COOKIE['storedsesslang'];
}
$user_defaultFile = '';
if ($handle = opendir('languages'))
{
// Read the language name for each language.
while (false !== ($file = readdir($handle)))
{
if ($file{0} != '.' && !is_dir('languages'.DIRECTORY_SEPARATOR.$file))
{
$lang['LANGUAGENAME'] = '';
require 'languages/'.$file;
if ($lang['LANGUAGENAME'] != '')
{
$langNames[] = $lang['LANGUAGENAME'];
if ($lang['LANGUAGENAME'] == $user_defaultLang)
$user_defaultFile = $file;
}
}
}
 
closedir($handle);
// XXX: this shouldn't be necessary
// ^ i.e. just require english.inc, then the desired language
// Reload english to get untranslated strings
require 'languages/english.inc';
// Reload the default language
if (!empty($user_defaultFile))
require 'languages/'.$user_defaultFile;
$url = getParameterisedSelfUrl(true);
$vars["lang_form"] = "<form action=\"$url\" method=\"post\" id=\"langform\">";
$vars["lang_select"] = "<select name=\"langchoice\" onchange=\"javascript:this.form.submit();\">";
reset($langNames);
foreach ($langNames as $name)
{
$sel = "";
if ($name == $user_defaultLang) $sel = "selected";
$vars["lang_select"] .= "<option value=\"$name\" $sel>$name</option>";
}
$vars["lang_select"] .= "</select>";
$vars["lang_submit"] = "<input type=\"submit\" value=\"${lang["GO"]}\">";
$vars["lang_endform"] = "</form>";
}
 
// Set up headers
 
header("Content-type: text/html; charset=".$config->outputEnc);
 
// Make sure that the user has set up a repository
 
$reps = $config->getRepositories();
if (empty($reps[0]))
{
echo $lang["SUPPLYREP"];
exit;
}
 
// Override the rep parameter with the repository name if it's available
$repname = @$_REQUEST["repname"];
if (isset($repname))
{
$rep = $config->findRepository($repname);
}
else
$rep = $reps[0];
// Retrieve other standard parameters
 
# due to possible XSS exploit, we need to clean up path first
$path = !empty($_REQUEST['path']) ? $_REQUEST['path'] : null;
$vars['safepath'] = htmlentities($path);
$rev = (int)@$_REQUEST["rev"];
$showchanged = (@$_REQUEST["sc"] == 1)?1:0;
 
// Function to create the project selection HTML form
function createProjectSelectionForm()
{
global $config, $vars, $rep, $lang, $showchanged;
$url = $config->getURL(-1, "", "form");
$vars["projects_form"] = "<form action=\"$url\" method=\"post\" id=\"projectform\">";
$reps = $config->getRepositories();
$vars["projects_select"] = "<select name=\"repname\" onchange=\"javascript:this.form.submit();\">";
foreach ($reps as $trep)
{
if ($trep->hasReadAccess("/", true))
{
if ($rep->getDisplayName() == $trep->getDisplayName())
$sel = "selected";
else
$sel = "";
$vars["projects_select"] .= "<option value=\"".$trep->getDisplayName()."\" $sel>".$trep->getDisplayName()."</option>";
}
}
$vars["projects_select"] .= "</select>";
$vars["projects_submit"] = "<input type=\"submit\" value=\"${lang["GO"]}\" />";
$vars["projects_endform"] = "<input type=\"hidden\" name=\"selectproj\" value=\"1\" /><input type=\"hidden\" name=\"op\" value=\"form\" /><input type=\"hidden\" name=\"sc\" value=\"$showchanged\" /></form>";
}
 
// Create the form if we're not in MultiViews. Otherwise wsvn must create the form once the current project has
// been found
 
if (!$config->multiViews)
{
createProjectSelectionForm();
}
 
if ($rep)
{
$vars["allowdownload"] = $rep->getAllowDownload();
$vars["repname"] = $rep->getDisplayName();
}
 
// As of version 1.70 the output encoding is forced to be UTF-8, since this is the output
// encoding returned by svn log --xml. This is good, since we are no longer reliant on PHP's
// rudimentary conversions.
 
$vars["charset"] = "UTF-8";
?>
/WebSVN/include/template.inc
1,306 → 1,306
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// templates.inc
//
// Templating system to allow advanced page customisation
 
$ignore = false;
 
// Stack of previous test results
$ignorestack = array();
 
// Number of test levels currently ignored
$ignorelevel = 0;
 
// parseCommand
//
// Parse a special command
 
function parseCommand($line, $vars, $handle)
{
global $ignore, $ignorestack, $ignorelevel;
// Check for test conditions
if (strncmp(trim($line), "[websvn-test:", 13) == 0)
{
if (!$ignore)
{
$line = trim($line);
$var = substr($line, 13, -1);
if (empty($vars[$var]))
{
array_push($ignorestack, $ignore);
$ignore = true;
}
}
else
{
$ignorelevel++;
}
return true;
}
if (strncmp(trim($line), "[websvn-else]", 13) == 0)
{
if ($ignorelevel == 0)
{
$ignore = !$ignore;
}
return true;
}
 
if (strncmp(trim($line), "[websvn-endtest]", 16) == 0)
{
if ($ignorelevel > 0)
{
$ignorelevel--;
}
else
{
$ignore = array_pop($ignorestack);
}
return true;
}
if (strncmp(trim($line), "[websvn-getlisting]", 19) == 0)
{
global $path, $rev, $svnrep;
if (!$ignore)
$svnrep->listFileContents($path, $rev);
return true;
}
if (strncmp(trim($line), "[websvn-defineicons]", 19) == 0)
{
global $icons;
if (!isset($icons))
$icons = array();
// Read all the lines until we reach the end of the definition, storing
// each one...
if (!$ignore)
{
while (!feof($handle))
{
$line = trim(fgets($handle));
if (strncmp($line, "[websvn-enddefineicons]", 22) == 0)
{
return true;
}
$eqsign = strpos($line, "=");
$match = substr($line, 0, $eqsign);
$def = substr($line, $eqsign + 1);
$icons[$match] = $def;
}
}
return true;
}
 
if (strncmp(trim($line), "[websvn-icon]", 13) == 0)
{
global $icons, $vars;
if (!$ignore)
{
// The current filetype should be defined my $vars["filetype"]
if (!empty($icons[$vars["filetype"]]))
{
echo parseTags($icons[$vars["filetype"]], $vars);
}
else if (!empty($icons["*"]))
{
echo parseTags($icons["*"], $vars);
}
}
return true;
}
 
if (strncmp(trim($line), "[websvn-treenode]", 17) == 0)
{
global $icons, $vars;
if (!$ignore)
{
if ((!empty($icons["i-node"])) && (!empty($icons["t-node"])) && (!empty($icons["l-node"])))
{
for ($n = 1; $n < $vars["level"]; $n++)
{
if ($vars["last_i_node"][$n])
{
echo parseTags($icons["e-node"], $vars);
}
else
{
echo parseTags($icons["i-node"], $vars);
}
}
 
if ($vars["level"] != 0)
{
if ($vars["node"] == 0)
{
echo parseTags($icons["t-node"], $vars);
}
else
{
echo parseTags($icons["l-node"], $vars);
$vars["last_i_node"][$vars["level"]] = TRUE;
}
}
}
}
 
return true;
}
return false;
}
 
// parseTemplate
//
// Parse the given template, replacing the variables with the values passed
 
function parseTemplate($template, $vars, $listing)
{
global $ignore, $vars;
if (!is_file($template))
{
print "No template file found ($template)";
exit;
}
 
$handle = fopen($template, "r");
$inListing = false;
$ignore = false;
$listLines = array();
while (!feof($handle))
{
$line = fgets($handle);
// Check for the end of the file list
if ($inListing)
{
if (strcmp(trim($line), "[websvn-endlisting]") == 0)
{
$inListing = false;
 
// For each item in the list
foreach ($listing as $listvars)
{
// Copy the value for this list item into the $vars array
foreach ($listvars as $id => $value)
{
$vars[$id] = $value;
}
// Output the list item
foreach ($listLines as $line)
{
if (!parseCommand($line, $vars, $handle))
{
if (!$ignore)
print parseTags($line, $vars);
}
}
}
}
else
{
if ($ignore == false)
$listLines[] = $line;
}
}
else if (parseCommand($line, $vars, $handle))
{
continue;
}
else
{
// Check for the start of the file list
if (strncmp(trim($line), "[websvn-startlisting]", 21) == 0)
{
$inListing = true;
}
else
{
if ($ignore == false)
print parseTags($line, $vars);
}
}
}
fclose($handle);
}
 
// parseTags
//
// Replace all occurences of [websvn:varname] with the give variable
 
function parseTags($line, $vars)
{
global $lang;
// Replace the websvn variables
while (ereg("\[websvn:([a-zA-Z0-9_]+)\]", $line, $matches))
{
// Make sure that the variable exists
if (!isset($vars[$matches[1]]))
{
$vars[$matches[1]] = "?${matches[1]}?";
}
$line = str_replace($matches[0], $vars[$matches[1]], $line);
}
// Replace the language strings
while (ereg("\[lang:([a-zA-Z0-9_]+)\]", $line, $matches))
{
// Make sure that the variable exists
if (!isset($lang[$matches[1]]))
{
$lang[$matches[1]] = "?${matches[1]}?";
}
$line = str_replace($matches[0], $lang[$matches[1]], $line);
}
 
// Return the results
return $line;
}
?>
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// templates.inc
//
// Templating system to allow advanced page customisation
 
$ignore = false;
 
// Stack of previous test results
$ignorestack = array();
 
// Number of test levels currently ignored
$ignorelevel = 0;
 
// parseCommand
//
// Parse a special command
 
function parseCommand($line, $vars, $handle)
{
global $ignore, $ignorestack, $ignorelevel;
// Check for test conditions
if (strncmp(trim($line), "[websvn-test:", 13) == 0)
{
if (!$ignore)
{
$line = trim($line);
$var = substr($line, 13, -1);
if (empty($vars[$var]))
{
array_push($ignorestack, $ignore);
$ignore = true;
}
}
else
{
$ignorelevel++;
}
return true;
}
if (strncmp(trim($line), "[websvn-else]", 13) == 0)
{
if ($ignorelevel == 0)
{
$ignore = !$ignore;
}
return true;
}
 
if (strncmp(trim($line), "[websvn-endtest]", 16) == 0)
{
if ($ignorelevel > 0)
{
$ignorelevel--;
}
else
{
$ignore = array_pop($ignorestack);
}
return true;
}
if (strncmp(trim($line), "[websvn-getlisting]", 19) == 0)
{
global $path, $rev, $svnrep;
if (!$ignore)
$svnrep->listFileContents($path, $rev);
return true;
}
if (strncmp(trim($line), "[websvn-defineicons]", 19) == 0)
{
global $icons;
if (!isset($icons))
$icons = array();
// Read all the lines until we reach the end of the definition, storing
// each one...
if (!$ignore)
{
while (!feof($handle))
{
$line = trim(fgets($handle));
if (strncmp($line, "[websvn-enddefineicons]", 22) == 0)
{
return true;
}
$eqsign = strpos($line, "=");
$match = substr($line, 0, $eqsign);
$def = substr($line, $eqsign + 1);
$icons[$match] = $def;
}
}
return true;
}
 
if (strncmp(trim($line), "[websvn-icon]", 13) == 0)
{
global $icons, $vars;
if (!$ignore)
{
// The current filetype should be defined my $vars["filetype"]
if (!empty($icons[$vars["filetype"]]))
{
echo parseTags($icons[$vars["filetype"]], $vars);
}
else if (!empty($icons["*"]))
{
echo parseTags($icons["*"], $vars);
}
}
return true;
}
 
if (strncmp(trim($line), "[websvn-treenode]", 17) == 0)
{
global $icons, $vars;
if (!$ignore)
{
if ((!empty($icons["i-node"])) && (!empty($icons["t-node"])) && (!empty($icons["l-node"])))
{
for ($n = 1; $n < $vars["level"]; $n++)
{
if ($vars["last_i_node"][$n])
{
echo parseTags($icons["e-node"], $vars);
}
else
{
echo parseTags($icons["i-node"], $vars);
}
}
 
if ($vars["level"] != 0)
{
if ($vars["node"] == 0)
{
echo parseTags($icons["t-node"], $vars);
}
else
{
echo parseTags($icons["l-node"], $vars);
$vars["last_i_node"][$vars["level"]] = TRUE;
}
}
}
}
 
return true;
}
return false;
}
 
// parseTemplate
//
// Parse the given template, replacing the variables with the values passed
 
function parseTemplate($template, $vars, $listing)
{
global $ignore, $vars;
if (!is_file($template))
{
print "No template file found ($template)";
exit;
}
 
$handle = fopen($template, "r");
$inListing = false;
$ignore = false;
$listLines = array();
while (!feof($handle))
{
$line = fgets($handle);
// Check for the end of the file list
if ($inListing)
{
if (strcmp(trim($line), "[websvn-endlisting]") == 0)
{
$inListing = false;
 
// For each item in the list
foreach ($listing as $listvars)
{
// Copy the value for this list item into the $vars array
foreach ($listvars as $id => $value)
{
$vars[$id] = $value;
}
// Output the list item
foreach ($listLines as $line)
{
if (!parseCommand($line, $vars, $handle))
{
if (!$ignore)
print parseTags($line, $vars);
}
}
}
}
else
{
if ($ignore == false)
$listLines[] = $line;
}
}
else if (parseCommand($line, $vars, $handle))
{
continue;
}
else
{
// Check for the start of the file list
if (strncmp(trim($line), "[websvn-startlisting]", 21) == 0)
{
$inListing = true;
}
else
{
if ($ignore == false)
print parseTags($line, $vars);
}
}
}
fclose($handle);
}
 
// parseTags
//
// Replace all occurences of [websvn:varname] with the give variable
 
function parseTags($line, $vars)
{
global $lang;
// Replace the websvn variables
while (ereg("\[websvn:([a-zA-Z0-9_]+)\]", $line, $matches))
{
// Make sure that the variable exists
if (!isset($vars[$matches[1]]))
{
$vars[$matches[1]] = "?${matches[1]}?";
}
$line = str_replace($matches[0], $vars[$matches[1]], $line);
}
// Replace the language strings
while (ereg("\[lang:([a-zA-Z0-9_]+)\]", $line, $matches))
{
// Make sure that the variable exists
if (!isset($lang[$matches[1]]))
{
$lang[$matches[1]] = "?${matches[1]}?";
}
$line = str_replace($matches[0], $lang[$matches[1]], $line);
}
 
// Return the results
return $line;
}
?>
/WebSVN/include/version.inc
1,28 → 1,28
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// version.inc
//
// Version information
 
$version = '2.1 alpha 1';
?>
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// version.inc
//
// Version information
 
$version = '2.1 alpha 1';
?>
/WebSVN/templates/MLAB/header.tmpl
39,7 → 39,7
<link rel="alternate" type="application/rss+xml" title="WebSVN RSS" href="[websvn:curdirrsshref]">
[websvn-endtest]
</head>
<body lang="[lang:LANGUAGETAG]">
<body lang="[lang:LANG]">
<!-- AUTOINCLUDE START "Page/Header.cs.ihtml" DO NOT REMOVE -->
<!-- ============== HLAVIČKA ============== -->
<div class="Header">
/WebSVN/templates/Standard/blame.tmpl
1,27 → 1,27
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
<h2>[websvn:repname]</h2>
[websvn:curdirlinks] - <h2> [lang:BLAMEFOR] [websvn:rev]</h2>
<p>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
<table border="1" class="blame" width="100%">
<tr>
<th style="padding-bottom: 5px" align="left"><b>[lang:LINENO]</b></th>
<th style="padding-bottom: 5px" align="left"><b>[lang:REV]</b></th>
<th style="padding-bottom: 5px" align="left"><b>[lang:AUTHOR]</b></th>
<th style="padding-bottom: 5px" align="left"><b>[lang:LINE]</b></th>
</tr>
[websvn-startlisting]
<tr>
<td>[websvn:lineno]</td>
<td>[websvn:revision]</td>
<td>[websvn:author]</td>
<td>[websvn:line]</td>
</tr>
[websvn-endlisting]
</table>
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
<h2>[websvn:repname]</h2>
[websvn:curdirlinks] - <h2> [lang:BLAMEFOR] [websvn:rev]</h2>
<p>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
<table border="1" class="blame" width="100%">
<tr>
<th style="padding-bottom: 5px" align="left"><b>[lang:LINENO]</b></th>
<th style="padding-bottom: 5px" align="left"><b>[lang:REV]</b></th>
<th style="padding-bottom: 5px" align="left"><b>[lang:AUTHOR]</b></th>
<th style="padding-bottom: 5px" align="left"><b>[lang:LINE]</b></th>
</tr>
[websvn-startlisting]
<tr>
<td>[websvn:lineno]</td>
<td>[websvn:revision]</td>
<td>[websvn:author]</td>
<td>[websvn:line]</td>
</tr>
[websvn-endlisting]
</table>
[websvn-endtest]
/WebSVN/templates/Standard/compare.tmpl
1,66 → 1,66
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
<h2>[websvn:repname]</h2>
<p>
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
<center>
[websvn:compare_form]
<table>
<tr><td>
<table class="outlined">
<tr><td>[lang:COMPPATH]&nbsp;</td><td>[websvn:compare_path1input] [lang:REV] [websvn:compare_rev1input]</td></tr>
<tr><td>[lang:WITHPATH]&nbsp;</td><td>[websvn:compare_path2input] [lang:REV] [websvn:compare_rev2input]</td></tr>
</table>
</td><tr>
<tr><td align="center">[websvn:compare_submit]</td></tr>
</table>
[websvn:compare_endform]
</center>
<hr>
[websvn-test:success]
[lang:CONVFROM] <b>[websvn:path1] ([lang:REV] [websvn:rev1])</b> [lang:TO] <b>[websvn:path2] ([lang:REV] [websvn:rev2])</b>
<p>
[websvn:revlink]
[websvn-endtest]
<p>
[websvn-startlisting]
[websvn-test:newpath]
<p>
<div class="newpath">
<b>[websvn:newpath]</b><br>
[websvn-endtest]
[websvn-test:info]
[websvn:info]<br>
[websvn-endtest]
[websvn-test:difflines]
<div class="difflines">
<p>
[websvn:difflines]<br>
<table class="diff" cellspacing="0">
[websvn-endtest]
[websvn-test:diffclass]
<tr><td class="[websvn:diffclass]">[websvn:line]</td></tr>
[websvn-endtest]
[websvn-test:enddifflines]
</table>
</div>
[websvn-endtest]
[websvn-test:endpath]
</div>
<p><hr>
[websvn-endtest]
[websvn-test:properties]
<p><i>[lang:PROPCHANGES]</i><p>
[websvn-endtest]
[websvn-endlisting]
</table>
[websvn-endtest]
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
<h2>[websvn:repname]</h2>
<p>
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
<center>
[websvn:compare_form]
<table>
<tr><td>
<table class="outlined">
<tr><td>[lang:COMPPATH]&nbsp;</td><td>[websvn:compare_path1input] [lang:REV] [websvn:compare_rev1input]</td></tr>
<tr><td>[lang:WITHPATH]&nbsp;</td><td>[websvn:compare_path2input] [lang:REV] [websvn:compare_rev2input]</td></tr>
</table>
</td><tr>
<tr><td align="center">[websvn:compare_submit]</td></tr>
</table>
[websvn:compare_endform]
</center>
<hr>
[websvn-test:success]
[lang:CONVFROM] <b>[websvn:path1] ([lang:REV] [websvn:rev1])</b> [lang:TO] <b>[websvn:path2] ([lang:REV] [websvn:rev2])</b>
<p>
[websvn:revlink]
[websvn-endtest]
<p>
[websvn-startlisting]
[websvn-test:newpath]
<p>
<div class="newpath">
<b>[websvn:newpath]</b><br>
[websvn-endtest]
[websvn-test:info]
[websvn:info]<br>
[websvn-endtest]
[websvn-test:difflines]
<div class="difflines">
<p>
[websvn:difflines]<br>
<table class="diff" cellspacing="0">
[websvn-endtest]
[websvn-test:diffclass]
<tr><td class="[websvn:diffclass]">[websvn:line]</td></tr>
[websvn-endtest]
[websvn-test:enddifflines]
</table>
</div>
[websvn-endtest]
[websvn-test:endpath]
</div>
<p><hr>
[websvn-endtest]
[websvn-test:properties]
<p><i>[lang:PROPCHANGES]</i><p>
[websvn-endtest]
[websvn-endlisting]
</table>
[websvn-endtest]
/WebSVN/templates/Standard/diff.tmpl
1,40 → 1,40
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
[websvn-test:noprev]
[lang:NOPREVREV]
[websvn-else]
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
<h2>[websvn:repname]</h2>
[websvn:curdirlinks] - <h2>[lang:DIFFREVS] <b>[websvn:rev2]</b> [lang:AND] <b>[websvn:rev1]</b></h2>
<p>
<p><center>
[websvn:showcompactlink]
[websvn:showalllink]
</center>
<p>
<table class="diff" width="100%">
<tr>
<th style="padding-bottom: 5px" width="50%" align="left"><b>[lang:REV] [websvn:rev2]</b></th>
<th width="5"></th>
<th style="padding-bottom: 5px" width="50%" align="left"><b>[lang:REV] [websvn:rev1]</b></th>
</tr>
[websvn-startlisting]
[websvn-test:rev1lineno]
<tr>
<td width="50%" style="padding: 3px 0 3px 0" align="center"><b>[lang:LINE] [websvn:rev1lineno]...</b></td>
<td width="5"></td>
<td width="50%" style="padding: 3px 0 3px 0" align="center"><b>[lang:LINE] [websvn:rev2lineno]...</b></td>
<tr>
[websvn-else]
<tr><td class="[websvn:rev1diffclass]">[websvn:rev1line]</td>
<td width="5"></td>
<td class="[websvn:rev2diffclass]">[websvn:rev2line]</td></tr>
[websvn-endtest]
[websvn-endlisting]
</table>
[websvn-endtest]
[websvn-endtest]
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
[websvn-test:noprev]
No Previous Revision
[websvn-else]
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
<h2>[websvn:repname]</h2>
[websvn:curdirlinks] - <h2>[lang:DIFFREVS] <b>[websvn:rev2]</b> [lang:AND] <b>[websvn:rev1]</b></h2>
<p>
<p><center>
[websvn:showcompactlink]
[websvn:showalllink]
</center>
<p>
<table class="diff" width="100%">
<tr>
<th style="padding-bottom: 5px" width="50%" align="left"><b>[lang:REV] [websvn:rev2]</b></th>
<th width="5"></th>
<th style="padding-bottom: 5px" width="50%" align="left"><b>[lang:REV] [websvn:rev1]</b></th>
</tr>
[websvn-startlisting]
[websvn-test:rev1lineno]
<tr>
<td width="50%" style="padding: 3px 0 3px 0" align="center"><b>[lang:LINE] [websvn:rev1lineno]...</b></td>
<td width="5"></td>
<td width="50%" style="padding: 3px 0 3px 0" align="center"><b>[lang:LINE] [websvn:rev2lineno]...</b></td>
<tr>
[websvn-else]
<tr><td class="[websvn:rev1diffclass]">[websvn:rev1line]</td>
<td width="5"></td>
<td class="[websvn:rev2diffclass]">[websvn:rev2line]</td></tr>
[websvn-endtest]
[websvn-endlisting]
</table>
[websvn-endtest]
[websvn-endtest]
/WebSVN/templates/Standard/directory.tmpl
1,117 → 1,117
 
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
<h1>[websvn:repname]</h1>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
[websvn-test:restricted]
[websvn-else]
<p><b>[lang:PATH]:</b> [websvn:path]
<br><b>[lang:REV]:</b> [websvn:rev]
[websvn-test:goyoungestlink]
- [websvn:goyoungestlink]
[websvn-endtest]
<br><b>[lang:LASTMOD]:</b> [lang:REV] [websvn:lastchangedrev] - [websvn:author] - [websvn:date]
<br><b>[lang:LOGMSG]:</b><br>
[websvn:log]
<p>
[websvn-test:hidechanges]
<p>[websvn:showchangeslink]
[websvn-endtest]
[websvn-test:showchanges]
<p><b>[lang:CHANGES]:</b><br>
<p>[websvn:hidechangeslink]
<p>
<center>
<table border=1 class="bordered" cellpadding=4>
<tr>
<th><center><b>[lang:NEWFILES]</b></center></th>
<th><center><b>[lang:CHANGEDFILES]</b></center></th>
<th><center><b>[lang:DELETEDFILES]</b></center></th>
</tr>
<tr>
<td valign="top">
[websvn-test:newfilesbr]
[websvn:newfilesbr]
[websvn-else]
&nbsp;
[websvn-endtest]
</td>
<td valign="top">
[websvn-test:changedfilesbr]
[websvn:changedfilesbr]
[websvn-else]
&nbsp;
[websvn-endtest]
</td>
<td valign="top">
[websvn-test:deletedfilesbr]
[websvn:deletedfilesbr]
[websvn-else]
&nbsp;
[websvn-endtest]
</td>
</tr>
</table>
</center>
[websvn-endtest]
[websvn-endtest]
[websvn-defineicons]
dir=&nbsp;&nbsp;&nbsp;&nbsp;
diropen=&nbsp;&nbsp;&nbsp;&nbsp;
i-node=&nbsp;&nbsp;&nbsp;&nbsp;
t-node=&nbsp;&nbsp;&nbsp;&nbsp;
l-node=&nbsp;&nbsp;&nbsp;&nbsp;
e-node=&nbsp;&nbsp;&nbsp;&nbsp;
*=&nbsp;&nbsp;&nbsp;&nbsp;
[websvn-enddefineicons]
<p><hr>
<b>[lang:CURDIR]:</b> [websvn:curdirlinks] - [websvn:curdirloglink]
[websvn-test:curdircomplink]
- [websvn:curdircomplink]
[websvn-endtest]
[websvn-test:curdirdllink]
- [websvn:curdirdllink]
[websvn-endtest]
[websvn-test:curdirrsslink]
- [websvn:curdirrssanchor]<img style="border: 0;" src="[websvn:locwebsvnhttp]/templates/Standard/xml.gif" width="36" height="14" alt="[lang:RSSFEED]"></a>
[websvn-endtest]
<p>
[websvn:compare_form]
<table class="outlined" width="100%" cellpadding=2>
<tr>
<th width="100%"><b>[lang:PATH]</b></th>
<th><b>[lang:NOBR][lang:LOG][lang:ENDNOBR]</b></th>
[websvn-test:allowdownload]
<th><b>[lang:TARBALL]</b></th>
[websvn-endtest]
[websvn-test:curdirrsslink]
<th><b>[lang:RSSFEED]</b></th>
[websvn-endtest]
</tr>
[websvn-startlisting]
<tr>
<td class="[websvn:rowparity]">
[websvn:compare_box]
[websvn-treenode]
[websvn:filelink]
</td>
<td class="[websvn:rowparity]">[lang:NOBR][websvn:fileviewloglink][lang:ENDNOBR]</td>
[websvn-test:allowdownload]
<td class="[websvn:rowparity]">[websvn:fileviewdllink]</td>
[websvn-endtest]
[websvn-test:curdirrsslink]
<td class="row[websvn:rowparity]">[websvn:rssanchor]<img style="border: 0;" src="[websvn:locwebsvnhttp]/templates/Standard/xml.gif" width="36" height="14" alt="[lang:RSSFEED]"></a></td>
[websvn-endtest]
</tr>
[websvn-endlisting]
</table>
<p>
[websvn:compare_submit]
[websvn:compare_endform]
 
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
<h1>[websvn:repname]</h1>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
[websvn-test:restricted]
[websvn-else]
<p><b>[lang:PATH]:</b> [websvn:path]
<br><b>[lang:REV]:</b> [websvn:rev]
[websvn-test:goyoungestlink]
- [websvn:goyoungestlink]
[websvn-endtest]
<br><b>[lang:LASTMOD]:</b> [lang:REV] [websvn:lastchangedrev] - [websvn:author] - [websvn:date]
<br><b>[lang:LOGMSG]:</b><br>
[websvn:log]
<p>
[websvn-test:hidechanges]
<p>[websvn:showchangeslink]
[websvn-endtest]
[websvn-test:showchanges]
<p><b>[lang:CHANGES]:</b><br>
<p>[websvn:hidechangeslink]
<p>
<center>
<table border=1 class="bordered" cellpadding=4>
<tr>
<th><center><b>[lang:NEWFILES]</b></center></th>
<th><center><b>[lang:CHANGEDFILES]</b></center></th>
<th><center><b>[lang:DELETEDFILES]</b></center></th>
</tr>
<tr>
<td valign="top">
[websvn-test:newfilesbr]
[websvn:newfilesbr]
[websvn-else]
&nbsp;
[websvn-endtest]
</td>
<td valign="top">
[websvn-test:changedfilesbr]
[websvn:changedfilesbr]
[websvn-else]
&nbsp;
[websvn-endtest]
</td>
<td valign="top">
[websvn-test:deletedfilesbr]
[websvn:deletedfilesbr]
[websvn-else]
&nbsp;
[websvn-endtest]
</td>
</tr>
</table>
</center>
[websvn-endtest]
[websvn-endtest]
[websvn-defineicons]
dir=&nbsp;&nbsp;&nbsp;&nbsp;
diropen=&nbsp;&nbsp;&nbsp;&nbsp;
i-node=&nbsp;&nbsp;&nbsp;&nbsp;
t-node=&nbsp;&nbsp;&nbsp;&nbsp;
l-node=&nbsp;&nbsp;&nbsp;&nbsp;
e-node=&nbsp;&nbsp;&nbsp;&nbsp;
*=&nbsp;&nbsp;&nbsp;&nbsp;
[websvn-enddefineicons]
<p><hr>
<b>[lang:CURDIR]:</b> [websvn:curdirlinks] - [websvn:curdirloglink]
[websvn-test:curdircomplink]
- [websvn:curdircomplink]
[websvn-endtest]
[websvn-test:curdirdllink]
- [websvn:curdirdllink]
[websvn-endtest]
[websvn-test:curdirrsslink]
- [websvn:curdirrssanchor]<img style="border: 0;" src="[websvn:locwebsvnhttp]/templates/Standard/xml.gif" width="36" height="14" alt="[lang:RSSFEED]"></a>
[websvn-endtest]
<p>
[websvn:compare_form]
<table class="outlined" width="100%" cellpadding=2>
<tr>
<th width="100%"><b>[lang:PATH]</b></th>
<th><b>[lang:NOBR][lang:LOG][lang:ENDNOBR]</b></th>
[websvn-test:allowdownload]
<th><b>[lang:TARBALL]</b></th>
[websvn-endtest]
[websvn-test:curdirrsslink]
<th><b>[lang:RSSFEED]</b></th>
[websvn-endtest]
</tr>
[websvn-startlisting]
<tr>
<td class="[websvn:rowparity]">
[websvn:compare_box]
[websvn-treenode]
[websvn:filelink]
</td>
<td class="[websvn:rowparity]">[lang:NOBR][websvn:fileviewloglink][lang:ENDNOBR]</td>
[websvn-test:allowdownload]
<td class="[websvn:rowparity]">[websvn:fileviewdllink]</td>
[websvn-endtest]
[websvn-test:curdirrsslink]
<td class="row[websvn:rowparity]">[websvn:rssanchor]<img style="border: 0;" src="[websvn:locwebsvnhttp]/templates/Standard/xml.gif" width="36" height="14" alt="[lang:RSSFEED]"></a></td>
[websvn-endtest]
</tr>
[websvn-endlisting]
</table>
<p>
[websvn:compare_submit]
[websvn:compare_endform]
[websvn-endtest]
/WebSVN/templates/Standard/file.tmpl
1,18 → 1,18
 
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
<h2>[websvn:repname]</h2>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
[websvn:curdirlinks] - [lang:REV] [websvn:rev]<p>
[websvn-test:goyoungestlink]
[websvn:goyoungestlink]<p>
[websvn-endtest]
[websvn:prevdifflink] - [websvn:blamelink]
<p>
<table width="100%" border=0><tr><td>
[websvn-getlisting]
</td></tr></table>
 
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
<h2>[websvn:repname]</h2>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
[websvn:curdirlinks] - [lang:REV] [websvn:rev]<p>
[websvn-test:goyoungestlink]
[websvn:goyoungestlink]<p>
[websvn-endtest]
[websvn:prevdifflink] - [websvn:blamelink]
<p>
<table width="100%" border=0><tr><td>
[websvn-getlisting]
</td></tr></table>
[websvn-endtest]
/WebSVN/templates/Standard/footer.tmpl
1,3 → 1,3
<p><center><font size="-1"><i><b>[lang:POWERED] v[websvn:version]</b></i></font></center>
</body>
</html>
<p><center><font size="-1"><i><b>[lang:POWERED] v[websvn:version]</b></i></font></center>
</body>
</html>
/WebSVN/templates/Standard/header.tmpl
1,73 → 1,73
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=[websvn:charset]">
<link href="[websvn:locwebsvnhttp]/templates/Standard/styles.css" rel="stylesheet" media="screen">
<script type="text/javascript" src="[websvn:locwebsvnhttp]/templates/Standard/collapse.js"></script>
<script type="text/javascript">
function checkCB(chBox)
{
count = 0
first = null
f = chBox.form
for (i = 0 ; i < f.elements.length ; i++)
if (f.elements[i].type == 'checkbox' && f.elements[i].checked)
{
if (first == null && f.elements[i] != chBox)
first = f.elements[i]
count += 1
}
if (count > 2)
{
first.checked = false
count -= 1
}
 
[websvn-test:opentree]
expandonload = true
[websvn-endtest]
 
}
</script>
<title>
WebSVN
[websvn-test:repname]
- [websvn:repname]
[websvn-endtest]
[websvn-test:action]
- [websvn:action]
[websvn-endtest]
[websvn-test:rev2]
[websvn-test:path2]
- [websvn:safepath1] [lang:REV] [websvn:rev1] [lang:AND] [websvn:safepath2] [lang:REV] [websvn:rev2]
[websvn-else]
- [lang:REV] [websvn:rev1] [lang:AND] [websvn:rev2]
[websvn-endtest]
[websvn-else]
[websvn-test:rev]
- [lang:REV] [websvn:rev]
[websvn-endtest]
[websvn-endtest]
[websvn-test:path]
- [websvn:safepath]
[websvn-endtest]
</title>
 
[websvn-test:curdirrsslink]
<link rel="alternate" type="application/rss+xml" title="WebSVN RSS" href="[websvn:curdirrsshref]">
[websvn-endtest]
 
</head>
<body>
<table width="100%" border="0">
<tr>
<td width="33%">&nbsp;</td>
<td width="33%" align="center"><h1>[lang:SERVER]</h1></td>
<td width="33%"><div style="float: right">[websvn:lang_form][websvn:lang_select][websvn:lang_submit][websvn:lang_endform]</div></td>
</tr>
</table>
 
<hr>
<p>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=[websvn:charset]">
<link href="[websvn:locwebsvnhttp]/templates/Standard/styles.css" rel="stylesheet" media="screen">
<script type="text/javascript" src="[websvn:locwebsvnhttp]/templates/Standard/collapse.js"></script>
<script type="text/javascript">
function checkCB(chBox)
{
count = 0
first = null
f = chBox.form
for (i = 0 ; i < f.elements.length ; i++)
if (f.elements[i].type == 'checkbox' && f.elements[i].checked)
{
if (first == null && f.elements[i] != chBox)
first = f.elements[i]
count += 1
}
if (count > 2)
{
first.checked = false
count -= 1
}
 
[websvn-test:opentree]
expandonload = true
[websvn-endtest]
 
}
</script>
<title>
WebSVN
[websvn-test:repname]
- [websvn:repname]
[websvn-endtest]
[websvn-test:action]
- [websvn:action]
[websvn-endtest]
[websvn-test:rev2]
[websvn-test:path2]
- [websvn:safepath1] [lang:REV] [websvn:rev1] [lang:AND] [websvn:safepath2] [lang:REV] [websvn:rev2]
[websvn-else]
- [lang:REV] [websvn:rev1] [lang:AND] [websvn:rev2]
[websvn-endtest]
[websvn-else]
[websvn-test:rev]
- [lang:REV] [websvn:rev]
[websvn-endtest]
[websvn-endtest]
[websvn-test:path]
- [websvn:safepath]
[websvn-endtest]
</title>
 
[websvn-test:curdirrsslink]
<link rel="alternate" type="application/rss+xml" title="WebSVN RSS" href="[websvn:curdirrsshref]">
[websvn-endtest]
 
</head>
<body>
<table width="100%" border="0">
<tr>
<td width="33%">&nbsp;</td>
<td width="33%" align="center"><h1>[lang:SERVER]</h1></td>
<td width="33%"><div style="float: right">[websvn:lang_form][websvn:lang_select][websvn:lang_submit][websvn:lang_endform]</div></td>
</tr>
</table>
 
<hr>
<p>
/WebSVN/templates/Standard/index.tmpl
1,35 → 1,35
[websvn-test:flatview]
<table border=0 cellspacing=0 cellpadding=0 align="center">
<tr>
<td align="center">
<br><h2>[lang:PROJECTS]:</h2>
<table border=0>
<tr><td><ul>
[websvn-startlisting]
<li><strong>[websvn:projlink]</strong></li>
[websvn-endlisting]
</ul></td></tr>
</table>
</td>
</tr>
</table>
[websvn-else]
<table border=0 cellspacing=0 cellpadding=0 align="center">
<tr>
<td align="center">
<br><h2>[lang:PROJECTS]:</h2>
<table border=0>
<tr><td>
[websvn-startlisting]
[websvn-test:isprojlink]
<div style="padding: 3px">[websvn:listitem]</div>
[websvn-else]
[websvn:listitem]
[websvn-endtest]
[websvn-endlisting]
</td></tr>
</table>
</td>
</tr>
</table>
[websvn-endtest]
[websvn-test:flatview]
<table border=0 cellspacing=0 cellpadding=0 align="center">
<tr>
<td align="center">
<br><h2>[lang:PROJECTS]:</h2>
<table border=0>
<tr><td><ul>
[websvn-startlisting]
<li><strong>[websvn:projlink]</strong></li>
[websvn-endlisting]
</ul></td></tr>
</table>
</td>
</tr>
</table>
[websvn-else]
<table border=0 cellspacing=0 cellpadding=0 align="center">
<tr>
<td align="center">
<br><h2>[lang:PROJECTS]:</h2>
<table border=0>
<tr><td>
[websvn-startlisting]
[websvn-test:isprojlink]
<div style="padding: 3px">[websvn:listitem]</div>
[websvn-else]
[websvn:listitem]
[websvn-endtest]
[websvn-endlisting]
</td></tr>
</table>
</td>
</tr>
</table>
[websvn-endtest]
/WebSVN/templates/Standard/log.tmpl
1,64 → 1,64
 
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
<h2>[websvn:repname] - [lang:REV] [websvn:rev]</h2>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
[websvn:curdirlinks]<p>
[websvn-test:goyoungestlink]
[websvn:goyoungestlink]<p>
[websvn-endtest]
<center>
[websvn:logsearch_form]
<b>[lang:FILTER]</b><p>
[lang:STARTLOG]:[websvn:logsearch_startbox] [lang:ENDLOG]:[websvn:logsearch_endbox] [lang:MAXLOG]:[websvn:logsearch_maxbox] [lang:SEARCHLOG]:[websvn:logsearch_inputbox]
[websvn:logsearch_submit]
[websvn-test:logsearch_clearloglink]
<p><font size="-1">[websvn:logsearch_clearloglink]</font><p>
[websvn-endtest]
[websvn:logsearch_endform]
</center>
[websvn-test:logsearch_nomatches]
<center>[lang:NORESULTS]</center>
[websvn-endtest]
[websvn-test:error]
<center>[websvn:error]</center>
[websvn-endtest]
 
[websvn-test:logsearch_resultsfound]
[websvn:compare_form]
<table border=1 class="outlined" width="100%" cellpadding=2>
<tr>
<th>[lang:REV]</th>
<th>[lang:PATH]</th>
<th>[lang:AUTHOR]</th>
<th>[lang:AGE]</th>
<th>[lang:LOGMSG]</th>
</tr>
[websvn-startlisting]
<tr>
<td valign="top" class="[websvn:rowparity]"><nobr>[websvn:compare_box][websvn:revlink]</nobr></td>
<td valign="top" class="[websvn:rowparity]">[websvn:revpathlink]</td>
<td valign="top" class="[websvn:rowparity]">[websvn:revauthor]</td>
<td valign="top" class="[websvn:rowparity]">[websvn:revage]</td>
<td valign="top" class="[websvn:rowparity]">[websvn:revlog]</td>
</tr>
[websvn-endlisting]
</table>
<p>
[websvn:compare_submit]
[websvn:compare_endform]
[websvn-endtest]
[websvn-test:logsearch_nomorematches]
<p><center>[lang:NOMORERESULTS]</center>
[websvn-endtest]
<p><center>[websvn:logsearch_moreresultslink]</center>
<p><center>[websvn:pagelinks]<p>[websvn:showalllink]</center>
 
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
<h2>[websvn:repname] - [lang:REV] [websvn:rev]</h2>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
[websvn:curdirlinks]<p>
[websvn-test:goyoungestlink]
[websvn:goyoungestlink]<p>
[websvn-endtest]
<center>
[websvn:logsearch_form]
<b>[lang:FILTER]</b><p>
[lang:STARTLOG]:[websvn:logsearch_startbox] [lang:ENDLOG]:[websvn:logsearch_endbox] [lang:MAXLOG]:[websvn:logsearch_maxbox] [lang:SEARCHLOG]:[websvn:logsearch_inputbox]
[websvn:logsearch_submit]
[websvn-test:logsearch_clearloglink]
<p><font size="-1">[websvn:logsearch_clearloglink]</font><p>
[websvn-endtest]
[websvn:logsearch_endform]
</center>
[websvn-test:logsearch_nomatches]
<center>[lang:NORESULTS]</center>
[websvn-endtest]
[websvn-test:error]
<center>[websvn:error]</center>
[websvn-endtest]
 
[websvn-test:logsearch_resultsfound]
[websvn:compare_form]
<table border=1 class="outlined" width="100%" cellpadding=2>
<tr>
<th>[lang:REV]</th>
<th>[lang:PATH]</th>
<th>[lang:AUTHOR]</th>
<th>[lang:AGE]</th>
<th>[lang:LOGMSG]</th>
</tr>
[websvn-startlisting]
<tr>
<td valign="top" class="[websvn:rowparity]"><nobr>[websvn:compare_box][websvn:revlink]</nobr></td>
<td valign="top" class="[websvn:rowparity]">[websvn:revpathlink]</td>
<td valign="top" class="[websvn:rowparity]">[websvn:revauthor]</td>
<td valign="top" class="[websvn:rowparity]">[websvn:revage]</td>
<td valign="top" class="[websvn:rowparity]">[websvn:revlog]</td>
</tr>
[websvn-endlisting]
</table>
<p>
[websvn:compare_submit]
[websvn:compare_endform]
[websvn-endtest]
[websvn-test:logsearch_nomorematches]
<p><center>[lang:NOMORERESULTS]</center>
[websvn-endtest]
<p><center>[websvn:logsearch_moreresultslink]</center>
<p><center>[websvn:pagelinks]<p>[websvn:showalllink]</center>
[websvn-endtest]
/WebSVN/templates/Standard/collapse.js
1,169 → 1,169
/***********************************************
* Switch Content script- © Dynamic Drive (www.dynamicdrive.com)
* This notice must stay intact for legal use. Last updated April 2nd, 2005.
* Visit http://www.dynamicdrive.com/ for full source code
***********************************************/
 
var enablepersist="on" // Enable saving state of content structure using session cookies? (on/off)
var collapseprevious="yes" // Collapse previously open content when opening present? (yes/no)
 
var contractsymbol='<div class="minusbox">-</div>' // HTML for contract symbol. For image, use: <img src="${prefix}whatever.gif">
var expandsymbol='<div class="plusbox">+</div>' // HTML for expand symbol.
var expandonload=false
 
if (document.getElementById)
{
document.write('<style type="text/css">')
document.write('.switchcontent{display:none;}')
document.write('</style>')
}
 
function getElementbyClass(rootobj, classname)
{
var temparray=new Array()
var inc=0
for (i=0; i<rootobj.length; i++)
{
if (rootobj[i].className==classname)
temparray[inc++]=rootobj[i]
}
return temparray
}
 
function sweeptoggle(ec)
{
var thestate=(ec=="expand")? "block" : "none"
var inc=0
while (ccollect[inc])
{
ccollect[inc].style.display=thestate
inc++
}
revivestatus()
collapseprevious = (ec=="expand")? "no" : "yes"
}
 
 
function contractcontent(omit)
{
var inc=0
while (ccollect[inc])
{
if (ccollect[inc].id!=omit)
ccollect[inc].style.display="none"
inc++
}
}
 
function expandcontent(curobj, cid)
{
var spantags=curobj.getElementsByTagName("SPAN")
var showstateobj=getElementbyClass(spantags, "showstate")
if (ccollect.length>0)
{
if (collapseprevious=="yes")
contractcontent(cid)
document.getElementById(cid).style.display=(document.getElementById(cid).style.display!="block")? "block" : "none"
if (showstateobj.length>0) //if "showstate" span exists in header
{
if (collapseprevious=="no")
showstateobj[0].innerHTML=(document.getElementById(cid).style.display=="block")? contractsymbol : expandsymbol
else
revivestatus()
}
}
}
 
function revivecontent()
{
contractcontent("omitnothing")
selectedItem=getselectedItem()
selectedComponents=selectedItem.split("|")
collapseprevious=selectedComponents[0]
for (i=1; i<selectedComponents.length-1; i++)
document.getElementById(selectedComponents[i]).style.display="block"
}
 
function revivestatus()
{
var inc=0
while (statecollect[inc])
{
if (ccollect[inc].style.display=="block")
statecollect[inc].innerHTML=contractsymbol
else
statecollect[inc].innerHTML=expandsymbol
inc++
}
}
 
function get_cookie(Name)
{
var search = Name + "="
var returnvalue = "";
if (document.cookie.length > 0)
{
offset = document.cookie.indexOf(search)
if (offset != -1)
{
offset += search.length
end = document.cookie.indexOf(";", offset);
if (end == -1) end = document.cookie.length;
returnvalue=unescape(document.cookie.substring(offset, end))
}
}
return returnvalue;
}
 
function getselectedItem()
{
if (get_cookie(window.location.pathname) != "")
{
selectedItem=get_cookie(window.location.pathname)
return selectedItem
}
else
return ""
}
 
function saveswitchstate()
{
var inc=0, selectedItem=collapseprevious+"|"
while (ccollect[inc])
{
if (ccollect[inc].style.display=="block")
selectedItem+=ccollect[inc].id+"|"
inc++
}
document.cookie=window.location.pathname+"="+selectedItem
}
 
function do_onload()
{
uniqueidn=window.location.pathname+"firsttimeload"
var alltags=document.all? document.all : document.getElementsByTagName("*")
ccollect=getElementbyClass(alltags, "switchcontent")
statecollect=getElementbyClass(alltags, "showstate")
if (enablepersist=="on" && ccollect.length>0)
{
document.cookie=(get_cookie(uniqueidn)=="")? uniqueidn+"=1" : uniqueidn+"=0"
firsttimeload=(get_cookie(uniqueidn)==1)? 1 : 0 //check if this is 1st page load
if (!firsttimeload)
revivecontent()
}
if (ccollect.length>0 && statecollect.length>0)
revivestatus()
if (expandonload)
sweeptoggle('expand')
}
 
if (window.addEventListener)
window.addEventListener("load", do_onload, false)
else if (window.attachEvent)
window.attachEvent("onload", do_onload)
else if (document.getElementById)
window.onload=do_onload
 
if (enablepersist=="on" && document.getElementById)
window.onunload=saveswitchstate
/***********************************************
* Switch Content script- © Dynamic Drive (www.dynamicdrive.com)
* This notice must stay intact for legal use. Last updated April 2nd, 2005.
* Visit http://www.dynamicdrive.com/ for full source code
***********************************************/
 
var enablepersist="on" // Enable saving state of content structure using session cookies? (on/off)
var collapseprevious="yes" // Collapse previously open content when opening present? (yes/no)
 
var contractsymbol='<div class="minusbox">-</div>' // HTML for contract symbol. For image, use: <img src="${prefix}whatever.gif">
var expandsymbol='<div class="plusbox">+</div>' // HTML for expand symbol.
var expandonload=false
 
if (document.getElementById)
{
document.write('<style type="text/css">')
document.write('.switchcontent{display:none;}')
document.write('</style>')
}
 
function getElementbyClass(rootobj, classname)
{
var temparray=new Array()
var inc=0
for (i=0; i<rootobj.length; i++)
{
if (rootobj[i].className==classname)
temparray[inc++]=rootobj[i]
}
return temparray
}
 
function sweeptoggle(ec)
{
var thestate=(ec=="expand")? "block" : "none"
var inc=0
while (ccollect[inc])
{
ccollect[inc].style.display=thestate
inc++
}
revivestatus()
collapseprevious = (ec=="expand")? "no" : "yes"
}
 
 
function contractcontent(omit)
{
var inc=0
while (ccollect[inc])
{
if (ccollect[inc].id!=omit)
ccollect[inc].style.display="none"
inc++
}
}
 
function expandcontent(curobj, cid)
{
var spantags=curobj.getElementsByTagName("SPAN")
var showstateobj=getElementbyClass(spantags, "showstate")
if (ccollect.length>0)
{
if (collapseprevious=="yes")
contractcontent(cid)
document.getElementById(cid).style.display=(document.getElementById(cid).style.display!="block")? "block" : "none"
if (showstateobj.length>0) //if "showstate" span exists in header
{
if (collapseprevious=="no")
showstateobj[0].innerHTML=(document.getElementById(cid).style.display=="block")? contractsymbol : expandsymbol
else
revivestatus()
}
}
}
 
function revivecontent()
{
contractcontent("omitnothing")
selectedItem=getselectedItem()
selectedComponents=selectedItem.split("|")
collapseprevious=selectedComponents[0]
for (i=1; i<selectedComponents.length-1; i++)
document.getElementById(selectedComponents[i]).style.display="block"
}
 
function revivestatus()
{
var inc=0
while (statecollect[inc])
{
if (ccollect[inc].style.display=="block")
statecollect[inc].innerHTML=contractsymbol
else
statecollect[inc].innerHTML=expandsymbol
inc++
}
}
 
function get_cookie(Name)
{
var search = Name + "="
var returnvalue = "";
if (document.cookie.length > 0)
{
offset = document.cookie.indexOf(search)
if (offset != -1)
{
offset += search.length
end = document.cookie.indexOf(";", offset);
if (end == -1) end = document.cookie.length;
returnvalue=unescape(document.cookie.substring(offset, end))
}
}
return returnvalue;
}
 
function getselectedItem()
{
if (get_cookie(window.location.pathname) != "")
{
selectedItem=get_cookie(window.location.pathname)
return selectedItem
}
else
return ""
}
 
function saveswitchstate()
{
var inc=0, selectedItem=collapseprevious+"|"
while (ccollect[inc])
{
if (ccollect[inc].style.display=="block")
selectedItem+=ccollect[inc].id+"|"
inc++
}
document.cookie=window.location.pathname+"="+selectedItem
}
 
function do_onload()
{
uniqueidn=window.location.pathname+"firsttimeload"
var alltags=document.all? document.all : document.getElementsByTagName("*")
ccollect=getElementbyClass(alltags, "switchcontent")
statecollect=getElementbyClass(alltags, "showstate")
if (enablepersist=="on" && ccollect.length>0)
{
document.cookie=(get_cookie(uniqueidn)=="")? uniqueidn+"=1" : uniqueidn+"=0"
firsttimeload=(get_cookie(uniqueidn)==1)? 1 : 0 //check if this is 1st page load
if (!firsttimeload)
revivecontent()
}
if (ccollect.length>0 && statecollect.length>0)
revivestatus()
if (expandonload)
sweeptoggle('expand')
}
 
if (window.addEventListener)
window.addEventListener("load", do_onload, false)
else if (window.attachEvent)
window.attachEvent("onload", do_onload)
else if (document.getElementById)
window.onload=do_onload
 
if (enablepersist=="on" && document.getElementById)
window.onunload=saveswitchstate
/WebSVN/templates/BlueGrey/blame.tmpl
3,30 → 3,30
<td align="left"><h1>[websvn:repname]</h1></td>
<td align="right"><b>[lang:PROJECTS]:</b> [websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</td>
</tr>
</table>
</table>
 
[websvn:curdirlinks] - <h2> [lang:BLAMEFOR] [websvn:rev]</h2>
<p>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
<table cellpadding="2px" cellspacing="0" width="100%">
<tr>
<th class="HdrClmn"><b>[lang:LINENO]</b></th>
<th class="HdrClmn"><b>[lang:REV]</b></th>
<th class="HdrClmn"><b>[lang:AUTHOR]</b></th>
<th class="HdrClmnEnd"><b>[lang:LINE]</b></th>
</tr>
[websvn-startlisting]
<tr>
<td class="CatClmn0" style="border-right: 1px solid black" valign="top">[websvn:lineno]</td>
<td class="CatClmn0" style="border-right: 1px solid black" valign="top">[websvn:revision]</td>
<td class="CatClmn0" style="border-right: 1px solid black" valign="top">[websvn:author]</td>
<td style="border-right: 1px solid black" valign="top">[websvn:line]</td>
</tr>
[websvn-endlisting]
</table>
[websvn-endtest]
[websvn:curdirlinks] - <h2> [lang:BLAMEFOR] [websvn:rev]</h2>
<p>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
<table cellpadding="2px" cellspacing="0" width="100%">
<tr>
<th class="HdrClmn"><b>[lang:LINENO]</b></th>
<th class="HdrClmn"><b>[lang:REV]</b></th>
<th class="HdrClmn"><b>[lang:AUTHOR]</b></th>
<th class="HdrClmnEnd"><b>[lang:LINE]</b></th>
</tr>
[websvn-startlisting]
<tr>
<td class="CatClmn0" style="border-right: 1px solid black" valign="top">[websvn:lineno]</td>
<td class="CatClmn0" style="border-right: 1px solid black" valign="top">[websvn:revision]</td>
<td class="CatClmn0" style="border-right: 1px solid black" valign="top">[websvn:author]</td>
<td style="border-right: 1px solid black" valign="top">[websvn:line]</td>
</tr>
[websvn-endlisting]
</table>
[websvn-endtest]
/WebSVN/templates/BlueGrey/compare.tmpl
3,63 → 3,63
<td align="left"><h1>[websvn:repname]</h1></td>
<td align="right"><b>[lang:PROJECTS]:</b> [websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</td>
</tr>
</table>
</table>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
[websvn:compare_form]
<table>
<tr><td>[lang:COMPPATH]&nbsp</td><td>[websvn:compare_path1input] [lang:REV] [websvn:compare_rev1input]</td></tr>
<tr><td>[lang:WITHPATH]</td><td>[websvn:compare_path2input] [lang:REV] [websvn:compare_rev2input]</td></tr>
</table>
[websvn:compare_submit]
[websvn:compare_endform]
[websvn-test:success]
<hr>
<p>[lang:CONVFROM] <b>[websvn:path1] ([lang:REV] [websvn:rev1])</b> [lang:TO] <b>[websvn:path2] ([lang:REV] [websvn:rev2])</b>
<p>
[websvn:revlink]
<p>
[websvn-endtest]
[websvn-startlisting]
[websvn-test:newpath]
<p>
<div class="newpath">
<b>[websvn:newpath]</b><br>
[websvn-endtest]
[websvn-test:info]
[websvn:info]<br>
[websvn-endtest]
[websvn-test:difflines]
<div class="difflines">
<p>
[websvn:difflines]<br>
<table class="diff" cellspacing="0">
[websvn-endtest]
[websvn-test:diffclass]
<tr><td class="[websvn:diffclass]">[websvn:line]</td></tr>
[websvn-endtest]
[websvn-test:enddifflines]
</table>
</div>
[websvn-endtest]
[websvn-test:endpath]
</div>
<p><hr>
[websvn-endtest]
[websvn-test:properties]
<p><i>[lang:PROPCHANGES]</i><p>
[websvn-endtest]
[websvn-endlisting]
</table>
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
[websvn:compare_form]
<table>
<tr><td>[lang:COMPPATH]&nbsp</td><td>[websvn:compare_path1input] [lang:REV] [websvn:compare_rev1input]</td></tr>
<tr><td>[lang:WITHPATH]</td><td>[websvn:compare_path2input] [lang:REV] [websvn:compare_rev2input]</td></tr>
</table>
[websvn:compare_submit]
[websvn:compare_endform]
[websvn-test:success]
<hr>
<p>[lang:CONVFROM] <b>[websvn:path1] ([lang:REV] [websvn:rev1])</b> [lang:TO] <b>[websvn:path2] ([lang:REV] [websvn:rev2])</b>
<p>
[websvn:revlink]
<p>
[websvn-endtest]
[websvn-startlisting]
[websvn-test:newpath]
<p>
<div class="newpath">
<b>[websvn:newpath]</b><br>
[websvn-endtest]
[websvn-test:info]
[websvn:info]<br>
[websvn-endtest]
[websvn-test:difflines]
<div class="difflines">
<p>
[websvn:difflines]<br>
<table class="diff" cellspacing="0">
[websvn-endtest]
[websvn-test:diffclass]
<tr><td class="[websvn:diffclass]">[websvn:line]</td></tr>
[websvn-endtest]
[websvn-test:enddifflines]
</table>
</div>
[websvn-endtest]
[websvn-test:endpath]
</div>
<p><hr>
[websvn-endtest]
[websvn-test:properties]
<p><i>[lang:PROPCHANGES]</i><p>
[websvn-endtest]
[websvn-endlisting]
</table>
[websvn-endtest]
/WebSVN/templates/BlueGrey/diff.tmpl
1,46 → 1,46
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
[websvn-test:noprev]
[lang:NOPREVREV]
[websvn-else]
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
[websvn-test:noprev]
No Previous Revision
[websvn-else]
<table cellspacing="0" cellpadding="0" border="0" width="100%">
<tr>
<td align="left"><h1>[websvn:repname]</h1></td>
<td align="right"><b>[lang:PROJECTS]:</b> [websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</td>
</tr>
</table>
[websvn:curdirlinks] - [lang:DIFFREVS] <b>[websvn:rev2]</b> [lang:AND] <b>[websvn:rev1]</b>
<p>
<p><center>
[websvn:showcompactlink]
[websvn:showalllink]
</center>
<p>
<table class="diff" width="100%" cellspacing="0">
<tr>
<th class="HdrClmnEnd" style="padding-bottom: 5px" width="50%" align="left"><b>[lang:REV] [websvn:rev2]</b></th>
<th width="5"></th>
<th class="HdrClmnEnd" style="padding-bottom: 5px" width="50%" align="left"><b>[lang:REV] [websvn:rev1]</b></th>
</tr>
[websvn-startlisting]
[websvn-test:rev1lineno]
<tr>
<td width="50%" style="padding: 3px 0 3px 0" align="center" class="row1"><b>[lang:LINE] [websvn:rev1lineno]...</b></td>
<td width="5"></td>
<td width="50%" style="padding: 3px 0 3px 0" align="center" class="row1"><b>[lang:LINE] [websvn:rev2lineno]...</b></td>
<tr>
[websvn-else]
<tr><td class="[websvn:rev1diffclass]">[websvn:rev1line]</td>
<td width="5"></td>
<td class="[websvn:rev2diffclass]">[websvn:rev2line]</td></tr>
[websvn-endtest]
[websvn-endlisting]
</table>
[websvn-endtest]
[websvn-endtest]
 
</table>
[websvn:curdirlinks] - [lang:DIFFREVS] <b>[websvn:rev2]</b> [lang:AND] <b>[websvn:rev1]</b>
<p>
<p><center>
[websvn:showcompactlink]
[websvn:showalllink]
</center>
<p>
<table class="diff" width="100%" cellspacing="0">
<tr>
<th class="HdrClmnEnd" style="padding-bottom: 5px" width="50%" align="left"><b>[lang:REV] [websvn:rev2]</b></th>
<th width="5"></th>
<th class="HdrClmnEnd" style="padding-bottom: 5px" width="50%" align="left"><b>[lang:REV] [websvn:rev1]</b></th>
</tr>
[websvn-startlisting]
[websvn-test:rev1lineno]
<tr>
<td width="50%" style="padding: 3px 0 3px 0" align="center" class="row1"><b>[lang:LINE] [websvn:rev1lineno]...</b></td>
<td width="5"></td>
<td width="50%" style="padding: 3px 0 3px 0" align="center" class="row1"><b>[lang:LINE] [websvn:rev2lineno]...</b></td>
<tr>
[websvn-else]
<tr><td class="[websvn:rev1diffclass]">[websvn:rev1line]</td>
<td width="5"></td>
<td class="[websvn:rev2diffclass]">[websvn:rev2line]</td></tr>
[websvn-endtest]
[websvn-endlisting]
</table>
[websvn-endtest]
[websvn-endtest]
 
/WebSVN/templates/BlueGrey/directory.tmpl
3,140 → 3,140
<td align="left"><h1>[websvn:repname]</h1></td>
<td align="right"><b>[lang:PROJECTS]:</b> [websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</td>
</tr>
</table>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
<table cellpadding="2px" cellspacing="0px" class="outline">
<tr><th colspan=2 class="HdrClmnEnd">[lang:REVINFO]</th></tr>
<tr><td class="CatClmn1" valign="top">[lang:CURDIR]:</td><td class="row1">[websvn:path]</td></tr>
<tr><td class="CatClmn0">[lang:REV] &amp; [lang:AUTHOR]:</td><td class="row0">[lang:REV] [websvn:rev] - [websvn:author]
[websvn-test:goyoungestlink]
- [websvn:goyoungestlink]
[websvn-endtest]
</td></tr>
[websvn-test:restricted]
[websvn-else]
<tr><td class="CatClmn1" valign="top">[lang:LASTMOD]:</td><td class="row1">[lang:REV] [websvn:lastchangedrev] - [websvn:date]</td></tr>
<tr><td class="CatClmn0" valign="top">[lang:LOGMSG]:</td><td class="row0">[websvn:log]</td></tr>
[websvn-test:hidechanges]
<tr><td class="CatClmn1" valign="top">&nbsp;</td><td class="row1">([websvn:showchangeslink])</td></tr>
[websvn-else]
[websvn:showchangeslink]
<tr><td class="CatClmn1" valign="top">&nbsp;</td><td class="row1">([websvn:hidechangeslink])</td></tr>
[websvn-test:changedfilesbr]
<tr><td class="CatClmn0" valign="top">[lang:CHANGEDFILES]:</td><td class="row0">[websvn:changedfilesbr]</td></tr>
[websvn-endtest]
[websvn-test:newfilesbr]
[websvn-test:changedfilesbr]
<tr><td class="CatClmn1" valign="top">[lang:NEWFILES]:</td><td class="row1">[websvn:newfilesbr]</td></tr>
[websvn-else]
<tr><td class="CatClmn0" valign="top">[lang:NEWFILES]:</td><td class="row0">[websvn:newfilesbr]</td></tr>
[websvn-endtest]
[websvn-endtest]
[websvn-test:deletedfilesbr]
[websvn-test:changedfilesbr]
[websvn-test:newfilesbr]
<tr><td class="CatClmn0" valign="top">[lang:DELETEDFILES]:</td><td class="row0">[websvn:deletedfilesbr]</td></tr>
[websvn-else]
<tr><td class="CatClmn1" valign="top">[lang:DELETEDFILES]:</td><td class="row1">[websvn:deletedfilesbr]</td></tr>
[websvn-endtest]
[websvn-else]
[websvn-test:newfilesbr]
<tr><td class="CatClmn1" valign="top">[lang:DELETEDFILES]:</td><td class="row1">[websvn:deletedfilesbr]</td></tr>
[websvn-else]
<tr><td class="CatClmn0" valign="top">[lang:DELETEDFILES]:</td><td class="row0">[websvn:deletedfilesbr]</td></tr>
[websvn-endtest]
[websvn-endtest]
[websvn-endtest]
[websvn-endtest]
[websvn-endtest]
</table>
[websvn-defineicons]
dir=<img align="middle" valign="center" src="[websvn:locwebsvnhttp]/templates/BlueGrey/folder.png" alt="[FOLDER]">
diropen=<img align="middle" valign="center" src="[websvn:locwebsvnhttp]/templates/BlueGrey/folder.png" alt="[OPEN-FOLDER]">
*=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/file.png" alt="[FILE]">
.c=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/filec.png" alt="[C-FILE]">
.cpp=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/filecpp.png" alt="[CPP-FILE]">
.h=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/fileh.png" alt="[H-FILE]">
.html=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/filehtml.png" alt="[HTML-FILE]">
.java=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/filejava.png" alt="[JAVA-FILE]">
.m=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/filem.png" alt="[M-FILE]">
.py=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/filepy.png" alt="[PY-FILE]">
.s=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/files.png" alt="[S-FILE]">
i-node=<img align="middle" border="0" width="24" height="22" src="[websvn:locwebsvnhttp]/templates/BlueGrey/i-node.png" alt="[NODE]">
t-node=<img align="middle" border="0" width="24" height="22" src="[websvn:locwebsvnhttp]/templates/BlueGrey/t-node.png" alt="[NODE]">
l-node=<img align="middle" border="0" width="24" height="22" src="[websvn:locwebsvnhttp]/templates/BlueGrey/l-node.png" alt="[NODE]">
e-node=<img align="middle" border="0" width="24" height="22" src="[websvn:locwebsvnhttp]/templates/BlueGrey/e-node.png" alt="[NODE]">
[websvn-enddefineicons]
<p><hr>
[websvn:curdirlinks] - [websvn:curdirloglink]
[websvn-test:curdircomplink]
- [websvn:curdircomplink]
[websvn-endtest]
[websvn-test:curdirdllink]
- [websvn:curdirdllink]
[websvn-endtest]
[websvn-test:curdirrsslink]
- [websvn:curdirrssanchor]<img style="border: 0;" src="[websvn:locwebsvnhttp]/templates/BlueGrey/xml.gif" width="36" height="14" alt="[lang:RSSFEED]"></a>
[websvn-endtest]
<p>
[websvn:compare_form]
<table cellpadding="2px" cellspacing="0px" width="100%" class="outline">
<tr>
<th class="HdrClmn" width="100%"><b>[lang:PATH]</b></th>
[websvn-test:allowdownload]
[websvn-test:curdirrsslink]
<th class="HdrClmn"><b>[lang:NOBR][lang:LOG][lang:ENDNOBR]</b></th>
<th class="HdrClmn"><b>[lang:TARBALL]</b></th>
<th class="HdrClmnEnd"><b>RSS</b></th>
[websvn-else]
<th class="HdrClmn"><b>[lang:NOBR][lang:LOG][lang:ENDNOBR]</b></th>
<th class="HdrClmnEnd"><b>[lang:TARBALL]</b></th>
[websvn-endtest]
[websvn-else]
[websvn-test:curdirrsslink]
<th class="HdrClmn"><b>[lang:LOG]</b></th>
<th class="HdrClmnEnd"><b>RSS</b></th>
[websvn-else]
<th class="HdrClmnEnd"><b>[lang:NOBR][lang:LOG][lang:ENDNOBR]</b></th>
[websvn-endtest]
[websvn-endtest]
</tr>
[websvn-startlisting]
<tr>
<td valign="middle" style="border-right: 1px solid black; padding: 0 2px 0 2px;" class="row[websvn:rowparity]">
[websvn:compare_box]
[websvn-treenode]
[websvn-icon]
[websvn:filelink]
</td>
[websvn-test:allowdownload]
[websvn-test:curdirrsslink]
<td style="border-right: 1px solid black; padding: 0 2px 0 2px;" class="row[websvn:rowparity]">[lang:NOBR][websvn:fileviewloglink][lang:ENDNOBR]</td>
<td style="border-right: 1px solid black; padding: 0 2px 0 2px;" class="row[websvn:rowparity]">[websvn:fileviewdllink]</td>
<td style="padding: 0 2px 0 2px;" class="row[websvn:rowparity]">[websvn:rssanchor]<img style="border: 0;" src="[websvn:locwebsvnhttp]/templates/BlueGrey/xml.gif" width="36" height="14" alt="[lang:RSSFEED]"></a></td>
[websvn-else]
<td style="border-right: 1px solid black; padding: 0 2px 0 2px;" class="row[websvn:rowparity]">[lang:NOBR][websvn:fileviewloglink][lang:ENDNOBR]</td>
<td style="padding: 0 2px 0 2px;" class="row[websvn:rowparity]">[websvn:fileviewdllink]</td>
[websvn-endtest]
[websvn-else]
[websvn-test:curdirrsslink]
<td style="border-right: 1px solid black; padding: 0 2px 0 2px;" class="row[websvn:rowparity]">[lang:NOBR][websvn:fileviewloglink][lang:ENDNOBR]</td>
<td style="padding: 0 2px 0 2px;" class="row[websvn:rowparity]">[websvn:rssanchor]<img style="border: 0;" src="[websvn:locwebsvnhttp]/templates/BlueGrey/xml.gif" width="36" height="14" alt="[lang:RSSFEED]"></a></td>
[websvn-else]
<td style="padding: 0 2px 0 2px;" class="row[websvn:rowparity]">[lang:NOBR][websvn:fileviewloglink][lang:ENDNOBR]</td>
[websvn-endtest]
[websvn-endtest]
</tr>
[websvn-endlisting]
</table>
<p>
[websvn:compare_submit]
[websvn:compare_endform]
<hr>
[websvn-endtest]
</table>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
<table cellpadding="2px" cellspacing="0px" class="outline">
<tr><th colspan=2 class="HdrClmnEnd">[lang:REVINFO]</th></tr>
<tr><td class="CatClmn1" valign="top">[lang:CURDIR]:</td><td class="row1">[websvn:path]</td></tr>
<tr><td class="CatClmn0">[lang:REV] &amp; [lang:AUTHOR]:</td><td class="row0">[lang:REV] [websvn:rev] - [websvn:author]
[websvn-test:goyoungestlink]
- [websvn:goyoungestlink]
[websvn-endtest]
</td></tr>
[websvn-test:restricted]
[websvn-else]
<tr><td class="CatClmn1" valign="top">[lang:LASTMOD]:</td><td class="row1">[lang:REV] [websvn:lastchangedrev] - [websvn:date]</td></tr>
<tr><td class="CatClmn0" valign="top">[lang:LOGMSG]:</td><td class="row0">[websvn:log]</td></tr>
[websvn-test:hidechanges]
<tr><td class="CatClmn1" valign="top">&nbsp;</td><td class="row1">([websvn:showchangeslink])</td></tr>
[websvn-else]
[websvn:showchangeslink]
<tr><td class="CatClmn1" valign="top">&nbsp;</td><td class="row1">([websvn:hidechangeslink])</td></tr>
[websvn-test:changedfilesbr]
<tr><td class="CatClmn0" valign="top">[lang:CHANGEDFILES]:</td><td class="row0">[websvn:changedfilesbr]</td></tr>
[websvn-endtest]
[websvn-test:newfilesbr]
[websvn-test:changedfilesbr]
<tr><td class="CatClmn1" valign="top">[lang:NEWFILES]:</td><td class="row1">[websvn:newfilesbr]</td></tr>
[websvn-else]
<tr><td class="CatClmn0" valign="top">[lang:NEWFILES]:</td><td class="row0">[websvn:newfilesbr]</td></tr>
[websvn-endtest]
[websvn-endtest]
[websvn-test:deletedfilesbr]
[websvn-test:changedfilesbr]
[websvn-test:newfilesbr]
<tr><td class="CatClmn0" valign="top">[lang:DELETEDFILES]:</td><td class="row0">[websvn:deletedfilesbr]</td></tr>
[websvn-else]
<tr><td class="CatClmn1" valign="top">[lang:DELETEDFILES]:</td><td class="row1">[websvn:deletedfilesbr]</td></tr>
[websvn-endtest]
[websvn-else]
[websvn-test:newfilesbr]
<tr><td class="CatClmn1" valign="top">[lang:DELETEDFILES]:</td><td class="row1">[websvn:deletedfilesbr]</td></tr>
[websvn-else]
<tr><td class="CatClmn0" valign="top">[lang:DELETEDFILES]:</td><td class="row0">[websvn:deletedfilesbr]</td></tr>
[websvn-endtest]
[websvn-endtest]
[websvn-endtest]
[websvn-endtest]
[websvn-endtest]
</table>
[websvn-defineicons]
dir=<img align="middle" valign="center" src="[websvn:locwebsvnhttp]/templates/BlueGrey/folder.png" alt="[FOLDER]">
diropen=<img align="middle" valign="center" src="[websvn:locwebsvnhttp]/templates/BlueGrey/folder.png" alt="[OPEN-FOLDER]">
*=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/file.png" alt="[FILE]">
.c=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/filec.png" alt="[C-FILE]">
.cpp=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/filecpp.png" alt="[CPP-FILE]">
.h=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/fileh.png" alt="[H-FILE]">
.html=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/filehtml.png" alt="[HTML-FILE]">
.java=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/filejava.png" alt="[JAVA-FILE]">
.m=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/filem.png" alt="[M-FILE]">
.py=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/filepy.png" alt="[PY-FILE]">
.s=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/files.png" alt="[S-FILE]">
i-node=<img align="middle" border="0" width="24" height="22" src="[websvn:locwebsvnhttp]/templates/BlueGrey/i-node.png" alt="[NODE]">
t-node=<img align="middle" border="0" width="24" height="22" src="[websvn:locwebsvnhttp]/templates/BlueGrey/t-node.png" alt="[NODE]">
l-node=<img align="middle" border="0" width="24" height="22" src="[websvn:locwebsvnhttp]/templates/BlueGrey/l-node.png" alt="[NODE]">
e-node=<img align="middle" border="0" width="24" height="22" src="[websvn:locwebsvnhttp]/templates/BlueGrey/e-node.png" alt="[NODE]">
[websvn-enddefineicons]
<p><hr>
[websvn:curdirlinks] - [websvn:curdirloglink]
[websvn-test:curdircomplink]
- [websvn:curdircomplink]
[websvn-endtest]
[websvn-test:curdirdllink]
- [websvn:curdirdllink]
[websvn-endtest]
[websvn-test:curdirrsslink]
- [websvn:curdirrssanchor]<img style="border: 0;" src="[websvn:locwebsvnhttp]/templates/BlueGrey/xml.gif" width="36" height="14" alt="[lang:RSSFEED]"></a>
[websvn-endtest]
<p>
[websvn:compare_form]
<table cellpadding="2px" cellspacing="0px" width="100%" class="outline">
<tr>
<th class="HdrClmn" width="100%"><b>[lang:PATH]</b></th>
[websvn-test:allowdownload]
[websvn-test:curdirrsslink]
<th class="HdrClmn"><b>[lang:NOBR][lang:LOG][lang:ENDNOBR]</b></th>
<th class="HdrClmn"><b>[lang:TARBALL]</b></th>
<th class="HdrClmnEnd"><b>RSS</b></th>
[websvn-else]
<th class="HdrClmn"><b>[lang:NOBR][lang:LOG][lang:ENDNOBR]</b></th>
<th class="HdrClmnEnd"><b>[lang:TARBALL]</b></th>
[websvn-endtest]
[websvn-else]
[websvn-test:curdirrsslink]
<th class="HdrClmn"><b>[lang:LOG]</b></th>
<th class="HdrClmnEnd"><b>RSS</b></th>
[websvn-else]
<th class="HdrClmnEnd"><b>[lang:NOBR][lang:LOG][lang:ENDNOBR]</b></th>
[websvn-endtest]
[websvn-endtest]
</tr>
[websvn-startlisting]
<tr>
<td valign="middle" style="border-right: 1px solid black; padding: 0 2px 0 2px;" class="row[websvn:rowparity]">
[websvn:compare_box]
[websvn-treenode]
[websvn-icon]
[websvn:filelink]
</td>
[websvn-test:allowdownload]
[websvn-test:curdirrsslink]
<td style="border-right: 1px solid black; padding: 0 2px 0 2px;" class="row[websvn:rowparity]">[lang:NOBR][websvn:fileviewloglink][lang:ENDNOBR]</td>
<td style="border-right: 1px solid black; padding: 0 2px 0 2px;" class="row[websvn:rowparity]">[websvn:fileviewdllink]</td>
<td style="padding: 0 2px 0 2px;" class="row[websvn:rowparity]">[websvn:rssanchor]<img style="border: 0;" src="[websvn:locwebsvnhttp]/templates/BlueGrey/xml.gif" width="36" height="14" alt="[lang:RSSFEED]"></a></td>
[websvn-else]
<td style="border-right: 1px solid black; padding: 0 2px 0 2px;" class="row[websvn:rowparity]">[lang:NOBR][websvn:fileviewloglink][lang:ENDNOBR]</td>
<td style="padding: 0 2px 0 2px;" class="row[websvn:rowparity]">[websvn:fileviewdllink]</td>
[websvn-endtest]
[websvn-else]
[websvn-test:curdirrsslink]
<td style="border-right: 1px solid black; padding: 0 2px 0 2px;" class="row[websvn:rowparity]">[lang:NOBR][websvn:fileviewloglink][lang:ENDNOBR]</td>
<td style="padding: 0 2px 0 2px;" class="row[websvn:rowparity]">[websvn:rssanchor]<img style="border: 0;" src="[websvn:locwebsvnhttp]/templates/BlueGrey/xml.gif" width="36" height="14" alt="[lang:RSSFEED]"></a></td>
[websvn-else]
<td style="padding: 0 2px 0 2px;" class="row[websvn:rowparity]">[lang:NOBR][websvn:fileviewloglink][lang:ENDNOBR]</td>
[websvn-endtest]
[websvn-endtest]
</tr>
[websvn-endlisting]
</table>
<p>
[websvn:compare_submit]
[websvn:compare_endform]
<hr>
[websvn-endtest]
/WebSVN/templates/BlueGrey/file.tmpl
3,17 → 3,17
<td align="left"><h1>[websvn:repname]</h1></td>
<td align="right"><b>[lang:PROJECTS]:</b> [websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</td>
</tr>
</table>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
[websvn:curdirlinks] - [lang:REV] [websvn:rev]
[websvn-test:goyoungestlink]
[websvn:goyoungestlink]<p>
[websvn-endtest]
<p>[websvn:prevdifflink] - [websvn:blamelink]</p>
</table>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
[websvn:curdirlinks] - [lang:REV] [websvn:rev]
[websvn-test:goyoungestlink]
[websvn:goyoungestlink]<p>
[websvn-endtest]
<p>[websvn:prevdifflink] - [websvn:blamelink]</p>
<hr />
[websvn-getlisting]
<hr />
[websvn-endtest]
<hr />
[websvn-endtest]
/WebSVN/templates/BlueGrey/header.tmpl
1,73 → 1,73
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=[websvn:charset]">
<link href="[websvn:locwebsvnhttp]/templates/BlueGrey/styles.css" rel="stylesheet" media="screen">
<!--[if lt IE 7]>
<script type="text/javascript" src="[websvn:locwebsvnhttp]/templates/BlueGrey/png.js"></script>
<![endif]-->
<script type="text/javascript" src="[websvn:locwebsvnhttp]/templates/BlueGrey/collapse.js"></script>
<title>
WebSVN
[websvn-test:repname]
- [websvn:repname]
[websvn-endtest]
[websvn-test:action]
- [websvn:action]
[websvn-endtest]
[websvn-test:rev2]
[websvn-test:path2]
- [websvn:safepath1] [lang:REV] [websvn:rev1] [lang:AND] [websvn:safepath2] [lang:REV] [websvn:rev2]
[websvn-else]
- [lang:REV] [websvn:rev1] [lang:AND] [websvn:rev2]
[websvn-endtest]
[websvn-else]
[websvn-test:rev]
- [lang:REV] [websvn:rev]
[websvn-endtest]
[websvn-endtest]
[websvn-test:path]
- [websvn:safepath]
[websvn-endtest]
</title>
 
<script type="text/javascript">
function checkCB(chBox)
{
count = 0
first = null
f = chBox.form
for (i = 0 ; i < f.elements.length ; i++)
if (f.elements[i].type == 'checkbox' && f.elements[i].checked)
{
if (first == null && f.elements[i] != chBox)
first = f.elements[i]
count += 1
}
if (count > 2)
{
first.checked = false
count -= 1
}
}
[websvn-test:opentree]
expandonload = true
[websvn-endtest]
</script>
 
[websvn-test:curdirrsslink]
<link rel="alternate" type="application/rss+xml" title="WebSVN RSS" href="[websvn:curdirrsshref]">
[websvn-endtest]
 
</head>
<body>
<table width="100%" border="0">
<tr>
<td width="33%">&nbsp;</td>
<td width="33%" align="center"><a href="http://subversion.tigris.org/"><img style="border: 0; width: 468px; height: 64px;" src="[websvn:locwebsvnhttp]/templates/BlueGrey/subversion.png" alt="Subversion" /></a></td>
<td width="33%"><div style="float: right">[websvn:lang_form][websvn:lang_select][websvn:lang_submit][websvn:lang_endform]</div></td>
</tr>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=[websvn:charset]">
<link href="[websvn:locwebsvnhttp]/templates/BlueGrey/styles.css" rel="stylesheet" media="screen">
<!--[if lt IE 7]>
<script type="text/javascript" src="[websvn:locwebsvnhttp]/templates/BlueGrey/png.js"></script>
<![endif]-->
<script type="text/javascript" src="[websvn:locwebsvnhttp]/templates/BlueGrey/collapse.js"></script>
<title>
WebSVN
[websvn-test:repname]
- [websvn:repname]
[websvn-endtest]
[websvn-test:action]
- [websvn:action]
[websvn-endtest]
[websvn-test:rev2]
[websvn-test:path2]
- [websvn:safepath1] [lang:REV] [websvn:rev1] [lang:AND] [websvn:safepath2] [lang:REV] [websvn:rev2]
[websvn-else]
- [lang:REV] [websvn:rev1] [lang:AND] [websvn:rev2]
[websvn-endtest]
[websvn-else]
[websvn-test:rev]
- [lang:REV] [websvn:rev]
[websvn-endtest]
[websvn-endtest]
[websvn-test:path]
- [websvn:safepath]
[websvn-endtest]
</title>
 
<script type="text/javascript">
function checkCB(chBox)
{
count = 0
first = null
f = chBox.form
for (i = 0 ; i < f.elements.length ; i++)
if (f.elements[i].type == 'checkbox' && f.elements[i].checked)
{
if (first == null && f.elements[i] != chBox)
first = f.elements[i]
count += 1
}
if (count > 2)
{
first.checked = false
count -= 1
}
}
[websvn-test:opentree]
expandonload = true
[websvn-endtest]
</script>
 
[websvn-test:curdirrsslink]
<link rel="alternate" type="application/rss+xml" title="WebSVN RSS" href="[websvn:curdirrsshref]">
[websvn-endtest]
 
</head>
<body>
<table width="100%" border="0">
<tr>
<td width="33%">&nbsp;</td>
<td width="33%" align="center"><a href="http://subversion.tigris.org/"><img style="border: 0; width: 468px; height: 64px;" src="[websvn:locwebsvnhttp]/templates/BlueGrey/subversion.png" alt="Subversion" /></a></td>
<td width="33%"><div style="float: right">[websvn:lang_form][websvn:lang_select][websvn:lang_submit][websvn:lang_endform]</div></td>
</tr>
</table>
<hr />
<hr />
/WebSVN/templates/BlueGrey/index.tmpl
1,26 → 1,26
<p>
[websvn-test:flatview]
<table align="center" cellspacing="0" cellpadding="0" width="50%">
<tr><th align="center" colspan=2 class="HdrClmnEnd">[lang:PROJECTS]</th></tr>
[websvn-startlisting]
<p>
[websvn-test:flatview]
<table align="center" cellspacing="0" cellpadding="0" width="50%">
<tr><th align="center" colspan=2 class="HdrClmnEnd">[lang:PROJECTS]</th></tr>
[websvn-startlisting]
<tr><td class="row[websvn:rowparity]"><img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/repo.png" alt="[FOLDER]"> [websvn:projlink]</td>
</tr>
[websvn-endlisting]
</table>
[websvn-else]
<table align="center" cellspacing=0 cellpadding=0 width="50%">
<tr><th align="left" colspan=2 class="HdrClmnEnd">[lang:PROJECTS]</th></tr>
<td>
[websvn-startlisting]
[websvn-test:isprojlink]
<div class="row[websvn:rowparity]"><img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/repo.png" alt="[FOLDER]"> [websvn:listitem]</div>
[websvn-else]
[websvn:listitem]
[websvn-endtest]
[websvn-endlisting]
</td>
</tr>
</table>
[websvn-endtest]
</tr>
[websvn-endlisting]
</table>
[websvn-else]
<table align="center" cellspacing=0 cellpadding=0 width="50%">
<tr><th align="left" colspan=2 class="HdrClmnEnd">[lang:PROJECTS]</th></tr>
<td>
[websvn-startlisting]
[websvn-test:isprojlink]
<div class="row[websvn:rowparity]"><img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/repo.png" alt="[FOLDER]"> [websvn:listitem]</div>
[websvn-else]
[websvn:listitem]
[websvn-endtest]
[websvn-endlisting]
</td>
</tr>
</table>
[websvn-endtest]
<hr />
/WebSVN/templates/BlueGrey/log.tmpl
3,68 → 3,68
<td align="left"><h1>[websvn:repname] - [lang:REV] [websvn:rev]</h1></td>
<td align="right"><b>[lang:PROJECTS]:</b> [websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</td>
</tr>
</table>
 
[websvn:curdirlinks]<p>
[websvn-test:goyoungestlink]
[websvn:goyoungestlink]<p>
[websvn-endtest]
<hr>
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
<center>
[websvn:logsearch_form]
<b>[lang:FILTER]</b><p>
[lang:STARTLOG]:[websvn:logsearch_startbox] [lang:ENDLOG]:[websvn:logsearch_endbox] [lang:MAXLOG]:[websvn:logsearch_maxbox] [lang:SEARCHLOG]:[websvn:logsearch_inputbox]
[websvn:logsearch_submit]
[websvn-test:logsearch_clearloglink]
<p><font size="-1">[websvn:logsearch_clearloglink]</font><p>
[websvn-endtest]
[websvn:logsearch_endform]
</center>
[websvn-test:logsearch_nomatches]
<center>[lang:NORESULTS]</center>
[websvn-endtest]
[websvn-test:error]
<center>[websvn:error]</center>
[websvn-endtest]
 
[websvn-test:logsearch_resultsfound]
[websvn:compare_form]
<table cellpadding="2px" cellspacing="0" width="100%">
<tr>
<th class="HdrClmn">[lang:REV]</th>
<th class="HdrClmn">[lang:PATH]</th>
<th class="HdrClmn">[lang:AUTHOR]</th>
<th class="HdrClmn">[lang:AGE]</th>
<th class="HdrClmnEnd">[lang:LOGMSG]</th>
</tr>
[websvn-startlisting]
<tr>
<td style="border-right: 1px solid black" valign="top" class="row[websvn:rowparity]"><nobr>[websvn:compare_box][websvn:revlink]</nobr></td>
<td style="border-right: 1px solid black" valign="top" class="row[websvn:rowparity]">[websvn:revpathlink]</td>
<td style="border-right: 1px solid black" valign="top" class="row[websvn:rowparity]">[websvn:revauthor]</td>
<td style="border-right: 1px solid black" valign="top" class="row[websvn:rowparity]">[websvn:revage]</td>
<td valign="top" class="row[websvn:rowparity]">[websvn:revlog]</td>
</tr>
[websvn-endlisting]
</table>
<p>
[websvn:compare_submit]
[websvn:compare_endform]
[websvn-endtest]
[websvn-test:logsearch_nomorematches]
<p><center>[lang:NOMORERESULTS]</center>
[websvn-endtest]
<p><center>[websvn:logsearch_moreresultslink]</center>
<hr>
<p><center>[websvn:pagelinks]<p>[websvn:showalllink]</center>
[websvn-endtest]
</table>
 
[websvn:curdirlinks]<p>
[websvn-test:goyoungestlink]
[websvn:goyoungestlink]<p>
[websvn-endtest]
<hr>
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
<center>
[websvn:logsearch_form]
<b>[lang:FILTER]</b><p>
[lang:STARTLOG]:[websvn:logsearch_startbox] [lang:ENDLOG]:[websvn:logsearch_endbox] [lang:MAXLOG]:[websvn:logsearch_maxbox] [lang:SEARCHLOG]:[websvn:logsearch_inputbox]
[websvn:logsearch_submit]
[websvn-test:logsearch_clearloglink]
<p><font size="-1">[websvn:logsearch_clearloglink]</font><p>
[websvn-endtest]
[websvn:logsearch_endform]
</center>
[websvn-test:logsearch_nomatches]
<center>[lang:NORESULTS]</center>
[websvn-endtest]
[websvn-test:error]
<center>[websvn:error]</center>
[websvn-endtest]
 
[websvn-test:logsearch_resultsfound]
[websvn:compare_form]
<table cellpadding="2px" cellspacing="0" width="100%">
<tr>
<th class="HdrClmn">[lang:REV]</th>
<th class="HdrClmn">[lang:PATH]</th>
<th class="HdrClmn">[lang:AUTHOR]</th>
<th class="HdrClmn">[lang:AGE]</th>
<th class="HdrClmnEnd">[lang:LOGMSG]</th>
</tr>
[websvn-startlisting]
<tr>
<td style="border-right: 1px solid black" valign="top" class="row[websvn:rowparity]"><nobr>[websvn:compare_box][websvn:revlink]</nobr></td>
<td style="border-right: 1px solid black" valign="top" class="row[websvn:rowparity]">[websvn:revpathlink]</td>
<td style="border-right: 1px solid black" valign="top" class="row[websvn:rowparity]">[websvn:revauthor]</td>
<td style="border-right: 1px solid black" valign="top" class="row[websvn:rowparity]">[websvn:revage]</td>
<td valign="top" class="row[websvn:rowparity]">[websvn:revlog]</td>
</tr>
[websvn-endlisting]
</table>
<p>
[websvn:compare_submit]
[websvn:compare_endform]
[websvn-endtest]
[websvn-test:logsearch_nomorematches]
<p><center>[lang:NOMORERESULTS]</center>
[websvn-endtest]
<p><center>[websvn:logsearch_moreresultslink]</center>
<hr>
<p><center>[websvn:pagelinks]<p>[websvn:showalllink]</center>
[websvn-endtest]
/WebSVN/templates/BlueGrey/styles.css
1,8 → 1,8
body
{
body
{
font-family: verdana, sans-serif;
color: black;
background-color: white
color: black;
background-color: white
}
body *
{
17,12 → 17,12
font-size: 125%;
}
hr
{
border: 0px;
padding: 0px;
height: 1px;
background-color: #808080
}
{
border: 0px;
padding: 0px;
height: 1px;
background-color: #808080
}
a:link, a:visited
{
color: #004080;
35,16 → 35,16
.HdrClmn,
.HdrClmnEnd
{
border: black 1px solid;
font-weight: bold;
color: white;
border: black 1px solid;
font-weight: bold;
color: white;
background-color: #809cc8
}
}
table
{
border-width:0px;
border-collapse:collapse;
}
}
.row0,
.row1
{
56,28 → 56,28
padding: 0px;
margin: 0px;
vertical-align:middle;
}
.row0
{
background-color: #f0f0f0;
}
.row1
{
background-color: #e0e0e0;
}
 
}
.row0
{
background-color: #f0f0f0;
}
.row1
{
background-color: #e0e0e0;
}
 
.CatClmn0
{
border-right: black 1px solid;
background-color: #e0e0ff
}
{
border-right: black 1px solid;
background-color: #e0e0ff
}
 
.CatClmn1
{
border-right: black 1px solid;
background-color: #d0d0ee
}
 
{
border-right: black 1px solid;
background-color: #d0d0ee
}
 
table.outline
{
border-collapse:collapse;
84,47 → 84,47
border: 1px black solid;
}
 
td.diffdeleted
{
font-size: 11px;
background-color: #ff8888;
}
 
td.diffchanged
{
font-size: 11px;
background-color: #ffff88;
}
 
td.diffadded
{
font-size: 11px;
background-color: #88ff88;
}
 
td.diff
{
font-size: 11px;
background-color: #F0F0F0;
}
 
div.newpath
{
padding: 10px;
background-color: #d0d0ee
}
 
div.difflines
{
}
 
.plusbox { float: left; clear: both; position: relative; top: -3px; font-size: 13px; font-weight: bold; width: 16px; text-indent: 0; height: 16px; color: black; background-color: #D0D0D0; text-align: center; padding: 0px 2px 0px 3px; border: black solid 1px; margin-right: 5px; }
.minusbox { float: left; clear: both; position: relative; top: -3px; font-size: 13px; font-weight: bold; width: 16px; text-indent: 0; height: 16px; color: black; background-color: #809cc8; text-align: center; padding: 0px 2px 0px 3px; border: black solid 1px; margin-right: 5px; }
 
.groupname { padding-left: 0px; text-indent: -25px; margin: 3px 0 3px 0;}
.switchcontent { margin: 3px 0 0 20px; }
.project { padding: 2px; }
 
td.diffdeleted
{
font-size: 11px;
background-color: #ff8888;
}
 
td.diffchanged
{
font-size: 11px;
background-color: #ffff88;
}
 
td.diffadded
{
font-size: 11px;
background-color: #88ff88;
}
 
td.diff
{
font-size: 11px;
background-color: #F0F0F0;
}
 
div.newpath
{
padding: 10px;
background-color: #d0d0ee
}
 
div.difflines
{
}
 
.plusbox { float: left; clear: both; position: relative; top: -3px; font-size: 13px; font-weight: bold; width: 16px; text-indent: 0; height: 16px; color: black; background-color: #D0D0D0; text-align: center; padding: 0px 2px 0px 3px; border: black solid 1px; margin-right: 5px; }
.minusbox { float: left; clear: both; position: relative; top: -3px; font-size: 13px; font-weight: bold; width: 16px; text-indent: 0; height: 16px; color: black; background-color: #809cc8; text-align: center; padding: 0px 2px 0px 3px; border: black solid 1px; margin-right: 5px; }
 
.groupname { padding-left: 0px; text-indent: -25px; margin: 3px 0 3px 0;}
.switchcontent { margin: 3px 0 0 20px; }
.project { padding: 2px; }
 
code
{
white-space: pre-wrap;
/WebSVN/templates/BlueGrey/collapse.js
1,169 → 1,169
/***********************************************
* Switch Content script- © Dynamic Drive (www.dynamicdrive.com)
* This notice must stay intact for legal use. Last updated April 2nd, 2005.
* Visit http://www.dynamicdrive.com/ for full source code
***********************************************/
 
var enablepersist="on" // Enable saving state of content structure using session cookies? (on/off)
var collapseprevious="yes" // Collapse previously open content when opening present? (yes/no)
 
var contractsymbol='<div class="minusbox">-</div>' // HTML for contract symbol. For image, use: <img src="${prefix}whatever.gif">
var expandsymbol='<div class="plusbox">+</div>' // HTML for expand symbol.
var expandonload=false
 
if (document.getElementById)
{
document.write('<style type="text/css">')
document.write('.switchcontent{display:none;}')
document.write('</style>')
}
 
function getElementbyClass(rootobj, classname)
{
var temparray=new Array()
var inc=0
for (i=0; i<rootobj.length; i++)
{
if (rootobj[i].className==classname)
temparray[inc++]=rootobj[i]
}
return temparray
}
 
function sweeptoggle(ec)
{
var thestate=(ec=="expand")? "block" : "none"
var inc=0
while (ccollect[inc])
{
ccollect[inc].style.display=thestate
inc++
}
revivestatus()
collapseprevious = (ec=="expand")? "no" : "yes"
}
 
 
function contractcontent(omit)
{
var inc=0
while (ccollect[inc])
{
if (ccollect[inc].id!=omit)
ccollect[inc].style.display="none"
inc++
}
}
 
function expandcontent(curobj, cid)
{
var spantags=curobj.getElementsByTagName("SPAN")
var showstateobj=getElementbyClass(spantags, "showstate")
if (ccollect.length>0)
{
if (collapseprevious=="yes")
contractcontent(cid)
document.getElementById(cid).style.display=(document.getElementById(cid).style.display!="block")? "block" : "none"
if (showstateobj.length>0) //if "showstate" span exists in header
{
if (collapseprevious=="no")
showstateobj[0].innerHTML=(document.getElementById(cid).style.display=="block")? contractsymbol : expandsymbol
else
revivestatus()
}
}
}
 
function revivecontent()
{
contractcontent("omitnothing")
selectedItem=getselectedItem()
selectedComponents=selectedItem.split("|")
collapseprevious=selectedComponents[0]
for (i=1; i<selectedComponents.length-1; i++)
document.getElementById(selectedComponents[i]).style.display="block"
}
 
function revivestatus()
{
var inc=0
while (statecollect[inc])
{
if (ccollect[inc].style.display=="block")
statecollect[inc].innerHTML=contractsymbol
else
statecollect[inc].innerHTML=expandsymbol
inc++
}
}
 
function get_cookie(Name)
{
var search = Name + "="
var returnvalue = "";
if (document.cookie.length > 0)
{
offset = document.cookie.indexOf(search)
if (offset != -1)
{
offset += search.length
end = document.cookie.indexOf(";", offset);
if (end == -1) end = document.cookie.length;
returnvalue=unescape(document.cookie.substring(offset, end))
}
}
return returnvalue;
}
 
function getselectedItem()
{
if (get_cookie(window.location.pathname) != "")
{
selectedItem=get_cookie(window.location.pathname)
return selectedItem
}
else
return ""
}
 
function saveswitchstate()
{
var inc=0, selectedItem=collapseprevious+"|"
while (ccollect[inc])
{
if (ccollect[inc].style.display=="block")
selectedItem+=ccollect[inc].id+"|"
inc++
}
document.cookie=window.location.pathname+"="+selectedItem
}
 
function do_onload()
{
uniqueidn=window.location.pathname+"firsttimeload"
var alltags=document.all? document.all : document.getElementsByTagName("*")
ccollect=getElementbyClass(alltags, "switchcontent")
statecollect=getElementbyClass(alltags, "showstate")
if (enablepersist=="on" && ccollect.length>0)
{
document.cookie=(get_cookie(uniqueidn)=="")? uniqueidn+"=1" : uniqueidn+"=0"
firsttimeload=(get_cookie(uniqueidn)==1)? 1 : 0 //check if this is 1st page load
if (!firsttimeload)
revivecontent()
}
if (ccollect.length>0 && statecollect.length>0)
revivestatus()
if (expandonload)
sweeptoggle('expand')
}
 
if (window.addEventListener)
window.addEventListener("load", do_onload, false)
else if (window.attachEvent)
window.attachEvent("onload", do_onload)
else if (document.getElementById)
window.onload=do_onload
 
if (enablepersist=="on" && document.getElementById)
window.onunload=saveswitchstate
/***********************************************
* Switch Content script- © Dynamic Drive (www.dynamicdrive.com)
* This notice must stay intact for legal use. Last updated April 2nd, 2005.
* Visit http://www.dynamicdrive.com/ for full source code
***********************************************/
 
var enablepersist="on" // Enable saving state of content structure using session cookies? (on/off)
var collapseprevious="yes" // Collapse previously open content when opening present? (yes/no)
 
var contractsymbol='<div class="minusbox">-</div>' // HTML for contract symbol. For image, use: <img src="${prefix}whatever.gif">
var expandsymbol='<div class="plusbox">+</div>' // HTML for expand symbol.
var expandonload=false
 
if (document.getElementById)
{
document.write('<style type="text/css">')
document.write('.switchcontent{display:none;}')
document.write('</style>')
}
 
function getElementbyClass(rootobj, classname)
{
var temparray=new Array()
var inc=0
for (i=0; i<rootobj.length; i++)
{
if (rootobj[i].className==classname)
temparray[inc++]=rootobj[i]
}
return temparray
}
 
function sweeptoggle(ec)
{
var thestate=(ec=="expand")? "block" : "none"
var inc=0
while (ccollect[inc])
{
ccollect[inc].style.display=thestate
inc++
}
revivestatus()
collapseprevious = (ec=="expand")? "no" : "yes"
}
 
 
function contractcontent(omit)
{
var inc=0
while (ccollect[inc])
{
if (ccollect[inc].id!=omit)
ccollect[inc].style.display="none"
inc++
}
}
 
function expandcontent(curobj, cid)
{
var spantags=curobj.getElementsByTagName("SPAN")
var showstateobj=getElementbyClass(spantags, "showstate")
if (ccollect.length>0)
{
if (collapseprevious=="yes")
contractcontent(cid)
document.getElementById(cid).style.display=(document.getElementById(cid).style.display!="block")? "block" : "none"
if (showstateobj.length>0) //if "showstate" span exists in header
{
if (collapseprevious=="no")
showstateobj[0].innerHTML=(document.getElementById(cid).style.display=="block")? contractsymbol : expandsymbol
else
revivestatus()
}
}
}
 
function revivecontent()
{
contractcontent("omitnothing")
selectedItem=getselectedItem()
selectedComponents=selectedItem.split("|")
collapseprevious=selectedComponents[0]
for (i=1; i<selectedComponents.length-1; i++)
document.getElementById(selectedComponents[i]).style.display="block"
}
 
function revivestatus()
{
var inc=0
while (statecollect[inc])
{
if (ccollect[inc].style.display=="block")
statecollect[inc].innerHTML=contractsymbol
else
statecollect[inc].innerHTML=expandsymbol
inc++
}
}
 
function get_cookie(Name)
{
var search = Name + "="
var returnvalue = "";
if (document.cookie.length > 0)
{
offset = document.cookie.indexOf(search)
if (offset != -1)
{
offset += search.length
end = document.cookie.indexOf(";", offset);
if (end == -1) end = document.cookie.length;
returnvalue=unescape(document.cookie.substring(offset, end))
}
}
return returnvalue;
}
 
function getselectedItem()
{
if (get_cookie(window.location.pathname) != "")
{
selectedItem=get_cookie(window.location.pathname)
return selectedItem
}
else
return ""
}
 
function saveswitchstate()
{
var inc=0, selectedItem=collapseprevious+"|"
while (ccollect[inc])
{
if (ccollect[inc].style.display=="block")
selectedItem+=ccollect[inc].id+"|"
inc++
}
document.cookie=window.location.pathname+"="+selectedItem
}
 
function do_onload()
{
uniqueidn=window.location.pathname+"firsttimeload"
var alltags=document.all? document.all : document.getElementsByTagName("*")
ccollect=getElementbyClass(alltags, "switchcontent")
statecollect=getElementbyClass(alltags, "showstate")
if (enablepersist=="on" && ccollect.length>0)
{
document.cookie=(get_cookie(uniqueidn)=="")? uniqueidn+"=1" : uniqueidn+"=0"
firsttimeload=(get_cookie(uniqueidn)==1)? 1 : 0 //check if this is 1st page load
if (!firsttimeload)
revivecontent()
}
if (ccollect.length>0 && statecollect.length>0)
revivestatus()
if (expandonload)
sweeptoggle('expand')
}
 
if (window.addEventListener)
window.addEventListener("load", do_onload, false)
else if (window.attachEvent)
window.attachEvent("onload", do_onload)
else if (document.getElementById)
window.onload=do_onload
 
if (enablepersist=="on" && document.getElementById)
window.onunload=saveswitchstate
/WebSVN/templates/BlueGrey/footer.tmpl
1,3 → 1,3
<p><center><font size="-1"><i><b>[lang:POWERED] v[websvn:version]</b></i></font></center>
</body>
</html>
<p><center><font size="-1"><i><b>[lang:POWERED] v[websvn:version]</b></i></font></center>
</body>
</html>
/WebSVN/templates/BlueGrey/png.js
1,39 → 1,39
// correctly handle PNG transparency in Win IE 5.5 or higher.
function correctPNG()
{
for(var i = 0; i < document.images.length; i++)
{
var img = document.images[i]
var imgName = img.src.toUpperCase()
if (imgName.substring(imgName.length-3, imgName.length) == "PNG")
{
var imgID = (img.id) ? "id='" + img.id + "' " : ""
var imgClass = (img.className) ? "class='" + img.className + "' " : ""
var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt + "' "
var imgStyle = "display:inline-block;" + img.style.cssText
var imgAttribs = img.attributes;
for (var j=0; j<imgAttribs.length; j++)
{
var imgAttrib = imgAttribs[j];
if (imgAttrib.nodeName == "align")
{
if (imgAttrib.nodeValue == "left") imgStyle = "float:left;" + imgStyle
if (imgAttrib.nodeValue == "right") imgStyle = "float:right;" + imgStyle
break
}
}
var strNewHTML = "<span " + imgID + imgClass + imgTitle
strNewHTML += " style=\"" + "width:" + img.width + "px; height:" + img.height + "px;" + imgStyle + ";"
strNewHTML += "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
strNewHTML += "(src=\'" + img.src + "\', sizingMethod='scale');\"></span>"
img.outerHTML = strNewHTML
i = i-1
}
}
}
 
var supported = /MSIE (5\.5)|[6789]/.test(navigator.userAgent) && navigator.platform == "Win32";
 
if (supported)
window.attachEvent("onload", correctPNG);
// correctly handle PNG transparency in Win IE 5.5 or higher.
function correctPNG()
{
for(var i = 0; i < document.images.length; i++)
{
var img = document.images[i]
var imgName = img.src.toUpperCase()
if (imgName.substring(imgName.length-3, imgName.length) == "PNG")
{
var imgID = (img.id) ? "id='" + img.id + "' " : ""
var imgClass = (img.className) ? "class='" + img.className + "' " : ""
var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt + "' "
var imgStyle = "display:inline-block;" + img.style.cssText
var imgAttribs = img.attributes;
for (var j=0; j<imgAttribs.length; j++)
{
var imgAttrib = imgAttribs[j];
if (imgAttrib.nodeName == "align")
{
if (imgAttrib.nodeValue == "left") imgStyle = "float:left;" + imgStyle
if (imgAttrib.nodeValue == "right") imgStyle = "float:right;" + imgStyle
break
}
}
var strNewHTML = "<span " + imgID + imgClass + imgTitle
strNewHTML += " style=\"" + "width:" + img.width + "px; height:" + img.height + "px;" + imgStyle + ";"
strNewHTML += "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
strNewHTML += "(src=\'" + img.src + "\', sizingMethod='scale');\"></span>"
img.outerHTML = strNewHTML
i = i-1
}
}
}
 
var supported = /MSIE (5\.5)|[6789]/.test(navigator.userAgent) && navigator.platform == "Win32";
 
if (supported)
window.attachEvent("onload", correctPNG);
/WebSVN/templates/StandardNG/collapse.js
1,169 → 1,169
/***********************************************
* Switch Content script- © Dynamic Drive (www.dynamicdrive.com)
* This notice must stay intact for legal use. Last updated April 2nd, 2005.
* Visit http://www.dynamicdrive.com/ for full source code
***********************************************/
 
var enablepersist="on" // Enable saving state of content structure using session cookies? (on/off)
var collapseprevious="yes" // Collapse previously open content when opening present? (yes/no)
 
var contractsymbol='<div class="minusbox">-</div>' // HTML for contract symbol. For image, use: <img src="${prefix}whatever.gif">
var expandsymbol='<div class="plusbox">+</div>' // HTML for expand symbol.
var expandonload=false
 
if (document.getElementById)
{
document.write('<style type="text/css">')
document.write('.switchcontent{display:none;}')
document.write('</style>')
}
 
function getElementbyClass(rootobj, classname)
{
var temparray=new Array()
var inc=0
for (i=0; i<rootobj.length; i++)
{
if (rootobj[i].className==classname)
temparray[inc++]=rootobj[i]
}
return temparray
}
 
function sweeptoggle(ec)
{
var thestate=(ec=="expand")? "block" : "none"
var inc=0
while (ccollect[inc])
{
ccollect[inc].style.display=thestate
inc++
}
revivestatus()
collapseprevious = (ec=="expand")? "no" : "yes"
}
 
 
function contractcontent(omit)
{
var inc=0
while (ccollect[inc])
{
if (ccollect[inc].id!=omit)
ccollect[inc].style.display="none"
inc++
}
}
 
function expandcontent(curobj, cid)
{
var spantags=curobj.getElementsByTagName("SPAN")
var showstateobj=getElementbyClass(spantags, "showstate")
if (ccollect.length>0)
{
if (collapseprevious=="yes")
contractcontent(cid)
document.getElementById(cid).style.display=(document.getElementById(cid).style.display!="block")? "block" : "none"
if (showstateobj.length>0) //if "showstate" span exists in header
{
if (collapseprevious=="no")
showstateobj[0].innerHTML=(document.getElementById(cid).style.display=="block")? contractsymbol : expandsymbol
else
revivestatus()
}
}
}
 
function revivecontent()
{
contractcontent("omitnothing")
selectedItem=getselectedItem()
selectedComponents=selectedItem.split("|")
collapseprevious=selectedComponents[0]
for (i=1; i<selectedComponents.length-1; i++)
document.getElementById(selectedComponents[i]).style.display="block"
}
 
function revivestatus()
{
var inc=0
while (statecollect[inc])
{
if (ccollect[inc].style.display=="block")
statecollect[inc].innerHTML=contractsymbol
else
statecollect[inc].innerHTML=expandsymbol
inc++
}
}
 
function get_cookie(Name)
{
var search = Name + "="
var returnvalue = "";
if (document.cookie.length > 0)
{
offset = document.cookie.indexOf(search)
if (offset != -1)
{
offset += search.length
end = document.cookie.indexOf(";", offset);
if (end == -1) end = document.cookie.length;
returnvalue=unescape(document.cookie.substring(offset, end))
}
}
return returnvalue;
}
 
function getselectedItem()
{
if (get_cookie(window.location.pathname) != "")
{
selectedItem=get_cookie(window.location.pathname)
return selectedItem
}
else
return ""
}
 
function saveswitchstate()
{
var inc=0, selectedItem=collapseprevious+"|"
while (ccollect[inc])
{
if (ccollect[inc].style.display=="block")
selectedItem+=ccollect[inc].id+"|"
inc++
}
document.cookie=window.location.pathname+"="+selectedItem
}
 
function do_onload()
{
uniqueidn=window.location.pathname+"firsttimeload"
var alltags=document.all? document.all : document.getElementsByTagName("*")
ccollect=getElementbyClass(alltags, "switchcontent")
statecollect=getElementbyClass(alltags, "showstate")
if (enablepersist=="on" && ccollect.length>0)
{
document.cookie=(get_cookie(uniqueidn)=="")? uniqueidn+"=1" : uniqueidn+"=0"
firsttimeload=(get_cookie(uniqueidn)==1)? 1 : 0 //check if this is 1st page load
if (!firsttimeload)
revivecontent()
}
if (ccollect.length>0 && statecollect.length>0)
revivestatus()
if (expandonload)
sweeptoggle('expand')
}
 
if (window.addEventListener)
window.addEventListener("load", do_onload, false)
else if (window.attachEvent)
window.attachEvent("onload", do_onload)
else if (document.getElementById)
window.onload=do_onload
 
if (enablepersist=="on" && document.getElementById)
window.onunload=saveswitchstate
/***********************************************
* Switch Content script- © Dynamic Drive (www.dynamicdrive.com)
* This notice must stay intact for legal use. Last updated April 2nd, 2005.
* Visit http://www.dynamicdrive.com/ for full source code
***********************************************/
 
var enablepersist="on" // Enable saving state of content structure using session cookies? (on/off)
var collapseprevious="yes" // Collapse previously open content when opening present? (yes/no)
 
var contractsymbol='<div class="minusbox">-</div>' // HTML for contract symbol. For image, use: <img src="${prefix}whatever.gif">
var expandsymbol='<div class="plusbox">+</div>' // HTML for expand symbol.
var expandonload=false
 
if (document.getElementById)
{
document.write('<style type="text/css">')
document.write('.switchcontent{display:none;}')
document.write('</style>')
}
 
function getElementbyClass(rootobj, classname)
{
var temparray=new Array()
var inc=0
for (i=0; i<rootobj.length; i++)
{
if (rootobj[i].className==classname)
temparray[inc++]=rootobj[i]
}
return temparray
}
 
function sweeptoggle(ec)
{
var thestate=(ec=="expand")? "block" : "none"
var inc=0
while (ccollect[inc])
{
ccollect[inc].style.display=thestate
inc++
}
revivestatus()
collapseprevious = (ec=="expand")? "no" : "yes"
}
 
 
function contractcontent(omit)
{
var inc=0
while (ccollect[inc])
{
if (ccollect[inc].id!=omit)
ccollect[inc].style.display="none"
inc++
}
}
 
function expandcontent(curobj, cid)
{
var spantags=curobj.getElementsByTagName("SPAN")
var showstateobj=getElementbyClass(spantags, "showstate")
if (ccollect.length>0)
{
if (collapseprevious=="yes")
contractcontent(cid)
document.getElementById(cid).style.display=(document.getElementById(cid).style.display!="block")? "block" : "none"
if (showstateobj.length>0) //if "showstate" span exists in header
{
if (collapseprevious=="no")
showstateobj[0].innerHTML=(document.getElementById(cid).style.display=="block")? contractsymbol : expandsymbol
else
revivestatus()
}
}
}
 
function revivecontent()
{
contractcontent("omitnothing")
selectedItem=getselectedItem()
selectedComponents=selectedItem.split("|")
collapseprevious=selectedComponents[0]
for (i=1; i<selectedComponents.length-1; i++)
document.getElementById(selectedComponents[i]).style.display="block"
}
 
function revivestatus()
{
var inc=0
while (statecollect[inc])
{
if (ccollect[inc].style.display=="block")
statecollect[inc].innerHTML=contractsymbol
else
statecollect[inc].innerHTML=expandsymbol
inc++
}
}
 
function get_cookie(Name)
{
var search = Name + "="
var returnvalue = "";
if (document.cookie.length > 0)
{
offset = document.cookie.indexOf(search)
if (offset != -1)
{
offset += search.length
end = document.cookie.indexOf(";", offset);
if (end == -1) end = document.cookie.length;
returnvalue=unescape(document.cookie.substring(offset, end))
}
}
return returnvalue;
}
 
function getselectedItem()
{
if (get_cookie(window.location.pathname) != "")
{
selectedItem=get_cookie(window.location.pathname)
return selectedItem
}
else
return ""
}
 
function saveswitchstate()
{
var inc=0, selectedItem=collapseprevious+"|"
while (ccollect[inc])
{
if (ccollect[inc].style.display=="block")
selectedItem+=ccollect[inc].id+"|"
inc++
}
document.cookie=window.location.pathname+"="+selectedItem
}
 
function do_onload()
{
uniqueidn=window.location.pathname+"firsttimeload"
var alltags=document.all? document.all : document.getElementsByTagName("*")
ccollect=getElementbyClass(alltags, "switchcontent")
statecollect=getElementbyClass(alltags, "showstate")
if (enablepersist=="on" && ccollect.length>0)
{
document.cookie=(get_cookie(uniqueidn)=="")? uniqueidn+"=1" : uniqueidn+"=0"
firsttimeload=(get_cookie(uniqueidn)==1)? 1 : 0 //check if this is 1st page load
if (!firsttimeload)
revivecontent()
}
if (ccollect.length>0 && statecollect.length>0)
revivestatus()
if (expandonload)
sweeptoggle('expand')
}
 
if (window.addEventListener)
window.addEventListener("load", do_onload, false)
else if (window.attachEvent)
window.attachEvent("onload", do_onload)
else if (document.getElementById)
window.onload=do_onload
 
if (enablepersist=="on" && document.getElementById)
window.onunload=saveswitchstate
/WebSVN/templates/StandardNG/diff.tmpl
1,5 → 1,5
[websvn-test:noprev]
[lang:NOPREVREV]
No Previous Revision
[websvn-else]
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
<h2>[websvn:repname]</h2>
/WebSVN/templates/Zinn/blame.tmpl
1,36 → 1,36
<table width="100%" border="0">
<tr>
<td>
<h1>[websvn:repname]</h1>
</td>
<td>
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
</td>
</tr>
</table>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
[websvn:curdirlinks] - [lang:BLAMEFOR] [websvn:rev]
<p>
<table border="1" class="blame" width="100%" cellpadding="2">
<tr>
<th style="padding-bottom: 5px" align="left"><b>[lang:LINENO]</b></th>
<th style="padding-bottom: 5px" align="left"><b>[lang:REV]</b></th>
<th style="padding-bottom: 5px" align="left"><b>[lang:AUTHOR]</b></th>
<th style="padding-bottom: 5px" align="left"><b>[lang:LINE]</b></th>
</tr>
[websvn-startlisting]
<tr>
<td>[websvn:lineno]</td>
<td>[websvn:revision]</td>
<td>[websvn:author]</td>
<td>[websvn:line]</td>
</tr>
[websvn-endlisting]
</table>
[websvn-endtest]
<table width="100%" border="0">
<tr>
<td>
<h1>[websvn:repname]</h1>
</td>
<td>
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
</td>
</tr>
</table>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
[websvn:curdirlinks] - [lang:BLAMEFOR] [websvn:rev]
<p>
<table border="1" class="blame" width="100%" cellpadding="2">
<tr>
<th style="padding-bottom: 5px" align="left"><b>[lang:LINENO]</b></th>
<th style="padding-bottom: 5px" align="left"><b>[lang:REV]</b></th>
<th style="padding-bottom: 5px" align="left"><b>[lang:AUTHOR]</b></th>
<th style="padding-bottom: 5px" align="left"><b>[lang:LINE]</b></th>
</tr>
[websvn-startlisting]
<tr>
<td>[websvn:lineno]</td>
<td>[websvn:revision]</td>
<td>[websvn:author]</td>
<td>[websvn:line]</td>
</tr>
[websvn-endlisting]
</table>
[websvn-endtest]
/WebSVN/templates/Zinn/collapse.js
1,169 → 1,169
/***********************************************
* Switch Content script- © Dynamic Drive (www.dynamicdrive.com)
* This notice must stay intact for legal use. Last updated April 2nd, 2005.
* Visit http://www.dynamicdrive.com/ for full source code
***********************************************/
 
var enablepersist="on" // Enable saving state of content structure using session cookies? (on/off)
var collapseprevious="yes" // Collapse previously open content when opening present? (yes/no)
 
var contractsymbol='<div class="minusbox">-</div>' // HTML for contract symbol. For image, use: <img src="${prefix}whatever.gif">
var expandsymbol='<div class="plusbox">+</div>' // HTML for expand symbol.
var expandonload=false
 
if (document.getElementById)
{
document.write('<style type="text/css">')
document.write('.switchcontent{display:none;}')
document.write('</style>')
}
 
function getElementbyClass(rootobj, classname)
{
var temparray=new Array()
var inc=0
for (i=0; i<rootobj.length; i++)
{
if (rootobj[i].className==classname)
temparray[inc++]=rootobj[i]
}
return temparray
}
 
function sweeptoggle(ec)
{
var thestate=(ec=="expand")? "block" : "none"
var inc=0
while (ccollect[inc])
{
ccollect[inc].style.display=thestate
inc++
}
revivestatus()
collapseprevious = (ec=="expand")? "no" : "yes"
}
 
 
function contractcontent(omit)
{
var inc=0
while (ccollect[inc])
{
if (ccollect[inc].id!=omit)
ccollect[inc].style.display="none"
inc++
}
}
 
function expandcontent(curobj, cid)
{
var spantags=curobj.getElementsByTagName("SPAN")
var showstateobj=getElementbyClass(spantags, "showstate")
if (ccollect.length>0)
{
if (collapseprevious=="yes")
contractcontent(cid)
document.getElementById(cid).style.display=(document.getElementById(cid).style.display!="block")? "block" : "none"
if (showstateobj.length>0) //if "showstate" span exists in header
{
if (collapseprevious=="no")
showstateobj[0].innerHTML=(document.getElementById(cid).style.display=="block")? contractsymbol : expandsymbol
else
revivestatus()
}
}
}
 
function revivecontent()
{
contractcontent("omitnothing")
selectedItem=getselectedItem()
selectedComponents=selectedItem.split("|")
collapseprevious=selectedComponents[0]
for (i=1; i<selectedComponents.length-1; i++)
document.getElementById(selectedComponents[i]).style.display="block"
}
 
function revivestatus()
{
var inc=0
while (statecollect[inc])
{
if (ccollect[inc].style.display=="block")
statecollect[inc].innerHTML=contractsymbol
else
statecollect[inc].innerHTML=expandsymbol
inc++
}
}
 
function get_cookie(Name)
{
var search = Name + "="
var returnvalue = "";
if (document.cookie.length > 0)
{
offset = document.cookie.indexOf(search)
if (offset != -1)
{
offset += search.length
end = document.cookie.indexOf(";", offset);
if (end == -1) end = document.cookie.length;
returnvalue=unescape(document.cookie.substring(offset, end))
}
}
return returnvalue;
}
 
function getselectedItem()
{
if (get_cookie(window.location.pathname) != "")
{
selectedItem=get_cookie(window.location.pathname)
return selectedItem
}
else
return ""
}
 
function saveswitchstate()
{
var inc=0, selectedItem=collapseprevious+"|"
while (ccollect[inc])
{
if (ccollect[inc].style.display=="block")
selectedItem+=ccollect[inc].id+"|"
inc++
}
document.cookie=window.location.pathname+"="+selectedItem
}
 
function do_onload()
{
uniqueidn=window.location.pathname+"firsttimeload"
var alltags=document.all? document.all : document.getElementsByTagName("*")
ccollect=getElementbyClass(alltags, "switchcontent")
statecollect=getElementbyClass(alltags, "showstate")
if (enablepersist=="on" && ccollect.length>0)
{
document.cookie=(get_cookie(uniqueidn)=="")? uniqueidn+"=1" : uniqueidn+"=0"
firsttimeload=(get_cookie(uniqueidn)==1)? 1 : 0 //check if this is 1st page load
if (!firsttimeload)
revivecontent()
}
if (ccollect.length>0 && statecollect.length>0)
revivestatus()
if (expandonload)
sweeptoggle('expand')
}
 
if (window.addEventListener)
window.addEventListener("load", do_onload, false)
else if (window.attachEvent)
window.attachEvent("onload", do_onload)
else if (document.getElementById)
window.onload=do_onload
 
if (enablepersist=="on" && document.getElementById)
window.onunload=saveswitchstate
/***********************************************
* Switch Content script- © Dynamic Drive (www.dynamicdrive.com)
* This notice must stay intact for legal use. Last updated April 2nd, 2005.
* Visit http://www.dynamicdrive.com/ for full source code
***********************************************/
 
var enablepersist="on" // Enable saving state of content structure using session cookies? (on/off)
var collapseprevious="yes" // Collapse previously open content when opening present? (yes/no)
 
var contractsymbol='<div class="minusbox">-</div>' // HTML for contract symbol. For image, use: <img src="${prefix}whatever.gif">
var expandsymbol='<div class="plusbox">+</div>' // HTML for expand symbol.
var expandonload=false
 
if (document.getElementById)
{
document.write('<style type="text/css">')
document.write('.switchcontent{display:none;}')
document.write('</style>')
}
 
function getElementbyClass(rootobj, classname)
{
var temparray=new Array()
var inc=0
for (i=0; i<rootobj.length; i++)
{
if (rootobj[i].className==classname)
temparray[inc++]=rootobj[i]
}
return temparray
}
 
function sweeptoggle(ec)
{
var thestate=(ec=="expand")? "block" : "none"
var inc=0
while (ccollect[inc])
{
ccollect[inc].style.display=thestate
inc++
}
revivestatus()
collapseprevious = (ec=="expand")? "no" : "yes"
}
 
 
function contractcontent(omit)
{
var inc=0
while (ccollect[inc])
{
if (ccollect[inc].id!=omit)
ccollect[inc].style.display="none"
inc++
}
}
 
function expandcontent(curobj, cid)
{
var spantags=curobj.getElementsByTagName("SPAN")
var showstateobj=getElementbyClass(spantags, "showstate")
if (ccollect.length>0)
{
if (collapseprevious=="yes")
contractcontent(cid)
document.getElementById(cid).style.display=(document.getElementById(cid).style.display!="block")? "block" : "none"
if (showstateobj.length>0) //if "showstate" span exists in header
{
if (collapseprevious=="no")
showstateobj[0].innerHTML=(document.getElementById(cid).style.display=="block")? contractsymbol : expandsymbol
else
revivestatus()
}
}
}
 
function revivecontent()
{
contractcontent("omitnothing")
selectedItem=getselectedItem()
selectedComponents=selectedItem.split("|")
collapseprevious=selectedComponents[0]
for (i=1; i<selectedComponents.length-1; i++)
document.getElementById(selectedComponents[i]).style.display="block"
}
 
function revivestatus()
{
var inc=0
while (statecollect[inc])
{
if (ccollect[inc].style.display=="block")
statecollect[inc].innerHTML=contractsymbol
else
statecollect[inc].innerHTML=expandsymbol
inc++
}
}
 
function get_cookie(Name)
{
var search = Name + "="
var returnvalue = "";
if (document.cookie.length > 0)
{
offset = document.cookie.indexOf(search)
if (offset != -1)
{
offset += search.length
end = document.cookie.indexOf(";", offset);
if (end == -1) end = document.cookie.length;
returnvalue=unescape(document.cookie.substring(offset, end))
}
}
return returnvalue;
}
 
function getselectedItem()
{
if (get_cookie(window.location.pathname) != "")
{
selectedItem=get_cookie(window.location.pathname)
return selectedItem
}
else
return ""
}
 
function saveswitchstate()
{
var inc=0, selectedItem=collapseprevious+"|"
while (ccollect[inc])
{
if (ccollect[inc].style.display=="block")
selectedItem+=ccollect[inc].id+"|"
inc++
}
document.cookie=window.location.pathname+"="+selectedItem
}
 
function do_onload()
{
uniqueidn=window.location.pathname+"firsttimeload"
var alltags=document.all? document.all : document.getElementsByTagName("*")
ccollect=getElementbyClass(alltags, "switchcontent")
statecollect=getElementbyClass(alltags, "showstate")
if (enablepersist=="on" && ccollect.length>0)
{
document.cookie=(get_cookie(uniqueidn)=="")? uniqueidn+"=1" : uniqueidn+"=0"
firsttimeload=(get_cookie(uniqueidn)==1)? 1 : 0 //check if this is 1st page load
if (!firsttimeload)
revivecontent()
}
if (ccollect.length>0 && statecollect.length>0)
revivestatus()
if (expandonload)
sweeptoggle('expand')
}
 
if (window.addEventListener)
window.addEventListener("load", do_onload, false)
else if (window.attachEvent)
window.attachEvent("onload", do_onload)
else if (document.getElementById)
window.onload=do_onload
 
if (enablepersist=="on" && document.getElementById)
window.onunload=saveswitchstate
/WebSVN/templates/Zinn/compare.tmpl
1,75 → 1,75
<table width="100%" border="0">
<tr>
<td>
<h1>[websvn:repname]</h1>
</td>
<td>
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
</td>
</tr>
</table>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
<center>
[websvn:compare_form]
<table>
<tr><td>
<table class="outlined">
<tr><td>[lang:COMPPATH]&nbsp;</td><td>[websvn:compare_path1input] [lang:REV] [websvn:compare_rev1input]</td></tr>
<tr><td>[lang:WITHPATH]&nbsp;</td><td>[websvn:compare_path2input] [lang:REV] [websvn:compare_rev2input]</td></tr>
</table>
</td><tr>
<tr><td align="center">[websvn:compare_submit]</td></tr>
</table>
[websvn:compare_endform]
<hr>
</center>
<p>
[websvn-test:success]
[lang:CONVFROM] <b>[websvn:path1] ([lang:REV] [websvn:rev1])</b> [lang:TO] <b>[websvn:path2] ([lang:REV] [websvn:rev2])</b>
<p>
[websvn:revlink]
[websvn-endtest]
<p>
[websvn-startlisting]
[websvn-test:newpath]
<p>
<div class="newpath">
<b>[websvn:newpath]</b><br>
[websvn-endtest]
[websvn-test:info]
[websvn:info]<br>
[websvn-endtest]
[websvn-test:difflines]
<div class="difflines">
<p>
[websvn:difflines]<br>
<table class="diff" cellspacing="0">
[websvn-endtest]
[websvn-test:diffclass]
<tr><td class="[websvn:diffclass]">[websvn:line]</td></tr>
[websvn-endtest]
[websvn-test:enddifflines]
</table>
</div>
[websvn-endtest]
[websvn-test:endpath]
</div>
<p><hr>
[websvn-endtest]
[websvn-test:properties]
<p><i>[lang:PROPCHANGES]</i><p>
[websvn-endtest]
[websvn-endlisting]
</table>
[websvn-endtest]
<table width="100%" border="0">
<tr>
<td>
<h1>[websvn:repname]</h1>
</td>
<td>
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
</td>
</tr>
</table>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
<center>
[websvn:compare_form]
<table>
<tr><td>
<table class="outlined">
<tr><td>[lang:COMPPATH]&nbsp;</td><td>[websvn:compare_path1input] [lang:REV] [websvn:compare_rev1input]</td></tr>
<tr><td>[lang:WITHPATH]&nbsp;</td><td>[websvn:compare_path2input] [lang:REV] [websvn:compare_rev2input]</td></tr>
</table>
</td><tr>
<tr><td align="center">[websvn:compare_submit]</td></tr>
</table>
[websvn:compare_endform]
<hr>
</center>
<p>
[websvn-test:success]
[lang:CONVFROM] <b>[websvn:path1] ([lang:REV] [websvn:rev1])</b> [lang:TO] <b>[websvn:path2] ([lang:REV] [websvn:rev2])</b>
<p>
[websvn:revlink]
[websvn-endtest]
<p>
[websvn-startlisting]
[websvn-test:newpath]
<p>
<div class="newpath">
<b>[websvn:newpath]</b><br>
[websvn-endtest]
[websvn-test:info]
[websvn:info]<br>
[websvn-endtest]
[websvn-test:difflines]
<div class="difflines">
<p>
[websvn:difflines]<br>
<table class="diff" cellspacing="0">
[websvn-endtest]
[websvn-test:diffclass]
<tr><td class="[websvn:diffclass]">[websvn:line]</td></tr>
[websvn-endtest]
[websvn-test:enddifflines]
</table>
</div>
[websvn-endtest]
[websvn-test:endpath]
</div>
<p><hr>
[websvn-endtest]
[websvn-test:properties]
<p><i>[lang:PROPCHANGES]</i><p>
[websvn-endtest]
[websvn-endlisting]
</table>
[websvn-endtest]
/WebSVN/templates/Zinn/diff.tmpl
1,51 → 1,51
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
[websvn-test:noprev]
[lang:NOPREVREV]
[websvn-else]
<table width="100%" border="0">
<tr>
<td>
<h1>[websvn:repname]</h1>
</td>
<td>
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
</td>
</tr>
</table>
<b>[lang:PATH]:</b> [websvn:path]
<br><b>[lang:REV]:</b> [websvn:rev]
<p><hr>
<b>[lang:CURDIR]:</b> [websvn:curdirlinks]
<p>
<p><center>
[websvn:showcompactlink]
[websvn:showalllink]
</center>
<p>
<table class="diff" width="100%">
<tr>
<th style="padding-bottom: 5px" width="50%" align="left"><b>[lang:REV] [websvn:rev2]</b></th>
<th width="5"></th>
<th style="padding-bottom: 5px" width="50%" align="left"><b>[lang:REV] [websvn:rev1]</b></th>
</tr>
[websvn-startlisting]
[websvn-test:rev1lineno]
<tr>
<td width="50%" style="padding: 3px 0 3px 0" align="center"><b>[lang:LINE] [websvn:rev1lineno]...</b></td>
<td width="5"></td>
<td width="50%" style="padding: 3px 0 3px 0" align="center"><b>[lang:LINE] [websvn:rev2lineno]...</b></td>
<tr>
[websvn-else]
<tr><td class="[websvn:rev1diffclass]">[websvn:rev1line]</td>
<td width="5"></td>
<td class="[websvn:rev2diffclass]">[websvn:rev2line]</td></tr>
[websvn-endtest]
[websvn-endlisting]
</table>
[websvn-endtest]
[websvn-endtest]
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
[websvn-test:noprev]
No Previous Revision
[websvn-else]
<table width="100%" border="0">
<tr>
<td>
<h1>[websvn:repname]</h1>
</td>
<td>
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
</td>
</tr>
</table>
<b>[lang:PATH]:</b> [websvn:path]
<br><b>[lang:REV]:</b> [websvn:rev]
<p><hr>
<b>[lang:CURDIR]:</b> [websvn:curdirlinks]
<p>
<p><center>
[websvn:showcompactlink]
[websvn:showalllink]
</center>
<p>
<table class="diff" width="100%">
<tr>
<th style="padding-bottom: 5px" width="50%" align="left"><b>[lang:REV] [websvn:rev2]</b></th>
<th width="5"></th>
<th style="padding-bottom: 5px" width="50%" align="left"><b>[lang:REV] [websvn:rev1]</b></th>
</tr>
[websvn-startlisting]
[websvn-test:rev1lineno]
<tr>
<td width="50%" style="padding: 3px 0 3px 0" align="center"><b>[lang:LINE] [websvn:rev1lineno]...</b></td>
<td width="5"></td>
<td width="50%" style="padding: 3px 0 3px 0" align="center"><b>[lang:LINE] [websvn:rev2lineno]...</b></td>
<tr>
[websvn-else]
<tr><td class="[websvn:rev1diffclass]">[websvn:rev1line]</td>
<td width="5"></td>
<td class="[websvn:rev2diffclass]">[websvn:rev2line]</td></tr>
[websvn-endtest]
[websvn-endlisting]
</table>
[websvn-endtest]
[websvn-endtest]
/WebSVN/templates/Zinn/directory.tmpl
1,125 → 1,125
<table width="100%" border="0">
<tr>
<td>
<h1>[websvn:repname]</h1>
</td>
<td>
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
</td>
</tr>
</table>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
[websvn-test:restricted]
[websvn-else]
<b>[lang:PATH]:</b> [websvn:path]
<br><b>[lang:REV]:</b> [websvn:rev]
<p><hr>
<b>[lang:CURDIR]:</b> [websvn:curdirlinks] - [websvn:curdirloglink]
[websvn-test:curdircomplink]
- [websvn:curdircomplink]
[websvn-endtest]
[websvn-test:curdirdllink]
- [websvn:curdirdllink]
[websvn-endtest]
[websvn-test:curdirrsslink]
- [websvn:curdirrssanchor]<img style="border: 0;" src="[websvn:locwebsvnhttp]/templates/Standard/xml.gif" width="36" height="14" alt="[lang:RSSFEED]"></a>
[websvn-endtest]
[websvn-endtest]
[websvn-defineicons]
dir=&nbsp;&nbsp;&nbsp;&nbsp;
diropen=&nbsp;&nbsp;&nbsp;&nbsp;
i-node=&nbsp;&nbsp;&nbsp;&nbsp;
t-node=&nbsp;&nbsp;&nbsp;&nbsp;
l-node=&nbsp;&nbsp;&nbsp;&nbsp;
e-node=&nbsp;&nbsp;&nbsp;&nbsp;
*=&nbsp;&nbsp;&nbsp;&nbsp;
[websvn-enddefineicons]
<p>
[websvn:compare_form]
<table class="outlined" width="100%" cellpadding="2">
<tr>
<th width="100%"><b>Path</b></th>
<th><b>[lang:NOBR][lang:LOG][lang:ENDNOBR]</b></th>
[websvn-test:allowdownload]
<th><b>[lang:TARBALL]</b></th>
[websvn-endtest]
[websvn-test:curdirrsslink]
<th><b>[lang:RSSFEED]</b></th>
[websvn-endtest]
</tr>
[websvn-startlisting]
<tr>
<td class="[websvn:rowparity]">
[websvn:compare_box]
[websvn-treenode]
[websvn:filelink]
</td>
<td class="[websvn:rowparity]">[lang:NOBR][websvn:fileviewloglink][lang:ENDNOBR]</td>
[websvn-test:allowdownload]
<td class="[websvn:rowparity]">[websvn:fileviewdllink]</td>
[websvn-endtest]
[websvn-test:curdirrsslink]
<td class="row[websvn:rowparity]">[websvn:rssanchor]<img style="border: 0;" src="[websvn:locwebsvnhttp]/templates/Standard/xml.gif" width="36" height="14" alt="[lang:RSSFEED]"></a></td>
[websvn-endtest]
</tr>
[websvn-endlisting]
</table>
<p>
[websvn:compare_submit]
[websvn:compare_endform]
<hr>
[websvn-test:goyoungestlink]
- [websvn:goyoungestlink]
[websvn-endtest]
<br><b>[lang:LASTMOD]:</b> [lang:REV] [websvn:lastchangedrev] - [websvn:author] - [websvn:date]
<br><b>[lang:LOGMSG]:</b><br>
[websvn:log]
<p>
[websvn-test:hidechanges]
<p>[websvn:showchangeslink]
[websvn-endtest]
[websvn-test:showchanges]
<p><b>[lang:CHANGES]:</b><br>
<p>[websvn:hidechangeslink]
<p>
<center>
<table border=1 class="bordered" cellpadding=4>
<tr>
<th><center><b>[lang:NEWFILES]</b></center></th>
<th><center><b>[lang:CHANGEDFILES]</b></center></th>
<th><center><b>[lang:DELETEDFILES]</b></center></th>
</tr>
<tr>
<td valign="top">
[websvn-test:newfilesbr]
[websvn:newfilesbr]
[websvn-else]
&nbsp;
[websvn-endtest]
</td>
<td valign="top">
[websvn-test:changedfilesbr]
[websvn:changedfilesbr]
[websvn-else]
&nbsp;
[websvn-endtest]
</td>
<td valign="top">
[websvn-test:deletedfilesbr]
[websvn:deletedfilesbr]
[websvn-else]
&nbsp;
[websvn-endtest]
</td>
</tr>
</table>
</center>
[websvn-endtest]
[websvn-endtest]
 
<table width="100%" border="0">
<tr>
<td>
<h1>[websvn:repname]</h1>
</td>
<td>
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
</td>
</tr>
</table>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
[websvn-test:restricted]
[websvn-else]
<b>[lang:PATH]:</b> [websvn:path]
<br><b>[lang:REV]:</b> [websvn:rev]
<p><hr>
<b>[lang:CURDIR]:</b> [websvn:curdirlinks] - [websvn:curdirloglink]
[websvn-test:curdircomplink]
- [websvn:curdircomplink]
[websvn-endtest]
[websvn-test:curdirdllink]
- [websvn:curdirdllink]
[websvn-endtest]
[websvn-test:curdirrsslink]
- [websvn:curdirrssanchor]<img style="border: 0;" src="[websvn:locwebsvnhttp]/templates/Standard/xml.gif" width="36" height="14" alt="[lang:RSSFEED]"></a>
[websvn-endtest]
[websvn-endtest]
[websvn-defineicons]
dir=&nbsp;&nbsp;&nbsp;&nbsp;
diropen=&nbsp;&nbsp;&nbsp;&nbsp;
i-node=&nbsp;&nbsp;&nbsp;&nbsp;
t-node=&nbsp;&nbsp;&nbsp;&nbsp;
l-node=&nbsp;&nbsp;&nbsp;&nbsp;
e-node=&nbsp;&nbsp;&nbsp;&nbsp;
*=&nbsp;&nbsp;&nbsp;&nbsp;
[websvn-enddefineicons]
<p>
[websvn:compare_form]
<table class="outlined" width="100%" cellpadding="2">
<tr>
<th width="100%"><b>Path</b></th>
<th><b>[lang:NOBR][lang:LOG][lang:ENDNOBR]</b></th>
[websvn-test:allowdownload]
<th><b>[lang:TARBALL]</b></th>
[websvn-endtest]
[websvn-test:curdirrsslink]
<th><b>[lang:RSSFEED]</b></th>
[websvn-endtest]
</tr>
[websvn-startlisting]
<tr>
<td class="[websvn:rowparity]">
[websvn:compare_box]
[websvn-treenode]
[websvn:filelink]
</td>
<td class="[websvn:rowparity]">[lang:NOBR][websvn:fileviewloglink][lang:ENDNOBR]</td>
[websvn-test:allowdownload]
<td class="[websvn:rowparity]">[websvn:fileviewdllink]</td>
[websvn-endtest]
[websvn-test:curdirrsslink]
<td class="row[websvn:rowparity]">[websvn:rssanchor]<img style="border: 0;" src="[websvn:locwebsvnhttp]/templates/Standard/xml.gif" width="36" height="14" alt="[lang:RSSFEED]"></a></td>
[websvn-endtest]
</tr>
[websvn-endlisting]
</table>
<p>
[websvn:compare_submit]
[websvn:compare_endform]
<hr>
[websvn-test:goyoungestlink]
- [websvn:goyoungestlink]
[websvn-endtest]
<br><b>[lang:LASTMOD]:</b> [lang:REV] [websvn:lastchangedrev] - [websvn:author] - [websvn:date]
<br><b>[lang:LOGMSG]:</b><br>
[websvn:log]
<p>
[websvn-test:hidechanges]
<p>[websvn:showchangeslink]
[websvn-endtest]
[websvn-test:showchanges]
<p><b>[lang:CHANGES]:</b><br>
<p>[websvn:hidechangeslink]
<p>
<center>
<table border=1 class="bordered" cellpadding=4>
<tr>
<th><center><b>[lang:NEWFILES]</b></center></th>
<th><center><b>[lang:CHANGEDFILES]</b></center></th>
<th><center><b>[lang:DELETEDFILES]</b></center></th>
</tr>
<tr>
<td valign="top">
[websvn-test:newfilesbr]
[websvn:newfilesbr]
[websvn-else]
&nbsp;
[websvn-endtest]
</td>
<td valign="top">
[websvn-test:changedfilesbr]
[websvn:changedfilesbr]
[websvn-else]
&nbsp;
[websvn-endtest]
</td>
<td valign="top">
[websvn-test:deletedfilesbr]
[websvn:deletedfilesbr]
[websvn-else]
&nbsp;
[websvn-endtest]
</td>
</tr>
</table>
</center>
[websvn-endtest]
[websvn-endtest]
 
/WebSVN/templates/Zinn/file.tmpl
1,30 → 1,30
<table width="100%" border="0">
<tr>
<td>
<h1>[websvn:repname]</h1>
</td>
<td>
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
</td>
</tr>
</table>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
<b>[lang:PATH]:</b> [websvn:path]
<br><b>[lang:REV]:</b> [websvn:rev]
<p><hr>
<b>[lang:CURDIR]:</b> [websvn:curdirlinks]
<p>
[websvn-test:goyoungestlink]
[websvn:goyoungestlink]<p>
[websvn-endtest]
[websvn:prevdifflink] - [websvn:blamelink]
<p>
<table width="100%" border=1><tr><td>
[websvn-getlisting]
</td></tr></table>
<table width="100%" border="0">
<tr>
<td>
<h1>[websvn:repname]</h1>
</td>
<td>
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
</td>
</tr>
</table>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
<b>[lang:PATH]:</b> [websvn:path]
<br><b>[lang:REV]:</b> [websvn:rev]
<p><hr>
<b>[lang:CURDIR]:</b> [websvn:curdirlinks]
<p>
[websvn-test:goyoungestlink]
[websvn:goyoungestlink]<p>
[websvn-endtest]
[websvn:prevdifflink] - [websvn:blamelink]
<p>
<table width="100%" border=1><tr><td>
[websvn-getlisting]
</td></tr></table>
[websvn-endtest]
/WebSVN/templates/Zinn/footer.tmpl
1,2 → 1,2
</body>
</html>
</body>
</html>
/WebSVN/templates/Zinn/header.tmpl
1,64 → 1,64
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=[websvn:charset]">
<link href="[websvn:locwebsvnhttp]/templates/zinn/styles.css" rel="stylesheet" media="screen">
<script type="text/javascript" src="[websvn:locwebsvnhttp]/templates/Zinn/collapse.js"></script>
<script type="text/javascript">
function checkCB(chBox)
{
count = 0
first = null
f = chBox.form
for (i = 0 ; i < f.elements.length ; i++)
if (f.elements[i].type == 'checkbox' && f.elements[i].checked)
{
if (first == null && f.elements[i] != chBox)
first = f.elements[i]
count += 1
}
if (count > 2)
{
first.checked = false
count -= 1
}
}
 
[websvn-test:opentree]
expandonload = true
[websvn-endtest]
 
</script>
<title>
WebSVN
[websvn-test:repname]
- [websvn:repname]
[websvn-endtest]
[websvn-test:action]
- [websvn:action]
[websvn-endtest]
[websvn-test:rev2]
[websvn-test:path2]
- [websvn:safepath1] [lang:REV] [websvn:rev1] [lang:AND] [websvn:safepath2] [lang:REV] [websvn:rev2]
[websvn-else]
- [lang:REV] [websvn:rev1] [lang:AND] [websvn:rev2]
[websvn-endtest]
[websvn-else]
[websvn-test:rev]
- [lang:REV] [websvn:rev]
[websvn-endtest]
[websvn-endtest]
[websvn-test:path]
- [websvn:safepath]
[websvn-endtest]
</title>
 
[websvn-test:curdirrsslink]
<link rel="alternate" type="application/rss+xml" title="WebSVN RSS" href="[websvn:curdirrsshref]">
[websvn-endtest]
 
</head>
<body>
<div style="float: right">[websvn:lang_form][websvn:lang_select][websvn:lang_submit][websvn:lang_endform]</div>
</tr>
</table>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=[websvn:charset]">
<link href="[websvn:locwebsvnhttp]/templates/zinn/styles.css" rel="stylesheet" media="screen">
<script type="text/javascript" src="[websvn:locwebsvnhttp]/templates/Zinn/collapse.js"></script>
<script type="text/javascript">
function checkCB(chBox)
{
count = 0
first = null
f = chBox.form
for (i = 0 ; i < f.elements.length ; i++)
if (f.elements[i].type == 'checkbox' && f.elements[i].checked)
{
if (first == null && f.elements[i] != chBox)
first = f.elements[i]
count += 1
}
if (count > 2)
{
first.checked = false
count -= 1
}
}
 
[websvn-test:opentree]
expandonload = true
[websvn-endtest]
 
</script>
<title>
WebSVN
[websvn-test:repname]
- [websvn:repname]
[websvn-endtest]
[websvn-test:action]
- [websvn:action]
[websvn-endtest]
[websvn-test:rev2]
[websvn-test:path2]
- [websvn:safepath1] [lang:REV] [websvn:rev1] [lang:AND] [websvn:safepath2] [lang:REV] [websvn:rev2]
[websvn-else]
- [lang:REV] [websvn:rev1] [lang:AND] [websvn:rev2]
[websvn-endtest]
[websvn-else]
[websvn-test:rev]
- [lang:REV] [websvn:rev]
[websvn-endtest]
[websvn-endtest]
[websvn-test:path]
- [websvn:safepath]
[websvn-endtest]
</title>
 
[websvn-test:curdirrsslink]
<link rel="alternate" type="application/rss+xml" title="WebSVN RSS" href="[websvn:curdirrsshref]">
[websvn-endtest]
 
</head>
<body>
<div style="float: right">[websvn:lang_form][websvn:lang_select][websvn:lang_submit][websvn:lang_endform]</div>
</tr>
</table>
/WebSVN/templates/Zinn/index.tmpl
1,34 → 1,34
[websvn-test:flatview]
<table border=0 cellspacing=0 cellpadding=0 align="center">
<tr>
<td align="center">
<br><h1>[lang:PROJECTS]:</h1>
<p><hr><p>
<table width="100%" class="outlined" cellpadding="2">
[websvn-startlisting]
<tr><td>[websvn:projlink]</td></tr>
[websvn-endlisting]
</table>
</td>
</tr>
</table>
[websvn-else]
<table border=0 cellspacing=0 cellpadding=0 align="center">
<tr>
<td align="center">
<br><h2>[lang:PROJECTS]:</h2>
<table border=0>
<tr><td>
[websvn-startlisting]
[websvn-test:isprojlink]
<div>[websvn:listitem]</div>
[websvn-else]
[websvn:listitem]
[websvn-endtest]
[websvn-endlisting]
</td></tr>
</table>
</td>
</tr>
</table>
[websvn-test:flatview]
<table border=0 cellspacing=0 cellpadding=0 align="center">
<tr>
<td align="center">
<br><h1>[lang:PROJECTS]:</h1>
<p><hr><p>
<table width="100%" class="outlined" cellpadding="2">
[websvn-startlisting]
<tr><td>[websvn:projlink]</td></tr>
[websvn-endlisting]
</table>
</td>
</tr>
</table>
[websvn-else]
<table border=0 cellspacing=0 cellpadding=0 align="center">
<tr>
<td align="center">
<br><h2>[lang:PROJECTS]:</h2>
<table border=0>
<tr><td>
[websvn-startlisting]
[websvn-test:isprojlink]
<div>[websvn:listitem]</div>
[websvn-else]
[websvn:listitem]
[websvn-endtest]
[websvn-endlisting]
</td></tr>
</table>
</td>
</tr>
</table>
[websvn-endtest]
/WebSVN/templates/Zinn/log.tmpl
1,74 → 1,74
<table width="100%" border="0">
<tr>
<td>
<h1>[websvn:repname]</h1>
</td>
<td>
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
</td>
</tr>
</table>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
<b>[lang:PATH]:</b> [websvn:path]
<br><b>[lang:REV]:</b> [websvn:rev]
<p><hr>
<b>[lang:CURDIR]:</b> [websvn:curdirlinks]<br><br>
[websvn-test:goyoungestlink]
[websvn:goyoungestlink]<p>
[websvn-endtest]
<center>
[websvn:logsearch_form]
<b>[lang:FILTER]</b><p>
[lang:STARTLOG]:[websvn:logsearch_startbox] [lang:ENDLOG]:[websvn:logsearch_endbox] [lang:MAXLOG]:[websvn:logsearch_maxbox] [lang:SEARCHLOG]:[websvn:logsearch_inputbox]
[websvn:logsearch_submit]
[websvn-test:logsearch_clearloglink]
<p><font size="-1">[websvn:logsearch_clearloglink]</font><p>
[websvn-endtest]
[websvn:logsearch_endform]
</center>
[websvn-test:logsearch_nomatches]
<center>[lang:NORESULTS]</center>
[websvn-endtest]
[websvn-test:error]
<center>[websvn:error]</center>
[websvn-endtest]
 
[websvn-test:logsearch_resultsfound]
[websvn:compare_form]
<table border=1 class="outlined" width="100%" cellpadding=2>
<tr>
<th>[lang:REV]</th>
<th>[lang:PATH]</th>
<th>[lang:AUTHOR]</th>
<th>[lang:AGE]</th>
<th>[lang:LOGMSG]</th>
</tr>
[websvn-startlisting]
<tr>
<td valign="top" class="[websvn:rowparity]"><nobr>[websvn:compare_box][websvn:revlink]</nobr></td>
<td valign="top" class="[websvn:rowparity]">[websvn:revpathlink]</td>
<td valign="top" class="[websvn:rowparity]">[websvn:revauthor]</td>
<td valign="top" class="[websvn:rowparity]">[websvn:revage]</td>
<td valign="top" class="[websvn:rowparity]">[websvn:revlog]</td>
</tr>
[websvn-endlisting]
</table>
<p>
[websvn:compare_submit]
[websvn:compare_endform]
[websvn-endtest]
[websvn-test:logsearch_nomorematches]
<p><center>[lang:NOMORERESULTS]</center>
[websvn-endtest]
<p><center>[websvn:logsearch_moreresultslink]</center>
<p><center>[websvn:pagelinks]<p>[websvn:showalllink]</center>
<table width="100%" border="0">
<tr>
<td>
<h1>[websvn:repname]</h1>
</td>
<td>
<div align="right">[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div>
</td>
</tr>
</table>
 
[websvn-test:noaccess]
[lang:NOACCESS]
[websvn-else]
<b>[lang:PATH]:</b> [websvn:path]
<br><b>[lang:REV]:</b> [websvn:rev]
<p><hr>
<b>[lang:CURDIR]:</b> [websvn:curdirlinks]<br><br>
[websvn-test:goyoungestlink]
[websvn:goyoungestlink]<p>
[websvn-endtest]
<center>
[websvn:logsearch_form]
<b>[lang:FILTER]</b><p>
[lang:STARTLOG]:[websvn:logsearch_startbox] [lang:ENDLOG]:[websvn:logsearch_endbox] [lang:MAXLOG]:[websvn:logsearch_maxbox] [lang:SEARCHLOG]:[websvn:logsearch_inputbox]
[websvn:logsearch_submit]
[websvn-test:logsearch_clearloglink]
<p><font size="-1">[websvn:logsearch_clearloglink]</font><p>
[websvn-endtest]
[websvn:logsearch_endform]
</center>
[websvn-test:logsearch_nomatches]
<center>[lang:NORESULTS]</center>
[websvn-endtest]
[websvn-test:error]
<center>[websvn:error]</center>
[websvn-endtest]
 
[websvn-test:logsearch_resultsfound]
[websvn:compare_form]
<table border=1 class="outlined" width="100%" cellpadding=2>
<tr>
<th>[lang:REV]</th>
<th>[lang:PATH]</th>
<th>[lang:AUTHOR]</th>
<th>[lang:AGE]</th>
<th>[lang:LOGMSG]</th>
</tr>
[websvn-startlisting]
<tr>
<td valign="top" class="[websvn:rowparity]"><nobr>[websvn:compare_box][websvn:revlink]</nobr></td>
<td valign="top" class="[websvn:rowparity]">[websvn:revpathlink]</td>
<td valign="top" class="[websvn:rowparity]">[websvn:revauthor]</td>
<td valign="top" class="[websvn:rowparity]">[websvn:revage]</td>
<td valign="top" class="[websvn:rowparity]">[websvn:revlog]</td>
</tr>
[websvn-endlisting]
</table>
<p>
[websvn:compare_submit]
[websvn:compare_endform]
[websvn-endtest]
[websvn-test:logsearch_nomorematches]
<p><center>[lang:NOMORERESULTS]</center>
[websvn-endtest]
<p><center>[websvn:logsearch_moreresultslink]</center>
<p><center>[websvn:pagelinks]<p>[websvn:showalllink]</center>
[websvn-endtest]
/WebSVN/templates/Zinn/styles.css
1,107 → 1,107
 
body
{
font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
background-color: white;
margin: 20px;
padding: 0px;
font-size: 76%;
}
 
H1
{
color: #8c0000;
font-size: 30px;
font-weight: normal;
font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
text-decoration: none;
}
 
a:link { color: black;
font-size: 76%;
}
a:visited { color: black;
font-size: 76%;
}
 
HR { color: #8c0000; background-color: #8c0000 }
 
.highlight { color: #8c0000; font-style: italic; }
 
TABLE.bordered, TABLE.outlined, TABLE.blame
{
border-collapse: collapse;
border: solid 2px #8c0000;
}
 
.bordered TD, .bordered TH
{
border: solid 2px #8c0000;
}
 
.outlined TH, .blame TH
{
padding: 5px 5px 5px 5px;
font-weight: bold;
border: solid 2px #8c0000;
}
 
.outlined TD, .blame TD
{
padding: 1px 5px 1px 5px;
border-right: solid 2px #8c0000;
border-bottom: solid 1px #F0F0F0;
}
 
.blame TD
{
font-size: 11px;
}
 
.blame TD A
{
font-size: 100%;
}
 
TD.diffdeleted
{
font-size: 11px;
background-color: red;
}
 
TD.diffchanged
{
font-size: 11px;
background-color: yellow;
}
 
TD.diffadded
{
font-size: 11px;
background-color: green;
}
 
TD.diff
{
font-size: 11px;
background-color: #D0D0D0;
}
 
TABLE.diff
{
border-collapse: collapse;
}
 
DIV.newpath
{
padding: 5px 5px 5px 5px;
border: solid 2px #8c0000;
}
 
.plusbox { float: left; clear: both; position: relative; top: -3px; font-size: 13px; font-weight: bold; width: 16px; text-indent: 0; height: 16px; color: black; text-align: center; padding: 0px 2px 0px 3px; border: black solid 1px; margin-right: 5px; }
.minusbox { float: left; clear: both; position: relative; top: -3px; font-size: 13px; font-weight: bold; width: 16px; text-indent: 0; height: 16px; color: black; background-color: #8c0000; text-align: center; padding: 0px 2px 0px 3px; border: black solid 1px; margin-right: 5px; }
 
.groupname { padding-left: 0px; text-indent: -25px; margin: 8px 0 3px 0;}
.switchcontent { margin: 3px 0 0 20px; }
 
code { white-space: pre-wrap; }
 
body
{
font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
background-color: white;
margin: 20px;
padding: 0px;
font-size: 76%;
}
 
H1
{
color: #8c0000;
font-size: 30px;
font-weight: normal;
font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
text-decoration: none;
}
 
a:link { color: black;
font-size: 76%;
}
a:visited { color: black;
font-size: 76%;
}
 
HR { color: #8c0000; background-color: #8c0000 }
 
.highlight { color: #8c0000; font-style: italic; }
 
TABLE.bordered, TABLE.outlined, TABLE.blame
{
border-collapse: collapse;
border: solid 2px #8c0000;
}
 
.bordered TD, .bordered TH
{
border: solid 2px #8c0000;
}
 
.outlined TH, .blame TH
{
padding: 5px 5px 5px 5px;
font-weight: bold;
border: solid 2px #8c0000;
}
 
.outlined TD, .blame TD
{
padding: 1px 5px 1px 5px;
border-right: solid 2px #8c0000;
border-bottom: solid 1px #F0F0F0;
}
 
.blame TD
{
font-size: 11px;
}
 
.blame TD A
{
font-size: 100%;
}
 
TD.diffdeleted
{
font-size: 11px;
background-color: red;
}
 
TD.diffchanged
{
font-size: 11px;
background-color: yellow;
}
 
TD.diffadded
{
font-size: 11px;
background-color: green;
}
 
TD.diff
{
font-size: 11px;
background-color: #D0D0D0;
}
 
TABLE.diff
{
border-collapse: collapse;
}
 
DIV.newpath
{
padding: 5px 5px 5px 5px;
border: solid 2px #8c0000;
}
 
.plusbox { float: left; clear: both; position: relative; top: -3px; font-size: 13px; font-weight: bold; width: 16px; text-indent: 0; height: 16px; color: black; text-align: center; padding: 0px 2px 0px 3px; border: black solid 1px; margin-right: 5px; }
.minusbox { float: left; clear: both; position: relative; top: -3px; font-size: 13px; font-weight: bold; width: 16px; text-indent: 0; height: 16px; color: black; background-color: #8c0000; text-align: center; padding: 0px 2px 0px 3px; border: black solid 1px; margin-right: 5px; }
 
.groupname { padding-left: 0px; text-indent: -25px; margin: 8px 0 3px 0;}
.switchcontent { margin: 3px 0 0 20px; }
 
code { white-space: pre-wrap; }
/WebSVN/listing.php
1,421 → 1,422
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// listing.php
//
// Show the listing for the given repository/path/revision
 
require_once("include/setup.inc");
require_once("include/svnlook.inc");
require_once("include/utils.inc");
require_once("include/template.inc");
require_once("include/bugtraq.inc");
 
function removeURLSeparator($url)
{
return preg_replace('#(\?|&(amp;)?)$#', '', $url);
}
 
function fileLink($path, $file, $returnjoin = false)
{
global $rep, $passrev, $showchanged, $config;
if ($path == "" || $path{0} != "/")
$ppath = "/".$path;
else
$ppath = $path;
 
if ($ppath{strlen($ppath)-1} != "/")
$ppath .= "/";
if ($file{0} == "/")
$pfile = substr($file, 1);
else
$pfile = $file;
 
if ($returnjoin)
return $ppath.$pfile;
 
$isDir = $pfile{strlen($pfile) - 1} == "/";
if ($passrev) $passrevstr = "rev=$passrev&amp;"; else $passrevstr = "";
if ($showchanged) $showchangedstr = "sc=$showchanged"; else $showchangedstr = "";
 
if ($isDir)
{
$url = $config->getURL($rep, $ppath.$pfile, "dir");
 
// XHTML doesn't allow slashes in IDs ~J
$id = str_replace('/', '_', $ppath.$pfile);
$url = "<a id='$id' href=\"${url}$passrevstr$showchangedstr";
 
$url = removeURLSeparator($url);
if ($config->treeView) $url .= "#$id";
$url .= "\">$pfile</a>";
}
else
{
$url = $config->getURL($rep, $ppath.$pfile, "file");
$url .= $passrevstr.$showchangedstr;
$url = removeURLSeparator($url);
$url = "<a href=\"${url}\">$pfile</a>";
}
 
return $url;
}
 
function showDirFiles($svnrep, $subs, $level, $limit, $rev, $listing, $index, $treeview = true)
{
global $rep, $passrev, $showchanged, $config, $lang;
 
$path = "";
 
if (!$treeview)
$level = $limit;
 
for ($n = 0; $n <= $level; $n++)
{
$path .= $subs[$n]."/";
}
 
$contents = $svnrep->dirContents($path, $rev);
 
// List each file in the current directory
$loop = 0;
$last_index = 0;
$openDir = false;
$fullaccess = $rep->hasReadAccess($path, false);
foreach($contents as $file)
{
$isDir = ($file{strlen($file) - 1} == "/"?1:0);
$access = false;
 
if ($isDir)
{
if ($rep->hasReadAccess($path.$file, true))
{
$access = true;
$openDir = (!strcmp($subs[$level+1]."/", $file) || !strcmp($subs[$level+1], $file));
if ($openDir)
$listing[$index]["filetype"] = "diropen";
else
$listing[$index]["filetype"] = "dir";
 
if ($rep->isDownloadAllowed($path.$file))
{
$dlurl = $config->getURL($rep, $path.$file, "dl");
$listing[$index]["fileviewdllink"] = "<a href=\"${dlurl}rev=$passrev&amp;isdir=1\">${lang["TARBALL"]}</a>";
}
else
$listing[$index]["fileviewdllink"] = "&nbsp;";
}
}
else
{
if ($fullaccess)
{
$access = true;
if ($level != $limit)
{
// List directories only, skip all files
continue;
}
$listing[$index]["fileviewdllink"] = "&nbsp;";
$listing[$index]["filetype"] = strrchr($file, ".");
}
}
if ($access)
{
$listing[$index]["rowparity"] = ($index % 2)?"1":"0";
if ($treeview)
$listing[$index]["compare_box"] = "<input type=\"checkbox\" name=\"compare[]\" value=\"".fileLink($path, $file, true)."@$passrev\" onclick=\"checkCB(this)\" />";
else
$listing[$index]["compare_box"] = "";
if ($openDir)
$listing[$index]["filelink"] = "<b>".fileLink($path, $file)."</b>";
else
$listing[$index]["filelink"] = fileLink($path, $file);
// The history command doesn't return with a trailing slash. We need to remember here if the
// file is a directory or not!
$listing[$index]["isDir"] = $isDir;
if ($treeview)
$listing[$index]["level"] = $level;
else
$listing[$index]["level"] = 0;
 
$listing[$index]["node"] = 0; // t-node
$fileurl = $config->getURL($rep, $path.$file, "log");
$listing[$index]["fileviewloglink"] = "<a href=\"${fileurl}rev=$passrev&amp;sc=$showchanged&amp;isdir=$isDir\">${lang["VIEWLOG"]}</a>";
$rssurl = $config->getURL($rep, $path.$file, "rss");
if ($rep->getHideRss())
{
$listing[$index]["rsslink"] = "<a href=\"${rssurl}rev=$passrev&amp;sc=$showchanged&amp;isdir=$isDir\">${lang["RSSFEED"]}</a>";
$listing[$index]["rssanchor"] = "<a href=\"${rssurl}rev=$passrev&amp;sc=$showchanged&amp;isdir=$isDir\">";
}
$index++;
$loop++;
$last_index = $index;
if (($level != $limit) && ($isDir))
{
if (!strcmp($subs[$level + 1]."/", $file))
{
$listing = showDirFiles($svnrep, $subs, $level + 1, $limit, $rev, $listing, $index);
$index = count($listing);
}
}
 
}
}
 
if ($last_index != 0 && $treeview)
{
$listing[$last_index - 1]["node"] = 1; // l-node
}
 
return $listing;
}
 
function showTreeDir($svnrep, $path, $rev, $listing)
{
global $vars, $config;
 
$subs = explode("/", $path);
 
// For directory, the last element in the subs is empty.
// For file, the last element in the subs is the file name.
// Therefore, it is always count($subs) - 2
$limit = count($subs) - 2;
 
for ($n = 0; $n < $limit; $n++)
{
$vars["last_i_node"][$n] = FALSE;
}
 
return showDirFiles($svnrep, $subs, 0, $limit, $rev, $listing, 0, $config->treeView);
 
}
 
// Make sure that we have a repository
if (!isset($rep))
{
echo $lang["NOREP"];
exit;
}
 
$svnrep = new SVNRepository($rep);
 
// Revision info to pass along chain
$passrev = $rev;
 
// Get the directory contents of the given revision, or HEAD if not defined
$contents = $svnrep->dirContents($path, @$rev);
 
// If there's no revision info, go to the lastest revision for this path
$history = $svnrep->getLog($path, "", "", false);
 
if (!empty($history->entries[0]))
$youngest = $history->entries[0]->rev;
else
$youngest = -1;
 
// Unless otherwise specified, we get the log details of the latest change
if (empty($rev))
$logrev = $youngest;
else
$logrev = $rev;
 
if ($logrev != $youngest)
{
$logEntry = $svnrep->getLog($path, $logrev, $logrev, false);
$logEntry = $logEntry->entries[0];
}
else
$logEntry = $history->entries[0];
 
$headlog = $svnrep->getLog("/", "", "", true, 1);
$headrev = $headlog->entries[0]->rev;
 
// If we're not looking at a specific revision, get the HEAD revision number
// (the revision of the rest of the tree display)
 
if (empty($rev))
{
$rev = $headrev;
}
 
if ($path == "" || $path{0} != "/")
$ppath = "/".$path;
else
$ppath = $path;
 
$vars["repname"] = $rep->getDisplayName();
 
$dirurl = $config->getURL($rep, $path, "dir");
$logurl = $config->getURL($rep, $path, "log");
$rssurl = $config->getURL($rep, $path, "rss");
$dlurl = $config->getURL($rep, $path, "dl");
$compurl = $config->getURL($rep, "/", "comp");
 
if ($passrev != 0 && $passrev != $headrev && $youngest != -1)
$vars["goyoungestlink"] = "<a href=\"${dirurl}opt=dir&amp;sc=1\">${lang["GOYOUNGEST"]}</a>";
else
$vars["goyoungestlink"] = "";
 
$bugtraq = new Bugtraq($rep, $svnrep, $ppath);
 
$vars["action"] = "";
$vars["rev"] = $rev;
$vars["path"] = $ppath;
$vars["lastchangedrev"] = $logrev;
$vars["date"] = $logEntry->date;
$vars["author"] = $logEntry->author;
$vars["log"] = nl2br($bugtraq->replaceIDs(create_anchors($logEntry->msg)));
 
if (!$showchanged)
{
$vars["showchangeslink"] = "<a href=\"${dirurl}rev=$passrev&amp;sc=1\">${lang["SHOWCHANGED"]}</a>";
$vars["hidechangeslink"] = "";
 
$vars["hidechanges"] = true;
$vars["showchanges"] = false;
}
else
{
$vars["showchangeslink"] = "";
$changes = $logEntry->mods;
$firstAdded = true;
$firstModded = true;
$firstDeleted = true;
 
$vars["newfilesbr"] = "";
$vars["newfiles"] = "";
$vars["changedfilesbr"] = "";
$vars["changedfiles"] = "";
$vars["deletedfilesbr"] = "";
$vars["deletedfiles"] = "";
 
foreach ($changes as $file)
{
switch ($file->action)
{
case "A":
if (!$firstAdded) $vars["newfilesbr"] .= "<br />";
$firstAdded = false;
$vars["newfilesbr"] .= fileLink("", $file->path);
$vars["newfiles"] .= " ".fileLink("", $file->path);
break;
case "M":
if (!$firstModded) $vars["changedfilesbr"] .= "<br />";
$firstModded = false;
$vars["changedfilesbr"] .= fileLink("", $file->path);
$vars["changedfiles"] .= " ".fileLink("", $file->path);
break;
 
case "D":
if (!$firstDeleted) $vars["deletedfilesbr"] .= "<br />";
$firstDeleted = false;
$vars["deletedfilesbr"] .= $file->path;
$vars["deletedfiles"] .= " ".$file->path;
break;
}
}
$vars["hidechangeslink"] = "<a href=\"${dirurl}rev=$passrev&amp;sc=0\">${lang["HIDECHANGED"]}</a>";
$vars["hidechanges"] = false;
$vars["showchanges"] = true;
}
 
createDirLinks($rep, $ppath, $passrev, $showchanged);
$vars["curdirloglink"] = "<a href=\"${logurl}rev=$passrev&amp;sc=$showchanged&amp;isdir=1\">${lang["VIEWLOG"]}</a>";
 
if ($rev != $headrev)
{
$history = $svnrep->getLog($path, $rev, "", false);
}
 
if (isset($history->entries[1]->rev))
{
$vars["curdircomplink"] = "<a href=\"${compurl}compare[]=".
urlencode($history->entries[1]->path)."@".$history->entries[1]->rev.
"&amp;compare[]=".urlencode($history->entries[0]->path)."@".$history->entries[0]->rev.
"\">${lang["DIFFPREV"]}</a>";
}
else
{
$vars["curdircomplink"] = "";
}
 
if ($rep->getHideRss())
{
$vars["curdirrsslink"] = "<a href=\"${rssurl}rev=$passrev&amp;sc=$showchanged&amp;isdir=1\">${lang["RSSFEED"]}</a>";
$vars["curdirrsshref"] = "${rssurl}rev=$passrev&amp;sc=$showchanged&amp;isdir=1";
$vars["curdirrssanchor"] = "<a href=\"${rssurl}rev=$passrev&amp;sc=$showchanged&amp;isdir=1\">";
}
 
// Set up the tarball link
 
$subs = explode("/", $path);
$level = count($subs) - 2;
if ($rep->isDownloadAllowed($path))
$vars["curdirdllink"] = "<a href=\"${dlurl}rev=$passrev&amp;isdir=1\">${lang["TARBALL"]}</a>";
else
$vars["curdirdllink"] = "";
$url = $config->getURL($rep, "/", "comp");
 
$vars["compare_form"] = "<form action=\"$url\" method=\"post\" name=\"compareform\">";
$vars["compare_submit"] = "<input name=\"comparesubmit\" type=\"submit\" value=\"${lang["COMPAREPATHS"]}\" />";
$vars["compare_endform"] = "<input type=\"hidden\" name=\"op\" value=\"comp\" /><input type=\"hidden\" name=\"sc\" value=\"$showchanged\" /></form>";
 
$listing = array();
$listing = showTreeDir($svnrep, $path, $rev, $listing);
 
$vars["version"] = $version;
 
if (!$rep->hasReadAccess($path, true))
$vars["noaccess"] = true;
 
if (!$rep->hasReadAccess($path, false))
$vars["restricted"] = true;
 
parseTemplate($rep->getTemplatePath()."header.tmpl", $vars, $listing);
parseTemplate($rep->getTemplatePath()."directory.tmpl", $vars, $listing);
parseTemplate($rep->getTemplatePath()."footer.tmpl", $vars, $listing);
 
?>
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// listing.php
//
// Show the listing for the given repository/path/revision
 
require_once("include/setup.inc");
require_once("include/svnlook.inc");
require_once("include/utils.inc");
require_once("include/template.inc");
require_once("include/bugtraq.inc");
 
function removeURLSeparator($url)
{
return preg_replace('#(\?|&(amp;)?)$#', '', $url);
}
 
function fileLink($path, $file, $returnjoin = false)
{
global $rep, $passrev, $showchanged, $config;
if ($path == "" || $path{0} != "/")
$ppath = "/".$path;
else
$ppath = $path;
 
if ($ppath{strlen($ppath)-1} != "/")
$ppath .= "/";
if ($file{0} == "/")
$pfile = substr($file, 1);
else
$pfile = $file;
//$pfile = rawurldecode($pfile);
 
if ($returnjoin)
return $ppath.$pfile;
 
$isDir = $pfile{strlen($pfile) - 1} == "/";
if ($passrev) $passrevstr = "rev=$passrev&amp;"; else $passrevstr = "";
if ($showchanged) $showchangedstr = "sc=$showchanged"; else $showchangedstr = "";
 
if ($isDir)
{
$url = $config->getURL($rep, $ppath.$pfile, "dir");
 
// XHTML doesn't allow slashes in IDs ~J
$id = str_replace('/', '_', $ppath.$pfile);
$url = "<a id='$id' href=\"${url}$passrevstr$showchangedstr";
 
$url = removeURLSeparator($url);
if ($config->treeView) $url .= "#$id";
$url .= "\">$pfile</a>";
}
else
{
$url = $config->getURL($rep, $ppath.$pfile, "file");
$url .= $passrevstr.$showchangedstr;
$url = removeURLSeparator($url);
$url = "<a href=\"${url}\">$pfile</a>";
}
 
return $url;
}
 
function showDirFiles($svnrep, $subs, $level, $limit, $rev, $listing, $index, $treeview = true)
{
global $rep, $passrev, $showchanged, $config, $lang;
 
$path = "";
 
if (!$treeview)
$level = $limit;
 
for ($n = 0; $n <= $level; $n++)
{
$path .= $subs[$n]."/";
}
 
$contents = $svnrep->dirContents($path, $rev);
 
// List each file in the current directory
$loop = 0;
$last_index = 0;
$openDir = false;
$fullaccess = $rep->hasReadAccess($path, false);
foreach($contents as $file)
{
$isDir = ($file{strlen($file) - 1} == "/"?1:0);
$access = false;
 
if ($isDir)
{
if ($rep->hasReadAccess($path.$file, true))
{
$access = true;
$openDir = (!strcmp($subs[$level+1]."/", $file) || !strcmp($subs[$level+1], $file));
if ($openDir)
$listing[$index]["filetype"] = "diropen";
else
$listing[$index]["filetype"] = "dir";
 
if ($rep->isDownloadAllowed($path.$file))
{
$dlurl = $config->getURL($rep, $path.$file, "dl");
$listing[$index]["fileviewdllink"] = "<a href=\"${dlurl}rev=$passrev&amp;isdir=1\">${lang["TARBALL"]}</a>";
}
else
$listing[$index]["fileviewdllink"] = "&nbsp;";
}
}
else
{
if ($fullaccess)
{
$access = true;
if ($level != $limit)
{
// List directories only, skip all files
continue;
}
$listing[$index]["fileviewdllink"] = "&nbsp;";
$listing[$index]["filetype"] = strrchr($file, ".");
}
}
if ($access)
{
$listing[$index]["rowparity"] = ($index % 2)?"1":"0";
if ($treeview)
$listing[$index]["compare_box"] = "<input type=\"checkbox\" name=\"compare[]\" value=\"".fileLink($path, $file, true)."@$passrev\" onclick=\"checkCB(this)\" />";
else
$listing[$index]["compare_box"] = "";
if ($openDir)
$listing[$index]["filelink"] = "<b>".fileLink($path, $file)."</b>";
else
$listing[$index]["filelink"] = fileLink($path, $file);
// The history command doesn't return with a trailing slash. We need to remember here if the
// file is a directory or not!
$listing[$index]["isDir"] = $isDir;
if ($treeview)
$listing[$index]["level"] = $level;
else
$listing[$index]["level"] = 0;
 
$listing[$index]["node"] = 0; // t-node
$fileurl = $config->getURL($rep, $path.$file, "log");
$listing[$index]["fileviewloglink"] = "<a href=\"${fileurl}rev=$passrev&amp;sc=$showchanged&amp;isdir=$isDir\">${lang["VIEWLOG"]}</a>";
$rssurl = $config->getURL($rep, $path.$file, "rss");
if ($rep->getHideRss())
{
$listing[$index]["rsslink"] = "<a href=\"${rssurl}rev=$passrev&amp;sc=$showchanged&amp;isdir=$isDir\">${lang["RSSFEED"]}</a>";
$listing[$index]["rssanchor"] = "<a href=\"${rssurl}rev=$passrev&amp;sc=$showchanged&amp;isdir=$isDir\">";
}
$index++;
$loop++;
$last_index = $index;
if (($level != $limit) && ($isDir))
{
if (!strcmp($subs[$level + 1]."/", $file))
{
$listing = showDirFiles($svnrep, $subs, $level + 1, $limit, $rev, $listing, $index);
$index = count($listing);
}
}
 
}
}
 
if ($last_index != 0 && $treeview)
{
$listing[$last_index - 1]["node"] = 1; // l-node
}
 
return $listing;
}
 
function showTreeDir($svnrep, $path, $rev, $listing)
{
global $vars, $config;
 
$subs = explode("/", $path);
 
// For directory, the last element in the subs is empty.
// For file, the last element in the subs is the file name.
// Therefore, it is always count($subs) - 2
$limit = count($subs) - 2;
 
for ($n = 0; $n < $limit; $n++)
{
$vars["last_i_node"][$n] = FALSE;
}
 
return showDirFiles($svnrep, $subs, 0, $limit, $rev, $listing, 0, $config->treeView);
 
}
 
// Make sure that we have a repository
if (!isset($rep))
{
echo $lang["NOREP"];
exit;
}
 
$svnrep = new SVNRepository($rep);
 
// Revision info to pass along chain
$passrev = $rev;
 
// Get the directory contents of the given revision, or HEAD if not defined
$contents = $svnrep->dirContents($path, @$rev);
 
// If there's no revision info, go to the lastest revision for this path
$history = $svnrep->getLog($path, "", "", false);
 
if (!empty($history->entries[0]))
$youngest = $history->entries[0]->rev;
else
$youngest = -1;
 
// Unless otherwise specified, we get the log details of the latest change
if (empty($rev))
$logrev = $youngest;
else
$logrev = $rev;
 
if ($logrev != $youngest)
{
$logEntry = $svnrep->getLog($path, $logrev, $logrev, false);
$logEntry = $logEntry->entries[0];
}
else
$logEntry = $history->entries[0];
 
$headlog = $svnrep->getLog("/", "", "", true, 1);
$headrev = $headlog->entries[0]->rev;
 
// If we're not looking at a specific revision, get the HEAD revision number
// (the revision of the rest of the tree display)
 
if (empty($rev))
{
$rev = $headrev;
}
 
if ($path == "" || $path{0} != "/")
$ppath = "/".$path;
else
$ppath = $path;
 
$vars["repname"] = $rep->getDisplayName();
 
$dirurl = $config->getURL($rep, $path, "dir");
$logurl = $config->getURL($rep, $path, "log");
$rssurl = $config->getURL($rep, $path, "rss");
$dlurl = $config->getURL($rep, $path, "dl");
$compurl = $config->getURL($rep, "/", "comp");
 
if ($passrev != 0 && $passrev != $headrev && $youngest != -1)
$vars["goyoungestlink"] = "<a href=\"${dirurl}opt=dir&amp;sc=1\">${lang["GOYOUNGEST"]}</a>";
else
$vars["goyoungestlink"] = "";
 
$bugtraq = new Bugtraq($rep, $svnrep, $ppath);
 
$vars["action"] = "";
$vars["rev"] = $rev;
$vars["path"] = $ppath;
$vars["lastchangedrev"] = $logrev;
$vars["date"] = $logEntry->date;
$vars["author"] = $logEntry->author;
$vars["log"] = nl2br($bugtraq->replaceIDs(create_anchors($logEntry->msg)));
 
if (!$showchanged)
{
$vars["showchangeslink"] = "<a href=\"${dirurl}rev=$passrev&amp;sc=1\">${lang["SHOWCHANGED"]}</a>";
$vars["hidechangeslink"] = "";
 
$vars["hidechanges"] = true;
$vars["showchanges"] = false;
}
else
{
$vars["showchangeslink"] = "";
$changes = $logEntry->mods;
$firstAdded = true;
$firstModded = true;
$firstDeleted = true;
 
$vars["newfilesbr"] = "";
$vars["newfiles"] = "";
$vars["changedfilesbr"] = "";
$vars["changedfiles"] = "";
$vars["deletedfilesbr"] = "";
$vars["deletedfiles"] = "";
 
foreach ($changes as $file)
{
switch ($file->action)
{
case "A":
if (!$firstAdded) $vars["newfilesbr"] .= "<br />";
$firstAdded = false;
$vars["newfilesbr"] .= fileLink("", $file->path);
$vars["newfiles"] .= " ".fileLink("", $file->path);
break;
case "M":
if (!$firstModded) $vars["changedfilesbr"] .= "<br />";
$firstModded = false;
$vars["changedfilesbr"] .= fileLink("", $file->path);
$vars["changedfiles"] .= " ".fileLink("", $file->path);
break;
 
case "D":
if (!$firstDeleted) $vars["deletedfilesbr"] .= "<br />";
$firstDeleted = false;
$vars["deletedfilesbr"] .= $file->path;
$vars["deletedfiles"] .= " ".$file->path;
break;
}
}
$vars["hidechangeslink"] = "<a href=\"${dirurl}rev=$passrev&amp;sc=0\">${lang["HIDECHANGED"]}</a>";
$vars["hidechanges"] = false;
$vars["showchanges"] = true;
}
 
createDirLinks($rep, $ppath, $passrev, $showchanged);
$vars["curdirloglink"] = "<a href=\"${logurl}rev=$passrev&amp;sc=$showchanged&amp;isdir=1\">${lang["VIEWLOG"]}</a>";
 
if ($rev != $headrev)
{
$history = $svnrep->getLog($path, $rev, "", false);
}
 
if (isset($history->entries[1]->rev))
{
$vars["curdircomplink"] = "<a href=\"${compurl}compare%5B%5D=".
urlencode($history->entries[1]->path)."@".$history->entries[1]->rev.
"&amp;compare%5B%5D=".urlencode($history->entries[0]->path)."@".$history->entries[0]->rev.
"\">${lang["DIFFPREV"]}</a>";
}
else
{
$vars["curdircomplink"] = "";
}
 
if ($rep->getHideRss())
{
$vars["curdirrsslink"] = "<a href=\"${rssurl}rev=$passrev&amp;sc=$showchanged&amp;isdir=1\">${lang["RSSFEED"]}</a>";
$vars["curdirrsshref"] = "${rssurl}rev=$passrev&amp;sc=$showchanged&amp;isdir=1";
$vars["curdirrssanchor"] = "<a href=\"${rssurl}rev=$passrev&amp;sc=$showchanged&amp;isdir=1\">";
}
 
// Set up the tarball link
 
$subs = explode("/", $path);
$level = count($subs) - 2;
if ($rep->isDownloadAllowed($path))
$vars["curdirdllink"] = "<a href=\"${dlurl}rev=$passrev&amp;isdir=1\">${lang["TARBALL"]}</a>";
else
$vars["curdirdllink"] = "";
$url = $config->getURL($rep, "/", "comp");
 
$vars["compare_form"] = "<form action=\"$url\" method=\"post\" name=\"compareform\">";
$vars["compare_submit"] = "<input name=\"comparesubmit\" type=\"submit\" value=\"${lang["COMPAREPATHS"]}\" />";
$vars["compare_endform"] = "<input type=\"hidden\" name=\"op\" value=\"comp\" /><input type=\"hidden\" name=\"sc\" value=\"$showchanged\" /></form>";
 
$listing = array();
$listing = showTreeDir($svnrep, $path, $rev, $listing);
 
$vars["version"] = $version;
 
if (!$rep->hasReadAccess($path, true))
$vars["noaccess"] = true;
 
if (!$rep->hasReadAccess($path, false))
$vars["restricted"] = true;
 
parseTemplate($rep->getTemplatePath()."header.tmpl", $vars, $listing);
parseTemplate($rep->getTemplatePath()."directory.tmpl", $vars, $listing);
parseTemplate($rep->getTemplatePath()."footer.tmpl", $vars, $listing);
 
?>
/WebSVN/blame.php
1,131 → 1,131
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// blame.php
//
// Show the blame information of a file.
//
 
require_once 'include/setup.inc';
require_once 'include/svnlook.inc';
require_once 'include/utils.inc';
require_once 'include/template.inc';
 
$vars['action'] = $lang['BLAME'];
 
$svnrep = new SVNRepository($rep);
 
// If there's no revision info, go to the lastest revision for this path
$history = $svnrep->getLog($path, '', '', true);
$youngest = $history->entries[0]->rev;
 
if (empty($rev))
$rev = $youngest;
 
if ($path{0} != '/')
$ppath = '/'.$path;
else
$ppath = $path;
 
// Find the parent path (or the whole path if it's already a directory)
$pos = strrpos($ppath, '/');
$parent = substr($ppath, 0, $pos + 1);
 
$vars['repname'] = $rep->getDisplayName();
$vars['rev'] = $rev;
$vars['path'] = $ppath;
 
createDirLinks($rep, $ppath, $rev, $showchanged);
 
$listing = array();
 
// Get the contents of the file
$tfname = tempnam('temp', '');
$svnrep->getFileContents($path, $tfname, $rev, '', true);
 
$filecache = array();
 
if ($file = fopen($tfname, 'r'))
{
// Get the blame info
$tbname = tempnam('temp', '');
$svnrep->getBlameDetails($path, $tbname, $rev);
$ent = true;
$extension = strrchr(basename($path), '.');
if (($extension && isset($extEnscript[$extension]) && ('php' == $extEnscript[$extension])) || ($config->useEnscript))
$ent = false;
 
if ($blame = fopen($tbname, 'r'))
{
// Create an array of version/author/line
$index = 0;
while (!feof($blame) && !feof($file))
{
$blameline = fgets($blame);
if ($blameline != '')
{
list($revision, $author) = sscanf($blameline, '%d %s');
$listing[$index]['lineno'] = $index + 1;
$url = $config->getURL($rep, $parent, 'dir');
$listing[$index]['revision'] = "<a href=\"${url}rev=$revision&amp;sc=1\">$revision</a>";
 
$listing[$index]['author'] = $author;
if ($ent)
$line = replaceEntities(rtrim(fgets($file)), $rep);
else
$line = rtrim(fgets($file));
 
$listing[$index]['line'] = hardspace($line);
if (trim($listing[$index]['line']) == '')
$listing[$index]['line'] = '&nbsp;';
$index++;
}
}
fclose($blame);
}
fclose($file);
}
 
unlink($tfname);
unlink($tbname);
 
$vars['version'] = $version;
 
if (!$rep->hasReadAccess($path, false))
$vars['noaccess'] = true;
 
parseTemplate($rep->getTemplatePath().'header.tmpl', $vars, $listing);
parseTemplate($rep->getTemplatePath().'blame.tmpl', $vars, $listing);
parseTemplate($rep->getTemplatePath().'footer.tmpl', $vars, $listing);
?>
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// blame.php
//
// Show the blame information of a file.
//
 
require_once 'include/setup.inc';
require_once 'include/svnlook.inc';
require_once 'include/utils.inc';
require_once 'include/template.inc';
 
$vars['action'] = $lang['BLAME'];
 
$svnrep = new SVNRepository($rep);
 
// If there's no revision info, go to the lastest revision for this path
$history = $svnrep->getLog($path, '', '', true);
$youngest = $history->entries[0]->rev;
 
if (empty($rev))
$rev = $youngest;
 
if ($path{0} != '/')
$ppath = '/'.$path;
else
$ppath = $path;
 
// Find the parent path (or the whole path if it's already a directory)
$pos = strrpos($ppath, '/');
$parent = substr($ppath, 0, $pos + 1);
 
$vars['repname'] = $rep->getDisplayName();
$vars['rev'] = $rev;
$vars['path'] = $ppath;
 
createDirLinks($rep, $ppath, $rev, $showchanged);
 
$listing = array();
 
// Get the contents of the file
$tfname = tempnam('temp', '');
$svnrep->getFileContents($path, $tfname, $rev, '', true);
 
$filecache = array();
 
if ($file = fopen($tfname, 'r'))
{
// Get the blame info
$tbname = tempnam('temp', '');
$svnrep->getBlameDetails($path, $tbname, $rev);
$ent = true;
$extension = strrchr(basename($path), '.');
if (($extension && isset($extEnscript[$extension]) && ('php' == $extEnscript[$extension])) || ($config->useEnscript))
$ent = false;
 
if ($blame = fopen($tbname, 'r'))
{
// Create an array of version/author/line
$index = 0;
while (!feof($blame) && !feof($file))
{
$blameline = fgets($blame);
if ($blameline != '')
{
list($revision, $author) = sscanf($blameline, '%d %s');
$listing[$index]['lineno'] = $index + 1;
$url = $config->getURL($rep, $parent, 'dir');
$listing[$index]['revision'] = "<a href=\"${url}rev=$revision&amp;sc=1\">$revision</a>";
 
$listing[$index]['author'] = $author;
if ($ent)
$line = replaceEntities(rtrim(fgets($file)), $rep);
else
$line = rtrim(fgets($file));
 
$listing[$index]['line'] = hardspace($line);
if (trim($listing[$index]['line']) == '')
$listing[$index]['line'] = '&nbsp;';
$index++;
}
}
fclose($blame);
}
fclose($file);
}
 
unlink($tfname);
unlink($tbname);
 
$vars['version'] = $version;
 
if (!$rep->hasReadAccess($path, false))
$vars['noaccess'] = true;
 
parseTemplate($rep->getTemplatePath().'header.tmpl', $vars, $listing);
parseTemplate($rep->getTemplatePath().'blame.tmpl', $vars, $listing);
parseTemplate($rep->getTemplatePath().'footer.tmpl', $vars, $listing);
?>
/WebSVN/changes.txt
1,463 → 1,460
2.1 alpha 1
 
* Changed: many cleanups and optimisations.
* Added: more documentation for *.inc files.
* Removed: extraneous bits.
* New: PHP_Compat usage to allow some new PHP5 functionality and remain
backwards-compatible.
* Changed: line endings now use UNIX-style across the board.
 
CHANGES
 
NEW: Template files may now be specified on a per repository basis
NEW: Add RSS 'alternate' <link> elements to the HTML headers in
directory listings. This lets you, for example, easily create a
'live bookmark' in Firefox to monitor commits to a particular SVN path.
NEW: Russian translation.
 
CHANGE: Bugtraq handling has been updated to account for the latest spec.
 
FIX: Syntax highlighting across lines has been fixed (Issue 85)
 
2.00 beta 8
 
CHANGE: Remove path comparison boxes when using the flat view display
CHANGE: Tidy up URLs generated from the listing view (Remove default parameters).
CHANGE: wsvn now selectes either the listing or file view automatically when the op parameter
isn't present. This allows for nicer URLS (eg. /http://example.com/wsvn/repo1/myfile.doc)
FIX: Fix warnings when using an access file that didn't define a groups section
FIX: Fix tarballing of directories with spaces
FIX: Path history information in the log view of a file was incorrect.
 
2.00 beta 7
 
NEW: Projects may now be assigned to groups, to simplify the index view
NEW: The index may be displayed as a collapsable tree of groups
 
CHANGE: The syntax for the per repository configurations has changed. It's now much simpler and
will work on all versions of PHP
 
FIX: Various bug fixes for the access rights module
FIX: Language choice selection with MultiViews enabled didn't work
FIX: Various small bugs introduced during 2.0 development
 
2.00 beta 6
 
Note: the $config->addRepository command now takes a URL and not a filesystem path!
 
NEW: WebSVN can now host remote repositories!
 
FIX: The access rights handling didn't work if you had give a repository a display name
different from it's "real" svn name.
FIX: The deleted file list no longer links to non-existant files!
FIX: Neaten the directory display when the download/compare links aren't available
 
2.00 beta 5
 
NEW: Access rights files can now be specified on a per repository basis
 
CHANGE: Further improvements have been made to character encoding handling. In particular,
it is now possible to specify the encoding of the repository contents separately
from the system encoding. This is the case for windows users, whereby the command
line tools typically returning CP850 encoded strings, whereas the source files are
encoded as iso-8859-1. Now, when displaying text files, WebSVN will convert them
from the content encoding to the output encoding (UTF-8).
 
CHANGE: Update Danish translation
CHANGE: The log display has a "max number of revisions to show" fiter option, which defaults
to 30. This significantly improves performance of the log display.
 
FIX: It wasn't possible to display the contents of a file which had brackets in the name.
FIX: Correct problem with download of tarballs containing special characters
FIX: Improve time display
FIX: Remove non-UTF8 language options from distconfig.inc
FIX: Fix recent bug whereby the log messages would contain unnecessary blank lines
FIX: Access right file section groups without a trailing / are no correctly treated
 
2.00 beta 4
 
NEW: The log display may now be filtered to show a range of revisions
NEW: You can now have control over the specification of directories that can or
cannot be tarball'ed. Tarballing can be turned on only after a certain directory
depth and directories can be allow/disallowed on a per directory/repository basis.
NEW: The user can now choose their language via a drop down box
 
CHANGE: Character encodings are now handled differently. The output encoding is ALWAYS
defined as UTF-8, and the setOutputEncoding option has been removed.
 
FIX: Diff had been broken by 1.70 beta 2
FIX: Download of tarballs is prohibited if the user doesn't have read access to the directory
AND all of its subdirectories
FIX: The character set type is now sent in the HTTP header. No need to hack the Apache config
 
2.00 beta 3
 
NEW: WebSVN may now be configured to display a flat view rather than a tree view
 
FIX: Only use --limit option on svn 1.2 or greater
FIX: Correct spelling of "danish" in distconfig
FIX: Fix RSS, previously broken 1.7 beta 1
 
2.00 beta 2
 
CHANGE: WebSVN no longer requires the entire revision history when accessing a directory,
resulting in a faster access for large repositories
 
FIX: The new access rights module didn't always hide directories
FIX: Tree icons have been fixed (broken in 1.70 beta 1)
 
2.00 beta 1
 
NEW: Access rights module (Finally!) - see install.txt for details
NEW: Added language file for Danish, Finnish, Turkish, Norwegian and Simplified Chinese
NEW: The "View Log" link is now available for templates to use from the file view
NEW: Added bugtraq:logregex support
 
CHANGE: Ages are now displayed with higher resolution
CHANGE: Update German translation
CHANGE: Tex file are no longer delivered as binary by defaut, but displayed by enscript
CHANGE: The last modified files display now shows the most recently modified files of
the current directory
CHANGE: Improve diff colours of Blue Grey Scheme for better readability
CHANGE: WebSVN no longer requires the entire revision history when accessing a directory,
resulting in a faster access for large repositories
 
FIX: Directories containing accents weren't always displayed
FIX: File version can be compared via the log display (as oppoed to just directories)
FIX: Corrected RSS encoding issue
FIX: Corrected bug whereby diff lines would be displayed twice
FIX: svn: Can't check path '/root/.subversion': Permission denied
FIX: Sometimes files delivered (as opposed to disaplyed) by WebSVN were empty
FIX: Fix problem with large tarball delivery
FIX: Compare with previous always used HEAD
FIX: .sh files are now viewable
FIX: Allow special characters in repository names
FIX: It wasn't possible to go into a module if another module starts with the same name.
FIX: Remove hard-coded timezone from the RSS feed creator.
FIX: Caching of RSS feeds wasn't working
 
1.62
 
NEW: RSS feed can now list changed files
NEW: Templates can now show an open folder icon
NEW: Polish translation
NEW: Dutch translation
 
CHANGE: Window is scrolled to appropriate location when opening a new directory
 
FIX: Allow repository names containing '/'
FIX: Fixed sloppy HTML in diff templates
FIX: Fix problems with the diff output
FIX: Repositories on Windows network shares can now be accessed.
FIX: Accented characters weren't shown correctly in the directory comparison
view.
FIX: Remove error when only one revision was available
 
1.61
 
NEW: Multibyte encodings are considered when urlencoding path names
 
CHANGE: The listing view will now always show the revision asked for
(HEAD by default), but the log message will show the log
string for the latest modification to the current directory).
This means the the parent directory structure won't change as you
browse through old directories.
 
FIX: A bug prevented downloading of tarballs from working
 
1.60
 
NEW: Directory displays are now shown in tree view (so that it's harder
to get lost). Many thanks to Brent Lu for this excellent patch.
The prettiest result are available in the BlueGrey scheme.
NEW: Comparison of entire directories
NEW: Tarballs of directories may now be downloaded.
Set $config->allowdownload(); in config.inc to allow this.
NEW: New style 'Zinn' based on the templates created for
http://www.projectzinn.org/. Thanks to Justin Doran.
NEW: File delivery now looks at the defined Mime-Type. Thanks to
Peter Valdemar Mørch for this patch.
NEW: Various configuration options may now be applied on a per project
basis. Look in distconfig for instructions.
NEW: Support for using 'bugtraq' properties when display log entries.
See http://svn.collab.net/repos/tortoisesvn/trunk/doc/issuetrackers.txt
NEW: Traditional Chinese translation
NEW: Spanish translation
CHANGE: Style information removed from RSS feed
CHANGE: Changed files are now hidden by defaut (since the directory
comparison link is far more useful)
 
FIX: File listing were't being shown with the correct accented characters
under windows.
FIX: File listing sometimes failed when there were spaces in the filename
FIX: Some setups wouldn't allow diff generations with enscript
enabled.
FIX: Filenames are URL encoded correctly before calling svn file:///
FIX: Keywords weren't expanded in file view when enscript was disabled
 
1.51
 
NEW: Korean translation
NEW: Russian translation
 
FIX: Repositories may now have spaces in their path (eg: c:\my reps)
FIX: Diff now works when the file name has changed between versions
FIX: RSS feed now generates Content-Type header for XML so that IE can display
the contents
FIX: Diff and Blame didn't work properly for php files when enscript wasn't used
FIX: Use svn --non-interactive to ensure that svn doesn't prompt WebSVN for input
FIX: Corrections to the French translation
FIX: Display an explanatory message when the user hasn't configured any
repository paths
FIX: When using Multiviews, change to the WebSVN directory before executing
commands so that tempnam works. This used to cause problems on some
systems when running diff and blame.
 
1.50
 
Notes: Before installing this version you should delete all the existing
cache files.
wsvn.php has changed. You should redo any appropriate configuration
changes inside this file.
 
NEW: Blame information for a file can now be viewed
NEW: The cached files are now compressed
NEW: The project selection box shows the current project by default
NEW: Swedish translation
NEW: Japanese translation
NEW: The install file explains how to set up permission based repository
access such that access via the web interface is the same as access
via a client (assuming Apache2).
NEW: SVN keywords are now expanded in file listings
 
CHANGE: The extraction of the directory listings is now accomplished using
the svn command via file:/// access rather than svnlook. This has
the advantage of being non-recursive, and thereby eliminates the need
for caching the entire directory listing, and is much quicker on
complex direcory structures. No more 50Mb directory caches!
FIX: Deleted directories are now viewable.
FIX: SHOWALL was being redefined in the language files
FIX: The directory listing view sometimes showed [lang:DELETEDFILES
FIX: Under Windows, links in the RSS output would start with "\" if WebSVN
was installed in the server's root directory.
FIX: Sed wouldn't work under all versions of Windows due to the use of single
quotes around the paramters
FIX: Improved character encoding support for log messages etc.
FIX: Paths passed by URL are encoded
FIX: Generated HTML code is strictly 4.01
 
1.40
 
NEW: RSS feed support (thanks to Lübbe Onken for his work on this)
NEW: Translatations for French and Portuguese
NEW: .exe is recognised by default as having content-type
application/x-msdownload
NEW: Recognised links are now 'linkified' in the log messages
NEW: Tabs in file/diff listings are now expanded by a user
configurable number of spaces.
NEW: WebSVN URLs now access the repository by name rather than number.
This means that bookmarks will stay the same when new projects
are added. The old behaviour can be configured in config.inc.
 
FIX: Removed the revision 0 that has appeared since the previous version
FIX: Repositories were not sorted alphabetically when using ParentPath
FIX: The PNG support script needed for IE (and the BlueGrey scheme) is
now only loaded with IE
 
1.39
 
CHANGE: In the human-readable date strings, display up to 119 minutes,
47 hours, 13 days or 23 months before moving up to the next
quantity, like ViewCVS.
 
FIX: Links followed after viewing the contents of a file go to the
revision of the repository previously being viewed
FIX: Paths with spaces are now correctly showed in the log view
FIX: Blank lines in the diff output are set to &nbsp; so the browser
won't compress them
FIX: A blank author field is set to an &nbsp; cell.
FIX: A year is 365 days, not 356.
FIX: Base ages correctly upon GMT
FIX: The diff output did not escape html entities when enscript was
enabled and the file extension was not recognised for enscript.
FIX: distconfig.inc has a few minor errors in the examples.
FIX: It wasn't possible to call ParentPath multiple times
 
1.38
 
NEW: Templates can now define icons for particular file types
(see BlueGrey scheme for an example)
NEW: Display of PHP files with syntax highlighting
NEW: Improve site navigation with links to each directory level on all
pages.
 
1.37
 
NEW: Display a message when there are no results found
 
CHANGE: Aesthetic changes to the BlueGrey scheme
CHANGE: Sort entries more naturally
 
FIX: Really make sure that we redirect to the right place when using the
drop-down box to select projects.
FIX: Nested [webtest]'s didn't always work
FIX: Fixed use of "standard" and "Standard", which caused problems on
non-windows machines
 
1.36
 
NEW: Log message search feature
NEW: Diff display tries to display changed lines as changed, rather than
showing the line deleted then added.
 
FIX: Problem surrounding the quoting of commands and command line arguments
on Windows machines.
 
1.35
 
NEW: You can now specify a list of file types (extensions) for files which
should be delivered to the user in a GZIP'd archive rather than
displayed as ASCII in the browser window.
 
CHANGE: Files delived with a MIME Content type are now sent as "inline".
The browser will try to display them in the browser window, offering
a save box only if they can't be displayed in this mannor.
 
FIX: Detect use of the HTTPS protocol when using the drop-down box to
select projects. (-- FIX INCORRECT. USE v1.36 -- )
FIX: The PNGs in the BlueGrey style are now transparent under Internet
Explorer 5.5 and higher.
 
1.34
 
NEW: Support for switching between projects using a drop-down box control
(MultiViews users - note that wsvn.php has been changed)
NEW: Sort the repositories alphabetically when using parentPath
NEW: Better support for internationalisation
(Template writers: Please note the use of the new variable 'charset')
NEW: More useful info in browser titles with the standard templates
 
FIX: Accented characters should now be displayed correctly (I hope).
FIX: HTML files now display correcly on all machines
FIX: Removed spurious BRs from the file listings
 
1.33
 
There are a few changes to the config file in this release. Copy
distconfig.inc to config.inc and redo any configuration changes that you
had made.
 
NEW: Recognised non-text files are now delivered to the user as attachments.
The list of files types to be sent back to the user (rather than displayed
using WebSVN) is user configurable.
NEW: File comparisons are now colourised based on the file extension
 
CHANGE: Only the Enscript file extensions that the user wishes to override are
now listed in the config file.
 
1.32
 
FIX: Links no longer functionned correctly when used in basic
(non-multiviews) mode.
FIX: Stop diff from comparing space changes
 
1.31
 
FIX: Directory view had disappeared!
FIX: Included missing file setup.inc
FIX: Handle spaces in filenames
 
1.30
 
There are a few changes to the config file in this release. Copy
distconfig.inc to config.inc and redo any configuration changes that you
had made.
 
NEW: MultiViews support. You can now set up WebSVN to access the
repositories using a URL such as:
http://server/wsvn/repname/path/to/rep
 
NEW: Colourisation support using Enscript
NEW: [websvn-test] function can now be nested
NEW: locwebsvnhttp variable added in template system
NEW: Bluegrey scheme now has show/hide changed link
 
FIX: Possible security hole with abuse of popen
FIX: WebSVN should now function correctly (again) on non windows servers.
FIX: First character of diff listing was missing
 
1.20
 
NEW: Comprehensive templating solution
NEW: Show the age of a revision in the log view
 
CHANGE: The youngest revision of the current directory is now shown by
default (as opposed to the head revision of the entire repository.
This means that clicking on a directory will show the lastest
changes associated with it. A specific revision can still be
selected from a log view
CHANGE: Only show the leaf name when viewing directory contents
 
FIX: Fixed error concerning use of pclose
 
1.10/1.10a
 
There are a few changes to the config file in this release. Copy
distconfig.inc to config.inc and redo any configuration changes that you
had made.
 
NEW: WebSVN now caches information on the repositories. Once a revision
has been viewed subsequent revisions use the cached infomation to
display the directory structure. This significantly improves the
browsing speed.
NEW: German language file (thanks to Stephan Stapel)
 
1.04/1.04a
 
Please note that the config file is now stored in include/
 
FIX: Directories in the log view lacked their trailing slashes.
FIX: Diff is now far more efficient with Apache's memory,
and shows the corrrect line numbers.
FIX: setDiffPath now works.
FIX: Bug introduced in 1.03 whereby the revision number always showed '1'
corrected.
 
Note that you can't view logs with 1.04! Use 1.04a.
 
1.03
 
Note that the config.inc file has completely changed in this release, in
order to make it more "future proof" and resiliant. You'll need to copy
distconfig.inc to config.inc redo the appropriate changes are described.
 
NEW: A 'ParentPath' can now be specified, rather than having to specify the
directories by hand.
 
FIX: Rewrite of the file list code. Should now be quite a bit faster
FIX: Use a more memory efficient algorithm to list file contents
FIX: Spaces in Windows path to svnlook and diff are now handled properly
FIX: Calls to external commands such as svnlook no longer require Windows
style line endings.
 
1.02
 
NEW: Improved command handling to report returned errors. Considerably helps
initial installation problems.
NEW: Show the author of each revision in the log view
 
FIX: Removed the spurious &nbsp that some people were seeing
 
1.01 (5 Feb 2004)
 
FIX: Files with HTML content are now shown correcty
FIX: The diff output had the revision lables the wrong way round
 
1.00 (4 Feb 2004)
 
First Public Release
2.1 alpha 1
 
* Many cleanups and optimisations.
* More documentation for *.inc files.
* Removed extraneous bits.
 
CHANGES
 
NEW: Template files may now be specified on a per repository basis
NEW: Add RSS 'alternate' <link> elements to the HTML headers in
directory listings. This lets you, for example, easily create a
'live bookmark' in Firefox to monitor commits to a particular SVN path.
NEW: Russian translation.
 
CHANGE: Bugtraq handling has been updated to account for the latest spec.
 
FIX: Syntax highlighting across lines has been fixed (Issue 85)
 
2.00 beta 8
 
CHANGE: Remove path comparison boxes when using the flat view display
CHANGE: Tidy up URLs generated from the listing view (Remove default parameters).
CHANGE: wsvn now selectes either the listing or file view automatically when the op parameter
isn't present. This allows for nicer URLS (eg. /http://example.com/wsvn/repo1/myfile.doc)
FIX: Fix warnings when using an access file that didn't define a groups section
FIX: Fix tarballing of directories with spaces
FIX: Path history information in the log view of a file was incorrect.
 
2.00 beta 7
 
NEW: Projects may now be assigned to groups, to simplify the index view
NEW: The index may be displayed as a collapsable tree of groups
 
CHANGE: The syntax for the per repository configurations has changed. It's now much simpler and
will work on all versions of PHP
 
FIX: Various bug fixes for the access rights module
FIX: Language choice selection with MultiViews enabled didn't work
FIX: Various small bugs introduced during 2.0 development
 
2.00 beta 6
 
Note: the $config->addRepository command now takes a URL and not a filesystem path!
 
NEW: WebSVN can now host remote repositories!
 
FIX: The access rights handling didn't work if you had give a repository a display name
different from it's "real" svn name.
FIX: The deleted file list no longer links to non-existant files!
FIX: Neaten the directory display when the download/compare links aren't available
 
2.00 beta 5
 
NEW: Access rights files can now be specified on a per repository basis
 
CHANGE: Further improvements have been made to character encoding handling. In particular,
it is now possible to specify the encoding of the repository contents separately
from the system encoding. This is the case for windows users, whereby the command
line tools typically returning CP850 encoded strings, whereas the source files are
encoded as iso-8859-1. Now, when displaying text files, WebSVN will convert them
from the content encoding to the output encoding (UTF-8).
 
CHANGE: Update Danish translation
CHANGE: The log display has a "max number of revisions to show" fiter option, which defaults
to 30. This significantly improves performance of the log display.
 
FIX: It wasn't possible to display the contents of a file which had brackets in the name.
FIX: Correct problem with download of tarballs containing special characters
FIX: Improve time display
FIX: Remove non-UTF8 language options from distconfig.inc
FIX: Fix recent bug whereby the log messages would contain unnecessary blank lines
FIX: Access right file section groups without a trailing / are no correctly treated
 
2.00 beta 4
 
NEW: The log display may now be filtered to show a range of revisions
NEW: You can now have control over the specification of directories that can or
cannot be tarball'ed. Tarballing can be turned on only after a certain directory
depth and directories can be allow/disallowed on a per directory/repository basis.
NEW: The user can now choose their language via a drop down box
 
CHANGE: Character encodings are now handled differently. The output encoding is ALWAYS
defined as UTF-8, and the setOutputEncoding option has been removed.
 
FIX: Diff had been broken by 1.70 beta 2
FIX: Download of tarballs is prohibited if the user doesn't have read access to the directory
AND all of its subdirectories
FIX: The character set type is now sent in the HTTP header. No need to hack the Apache config
 
2.00 beta 3
 
NEW: WebSVN may now be configured to display a flat view rather than a tree view
 
FIX: Only use --limit option on svn 1.2 or greater
FIX: Correct spelling of "danish" in distconfig
FIX: Fix RSS, previously broken 1.7 beta 1
 
2.00 beta 2
 
CHANGE: WebSVN no longer requires the entire revision history when accessing a directory,
resulting in a faster access for large repositories
 
FIX: The new access rights module didn't always hide directories
FIX: Tree icons have been fixed (broken in 1.70 beta 1)
 
2.00 beta 1
 
NEW: Access rights module (Finally!) - see install.txt for details
NEW: Added language file for Danish, Finnish, Turkish, Norwegian and Simplified Chinese
NEW: The "View Log" link is now available for templates to use from the file view
NEW: Added bugtraq:logregex support
 
CHANGE: Ages are now displayed with higher resolution
CHANGE: Update German translation
CHANGE: Tex file are no longer delivered as binary by defaut, but displayed by enscript
CHANGE: The last modified files display now shows the most recently modified files of
the current directory
CHANGE: Improve diff colours of Blue Grey Scheme for better readability
CHANGE: WebSVN no longer requires the entire revision history when accessing a directory,
resulting in a faster access for large repositories
 
FIX: Directories containing accents weren't always displayed
FIX: File version can be compared via the log display (as oppoed to just directories)
FIX: Corrected RSS encoding issue
FIX: Corrected bug whereby diff lines would be displayed twice
FIX: svn: Can't check path '/root/.subversion': Permission denied
FIX: Sometimes files delivered (as opposed to disaplyed) by WebSVN were empty
FIX: Fix problem with large tarball delivery
FIX: Compare with previous always used HEAD
FIX: .sh files are now viewable
FIX: Allow special characters in repository names
FIX: It wasn't possible to go into a module if another module starts with the same name.
FIX: Remove hard-coded timezone from the RSS feed creator.
FIX: Caching of RSS feeds wasn't working
 
1.62
 
NEW: RSS feed can now list changed files
NEW: Templates can now show an open folder icon
NEW: Polish translation
NEW: Dutch translation
 
CHANGE: Window is scrolled to appropriate location when opening a new directory
 
FIX: Allow repository names containing '/'
FIX: Fixed sloppy HTML in diff templates
FIX: Fix problems with the diff output
FIX: Repositories on Windows network shares can now be accessed.
FIX: Accented characters weren't shown correctly in the directory comparison
view.
FIX: Remove error when only one revision was available
 
1.61
 
NEW: Multibyte encodings are considered when urlencoding path names
 
CHANGE: The listing view will now always show the revision asked for
(HEAD by default), but the log message will show the log
string for the latest modification to the current directory).
This means the the parent directory structure won't change as you
browse through old directories.
 
FIX: A bug prevented downloading of tarballs from working
 
1.60
 
NEW: Directory displays are now shown in tree view (so that it's harder
to get lost). Many thanks to Brent Lu for this excellent patch.
The prettiest result are available in the BlueGrey scheme.
NEW: Comparison of entire directories
NEW: Tarballs of directories may now be downloaded.
Set $config->allowdownload(); in config.inc to allow this.
NEW: New style 'Zinn' based on the templates created for
http://www.projectzinn.org/. Thanks to Justin Doran.
NEW: File delivery now looks at the defined Mime-Type. Thanks to
Peter Valdemar Mørch for this patch.
NEW: Various configuration options may now be applied on a per project
basis. Look in distconfig for instructions.
NEW: Support for using 'bugtraq' properties when display log entries.
See http://svn.collab.net/repos/tortoisesvn/trunk/doc/issuetrackers.txt
NEW: Traditional Chinese translation
NEW: Spanish translation
CHANGE: Style information removed from RSS feed
CHANGE: Changed files are now hidden by defaut (since the directory
comparison link is far more useful)
 
FIX: File listing were't being shown with the correct accented characters
under windows.
FIX: File listing sometimes failed when there were spaces in the filename
FIX: Some setups wouldn't allow diff generations with enscript
enabled.
FIX: Filenames are URL encoded correctly before calling svn file:///
FIX: Keywords weren't expanded in file view when enscript was disabled
 
1.51
 
NEW: Korean translation
NEW: Russian translation
 
FIX: Repositories may now have spaces in their path (eg: c:\my reps)
FIX: Diff now works when the file name has changed between versions
FIX: RSS feed now generates Content-Type header for XML so that IE can display
the contents
FIX: Diff and Blame didn't work properly for php files when enscript wasn't used
FIX: Use svn --non-interactive to ensure that svn doesn't prompt WebSVN for input
FIX: Corrections to the French translation
FIX: Display an explanatory message when the user hasn't configured any
repository paths
FIX: When using Multiviews, change to the WebSVN directory before executing
commands so that tempnam works. This used to cause problems on some
systems when running diff and blame.
 
1.50
 
Notes: Before installing this version you should delete all the existing
cache files.
wsvn.php has changed. You should redo any appropriate configuration
changes inside this file.
 
NEW: Blame information for a file can now be viewed
NEW: The cached files are now compressed
NEW: The project selection box shows the current project by default
NEW: Swedish translation
NEW: Japanese translation
NEW: The install file explains how to set up permission based repository
access such that access via the web interface is the same as access
via a client (assuming Apache2).
NEW: SVN keywords are now expanded in file listings
 
CHANGE: The extraction of the directory listings is now accomplished using
the svn command via file:/// access rather than svnlook. This has
the advantage of being non-recursive, and thereby eliminates the need
for caching the entire directory listing, and is much quicker on
complex direcory structures. No more 50Mb directory caches!
FIX: Deleted directories are now viewable.
FIX: SHOWALL was being redefined in the language files
FIX: The directory listing view sometimes showed [lang:DELETEDFILES
FIX: Under Windows, links in the RSS output would start with "\" if WebSVN
was installed in the server's root directory.
FIX: Sed wouldn't work under all versions of Windows due to the use of single
quotes around the paramters
FIX: Improved character encoding support for log messages etc.
FIX: Paths passed by URL are encoded
FIX: Generated HTML code is strictly 4.01
 
1.40
 
NEW: RSS feed support (thanks to Lübbe Onken for his work on this)
NEW: Translatations for French and Portuguese
NEW: .exe is recognised by default as having content-type
application/x-msdownload
NEW: Recognised links are now 'linkified' in the log messages
NEW: Tabs in file/diff listings are now expanded by a user
configurable number of spaces.
NEW: WebSVN URLs now access the repository by name rather than number.
This means that bookmarks will stay the same when new projects
are added. The old behaviour can be configured in config.inc.
 
FIX: Removed the revision 0 that has appeared since the previous version
FIX: Repositories were not sorted alphabetically when using ParentPath
FIX: The PNG support script needed for IE (and the BlueGrey scheme) is
now only loaded with IE
 
1.39
 
CHANGE: In the human-readable date strings, display up to 119 minutes,
47 hours, 13 days or 23 months before moving up to the next
quantity, like ViewCVS.
 
FIX: Links followed after viewing the contents of a file go to the
revision of the repository previously being viewed
FIX: Paths with spaces are now correctly showed in the log view
FIX: Blank lines in the diff output are set to &nbsp; so the browser
won't compress them
FIX: A blank author field is set to an &nbsp; cell.
FIX: A year is 365 days, not 356.
FIX: Base ages correctly upon GMT
FIX: The diff output did not escape html entities when enscript was
enabled and the file extension was not recognised for enscript.
FIX: distconfig.inc has a few minor errors in the examples.
FIX: It wasn't possible to call ParentPath multiple times
 
1.38
 
NEW: Templates can now define icons for particular file types
(see BlueGrey scheme for an example)
NEW: Display of PHP files with syntax highlighting
NEW: Improve site navigation with links to each directory level on all
pages.
 
1.37
 
NEW: Display a message when there are no results found
 
CHANGE: Aesthetic changes to the BlueGrey scheme
CHANGE: Sort entries more naturally
 
FIX: Really make sure that we redirect to the right place when using the
drop-down box to select projects.
FIX: Nested [webtest]'s didn't always work
FIX: Fixed use of "standard" and "Standard", which caused problems on
non-windows machines
 
1.36
 
NEW: Log message search feature
NEW: Diff display tries to display changed lines as changed, rather than
showing the line deleted then added.
 
FIX: Problem surrounding the quoting of commands and command line arguments
on Windows machines.
 
1.35
 
NEW: You can now specify a list of file types (extensions) for files which
should be delivered to the user in a GZIP'd archive rather than
displayed as ASCII in the browser window.
 
CHANGE: Files delived with a MIME Content type are now sent as "inline".
The browser will try to display them in the browser window, offering
a save box only if they can't be displayed in this mannor.
 
FIX: Detect use of the HTTPS protocol when using the drop-down box to
select projects. (-- FIX INCORRECT. USE v1.36 -- )
FIX: The PNGs in the BlueGrey style are now transparent under Internet
Explorer 5.5 and higher.
 
1.34
 
NEW: Support for switching between projects using a drop-down box control
(MultiViews users - note that wsvn.php has been changed)
NEW: Sort the repositories alphabetically when using parentPath
NEW: Better support for internationalisation
(Template writers: Please note the use of the new variable 'charset')
NEW: More useful info in browser titles with the standard templates
 
FIX: Accented characters should now be displayed correctly (I hope).
FIX: HTML files now display correcly on all machines
FIX: Removed spurious BRs from the file listings
 
1.33
 
There are a few changes to the config file in this release. Copy
distconfig.inc to config.inc and redo any configuration changes that you
had made.
 
NEW: Recognised non-text files are now delivered to the user as attachments.
The list of files types to be sent back to the user (rather than displayed
using WebSVN) is user configurable.
NEW: File comparisons are now colourised based on the file extension
 
CHANGE: Only the Enscript file extensions that the user wishes to override are
now listed in the config file.
 
1.32
 
FIX: Links no longer functionned correctly when used in basic
(non-multiviews) mode.
FIX: Stop diff from comparing space changes
 
1.31
 
FIX: Directory view had disappeared!
FIX: Included missing file setup.inc
FIX: Handle spaces in filenames
 
1.30
 
There are a few changes to the config file in this release. Copy
distconfig.inc to config.inc and redo any configuration changes that you
had made.
 
NEW: MultiViews support. You can now set up WebSVN to access the
repositories using a URL such as:
http://server/wsvn/repname/path/to/rep
 
NEW: Colourisation support using Enscript
NEW: [websvn-test] function can now be nested
NEW: locwebsvnhttp variable added in template system
NEW: Bluegrey scheme now has show/hide changed link
 
FIX: Possible security hole with abuse of popen
FIX: WebSVN should now function correctly (again) on non windows servers.
FIX: First character of diff listing was missing
 
1.20
 
NEW: Comprehensive templating solution
NEW: Show the age of a revision in the log view
 
CHANGE: The youngest revision of the current directory is now shown by
default (as opposed to the head revision of the entire repository.
This means that clicking on a directory will show the lastest
changes associated with it. A specific revision can still be
selected from a log view
CHANGE: Only show the leaf name when viewing directory contents
 
FIX: Fixed error concerning use of pclose
 
1.10/1.10a
 
There are a few changes to the config file in this release. Copy
distconfig.inc to config.inc and redo any configuration changes that you
had made.
 
NEW: WebSVN now caches information on the repositories. Once a revision
has been viewed subsequent revisions use the cached infomation to
display the directory structure. This significantly improves the
browsing speed.
NEW: German language file (thanks to Stephan Stapel)
 
1.04/1.04a
 
Please note that the config file is now stored in include/
 
FIX: Directories in the log view lacked their trailing slashes.
FIX: Diff is now far more efficient with Apache's memory,
and shows the corrrect line numbers.
FIX: setDiffPath now works.
FIX: Bug introduced in 1.03 whereby the revision number always showed '1'
corrected.
 
Note that you can't view logs with 1.04! Use 1.04a.
 
1.03
 
Note that the config.inc file has completely changed in this release, in
order to make it more "future proof" and resiliant. You'll need to copy
distconfig.inc to config.inc redo the appropriate changes are described.
 
NEW: A 'ParentPath' can now be specified, rather than having to specify the
directories by hand.
 
FIX: Rewrite of the file list code. Should now be quite a bit faster
FIX: Use a more memory efficient algorithm to list file contents
FIX: Spaces in Windows path to svnlook and diff are now handled properly
FIX: Calls to external commands such as svnlook no longer require Windows
style line endings.
 
1.02
 
NEW: Improved command handling to report returned errors. Considerably helps
initial installation problems.
NEW: Show the author of each revision in the log view
 
FIX: Removed the spurious &nbsp that some people were seeing
 
1.01 (5 Feb 2004)
 
FIX: Files with HTML content are now shown correcty
FIX: The diff output had the revision lables the wrong way round
 
1.00 (4 Feb 2004)
 
First Public Release
/WebSVN/comp.php
1,355 → 1,355
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// comp.php
//
// Compare two paths using "svn diff"
//
 
require_once("include/setup.inc");
require_once("include/svnlook.inc");
require_once("include/utils.inc");
require_once("include/template.inc");
 
$svnrep = new SVNRepository($rep);
 
function checkRevision($rev)
{
if (is_numeric($rev) && ((int)$rev > 0))
return $rev;
$rev = strtoupper($rev);
switch($rev)
{
case "HEAD":
case "PREV":
case "COMMITTED":
return $rev;
}
return "HEAD";
}
 
$svnrep = new SVNRepository($rep);
 
// Retrieve the request information
$path1 = @$_REQUEST["compare"][0];
$path2 = @$_REQUEST["compare"][1];
$rev1 = @$_REQUEST["compare_rev"][0];
$rev2 = @$_REQUEST["compare_rev"][1];
 
// Some page links put the revision with the path...
if (strpos($path1, "@")) list($path1, $rev1) = explode("@", $path1);
if (strpos($path2, "@")) list($path2, $rev2) = explode("@", $path2);
 
$rev1 = checkRevision($rev1);
$rev2 = checkRevision($rev2);
 
// Choose a sensible comparison order unless told not to
if (!@$_REQUEST["manualorder"] && is_numeric($rev1) && is_numeric($rev2))
{
if ($rev1 > $rev2)
{
$temppath = $path1;
$temprev = $rev1;
$path1 = $path2;
$rev1 = $rev2;
$path2 = $temppath;
$rev2 = $temprev;
}
}
 
$url = $config->getURL($rep, "/", "comp");
$vars["revlink"] = "<a href=\"${url}compare%5B%5D=".urlencode($path2)."@$rev2&amp;compare%5B%5D=".urlencode($path1)."@$rev1&manualorder=1\">${lang["REVCOMP"]}</a>";
 
if ($rev1 == 0) $rev1 = "HEAD";
if ($rev2 == 0) $rev2 = "HEAD";
 
$vars["repname"] = $rep->getDisplayName();
$vars["action"] = $lang["PATHCOMPARISON"];
$vars["compare_form"] = "<form action=\"$url\" method=\"post\" name=\"compareform\">";
$vars["compare_path1input"] = "<input type=\"text\" size=\"40\" name=\"compare[0]\" value=\"$path1\" />";
$vars["compare_rev1input"] = "<input type=\"text\" size=\"5\" name=\"compare_rev[0]\" value=\"$rev1\" />";
$vars["compare_path2input"] = "<input type=\"text\" size=\"40\" name=\"compare[1]\" value=\"$path2\" />";
$vars["compare_rev2input"] = "<input type=\"text\" size=\"5\" name=\"compare_rev[1]\" value=\"$rev2\" />";
$vars["compare_submit"] = "<input name=\"comparesubmit\" type=\"submit\" value=\"${lang["COMPAREPATHS"]}\" />";
$vars["compare_endform"] = "<input type=\"hidden\" name=\"op\" value=\"comp\" /><input type=\"hidden\" name=\"manualorder\" value=\"1\" /><input type=\"hidden\" name=\"sc\" value=\"$showchanged\" /></form>";
 
# safe paths are a hack for fixing XSS sploit
$vars["path1"] = $path1;
$vars['safepath1'] = htmlentities($path1);
$vars["path2"] = $path2;
$vars['safepath2'] = htmlentities($path2);
 
$vars["rev1"] = $rev1;
$vars["rev2"] = $rev2;
 
$noinput = empty($path1) || empty($path2);
$listing = array();
 
// Generate the diff listing
$path1 = encodepath(str_replace(DIRECTORY_SEPARATOR, "/", $svnrep->repConfig->path.$path1));
$path2 = encodepath(str_replace(DIRECTORY_SEPARATOR, "/", $svnrep->repConfig->path.$path2));
 
$debug = false;
 
if (!$noinput)
{
$rawcmd = $config->svn." diff ".$rep->svnParams().quote($path1."@".$rev1)." ".quote($path2."@".$rev2);
$cmd = quoteCommand($rawcmd, true);
if ($debug) echo "$cmd\n";
}
 
function clearVars()
{
global $listing, $index;
$listing[$index]["newpath"] = null;
$listing[$index]["endpath"] = null;
$listing[$index]["info"] = null;
$listing[$index]["diffclass"] = null;
$listing[$index]["difflines"] = null;
$listing[$index]["enddifflines"] = null;
$listing[$index]["properties"] = null;
}
 
$vars["success"] = false;
 
if (!$noinput)
{
if ($diff = popen($cmd, "r"))
{
$index = 0;
$indiff = false;
$indiffproper = false;
$getLine = true;
$node = null;
$vars["success"] = true;
while (!feof($diff))
{
if ($getLine)
$line = fgets($diff);
clearVars();
$getLine = true;
if ($debug) print "Line = '$line'<br />" ;
if ($indiff)
{
// If we're in a diff proper, just set up the line
if ($indiffproper)
{
if ($line[0] == " " || $line[0] == "+" || $line[0] == "-")
{
switch ($line[0])
{
case " ":
$listing[$index]["diffclass"] = "diff";
$subline = hardspace(replaceEntities(rtrim(substr($line, 1)), $rep));
if (empty($subline)) $subline = "&nbsp;";
$listing[$index++]["line"] = $subline;
if ($debug) print "Including as diff: $subline<br />";
break;
case "+":
$listing[$index]["diffclass"] = "diffadded";
$subline = hardspace(replaceEntities(rtrim(substr($line, 1)), $rep));
if (empty($subline)) $subline = "&nbsp;";
$listing[$index++]["line"] = $subline;
if ($debug) print "Including as added: $subline<br />";
break;
case "-":
$listing[$index]["diffclass"] = "diffdeleted";
$subline = hardspace(replaceEntities(rtrim(substr($line, 1)), $rep));
if (empty($subline)) $subline = "&nbsp;";
$listing[$index++]["line"] = $subline;
if ($debug) print "Including as removed: $subline<br />";
break;
}
continue;
}
else
{
$indiffproper = false;
$listing[$index++]["enddifflines"] = true;
$getLine = false;
if ($debug) print "Ending lines<br />";
continue;
}
}
// Check for the start of a new diff area
if (!strncmp($line, "@@", 2))
{
$pos = strpos($line, "+");
$posline = substr($line, $pos);
sscanf($posline, "+%d,%d", $sline, $eline);
if ($debug) print "sline = '$sline', eline = '$eline'<br />";
// Check that this isn't a file deletion
if ($sline == 0 && $eline == 0)
{
$line = fgets($diff);
if ($debug) print "Ignoring: $line<br />" ;
while ($line[0] == " " || $line[0] == "+" || $line[0] == "-")
{
$line = fgets($diff);
if ($debug) print "Ignoring: $line<br />" ;
}
$getLine = false;
if ($debug) print "Unignoring previous - marking as deleted<b>";
$listing[$index++]["info"] = $lang["FILEDELETED"];
}
else
{
$listing[$index++]["difflines"] = $line;
$indiffproper = true;
}
continue;
}
else
{
$indiff = false;
if ($debug) print "Ending diff";
}
}
// Check for a new node entry
if (strncmp(trim($line), "Index: ", 7) == 0)
{
// End the current node
if ($node)
{
$listing[$index++]["endpath"] = true;
clearVars();
}
$node = trim($line);
$node = substr($node, 7);
$listing[$index]["newpath"] = $node;
if ($debug) echo "Creating node $node<br />";
// Skip past the line of ='s
$line = fgets($diff);
if ($debug) print "Skipping: $line<br />" ;
// Check for a file addition
$line = fgets($diff);
if ($debug) print "Examining: $line<br />" ;
if (strpos($line, "(revision 0)"))
$listing[$index]["info"] = $lang["FILEADDED"];
if (strncmp(trim($line), "Cannot display:", 15) == 0)
{
$index++;
clearVars();
$listing[$index++]["info"] = $line;
continue;
}
// Skip second file info
$line = fgets($diff);
if ($debug) print "Skipping: $line<br />" ;
$indiff = true;
$index++;
continue;
}
if (strncmp(trim($line), "Property changes on: ", 21) == 0)
{
$propnode = trim($line);
$propnode = substr($propnode, 21);
if ($debug) print "Properties on $propnode (cur node $ $node)";
if ($propnode != $node)
{
if ($node)
{
$listing[$index++]["endpath"] = true;
clearVars();
}
$node = $propnode;
$listing[$index++]["newpath"] = $node;
clearVars();
}
$listing[$index++]["properties"] = true;
clearVars();
if ($debug) echo "Creating node $node<br />";
// Skip the row of underscores
$line = fgets($diff);
if ($debug) print "Skipping: $line<br />" ;
while ($line = trim(fgets($diff)))
{
$listing[$index++]["info"] = $line;
clearVars();
}
continue;
}
// Check for error messages
if (strncmp(trim($line), "svn: ", 5) == 0)
{
$listing[$index++]["info"] = urldecode($line);
$vars["success"] = false;
continue;
}
$listing[$index++]["info"] = $line;
}
if ($node)
{
clearVars();
$listing[$index++]["endpath"] = true;
}
if ($debug) print_r($listing);
}
}
 
$vars["version"] = $version;
 
if (!$rep->hasUnrestrictedReadAccess($path1) || !$rep->hasUnrestrictedReadAccess($path2, false))
$vars["noaccess"] = true;
 
parseTemplate($rep->getTemplatePath()."header.tmpl", $vars, $listing);
parseTemplate($rep->getTemplatePath()."compare.tmpl", $vars, $listing);
parseTemplate($rep->getTemplatePath()."footer.tmpl", $vars, $listing);
?>
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// comp.php
//
// Compare two paths using "svn diff"
//
 
require_once("include/setup.inc");
require_once("include/svnlook.inc");
require_once("include/utils.inc");
require_once("include/template.inc");
 
$svnrep = new SVNRepository($rep);
 
function checkRevision($rev)
{
if (is_numeric($rev) && ((int)$rev > 0))
return $rev;
$rev = strtoupper($rev);
switch($rev)
{
case "HEAD":
case "PREV":
case "COMMITTED":
return $rev;
}
return "HEAD";
}
 
$svnrep = new SVNRepository($rep);
 
// Retrieve the request information
$path1 = @$_REQUEST["compare"][0];
$path2 = @$_REQUEST["compare"][1];
$rev1 = @$_REQUEST["compare_rev"][0];
$rev2 = @$_REQUEST["compare_rev"][1];
 
// Some page links put the revision with the path...
if (strpos($path1, "@")) list($path1, $rev1) = explode("@", $path1);
if (strpos($path2, "@")) list($path2, $rev2) = explode("@", $path2);
 
$rev1 = checkRevision($rev1);
$rev2 = checkRevision($rev2);
 
// Choose a sensible comparison order unless told not to
if (!@$_REQUEST["manualorder"] && is_numeric($rev1) && is_numeric($rev2))
{
if ($rev1 > $rev2)
{
$temppath = $path1;
$temprev = $rev1;
$path1 = $path2;
$rev1 = $rev2;
$path2 = $temppath;
$rev2 = $temprev;
}
}
 
$url = $config->getURL($rep, "/", "comp");
$vars["revlink"] = "<a href=\"${url}compare%5B%5D=".urlencode($path2)."@$rev2&amp;compare%5B%5D=".urlencode($path1)."@$rev1&manualorder=1\">${lang["REVCOMP"]}</a>";
 
if ($rev1 == 0) $rev1 = "HEAD";
if ($rev2 == 0) $rev2 = "HEAD";
 
$vars["repname"] = $rep->getDisplayName();
$vars["action"] = $lang["PATHCOMPARISON"];
$vars["compare_form"] = "<form action=\"$url\" method=\"post\" name=\"compareform\">";
$vars["compare_path1input"] = "<input type=\"text\" size=\"40\" name=\"compare[0]\" value=\"$path1\" />";
$vars["compare_rev1input"] = "<input type=\"text\" size=\"5\" name=\"compare_rev[0]\" value=\"$rev1\" />";
$vars["compare_path2input"] = "<input type=\"text\" size=\"40\" name=\"compare[1]\" value=\"$path2\" />";
$vars["compare_rev2input"] = "<input type=\"text\" size=\"5\" name=\"compare_rev[1]\" value=\"$rev2\" />";
$vars["compare_submit"] = "<input name=\"comparesubmit\" type=\"submit\" value=\"${lang["COMPAREPATHS"]}\" />";
$vars["compare_endform"] = "<input type=\"hidden\" name=\"op\" value=\"comp\" /><input type=\"hidden\" name=\"manualorder\" value=\"1\" /><input type=\"hidden\" name=\"sc\" value=\"$showchanged\" /></form>";
 
# safe paths are a hack for fixing XSS sploit
$vars["path1"] = $path1;
$vars['safepath1'] = htmlentities($path1);
$vars["path2"] = $path2;
$vars['safepath2'] = htmlentities($path2);
 
$vars["rev1"] = $rev1;
$vars["rev2"] = $rev2;
 
$noinput = empty($path1) || empty($path2);
$listing = array();
 
// Generate the diff listing
$path1 = encodepath(str_replace(DIRECTORY_SEPARATOR, "/", $svnrep->repConfig->path.$path1));
$path2 = encodepath(str_replace(DIRECTORY_SEPARATOR, "/", $svnrep->repConfig->path.$path2));
 
$debug = false;
 
if (!$noinput)
{
$rawcmd = $config->svn." diff ".$rep->svnParams().quote($path1."@".$rev1)." ".quote($path2."@".$rev2);
$cmd = quoteCommand($rawcmd, true);
if ($debug) echo "$cmd\n";
}
 
function clearVars()
{
global $listing, $index;
$listing[$index]["newpath"] = null;
$listing[$index]["endpath"] = null;
$listing[$index]["info"] = null;
$listing[$index]["diffclass"] = null;
$listing[$index]["difflines"] = null;
$listing[$index]["enddifflines"] = null;
$listing[$index]["properties"] = null;
}
 
$vars["success"] = false;
 
if (!$noinput)
{
if ($diff = popen($cmd, "r"))
{
$index = 0;
$indiff = false;
$indiffproper = false;
$getLine = true;
$node = null;
$vars["success"] = true;
while (!feof($diff))
{
if ($getLine)
$line = fgets($diff);
clearVars();
$getLine = true;
if ($debug) print "Line = '$line'<br />" ;
if ($indiff)
{
// If we're in a diff proper, just set up the line
if ($indiffproper)
{
if ($line[0] == " " || $line[0] == "+" || $line[0] == "-")
{
switch ($line[0])
{
case " ":
$listing[$index]["diffclass"] = "diff";
$subline = hardspace(replaceEntities(rtrim(substr($line, 1)), $rep));
if (empty($subline)) $subline = "&nbsp;";
$listing[$index++]["line"] = $subline;
if ($debug) print "Including as diff: $subline<br />";
break;
case "+":
$listing[$index]["diffclass"] = "diffadded";
$subline = hardspace(replaceEntities(rtrim(substr($line, 1)), $rep));
if (empty($subline)) $subline = "&nbsp;";
$listing[$index++]["line"] = $subline;
if ($debug) print "Including as added: $subline<br />";
break;
case "-":
$listing[$index]["diffclass"] = "diffdeleted";
$subline = hardspace(replaceEntities(rtrim(substr($line, 1)), $rep));
if (empty($subline)) $subline = "&nbsp;";
$listing[$index++]["line"] = $subline;
if ($debug) print "Including as removed: $subline<br />";
break;
}
continue;
}
else
{
$indiffproper = false;
$listing[$index++]["enddifflines"] = true;
$getLine = false;
if ($debug) print "Ending lines<br />";
continue;
}
}
// Check for the start of a new diff area
if (!strncmp($line, "@@", 2))
{
$pos = strpos($line, "+");
$posline = substr($line, $pos);
sscanf($posline, "+%d,%d", $sline, $eline);
if ($debug) print "sline = '$sline', eline = '$eline'<br />";
// Check that this isn't a file deletion
if ($sline == 0 && $eline == 0)
{
$line = fgets($diff);
if ($debug) print "Ignoring: $line<br />" ;
while ($line[0] == " " || $line[0] == "+" || $line[0] == "-")
{
$line = fgets($diff);
if ($debug) print "Ignoring: $line<br />" ;
}
$getLine = false;
if ($debug) print "Unignoring previous - marking as deleted<b>";
$listing[$index++]["info"] = $lang["FILEDELETED"];
}
else
{
$listing[$index++]["difflines"] = $line;
$indiffproper = true;
}
continue;
}
else
{
$indiff = false;
if ($debug) print "Ending diff";
}
}
// Check for a new node entry
if (strncmp(trim($line), "Index: ", 7) == 0)
{
// End the current node
if ($node)
{
$listing[$index++]["endpath"] = true;
clearVars();
}
$node = trim($line);
$node = substr($node, 7);
$listing[$index]["newpath"] = $node;
if ($debug) echo "Creating node $node<br />";
// Skip past the line of ='s
$line = fgets($diff);
if ($debug) print "Skipping: $line<br />" ;
// Check for a file addition
$line = fgets($diff);
if ($debug) print "Examining: $line<br />" ;
if (strpos($line, "(revision 0)"))
$listing[$index]["info"] = $lang["FILEADDED"];
if (strncmp(trim($line), "Cannot display:", 15) == 0)
{
$index++;
clearVars();
$listing[$index++]["info"] = $line;
continue;
}
// Skip second file info
$line = fgets($diff);
if ($debug) print "Skipping: $line<br />" ;
$indiff = true;
$index++;
continue;
}
if (strncmp(trim($line), "Property changes on: ", 21) == 0)
{
$propnode = trim($line);
$propnode = substr($propnode, 21);
if ($debug) print "Properties on $propnode (cur node $ $node)";
if ($propnode != $node)
{
if ($node)
{
$listing[$index++]["endpath"] = true;
clearVars();
}
$node = $propnode;
$listing[$index++]["newpath"] = $node;
clearVars();
}
$listing[$index++]["properties"] = true;
clearVars();
if ($debug) echo "Creating node $node<br />";
// Skip the row of underscores
$line = fgets($diff);
if ($debug) print "Skipping: $line<br />" ;
while ($line = trim(fgets($diff)))
{
$listing[$index++]["info"] = $line;
clearVars();
}
continue;
}
// Check for error messages
if (strncmp(trim($line), "svn: ", 5) == 0)
{
$listing[$index++]["info"] = urldecode($line);
$vars["success"] = false;
continue;
}
$listing[$index++]["info"] = $line;
}
if ($node)
{
clearVars();
$listing[$index++]["endpath"] = true;
}
if ($debug) print_r($listing);
}
}
 
$vars["version"] = $version;
 
if (!$rep->hasUnrestrictedReadAccess($path1) || !$rep->hasUnrestrictedReadAccess($path2, false))
$vars["noaccess"] = true;
 
parseTemplate($rep->getTemplatePath()."header.tmpl", $vars, $listing);
parseTemplate($rep->getTemplatePath()."compare.tmpl", $vars, $listing);
parseTemplate($rep->getTemplatePath()."footer.tmpl", $vars, $listing);
?>
/WebSVN/diff.php
1,358 → 1,358
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// diff.php
//
// Show the differences between 2 revisions of a file.
//
 
require_once("include/setup.inc");
require_once("include/svnlook.inc");
require_once("include/utils.inc");
require_once("include/template.inc");
 
$context = 5;
 
$vars["action"] = $lang["DIFF"];
$all = (@$_REQUEST["all"] == 1)?1:0;
 
// Make sure that we have a repository
if (!isset($rep))
{
echo $lang["NOREP"];
exit;
}
 
$svnrep = new SVNRepository($rep);
 
// If there's no revision info, go to the lastest revision for this path
$history = $svnrep->getLog($path, "", "", true);
$youngest = $history->entries[0]->rev;
 
if (empty($rev))
$rev = $youngest;
 
$history = $svnrep->getLog($path, $rev);
 
if ($path{0} != "/")
$ppath = "/".$path;
else
$ppath = $path;
 
$prevrev = @$history->entries[1]->rev;
 
$vars["repname"] = $rep->getDisplayName();
$vars["rev"] = $rev;
$vars["path"] = $ppath;
$vars["prevrev"] = $prevrev;
 
$vars["rev1"] = $history->entries[0]->rev;
$vars["rev2"] = $prevrev;
 
createDirLinks($rep, $ppath, $rev, $showchanged);
 
$listing = array();
 
if ($prevrev)
{
$url = $config->getURL($rep, $path, "diff");
if (!$all)
{
$vars["showalllink"] = "<a href=\"${url}rev=$rev&amp;sc=$showchanged&amp;all=1\">${lang["SHOWENTIREFILE"]}</a>";
$vars["showcompactlink"] = "";
}
else
{
$vars["showcompactlink"] = "<a href=\"${url}rev=$rev&amp;sc=$showchanged&amp;all=0\">${lang["SHOWCOMPACT"]}</a>";
$vars["showalllink"] = "";
}
 
// Get the contents of the two files
$newtname = tempnam("temp", "");
$new = $svnrep->getFileContents($history->entries[0]->path, $newtname, $history->entries[0]->rev, "", true);
 
$oldtname = tempnam("temp", "");
$old = $svnrep->getFileContents($history->entries[1]->path, $oldtname, $history->entries[1]->rev, "", true);
$ent = true;
$extension = strrchr(basename($path), ".");
if (($extension && isset($extEnscript[$extension]) && ('php' == $extEnscript[$extension])) || ($config->useEnscript))
$ent = false;
 
$file1cache = array();
 
if ($all)
$context = 1; // Setting the context to 0 makes diff generate the wrong line numbers!
 
// Open a pipe to the diff command with $context lines of context
$cmd = quoteCommand($config->diff." --ignore-all-space -U $context $oldtname $newtname", false);
if ($all)
{
$ofile = fopen($oldtname, "r");
$nfile = fopen($newtname, "r");
}
 
if ($diff = popen($cmd, "r"))
{
// Ignore the 3 header lines
$line = fgets($diff);
$line = fgets($diff);
 
// Get the first real line
$line = fgets($diff);
$index = 0;
$listing = array();
$curoline = 1;
$curnline = 1;
while (!feof($diff))
{
// Get the first line of this range
sscanf($line, "@@ -%d", $oline);
$line = substr($line, strpos($line, "+"));
sscanf($line, "+%d", $nline);
if ($all)
{
while ($curoline < $oline || $curnline < $nline)
{
$listing[$index]["rev1diffclass"] = "diff";
$listing[$index]["rev2diffclass"] = "diff";
if ($curoline < $oline)
{
$nl = fgets($ofile);
if ($ent)
$line = replaceEntities(rtrim($nl), $rep);
else
$line = rtrim($nl);
$listing[$index]["rev1line"] = hardspace($line);
 
$curoline++;
}
else
$listing[$index]["rev1line"] = "&nbsp;";
if ($curnline < $nline)
{
$nl = fgets($nfile);
 
if ($ent)
$line = replaceEntities(rtrim($nl), $rep);
else
$line = rtrim($nl);
$listing[$index]["rev2line"] = hardspace($line);
$curnline++;
}
else
$listing[$index]["rev2line"] = "&nbsp;";
$listing[$index]["rev1lineno"] = 0;
$listing[$index]["rev2lineno"] = 0;
 
$index++;
}
}
else
{
// Output the line numbers
$listing[$index]["rev1lineno"] = "$oline";
$listing[$index]["rev2lineno"] = "$nline";
$index++;
}
$fin = false;
while (!feof($diff) && !$fin)
{
$listing[$index]["rev1lineno"] = 0;
$listing[$index]["rev2lineno"] = 0;
 
$line = fgets($diff);
if (!strncmp($line, "@@", 2))
{
$fin = true;
}
else
{
$mod = $line{0};
 
if ($ent)
$line = replaceEntities(rtrim(substr($line, 1)), $rep);
else
$line = rtrim(substr($line, 1));
$listing[$index]["rev1line"] = hardspace($line);
 
$text = hardspace($line);
if ($text == "") $text = "&nbsp;";
switch ($mod)
{
case "-":
$listing[$index]["rev1diffclass"] = "diffdeleted";
$listing[$index]["rev2diffclass"] = "diff";
$listing[$index]["rev1line"] = $text;
$listing[$index]["rev2line"] = "&nbsp;";
if ($all)
{
fgets($ofile);
$curoline++;
}
break;
 
case "+":
// Try to mark "changed" line sensibly
if (!empty($listing[$index-1]) && empty($listing[$index-1]["rev1lineno"]) && @$listing[$index-1]["rev1diffclass"] == "diffdeleted" && @$listing[$index-1]["rev2diffclass"] == "diff")
{
$i = $index - 1;
while (!empty($listing[$i-1]) && empty($listing[$i-1]["rev1lineno"]) && $listing[$i-1]["rev1diffclass"] == "diffdeleted" && $listing[$i-1]["rev2diffclass"] == "diff")
$i--;
$listing[$i]["rev1diffclass"] = "diffchanged";
$listing[$i]["rev2diffclass"] = "diffchanged";
$listing[$i]["rev2line"] = $text;
if ($all)
{
fgets($nfile);
$curnline++;
}
 
// Don't increment the current index count
$index--;
}
else
{
$listing[$index]["rev1diffclass"] = "diff";
$listing[$index]["rev2diffclass"] = "diffadded";
$listing[$index]["rev1line"] = "&nbsp;";
$listing[$index]["rev2line"] = $text;
 
if ($all)
{
fgets($nfile);
$curnline++;
}
}
break;
default:
$listing[$index]["rev1diffclass"] = "diff";
$listing[$index]["rev2diffclass"] = "diff";
$listing[$index]["rev1line"] = $text;
$listing[$index]["rev2line"] = $text;
if ($all)
{
fgets($ofile);
fgets($nfile);
$curoline++;
$curnline++;
}
 
break;
}
}
if (!$fin)
$index++;
}
}
// Output the rest of the files
if ($all)
{
while (!feof($ofile) || !feof($nfile))
{
$listing[$index]["rev1diffclass"] = "diff";
$listing[$index]["rev2diffclass"] = "diff";
if ($ent)
$line = replaceEntities(rtrim(fgets($ofile)), $rep);
else
$line = rtrim(fgets($ofile));
 
if (!feof($ofile))
$listing[$index]["rev1line"] = hardspace($line);
else
$listing[$index]["rev1line"] = "&nbsp;";
if ($ent)
$line = replaceEntities(rtrim(fgets($nfile)), $rep);
else
$line = rtrim(fgets($nfile));
 
if (!feof($nfile))
$listing[$index]["rev2line"] = hardspace($line);
else
$listing[$index]["rev2line"] = "&nbsp;";
$listing[$index]["rev1lineno"] = 0;
$listing[$index]["rev2lineno"] = 0;
 
$index++;
}
}
pclose($diff);
}
if ($all)
{
fclose($ofile);
fclose($nfile);
}
 
// Remove our temporary files
unlink($oldtname);
unlink($newtname);
}
else
{
$vars["noprev"] = 1;
}
 
$vars["version"] = $version;
 
if (!$rep->hasReadAccess($path, false))
$vars["noaccess"] = true;
 
parseTemplate($rep->getTemplatePath()."header.tmpl", $vars, $listing);
parseTemplate($rep->getTemplatePath()."diff.tmpl", $vars, $listing);
parseTemplate($rep->getTemplatePath()."footer.tmpl", $vars, $listing);
?>
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// diff.php
//
// Show the differences between 2 revisions of a file.
//
 
require_once("include/setup.inc");
require_once("include/svnlook.inc");
require_once("include/utils.inc");
require_once("include/template.inc");
 
$context = 5;
 
$vars["action"] = $lang["DIFF"];
$all = (@$_REQUEST["all"] == 1)?1:0;
 
// Make sure that we have a repository
if (!isset($rep))
{
echo $lang["NOREP"];
exit;
}
 
$svnrep = new SVNRepository($rep);
 
// If there's no revision info, go to the lastest revision for this path
$history = $svnrep->getLog($path, "", "", true);
$youngest = $history->entries[0]->rev;
 
if (empty($rev))
$rev = $youngest;
 
$history = $svnrep->getLog($path, $rev);
 
if ($path{0} != "/")
$ppath = "/".$path;
else
$ppath = $path;
 
$prevrev = @$history->entries[1]->rev;
 
$vars["repname"] = $rep->getDisplayName();
$vars["rev"] = $rev;
$vars["path"] = $ppath;
$vars["prevrev"] = $prevrev;
 
$vars["rev1"] = $history->entries[0]->rev;
$vars["rev2"] = $prevrev;
 
createDirLinks($rep, $ppath, $rev, $showchanged);
 
$listing = array();
 
if ($prevrev)
{
$url = $config->getURL($rep, $path, "diff");
if (!$all)
{
$vars["showalllink"] = "<a href=\"${url}rev=$rev&amp;sc=$showchanged&amp;all=1\">${lang["SHOWENTIREFILE"]}</a>";
$vars["showcompactlink"] = "";
}
else
{
$vars["showcompactlink"] = "<a href=\"${url}rev=$rev&amp;sc=$showchanged&amp;all=0\">${lang["SHOWCOMPACT"]}</a>";
$vars["showalllink"] = "";
}
 
// Get the contents of the two files
$newtname = tempnam("temp", "");
$new = $svnrep->getFileContents($history->entries[0]->path, $newtname, $history->entries[0]->rev, "", true);
 
$oldtname = tempnam("temp", "");
$old = $svnrep->getFileContents($history->entries[1]->path, $oldtname, $history->entries[1]->rev, "", true);
$ent = true;
$extension = strrchr(basename($path), ".");
if (($extension && isset($extEnscript[$extension]) && ('php' == $extEnscript[$extension])) || ($config->useEnscript))
$ent = false;
 
$file1cache = array();
 
if ($all)
$context = 1; // Setting the context to 0 makes diff generate the wrong line numbers!
 
// Open a pipe to the diff command with $context lines of context
$cmd = quoteCommand($config->diff." --ignore-all-space -U $context $oldtname $newtname", false);
if ($all)
{
$ofile = fopen($oldtname, "r");
$nfile = fopen($newtname, "r");
}
 
if ($diff = popen($cmd, "r"))
{
// Ignore the 3 header lines
$line = fgets($diff);
$line = fgets($diff);
 
// Get the first real line
$line = fgets($diff);
$index = 0;
$listing = array();
$curoline = 1;
$curnline = 1;
while (!feof($diff))
{
// Get the first line of this range
sscanf($line, "@@ -%d", $oline);
$line = substr($line, strpos($line, "+"));
sscanf($line, "+%d", $nline);
if ($all)
{
while ($curoline < $oline || $curnline < $nline)
{
$listing[$index]["rev1diffclass"] = "diff";
$listing[$index]["rev2diffclass"] = "diff";
if ($curoline < $oline)
{
$nl = fgets($ofile);
if ($ent)
$line = replaceEntities(rtrim($nl), $rep);
else
$line = rtrim($nl);
$listing[$index]["rev1line"] = hardspace($line);
 
$curoline++;
}
else
$listing[$index]["rev1line"] = "&nbsp;";
if ($curnline < $nline)
{
$nl = fgets($nfile);
 
if ($ent)
$line = replaceEntities(rtrim($nl), $rep);
else
$line = rtrim($nl);
$listing[$index]["rev2line"] = hardspace($line);
$curnline++;
}
else
$listing[$index]["rev2line"] = "&nbsp;";
$listing[$index]["rev1lineno"] = 0;
$listing[$index]["rev2lineno"] = 0;
 
$index++;
}
}
else
{
// Output the line numbers
$listing[$index]["rev1lineno"] = "$oline";
$listing[$index]["rev2lineno"] = "$nline";
$index++;
}
$fin = false;
while (!feof($diff) && !$fin)
{
$listing[$index]["rev1lineno"] = 0;
$listing[$index]["rev2lineno"] = 0;
 
$line = fgets($diff);
if (!strncmp($line, "@@", 2))
{
$fin = true;
}
else
{
$mod = $line{0};
 
if ($ent)
$line = replaceEntities(rtrim(substr($line, 1)), $rep);
else
$line = rtrim(substr($line, 1));
$listing[$index]["rev1line"] = hardspace($line);
 
$text = hardspace($line);
if ($text == "") $text = "&nbsp;";
switch ($mod)
{
case "-":
$listing[$index]["rev1diffclass"] = "diffdeleted";
$listing[$index]["rev2diffclass"] = "diff";
$listing[$index]["rev1line"] = $text;
$listing[$index]["rev2line"] = "&nbsp;";
if ($all)
{
fgets($ofile);
$curoline++;
}
break;
 
case "+":
// Try to mark "changed" line sensibly
if (!empty($listing[$index-1]) && empty($listing[$index-1]["rev1lineno"]) && @$listing[$index-1]["rev1diffclass"] == "diffdeleted" && @$listing[$index-1]["rev2diffclass"] == "diff")
{
$i = $index - 1;
while (!empty($listing[$i-1]) && empty($listing[$i-1]["rev1lineno"]) && $listing[$i-1]["rev1diffclass"] == "diffdeleted" && $listing[$i-1]["rev2diffclass"] == "diff")
$i--;
$listing[$i]["rev1diffclass"] = "diffchanged";
$listing[$i]["rev2diffclass"] = "diffchanged";
$listing[$i]["rev2line"] = $text;
if ($all)
{
fgets($nfile);
$curnline++;
}
 
// Don't increment the current index count
$index--;
}
else
{
$listing[$index]["rev1diffclass"] = "diff";
$listing[$index]["rev2diffclass"] = "diffadded";
$listing[$index]["rev1line"] = "&nbsp;";
$listing[$index]["rev2line"] = $text;
 
if ($all)
{
fgets($nfile);
$curnline++;
}
}
break;
default:
$listing[$index]["rev1diffclass"] = "diff";
$listing[$index]["rev2diffclass"] = "diff";
$listing[$index]["rev1line"] = $text;
$listing[$index]["rev2line"] = $text;
if ($all)
{
fgets($ofile);
fgets($nfile);
$curoline++;
$curnline++;
}
 
break;
}
}
if (!$fin)
$index++;
}
}
// Output the rest of the files
if ($all)
{
while (!feof($ofile) || !feof($nfile))
{
$listing[$index]["rev1diffclass"] = "diff";
$listing[$index]["rev2diffclass"] = "diff";
if ($ent)
$line = replaceEntities(rtrim(fgets($ofile)), $rep);
else
$line = rtrim(fgets($ofile));
 
if (!feof($ofile))
$listing[$index]["rev1line"] = hardspace($line);
else
$listing[$index]["rev1line"] = "&nbsp;";
if ($ent)
$line = replaceEntities(rtrim(fgets($nfile)), $rep);
else
$line = rtrim(fgets($nfile));
 
if (!feof($nfile))
$listing[$index]["rev2line"] = hardspace($line);
else
$listing[$index]["rev2line"] = "&nbsp;";
$listing[$index]["rev1lineno"] = 0;
$listing[$index]["rev2lineno"] = 0;
 
$index++;
}
}
pclose($diff);
}
if ($all)
{
fclose($ofile);
fclose($nfile);
}
 
// Remove our temporary files
unlink($oldtname);
unlink($newtname);
}
else
{
$vars["noprev"] = 1;
}
 
$vars["version"] = $version;
 
if (!$rep->hasReadAccess($path, false))
$vars["noaccess"] = true;
 
parseTemplate($rep->getTemplatePath()."header.tmpl", $vars, $listing);
parseTemplate($rep->getTemplatePath()."diff.tmpl", $vars, $listing);
parseTemplate($rep->getTemplatePath()."footer.tmpl", $vars, $listing);
?>
/WebSVN/dl.php
1,110 → 1,110
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// dl.php
//
// Create gz/tar files of the requested item
 
require_once("include/setup.inc");
require_once("include/svnlook.inc");
require_once("include/utils.inc");
 
// Make sure that this operation is allowed
 
if (!$rep->isDownloadAllowed($path))
exit;
 
$svnrep = new SVNRepository($rep);
 
if ($path{0} != "/")
$ppath = "/".$path;
else
$ppath = $path;
 
// If there's no revision info, go to the lastest revision for this path
$history = $svnrep->getLog($path, "", "", true);
$youngest = $history->entries[0]->rev;
 
if (empty($rev))
$rev = $youngest;
 
// Create a temporary directory. Here we have an unavoidable but highly
// unlikely to occure race condition
 
$tmpname = tempnam("temp", "wsvn");
unlink($tmpname);
if (mkdir($tmpname))
{
// Get the name of the directory being archived
$arcname = substr($path, 0, -1);
$arcname = basename($arcname);
if (empty($arcname))
$arcname = $rep->name;
 
$svnrep->exportDirectory($path, $tmpname.DIRECTORY_SEPARATOR.$arcname, $rev);
// Create the tar file
chdir($tmpname);
exec($config->tar." -cf ".quote("$arcname.tar")." ".quote($arcname));
// ZIP it up
exec($config->gzip." ".quote("$arcname.tar"));
$size = filesize("$arcname.tar.gz");
 
// Give the file to the browser
 
if ($fp = @fopen("$arcname.tar.gz","rb"))
{
header("Content-Type: application/x-gzip");
header("Content-Length: $size");
header("Content-Disposition: attachment; filename=\"".$rep->name."-$arcname.tar.gz\"");
// Use a loop to transfer the data 4KB at a time.
while(!feof($fp))
{
echo fread($fp, 4096);
ob_flush();
}
}
else
{
print "Unable to open file $arcname.tar.gz";
}
fclose($fp);
chdir("..");
 
// Delete the directory. Why doesn't PHP have a generic recursive directory
// deletion command? It's stupid.
 
if ($config->serverIsWindows)
{
$cmd = quoteCommand("rmdir /S /Q ".quote($tmpname), false);
}
else
{
$cmd = quoteCommand("rm -rf ".quote($tmpname), false);
}
@exec($cmd);
}
?>
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// dl.php
//
// Create gz/tar files of the requested item
 
require_once("include/setup.inc");
require_once("include/svnlook.inc");
require_once("include/utils.inc");
 
// Make sure that this operation is allowed
 
if (!$rep->isDownloadAllowed($path))
exit;
 
$svnrep = new SVNRepository($rep);
 
if ($path{0} != "/")
$ppath = "/".$path;
else
$ppath = $path;
 
// If there's no revision info, go to the lastest revision for this path
$history = $svnrep->getLog($path, "", "", true);
$youngest = $history->entries[0]->rev;
 
if (empty($rev))
$rev = $youngest;
 
// Create a temporary directory. Here we have an unavoidable but highly
// unlikely to occure race condition
 
$tmpname = tempnam("temp", "wsvn");
unlink($tmpname);
if (mkdir($tmpname))
{
// Get the name of the directory being archived
$arcname = substr($path, 0, -1);
$arcname = basename($arcname);
if (empty($arcname))
$arcname = $rep->name;
 
$svnrep->exportDirectory($path, $tmpname.DIRECTORY_SEPARATOR.$arcname, $rev);
// Create the tar file
chdir($tmpname);
exec($config->tar." -cf ".quote("$arcname.tar")." ".quote($arcname));
// ZIP it up
exec($config->gzip." ".quote("$arcname.tar"));
$size = filesize("$arcname.tar.gz");
 
// Give the file to the browser
 
if ($fp = @fopen("$arcname.tar.gz","rb"))
{
header("Content-Type: application/x-gzip");
header("Content-Length: $size");
header("Content-Disposition: attachment; filename=\"".$rep->name."-$arcname.tar.gz\"");
// Use a loop to transfer the data 4KB at a time.
while(!feof($fp))
{
echo fread($fp, 4096);
ob_flush();
}
}
else
{
print "Unable to open file $arcname.tar.gz";
}
fclose($fp);
chdir("..");
 
// Delete the directory. Why doesn't PHP have a generic recursive directory
// deletion command? It's stupid.
 
if ($config->serverIsWindows)
{
$cmd = quoteCommand("rmdir /S /Q ".quote($tmpname), false);
}
else
{
$cmd = quoteCommand("rm -rf ".quote($tmpname), false);
}
@exec($cmd);
}
?>
/WebSVN/filedetails.php
1,156 → 1,156
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// filedetails.php
//
// Simply lists the contents of a file
 
require_once("include/setup.inc");
require_once("include/svnlook.inc");
require_once("include/utils.inc");
require_once("include/template.inc");
 
// Make sure that we have a repository
if (!isset($rep))
{
echo $lang["NOREP"];
exit;
}
 
$svnrep = new SVNRepository($rep);
 
if ($path{0} != "/")
$ppath = "/".$path;
else
$ppath = $path;
 
$passrev = $rev;
 
// If there's no revision info, go to the lastest revision for this path
$history = $svnrep->getLog($path, "", "", true);
$youngest = $history->entries[0]->rev;
 
if (empty($rev))
$rev = $youngest;
 
$extn = strrchr($path, ".");
 
// Check to see if the user has requested that this type be zipped and sent
// to the browser as an attachment
 
if (in_array($extn, $zipped))
{
$base = basename($path);
header("Content-Type: application/x-gzip");
header("Content-Disposition: attachment; filename=".urlencode($base).".gz");
 
// Get the file contents and pipe into gzip. All this without creating
// a temporary file. Damn clever.
$svnrep->getFileContents($path, "", $rev, "| ".$config->gzip." -n -f");
exit;
}
 
// Check to see if we should serve it with a particular content-type.
// The content-type could come from an svn:mime-type property on the
// file, or from the $contentType array in setup.inc.
 
if (!$rep->getIgnoreSvnMimeTypes())
{
$svnMimeType = $svnrep->getProperty($path, 'svn:mime-type', $rev);
}
 
if (!$rep->getIgnoreWebSVNContentTypes())
{
$setupContentType = @$contentType[$extn];
}
 
// Use this set of priorities when establishing what content-type to
// actually use.
 
if (!empty($svnMimeType) && $svnMimeType != 'application/octet-stream')
{
$cont = $svnMimeType;
}
else if (!empty($setupContentType))
{
$cont = $setupContentType;
}
else if (!empty($svnMimeType))
{
// It now is equal to application/octet-stream due to logic
// above....
$cont = $svnMimeType;
}
 
// If there's a MIME type associated with this format, then we deliver it
// with this information
 
if (!empty($cont))
{
$base = basename($path);
header("Content-Type: $cont");
//header("Content-Length: $size");
header("Content-Disposition: inline; filename=".urlencode($base));
$svnrep->getFileContents($path, "", $rev);
exit;
}
 
// There's no associated MIME type. Show the file using WebSVN.
 
$url = $config->getURL($rep, $path, "file");
 
if ($rev != $youngest)
$vars["goyoungestlink"] = "<a href=\"${url}sc=1\">${lang["GOYOUNGEST"]}</a>";
else
$vars["goyoungestlink"] = "";
 
$vars["action"] = "";
$vars["repname"] = $rep->getDisplayName();
$vars["rev"] = $rev;
$vars["path"] = $ppath;
 
createDirLinks($rep, $ppath, $passrev, $showchanged);
 
$url = $config->getURL($rep, $path, "log");
$vars["fileviewloglink"] = "<a href=\"${url}rev=$passrev&amp;sc=$showchanged&isdir=0\">${lang["VIEWLOG"]}</a>";
 
$url = $config->getURL($rep, $path, "diff");
$vars["prevdifflink"] = "<a href=\"${url}rev=$passrev&amp;sc=$showchanged\">${lang["DIFFPREV"]}</a>";
 
$url = $config->getURL($rep, $path, "blame");
$vars["blamelink"] = "<a href=\"${url}rev=$passrev&amp;sc=$showchanged\">${lang["BLAME"]}</a>";
 
$listing = array ();
 
$vars["version"] = $version;
 
if (!$rep->hasReadAccess($path, false))
$vars["noaccess"] = true;
 
parseTemplate($rep->getTemplatePath()."header.tmpl", $vars, $listing);
parseTemplate($rep->getTemplatePath()."file.tmpl", $vars, $listing);
parseTemplate($rep->getTemplatePath()."footer.tmpl", $vars, $listing);
?>
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// filedetails.php
//
// Simply lists the contents of a file
 
require_once("include/setup.inc");
require_once("include/svnlook.inc");
require_once("include/utils.inc");
require_once("include/template.inc");
 
// Make sure that we have a repository
if (!isset($rep))
{
echo $lang["NOREP"];
exit;
}
 
$svnrep = new SVNRepository($rep);
 
if ($path{0} != "/")
$ppath = "/".$path;
else
$ppath = $path;
 
$passrev = $rev;
 
// If there's no revision info, go to the lastest revision for this path
$history = $svnrep->getLog($path, "", "", true);
$youngest = $history->entries[0]->rev;
 
if (empty($rev))
$rev = $youngest;
 
$extn = strrchr($path, ".");
 
// Check to see if the user has requested that this type be zipped and sent
// to the browser as an attachment
 
if (in_array($extn, $zipped))
{
$base = basename($path);
header("Content-Type: application/x-gzip");
header("Content-Disposition: attachment; filename=".urlencode($base).".gz");
 
// Get the file contents and pipe into gzip. All this without creating
// a temporary file. Damn clever.
$svnrep->getFileContents($path, "", $rev, "| ".$config->gzip." -n -f");
exit;
}
 
// Check to see if we should serve it with a particular content-type.
// The content-type could come from an svn:mime-type property on the
// file, or from the $contentType array in setup.inc.
 
if (!$rep->getIgnoreSvnMimeTypes())
{
$svnMimeType = $svnrep->getProperty($path, 'svn:mime-type', $rev);
}
 
if (!$rep->getIgnoreWebSVNContentTypes())
{
$setupContentType = @$contentType[$extn];
}
 
// Use this set of priorities when establishing what content-type to
// actually use.
 
if (!empty($svnMimeType) && $svnMimeType != 'application/octet-stream')
{
$cont = $svnMimeType;
}
else if (!empty($setupContentType))
{
$cont = $setupContentType;
}
else if (!empty($svnMimeType))
{
// It now is equal to application/octet-stream due to logic
// above....
$cont = $svnMimeType;
}
 
// If there's a MIME type associated with this format, then we deliver it
// with this information
 
if (!empty($cont))
{
$base = basename($path);
header("Content-Type: $cont");
//header("Content-Length: $size");
header("Content-Disposition: inline; filename=".urlencode($base));
$svnrep->getFileContents($path, "", $rev);
exit;
}
 
// There's no associated MIME type. Show the file using WebSVN.
 
$url = $config->getURL($rep, $path, "file");
 
if ($rev != $youngest)
$vars["goyoungestlink"] = "<a href=\"${url}sc=1\">${lang["GOYOUNGEST"]}</a>";
else
$vars["goyoungestlink"] = "";
 
$vars["action"] = "";
$vars["repname"] = $rep->getDisplayName();
$vars["rev"] = $rev;
$vars["path"] = $ppath;
 
createDirLinks($rep, $ppath, $passrev, $showchanged);
 
$url = $config->getURL($rep, $path, "log");
$vars["fileviewloglink"] = "<a href=\"${url}rev=$passrev&amp;sc=$showchanged&isdir=0\">${lang["VIEWLOG"]}</a>";
 
$url = $config->getURL($rep, $path, "diff");
$vars["prevdifflink"] = "<a href=\"${url}rev=$passrev&amp;sc=$showchanged\">${lang["DIFFPREV"]}</a>";
 
$url = $config->getURL($rep, $path, "blame");
$vars["blamelink"] = "<a href=\"${url}rev=$passrev&amp;sc=$showchanged\">${lang["BLAME"]}</a>";
 
$listing = array ();
 
$vars["version"] = $version;
 
if (!$rep->hasReadAccess($path, false))
$vars["noaccess"] = true;
 
parseTemplate($rep->getTemplatePath()."header.tmpl", $vars, $listing);
parseTemplate($rep->getTemplatePath()."file.tmpl", $vars, $listing);
parseTemplate($rep->getTemplatePath()."footer.tmpl", $vars, $listing);
?>
/WebSVN/form.php
1,66 → 1,66
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// form.php
//
// Handling of WebSVN forms
 
require_once("include/setup.inc");
require_once("include/utils.inc");
 
// Generic redirect handling
 
function redirect($loc)
{
$url= getFullURL($loc);
# technically, a die(header('Location: '.$url)); would suffice for all web browsers... ~J
header("Location: $url");
echo "<html>\n <head>\n <title>Redirecting...</title>\n <meta http-equiv='refresh' content='0; url=$url' />
<script type='application/x-javascript'><![CDATA[ window.location.href = '$url'; ]]></script>
</head>
<body>
<p>If you are not automatically redirected, please click <a href='$url'>here</a> to continue.</p>
</body>\n</html>";
}
 
// Handle project selection
 
if (@$_REQUEST["selectproj"])
{
$basedir = dirname($_SERVER["PHP_SELF"]);
if ($basedir != "" && $basedir != DIRECTORY_SEPARATOR && $basedir != "\\" && $basedir != "/" )
$basedir .= "/";
else
$basedir = "/";
$url = $config->getURL($rep, "/", "dir");
$url = html_entity_decode($url);
if ($config->multiViews)
redirect($url."sc=$showchanged");
else
redirect($basedir.$url."sc=$showchanged");
}
 
 
?>
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// form.php
//
// Handling of WebSVN forms
 
require_once("include/setup.inc");
require_once("include/utils.inc");
 
// Generic redirect handling
 
function redirect($loc)
{
$url= getFullURL($loc);
# technically, a die(header('Location: '.$url)); would suffice for all web browsers... ~J
header("Location: $url");
echo "<html>\n <head>\n <title>Redirecting...</title>\n <meta http-equiv='refresh' content='0; url=$url' />
<script type='application/x-javascript'><![CDATA[ window.location.href = '$url'; ]]></script>
</head>
<body>
<p>If you are not automatically redirected, please click <a href='$url'>here</a> to continue.</p>
</body>\n</html>";
}
 
// Handle project selection
 
if (@$_REQUEST["selectproj"])
{
$basedir = dirname($_SERVER["PHP_SELF"]);
if ($basedir != "" && $basedir != DIRECTORY_SEPARATOR && $basedir != "\\" && $basedir != "/" )
$basedir .= "/";
else
$basedir = "/";
$url = $config->getURL($rep, "/", "dir");
$url = html_entity_decode($url);
if ($config->multiViews)
redirect($url."sc=$showchanged");
else
redirect($basedir.$url."sc=$showchanged");
}
 
 
?>
/WebSVN/index.php
1,112 → 1,111
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// index.php
//
// Main page. Lists all the projects
 
require_once("include/setup.inc");
require_once("include/svnlook.inc");
require_once("include/template.inc");
 
$vars["action"] = $lang["PROJECTS"];
$vars["repname"] = "";
$vars["rev"] = 0;
$vars["path"] = "";
 
// Sort the repositories by group
$config->sortByGroup();
 
if ($config->flatIndex)
{
// Create the flat view
$projects = $config->getRepositories();
$i = 0;
$listing = array ();
foreach ($projects as $project)
{
if ($project->hasReadAccess("/", true))
{
$url = $config->getURL($project, "/", "dir");
$listing[$i]["rowparity"] = $i % 2;
$listing[$i++]["projlink"] = "<a href=\"${url}sc=0\">".$project->getDisplayName()."</a>";
}
}
$vars["flatview"] = true;
$vars["treeview"] = false;
}
else
{
// Create the tree view
$projects = $config->getRepositories();
reset($projects);
$i = 0;
$listing = array ();
$curgroup = NULL;
$parity = 0;
foreach ($projects as $project)
{
if ($project->hasReadAccess("/", true))
{
$listing[$i]["rowparity"] = $parity % 2;
$url = $config->getURL($project, "/", "dir");
if ($curgroup != $project->group)
{
# TODO: this should be de-soupified
if (!empty($curgroup))
$listing[$i]["listitem"] = "</div>\n"; // Close the switchcontent div
else
$listing[$i]["listitem"] = "";
 
$listing[$i]["isprojlink"] = false;
$listing[$i]["isgrouphead"] = true;
$curgroup = $project->group;
$listing[$i++]["listitem"] .= "<div class=\"groupname\" onclick=\"expandcontent(this, '$curgroup');\" style=\"cursor:hand; cursor:pointer\"><div class=\"a\"><span class=\"showstate\"></span>$curgroup</div></div>\n<div id=\"$curgroup\" class=\"switchcontent\">";
}
 
$parity++;
$listing[$i]["isgrouphead"] = false;
$listing[$i]["isprojlink"] = true;
$listing[$i++]["listitem"] = "<a href=\"${url}sc=0\">".$project->name."</a>\n";
}
}
 
if (!empty($curgroup))
$listing[$i]["isprojlink"] = false;
$listing[$i]["isgrouphead"] = false;
$listing[$i]["listitem"] = "</div>"; // Close the switchcontent div
 
$vars["flatview"] = false;
$vars["treeview"] = true;
$vars["opentree"] = $config->openTree;
}
 
$vars["version"] = $version;
parseTemplate($config->getTemplatePath()."header.tmpl", $vars, $listing);
parseTemplate($config->getTemplatePath()."index.tmpl", $vars, $listing);
parseTemplate($config->getTemplatePath()."footer.tmpl", $vars, $listing);
 
?>
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// index.php
//
// Main page. Lists all the projects
 
require_once("include/setup.inc");
require_once("include/svnlook.inc");
require_once("include/template.inc");
 
$vars["action"] = $lang["PROJECTS"];
$vars["repname"] = "";
$vars["rev"] = 0;
$vars["path"] = "";
 
// Sort the repositories by group
$config->sortByGroup();
 
if ($config->flatIndex)
{
// Create the flat view
$projects = $config->getRepositories();
$i = 0;
$listing = array ();
foreach ($projects as $project)
{
if ($project->hasReadAccess("/", true))
{
$url = $config->getURL($project, "/", "dir");
$listing[$i]["rowparity"] = $i % 2;
$listing[$i++]["projlink"] = "<a href=\"${url}sc=0\">".$project->getDisplayName()."</a>";
}
}
$vars["flatview"] = true;
$vars["treeview"] = false;
}
else
{
// Create the tree view
$projects = $config->getRepositories();
reset($projects);
$i = 0;
$listing = array ();
$curgroup = NULL;
$parity = 0;
foreach ($projects as $project)
{
if ($project->hasReadAccess("/", true))
{
$listing[$i]["rowparity"] = $parity % 2;
$url = $config->getURL($project, "/", "dir");
if ($curgroup != $project->group)
{
if (!empty($curgroup))
$listing[$i]["listitem"] = "</div>\n"; // Close the switchcontent div
else
$listing[$i]["listitem"] = "";
 
$listing[$i]["isprojlink"] = false;
$listing[$i]["isgrouphead"] = true;
$curgroup = $project->group;
$listing[$i++]["listitem"] .= "<div class=\"groupname\" onclick=\"expandcontent(this, '$curgroup');\" style=\"cursor:hand; cursor:pointer\"><div class=\"a\"><span class=\"showstate\"></span>$curgroup</div></div>\n<div id=\"$curgroup\" class=\"switchcontent\">";
}
 
$parity++;
$listing[$i]["isgrouphead"] = false;
$listing[$i]["isprojlink"] = true;
$listing[$i++]["listitem"] = "<a href=\"${url}sc=0\">".$project->name."</a>\n";
}
}
 
if (!empty($curgroup))
$listing[$i]["isprojlink"] = false;
$listing[$i]["isgrouphead"] = false;
$listing[$i]["listitem"] = "</div>"; // Close the switchcontent div
 
$vars["flatview"] = false;
$vars["treeview"] = true;
$vars["opentree"] = $config->openTree;
}
 
$vars["version"] = $version;
parseTemplate($config->getTemplatePath()."header.tmpl", $vars, $listing);
parseTemplate($config->getTemplatePath()."index.tmpl", $vars, $listing);
parseTemplate($config->getTemplatePath()."footer.tmpl", $vars, $listing);
 
?>
/WebSVN/install.txt
1,216 → 1,216
 
WHY WebSVN?
 
WebSVN offers a view onto your subversion repositories that's been designed
to reflect the Subversion methodology. You can view the log of any file or
directory and see a list of all the files changed, added or deleted in any
given revision. You can also view the differences between 2 versions of a
file so as to see exactly what was changed in a particular revision.
 
WebSVN offers the following features:
 
* Easy to use interface
* Highly customisable templating system
* Colourisation of file listings
* Blame view
* Log message searching
* Fast browsing thanks to internal caching feature
* Apache MultiViews support
* RSS feed support
 
Since it's written using PHP, WebSVN is also very portable and easy to install.
 
INSTALLATION
 
Grab the source and stick it somewhere that your server can get to. You
obviously need to have PHP installed and working. Also note that WebSVN
won't currently work in safe mode, due to the need to call svnlook.
 
You'll also need diff (preferably the GNU version; for Windows users I'd
recommend the Cygwin version) and svnlook available.
 
Rename distconfig.inc as config.inc (found in the includes directory)and then
edit it as directed in the file itself.
 
If everything has gone well, you should be able to view your projects by
pointing your browser at the index.php file.
 
For those of you wishing to customise the look and feel a little, you should
read templates.txt, which explains the highly configurable template system.
 
Windows users - note that some of the features offered by WebSVN, when
enabled, require the use of various external programs. They can be downloaded
from these locations:
 
Diff/Sed/Gzip/Tar: http://www.cygwin.com/
Enscript: http://people.ssh.com/mtr/genscript/
 
ACCENTED CHARACTERS
 
WebSVN is designed to worked with accented characters. To do this, it uses
the iconv function. This may not be installed on your system. If you aren't
getting the characters that you expect, make sure that the iconv module is
being loaded in php.ini. Windows users will need to copy the appropriate
DLLs to the system directory (from the PHP installation directory).
 
CACHING
 
In order to return results with a reasonable speed, WebSVN caches the results
of it's requests to svnlook. Under normal usage this works correctly since
it's not generally possible to change a revision with subversion.
 
That said, one case that may cause confusion is if someone changes the log
message of a given revision. WebSVN will have cached the previous log message
and won't know that there's a new one available. There are various solutions
to this problem:
 
1) Turn off caching in the config file. This will severely impede the
perfomance of WebSVN.
 
2) Change the post-revprop-change hook so that is deletes the contents of the
cache after any change to a revision property
 
3) Only allow the administrator to change revision properties. He can then
delete the cache by hand should this occur.
 
COLOURISATION
 
You can few files with syntax colouring if you have Enscript 1.6 or higher
installed on your system. You'll also need Sed.
 
Simply set the paths in the config file and then uncomment the line:
 
$config->useEnscript();
 
MULTIVIEWS
 
You may choose to configure access to your repository via Apache's MultiView
system. This will enable you to access a respositoy using a url such as:
 
http://servername/wsvn/repname/path/in/repository
 
To do this you must:
 
- Place wsvn.php where you want to. Normally you place it such that it's
accessible straight after the servername, as shown above.
 
- Configure the parent directory of wsvn.php to use MultiViews (see Apache
docs).
 
- Change config.inc to include the line $config->useMultiViews();
 
- Change the paths configured at the beginning of the wsvn.php script.
 
Now go to http://servername/wsvn/ and make sure that you get the index page.
 
The repname part of the URL is the name given to it in the config.inc file.
For this reason you may wish to avoid putting spaces in the name.
 
MULTIVIEWS EXAMPLE
 
First, you must get the Multiviews option working. In my set up, my Apache
directory root is set to a location on my harddrive:
 
DocumentRoot "D:/svnpage"
 
In that directory, I have WebSVN installed in a directory called websvn.
Normally WebSVN would be accessed by http://servername/websvn
 
wsvn.php in then copied from the WebSVN installation to the document root
directory and the variables at the beginning of the script configured as
follows (based on your own directory locations, obviously):
 
// Location of websvn directory via HTTP
//
// e.g. For http://servername/websvn use /websvn
//
// Note that wsvn.php need not be in the /websvn directory (and normally isn't).
$locwebsvnhttp = "/websvn";
 
// Physical location of websvn directory
$locwebsvnreal = "d:/svnpage/websvn";
 
Next, turn on Multiviews in the WebSVN config.inc file:
 
$config->useMultiViews();
 
Finally, Apache needs to know that you want to enable MultiViews for the root
directory. This can be done by including this line in the directory's
.htaccess file (assuming that the appropriate AllowOverrides directive is set
up):
 
Options MultiViews
 
 
If all has gone well, repositories should now by accessible by
http://servername/wsvn/repname
 
Note the index page can be accessed through http://servername/wsvn
If you want to view the index page by http://servername/ you need to
add another directive to the .htaccess file:
 
DirectoryIndex wsvn.php
 
ACCESS RIGHTS AND AUTHENTICATION
 
You may wish to provide an authentication mechanism for WebSVN. One obvious
solution is to protect the entire WebSVN directory with some form of Apache
authentication mechanism, but that doesn't allow for per repository
authentication.
 
WebSVN provides and access rights mechanism that uses your SVN access file to
control read access to the repository. This means that you only have to
maintain one file to define both Subversion and WebSVN access rights.
 
For this to work, you need to configure your authentication method to the /WebSVN/
(or /wsvn/) directory. This should be the same authentication as you use for
the svn repositories themselves. Here's an example using SSPI:
 
<Location /WebSVN/>
AuthType SSPI
SSPIAuth On
SSPIAuthoritative On
SSPIDomain IMAJEMAIL
SSPIOfferBasic On
Require valid-user
</Location>
 
Note the use of the / after /WebSVN/ in the location directive. If you use
<Location /WebSVN> then you won't be able to access the index.
 
You should change /WebSVN/ to /wsvn/ if you're using multiviews.
 
Also note that you shouldn't use the AuthzSVNAccessFile command to define the
access file.
 
Now that you've defined your authentication, you'll be asked for your user name
and password in order to access the WebSVN directory. All that's left is to
configure WebSVN to use your Subversion access file to control access. Add this
line to your config.inc file:
 
$config->useAuthenticationFile("/path/to/accessfile");
 
Note that if your access file gives read access to, for example, path /a/b/c/ but
not to /a/b/, then the user will be given restricted access to /a/b/ in order to
reach /a/b/c/. The user will not be able to see any other files or directories in
/a or /a/b/.
 
You should read the Subversion book for information on the access file format.
 
COMMON PROBLEMS
 
1) On a Windows machine, this error is reported:
 
Warning: shell_exec(): Unable to execute
 
If you experience this problem, you need to give IUSR_<machinename> execute
permissions on %systemroot%\system32\cmd.exe. Under most systems, the file will
be C:\WINDOWS\system32\cmd.exe.
 
Right-click on the file, choose properties, and on the security tab click
the "Add" button. Add the IUSR_<machinename> user, and then select the
"read" and "read & execute" boxes.
 
LICENCE
 
GNU Public licence.
 
WHY WebSVN?
 
WebSVN offers a view onto your subversion repositories that's been designed
to reflect the Subversion methodology. You can view the log of any file or
directory and see a list of all the files changed, added or deleted in any
given revision. You can also view the differences between 2 versions of a
file so as to see exactly what was changed in a particular revision.
 
WebSVN offers the following features:
 
* Easy to use interface
* Highly customisable templating system
* Colourisation of file listings
* Blame view
* Log message searching
* Fast browsing thanks to internal caching feature
* Apache MultiViews support
* RSS feed support
 
Since it's written using PHP, WebSVN is also very portable and easy to install.
 
INSTALLATION
 
Grab the source and stick it somewhere that your server can get to. You
obviously need to have PHP installed and working. Also note that WebSVN
won't currently work in safe mode, due to the need to call svnlook.
 
You'll also need diff (preferably the GNU version; for Windows users I'd
recommend the Cygwin version) and svnlook available.
 
Rename distconfig.inc as config.inc (found in the includes directory)and then
edit it as directed in the file itself.
 
If everything has gone well, you should be able to view your projects by
pointing your browser at the index.php file.
 
For those of you wishing to customise the look and feel a little, you should
read templates.txt, which explains the highly configurable template system.
 
Windows users - note that some of the features offered by WebSVN, when
enabled, require the use of various external programs. They can be downloaded
from these locations:
 
Diff/Sed/Gzip/Tar: http://www.cygwin.com/
Enscript: http://people.ssh.com/mtr/genscript/
 
ACCENTED CHARACTERS
 
WebSVN is designed to worked with accented characters. To do this, it uses
the iconv function. This may not be installed on your system. If you aren't
getting the characters that you expect, make sure that the iconv module is
being loaded in php.ini. Windows users will need to copy the appropriate
DLLs to the system directory (from the PHP installation directory).
 
CACHING
 
In order to return results with a reasonable speed, WebSVN caches the results
of it's requests to svnlook. Under normal usage this works correctly since
it's not generally possible to change a revision with subversion.
 
That said, one case that may cause confusion is if someone changes the log
message of a given revision. WebSVN will have cached the previous log message
and won't know that there's a new one available. There are various solutions
to this problem:
 
1) Turn off caching in the config file. This will severely impede the
perfomance of WebSVN.
 
2) Change the post-revprop-change hook so that is deletes the contents of the
cache after any change to a revision property
 
3) Only allow the administrator to change revision properties. He can then
delete the cache by hand should this occur.
 
COLOURISATION
 
You can few files with syntax colouring if you have Enscript 1.6 or higher
installed on your system. You'll also need Sed.
 
Simply set the paths in the config file and then uncomment the line:
 
$config->useEnscript();
 
MULTIVIEWS
 
You may choose to configure access to your repository via Apache's MultiView
system. This will enable you to access a respositoy using a url such as:
 
http://servername/wsvn/repname/path/in/repository
 
To do this you must:
 
- Place wsvn.php where you want to. Normally you place it such that it's
accessible straight after the servername, as shown above.
 
- Configure the parent directory of wsvn.php to use MultiViews (see Apache
docs).
 
- Change config.inc to include the line $config->useMultiViews();
 
- Change the paths configured at the beginning of the wsvn.php script.
 
Now go to http://servername/wsvn/ and make sure that you get the index page.
 
The repname part of the URL is the name given to it in the config.inc file.
For this reason you may wish to avoid putting spaces in the name.
 
MULTIVIEWS EXAMPLE
 
First, you must get the Multiviews option working. In my set up, my Apache
directory root is set to a location on my harddrive:
 
DocumentRoot "D:/svnpage"
 
In that directory, I have WebSVN installed in a directory called websvn.
Normally WebSVN would be accessed by http://servername/websvn
 
wsvn.php in then copied from the WebSVN installation to the document root
directory and the variables at the beginning of the script configured as
follows (based on your own directory locations, obviously):
 
// Location of websvn directory via HTTP
//
// e.g. For http://servername/websvn use /websvn
//
// Note that wsvn.php need not be in the /websvn directory (and normally isn't).
$locwebsvnhttp = "/websvn";
 
// Physical location of websvn directory
$locwebsvnreal = "d:/svnpage/websvn";
 
Next, turn on Multiviews in the WebSVN config.inc file:
 
$config->useMultiViews();
 
Finally, Apache needs to know that you want to enable MultiViews for the root
directory. This can be done by including this line in the directory's
.htaccess file (assuming that the appropriate AllowOverrides directive is set
up):
 
Options MultiViews
 
 
If all has gone well, repositories should now by accessible by
http://servername/wsvn/repname
 
Note the index page can be accessed through http://servername/wsvn
If you want to view the index page by http://servername/ you need to
add another directive to the .htaccess file:
 
DirectoryIndex wsvn.php
 
ACCESS RIGHTS AND AUTHENTICATION
 
You may wish to provide an authentication mechanism for WebSVN. One obvious
solution is to protect the entire WebSVN directory with some form of Apache
authentication mechanism, but that doesn't allow for per repository
authentication.
 
WebSVN provides and access rights mechanism that uses your SVN access file to
control read access to the repository. This means that you only have to
maintain one file to define both Subversion and WebSVN access rights.
 
For this to work, you need to configure your authentication method to the /WebSVN/
(or /wsvn/) directory. This should be the same authentication as you use for
the svn repositories themselves. Here's an example using SSPI:
 
<Location /WebSVN/>
AuthType SSPI
SSPIAuth On
SSPIAuthoritative On
SSPIDomain IMAJEMAIL
SSPIOfferBasic On
Require valid-user
</Location>
 
Note the use of the / after /WebSVN/ in the location directive. If you use
<Location /WebSVN> then you won't be able to access the index.
 
You should change /WebSVN/ to /wsvn/ if you're using multiviews.
 
Also note that you shouldn't use the AuthzSVNAccessFile command to define the
access file.
 
Now that you've defined your authentication, you'll be asked for your user name
and password in order to access the WebSVN directory. All that's left is to
configure WebSVN to use your Subversion access file to control access. Add this
line to your config.inc file:
 
$config->useAuthenticationFile("/path/to/accessfile");
 
Note that if your access file gives read access to, for example, path /a/b/c/ but
not to /a/b/, then the user will be given restricted access to /a/b/ in order to
reach /a/b/c/. The user will not be able to see any other files or directories in
/a or /a/b/.
 
You should read the Subversion book for information on the access file format.
 
COMMON PROBLEMS
 
1) On a Windows machine, this error is reported:
 
Warning: shell_exec(): Unable to execute
 
If you experience this problem, you need to give IUSR_<machinename> execute
permissions on %systemroot%\system32\cmd.exe. Under most systems, the file will
be C:\WINDOWS\system32\cmd.exe.
 
Right-click on the file, choose properties, and on the security tab click
the "Add" button. Add the IUSR_<machinename> user, and then select the
"read" and "read & execute" boxes.
 
LICENCE
 
GNU Public licence.
/WebSVN/licence.txt
1,280 → 1,280
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
 
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
 
Preamble
 
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
 
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
 
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
 
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
 
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
 
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
 
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
 
The precise terms and conditions for copying, distribution and
modification follow.
 
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
 
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
 
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
 
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
 
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
 
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
 
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
 
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
 
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
 
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
 
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
 
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
 
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
 
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
 
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
 
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
 
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
 
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
 
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
 
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
 
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
 
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
 
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
 
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
 
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
 
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
 
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
 
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
 
NO WARRANTY
 
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
 
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
 
END OF TERMS AND CONDITIONS
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
 
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
 
Preamble
 
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
 
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
 
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
 
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
 
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
 
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
 
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
 
The precise terms and conditions for copying, distribution and
modification follow.
 
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
 
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
 
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
 
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
 
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
 
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
 
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
 
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
 
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
 
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
 
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
 
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
 
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
 
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
 
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
 
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
 
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
 
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
 
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
 
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
 
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
 
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
 
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
 
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
 
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
 
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
 
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
 
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
 
NO WARRANTY
 
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
 
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
 
END OF TERMS AND CONDITIONS
/WebSVN/log.php
1,333 → 1,333
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// log.php
//
// Show the logs for the given path
 
require_once("include/setup.inc");
require_once("include/svnlook.inc");
require_once("include/utils.inc");
require_once("include/template.inc");
require_once("include/bugtraq.inc");
 
$page = (int)@$_REQUEST["page"];
$all = (@$_REQUEST["all"] == 1)?1:0;
$isDir = (@$_REQUEST["isdir"] == 1)?1:0;
$dosearch = (@$_REQUEST["logsearch"] == 1)?1:0;
$search = trim(@$_REQUEST["search"]);
$words = preg_split('#\s+#', $search);
$fromRev = (int)@$_REQUEST["fr"];
$startrev = strtoupper(trim(@$_REQUEST["sr"]));
$endrev = strtoupper(trim(@$_REQUEST["er"]));
$max = @$_REQUEST["max"];
 
// Max number of results to find at a time
$numSearchResults = 15;
 
if ($search == "")
$dosearch = false;
 
// removeAccents
//
// Remove all the accents from a string. This function doesn't seem
// ideal, but expecting everyone to install 'unac' seems a little
// excessive as well...
 
function removeAccents($string)
{
return strtr($string,
"ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ",
"AAAAAAaaaaaaOOOOOOooooooEEEEeeeeCcIIIIiiiiUUUUuuuuyNn");
}
 
// Normalise the search words
foreach ($words as $index => $word)
{
$words[$index] = strtolower(removeAccents($word));
// Remove empty string introduced by multiple spaces
if (empty($words[$index]))
unset($words[$index]);
}
 
if (empty($page)) $page = 1;
 
// If searching, display all the results
$all = (bool) $dosearch;
 
$maxperpage = 20;
 
// Make sure that we have a repository
if (!isset($rep))
{
echo $lang["NOREP"];
exit;
}
 
$svnrep = new SVNRepository($rep);
 
$passrev = $rev;
 
// If there's no revision info, go to the lastest revision for this path
$history = $svnrep->getLog($path, "", "", true);
$youngest = $history->entries[0]->rev;
 
if (empty($rev))
$rev = $youngest;
 
// make sure path is prefixed by a /
$ppath = $path;
if ($path == "" || $path{0} != "/")
$ppath = "/".$path;
 
$vars["action"] = $lang["LOG"];
$vars["repname"] = $rep->getDisplayName();
$vars["rev"] = $rev;
$vars["path"] = $ppath;
 
createDirLinks($rep, $ppath, $passrev, $showchanged);
 
$logurl = $config->getURL($rep, $path, "log");
 
if ($rev != $youngest)
$vars["goyoungestlink"] = "<a href=\"${logurl}sc=1\">${lang["GOYOUNGEST"]}</a>";
else
$vars["goyoungestlink"] = "";
 
// We get the bugtraq variable just once based on the HEAD
$bugtraq = new Bugtraq($rep, $svnrep, $ppath);
 
if ($startrev != "HEAD") $startrev = (int)$startrev;
if (empty($startrev)) $startrev = $rev;
if (empty($endrev)) $endrev = 1;
 
if (empty($_REQUEST["max"]))
{
if (empty($_REQUEST["logsearch"]))
$max = 30;
else
$max = 0;
}
else
{
$max = (int)$max;
if ($max < 0) $max = 30;
}
 
$history = $svnrep->getLog($path, $startrev, $endrev, true, $max);
$vars["logsearch_moreresultslink"] = "";
$vars["pagelinks"] = "";
$vars["showalllink"] = "";
$listing = array();
 
if (!empty($history))
{
// Get the number of separate revisions
$revisions = count($history->entries);
if ($all)
{
$firstrevindex = 0;
$lastrevindex = $revisions - 1;
$pages = 1;
}
else
{
// Calculate the number of pages
$pages = floor($revisions / $maxperpage);
if (($revisions % $maxperpage) > 0) $pages++;
if ($page > $pages) $page = $pages;
// Word out where to start and stop
$firstrevindex = ($page - 1) * $maxperpage;
$lastrevindex = $firstrevindex + $maxperpage - 1;
if ($lastrevindex > $revisions - 1) $lastrevindex = $revisions - 1;
}
$history = $svnrep->getLog($path, $history->entries[$firstrevindex ]->rev, $history->entries[$lastrevindex]->rev, false, 0);
$row = 0;
$index = 0;
$listing = array();
$found = false;
foreach ($history->entries as $r)
{
// Assume a good match
$match = true;
$thisrev = $r->rev;
// Check the log for the search words, if searching
if ($dosearch)
{
if ((empty($fromRev) || $fromRev > $thisrev))
{
// Turn all the HTML entities into real characters.
// Make sure that each word in the search in also in the log
foreach($words as $word)
{
if (strpos(strtolower(removeAccents($r->msg)), $word) === false)
{
$match = false;
break;
}
}
if ($match)
{
$numSearchResults--;
$found = true;
}
}
else
$match = false;
}
if ($match)
{
// Add the trailing slash if we need to (svnlook history doesn't return trailing slashes!)
$rpath = $r->path;
if (empty($rpath))
$rpath = "/";
else if ($isDir && $rpath{strlen($rpath) - 1} != "/")
$rpath .= "/";
// Find the parent path (or the whole path if it's already a directory)
$pos = strrpos($rpath, "/");
$parent = substr($rpath, 0, $pos + 1);
$url = $config->getURL($rep, $parent, "dir");
$listing[$index]["revlink"] = "<a href=\"${url}rev=$thisrev&amp;sc=1\">$thisrev</a>";
if ($isDir)
{
$listing[$index]["compare_box"] = "<input type=\"checkbox\" name=\"compare[]\" value=\"$parent@$thisrev\" onclick=\"checkCB(this)\" />";
$url = $config->getURL($rep, $rpath, "dir");
$listing[$index]["revpathlink"] = "<a href=\"${url}rev=$thisrev&amp;sc=$showchanged\">$rpath</a>";
}
else
{
$listing[$index]["compare_box"] = "<input type=\"checkbox\" name=\"compare[]\" value=\"$rpath@$thisrev\" onclick=\"checkCB(this)\" />";
$url = $config->getURL($rep, $rpath, "file");
$listing[$index]["revpathlink"] = "<a href=\"${url}rev=$thisrev&amp;sc=$showchanged\">$rpath</a>";
}
$listing[$index]["revauthor"] = $r->author;
$listing[$index]["revage"] = $r->age;
$listing[$index]["revlog"] = nl2br($bugtraq->replaceIDs(create_anchors($r->msg)));
$listing[$index]["rowparity"] = "$row";
$row = 1 - $row;
$index++;
}
// If we've reached the search limit, stop here...
if (!$numSearchResults)
{
$url = $config->getURL($rep, $path, "log");
$vars["logsearch_moreresultslink"] = "<a href=\"${url}rev=$rev&amp;sc=$showchanged&amp;isdir=$isDir&amp;logsearch=1&amp;search=$search&amp;fr=$thisrev\">${lang["MORERESULTS"]}</a>";
break;
}
}
$vars["logsearch_resultsfound"] = true;
if ($dosearch && !$found)
{
if ($fromRev == 0)
{
$vars["logsearch_nomatches"] = true;
$vars["logsearch_resultsfound"] = false;
}
else
$vars["logsearch_nomorematches"] = true;
}
else if ($dosearch && $numSearchResults > 0)
{
$vars["logsearch_nomorematches"] = true;
}
// Work out the paging options
if ($pages > 1)
{
$prev = $page - 1;
$next = $page + 1;
echo "<p><center>";
if ($page > 1) $vars["pagelinks"] .= "<a href=\"${logurl}rev=$rev&amp;sr=$startrev&amp;er=$endrev&amp;sc=$showchanged&amp;max=$max&amp;page=$prev\"><&nbsp;${lang["PREV"]}</a> ";
for ($p = 1; $p <= $pages; $p++)
{
if ($p != $page)
$vars["pagelinks"].= "<a href=\"${logurl}rev=$rev&amp;sr=$startrev&amp;er=$endrev&amp;sc=$showchanged&amp;max=$max&amp;page=$p\">$p</a> ";
else
$vars["pagelinks"] .= "<b>$p </b>";
}
if ($page < $pages) $vars["pagelinks"] .=" <a href=\"${logurl}rev=$rev&amp;sr=$startrev&amp;er=$endrev&amp;sc=$showchanged&amp;max=$max&amp;page=$next\">${lang["NEXT"]}&nbsp;></a>";
$vars["showalllink"] = "<a href=\"${logurl}rev=$rev&amp;sr=$startrev&amp;er=$endrev&amp;sc=$showchanged&amp;all=1&amp;max=$max\">${lang["SHOWALL"]}</a>";
echo "</center>";
}
}
 
// Create the project change combo box
$url = $config->getURL($rep, $path, "log");
# XXX: forms don't have the name attribute, but _everything_ has the id attribute,
# so what you're trying to do (if anything?) should be done via that ~J
$vars["logsearch_form"] = "<form action=\"$url\" method=\"post\" name=\"logsearchform\">";
 
$vars["logsearch_startbox"] = "<input name=\"sr\" size=\"5\" value=\"$startrev\" />";
$vars["logsearch_endbox" ] = "<input name=\"er\" size=\"5\" value=\"$endrev\" />";
$vars["logsearch_maxbox" ] = "<input name=\"max\" size=\"5\" value=\"".($max==0?"":$max)."\" />";
$vars["logsearch_inputbox"] = "<input name=\"search\" value=\"$search\" />";
 
$vars["logsearch_submit"] = "<input type=\"submit\" value=\"${lang["GO"]}\" />";
$vars["logsearch_endform"] = "<input type=\"hidden\" name=\"logsearch\" value=\"1\" />".
"<input type=\"hidden\" name=\"op\" value=\"log\" />".
"<input type=\"hidden\" name=\"rev\" value=\"$rev\" />".
"<input type=\"hidden\" name=\"sc\" value=\"$showchanged\" />".
"<input type=\"hidden\" name=\"isdir\" value=\"$isDir\" />".
"</form>";
 
$url = $config->getURL($rep, $path, "log");
$vars["logsearch_clearloglink"] = "<a href=\"${url}rev=$rev&amp;sc=$showchanged&amp;isdir=$isDir\">${lang["CLEARLOG"]}</a>";
 
$url = $config->getURL($rep, "/", "comp");
$vars["compare_form"] = "<form action=\"$url\" method=\"post\" name=\"compareform\">";
$vars["compare_submit"] = "<input name=\"comparesubmit\" type=\"submit\" value=\"${lang["COMPAREREVS"]}\" />";
$vars["compare_endform"] = "<input type=\"hidden\" name=\"op\" value=\"comp\" /><input type=\"hidden\" name=\"sc\" value=\"$showchanged\" /></form>";
 
$vars["version"] = $version;
 
if (!$rep->hasReadAccess($path, false))
$vars["noaccess"] = true;
 
parseTemplate($rep->getTemplatePath()."header.tmpl", $vars, $listing);
parseTemplate($rep->getTemplatePath()."log.tmpl", $vars, $listing);
parseTemplate($rep->getTemplatePath()."footer.tmpl", $vars, $listing);
 
?>
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// log.php
//
// Show the logs for the given path
 
require_once("include/setup.inc");
require_once("include/svnlook.inc");
require_once("include/utils.inc");
require_once("include/template.inc");
require_once("include/bugtraq.inc");
 
$page = (int)@$_REQUEST["page"];
$all = (@$_REQUEST["all"] == 1)?1:0;
$isDir = (@$_REQUEST["isdir"] == 1)?1:0;
$dosearch = (@$_REQUEST["logsearch"] == 1)?1:0;
$search = trim(@$_REQUEST["search"]);
$words = preg_split('#\s+#', $search);
$fromRev = (int)@$_REQUEST["fr"];
$startrev = strtoupper(trim(@$_REQUEST["sr"]));
$endrev = strtoupper(trim(@$_REQUEST["er"]));
$max = @$_REQUEST["max"];
 
// Max number of results to find at a time
$numSearchResults = 15;
 
if ($search == "")
$dosearch = false;
 
// removeAccents
//
// Remove all the accents from a string. This function doesn't seem
// ideal, but expecting everyone to install 'unac' seems a little
// excessive as well...
 
function removeAccents($string)
{
return strtr($string,
"ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ",
"AAAAAAaaaaaaOOOOOOooooooEEEEeeeeCcIIIIiiiiUUUUuuuuyNn");
}
 
// Normalise the search words
foreach ($words as $index => $word)
{
$words[$index] = strtolower(removeAccents($word));
// Remove empty string introduced by multiple spaces
if (empty($words[$index]))
unset($words[$index]);
}
 
if (empty($page)) $page = 1;
 
// If searching, display all the results
$all = (bool) $dosearch;
 
$maxperpage = 20;
 
// Make sure that we have a repository
if (!isset($rep))
{
echo $lang["NOREP"];
exit;
}
 
$svnrep = new SVNRepository($rep);
 
$passrev = $rev;
 
// If there's no revision info, go to the lastest revision for this path
$history = $svnrep->getLog($path, "", "", true);
$youngest = $history->entries[0]->rev;
 
if (empty($rev))
$rev = $youngest;
 
// make sure path is prefixed by a /
$ppath = $path;
if ($path == "" || $path{0} != "/")
$ppath = "/".$path;
 
$vars["action"] = $lang["LOG"];
$vars["repname"] = $rep->getDisplayName();
$vars["rev"] = $rev;
$vars["path"] = $ppath;
 
createDirLinks($rep, $ppath, $passrev, $showchanged);
 
$logurl = $config->getURL($rep, $path, "log");
 
if ($rev != $youngest)
$vars["goyoungestlink"] = "<a href=\"${logurl}sc=1\">${lang["GOYOUNGEST"]}</a>";
else
$vars["goyoungestlink"] = "";
 
// We get the bugtraq variable just once based on the HEAD
$bugtraq = new Bugtraq($rep, $svnrep, $ppath);
 
if ($startrev != "HEAD") $startrev = (int)$startrev;
if (empty($startrev)) $startrev = $rev;
if (empty($endrev)) $endrev = 1;
 
if (empty($_REQUEST["max"]))
{
if (empty($_REQUEST["logsearch"]))
$max = 30;
else
$max = 0;
}
else
{
$max = (int)$max;
if ($max < 0) $max = 30;
}
 
$history = $svnrep->getLog($path, $startrev, $endrev, true, $max);
$vars["logsearch_moreresultslink"] = "";
$vars["pagelinks"] = "";
$vars["showalllink"] = "";
$listing = array();
 
if (!empty($history))
{
// Get the number of separate revisions
$revisions = count($history->entries);
if ($all)
{
$firstrevindex = 0;
$lastrevindex = $revisions - 1;
$pages = 1;
}
else
{
// Calculate the number of pages
$pages = floor($revisions / $maxperpage);
if (($revisions % $maxperpage) > 0) $pages++;
if ($page > $pages) $page = $pages;
// Word out where to start and stop
$firstrevindex = ($page - 1) * $maxperpage;
$lastrevindex = $firstrevindex + $maxperpage - 1;
if ($lastrevindex > $revisions - 1) $lastrevindex = $revisions - 1;
}
$history = $svnrep->getLog($path, $history->entries[$firstrevindex ]->rev, $history->entries[$lastrevindex]->rev, false, 0);
$row = 0;
$index = 0;
$listing = array();
$found = false;
foreach ($history->entries as $r)
{
// Assume a good match
$match = true;
$thisrev = $r->rev;
// Check the log for the search words, if searching
if ($dosearch)
{
if ((empty($fromRev) || $fromRev > $thisrev))
{
// Turn all the HTML entities into real characters.
// Make sure that each word in the search in also in the log
foreach($words as $word)
{
if (strpos(strtolower(removeAccents($r->msg)), $word) === false)
{
$match = false;
break;
}
}
if ($match)
{
$numSearchResults--;
$found = true;
}
}
else
$match = false;
}
if ($match)
{
// Add the trailing slash if we need to (svnlook history doesn't return trailing slashes!)
$rpath = $r->path;
if (empty($rpath))
$rpath = "/";
else if ($isDir && $rpath{strlen($rpath) - 1} != "/")
$rpath .= "/";
// Find the parent path (or the whole path if it's already a directory)
$pos = strrpos($rpath, "/");
$parent = substr($rpath, 0, $pos + 1);
$url = $config->getURL($rep, $parent, "dir");
$listing[$index]["revlink"] = "<a href=\"${url}rev=$thisrev&amp;sc=1\">$thisrev</a>";
if ($isDir)
{
$listing[$index]["compare_box"] = "<input type=\"checkbox\" name=\"compare[]\" value=\"$parent@$thisrev\" onclick=\"checkCB(this)\" />";
$url = $config->getURL($rep, $rpath, "dir");
$listing[$index]["revpathlink"] = "<a href=\"${url}rev=$thisrev&amp;sc=$showchanged\">$rpath</a>";
}
else
{
$listing[$index]["compare_box"] = "<input type=\"checkbox\" name=\"compare[]\" value=\"$rpath@$thisrev\" onclick=\"checkCB(this)\" />";
$url = $config->getURL($rep, $rpath, "file");
$listing[$index]["revpathlink"] = "<a href=\"${url}rev=$thisrev&amp;sc=$showchanged\">$rpath</a>";
}
$listing[$index]["revauthor"] = $r->author;
$listing[$index]["revage"] = $r->age;
$listing[$index]["revlog"] = nl2br($bugtraq->replaceIDs(create_anchors($r->msg)));
$listing[$index]["rowparity"] = "$row";
$row = 1 - $row;
$index++;
}
// If we've reached the search limit, stop here...
if (!$numSearchResults)
{
$url = $config->getURL($rep, $path, "log");
$vars["logsearch_moreresultslink"] = "<a href=\"${url}rev=$rev&amp;&sc=$showchanged&amp;isdir=$isDir&logsearch=1&search=$search&fr=$thisrev\">${lang["MORERESULTS"]}</a>";
break;
}
}
$vars["logsearch_resultsfound"] = true;
if ($dosearch && !$found)
{
if ($fromRev == 0)
{
$vars["logsearch_nomatches"] = true;
$vars["logsearch_resultsfound"] = false;
}
else
$vars["logsearch_nomorematches"] = true;
}
else if ($dosearch && $numSearchResults > 0)
{
$vars["logsearch_nomorematches"] = true;
}
// Work out the paging options
if ($pages > 1)
{
$prev = $page - 1;
$next = $page + 1;
echo "<p><center>";
if ($page > 1) $vars["pagelinks"] .= "<a href=\"${logurl}rev=$rev&amp;sr=$startrev&amp;er=$endrev&amp;sc=$showchanged&amp;max=$max&amp;page=$prev\"><&nbsp;${lang["PREV"]}</a> ";
for ($p = 1; $p <= $pages; $p++)
{
if ($p != $page)
$vars["pagelinks"].= "<a href=\"${logurl}rev=$rev&amp;sr=$startrev&amp;er=$endrev&amp;sc=$showchanged&amp;max=$max&amp;page=$p\">$p</a> ";
else
$vars["pagelinks"] .= "<b>$p </b>";
}
if ($page < $pages) $vars["pagelinks"] .=" <a href=\"${logurl}rev=$rev&amp;sr=$startrev&amp;er=$endrev&amp;sc=$showchanged&amp;max=$max&amp;page=$next\">${lang["NEXT"]}&nbsp;></a>";
$vars["showalllink"] = "<a href=\"${logurl}rev=$rev&amp;sr=$startrev&amp;er=$endrev&amp;sc=$showchanged&amp;all=1&amp;max=$max\">${lang["SHOWALL"]}</a>";
echo "</center>";
}
}
 
// Create the project change combo box
$url = $config->getURL($rep, $path, "log");
# XXX: forms don't have the name attribute, but _everything_ has the id attribute,
# so what you're trying to do (if anything?) should be done via that ~J
$vars["logsearch_form"] = "<form action=\"$url\" method=\"post\" name=\"logsearchform\">";
 
$vars["logsearch_startbox"] = "<input name=\"sr\" size=\"5\" value=\"$startrev\" />";
$vars["logsearch_endbox" ] = "<input name=\"er\" size=\"5\" value=\"$endrev\" />";
$vars["logsearch_maxbox" ] = "<input name=\"max\" size=\"5\" value=\"".($max==0?"":$max)."\" />";
$vars["logsearch_inputbox"] = "<input name=\"search\" value=\"$search\" />";
 
$vars["logsearch_submit"] = "<input type=\"submit\" value=\"${lang["GO"]}\" />";
$vars["logsearch_endform"] = "<input type=\"hidden\" name=\"logsearch\" value=\"1\" />".
"<input type=\"hidden\" name=\"op\" value=\"log\" />".
"<input type=\"hidden\" name=\"rev\" value=\"$rev\" />".
"<input type=\"hidden\" name=\"sc\" value=\"$showchanged\" />".
"<input type=\"hidden\" name=\"isdir\" value=\"$isDir\" />".
"</form>";
 
$url = $config->getURL($rep, $path, "log");
$vars["logsearch_clearloglink"] = "<a href=\"${url}rev=$rev&amp;sc=$showchanged&amp;isdir=$isDir\">${lang["CLEARLOG"]}</a>";
 
$url = $config->getURL($rep, "/", "comp");
$vars["compare_form"] = "<form action=\"$url\" method=\"post\" name=\"compareform\">";
$vars["compare_submit"] = "<input name=\"comparesubmit\" type=\"submit\" value=\"${lang["COMPAREREVS"]}\" />";
$vars["compare_endform"] = "<input type=\"hidden\" name=\"op\" value=\"comp\" /><input type=\"hidden\" name=\"sc\" value=\"$showchanged\" /></form>";
 
$vars["version"] = $version;
 
if (!$rep->hasReadAccess($path, false))
$vars["noaccess"] = true;
 
parseTemplate($rep->getTemplatePath()."header.tmpl", $vars, $listing);
parseTemplate($rep->getTemplatePath()."log.tmpl", $vars, $listing);
parseTemplate($rep->getTemplatePath()."footer.tmpl", $vars, $listing);
 
?>
/WebSVN/rss.php
1,170 → 1,170
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// rss.php
//
// Creates an rss feed for the given repository number
 
include("include/feedcreator.class.php");
 
require_once("include/setup.inc");
require_once("include/svnlook.inc");
require_once("include/utils.inc");
require_once("include/template.inc");
 
$isDir = (@$_REQUEST["isdir"] == 1)?1:0;
 
$maxmessages = 20;
 
// Find the base URL name
if ($config->multiViews)
{
$baseurl = "";
}
else
{
$baseurl = dirname($_SERVER["PHP_SELF"]);
if ($baseurl != "" && $baseurl != DIRECTORY_SEPARATOR && $baseurl != "\\" && $baseurl != "/" )
$baseurl .= "/";
else
$baseurl = "/";
}
 
$svnrep = new SVNRepository($rep);
 
if ($path == "" || $path{0} != "/")
$ppath = "/".$path;
else
$ppath = $path;
 
// Make sure that the user has full access to the specified directory
if (!$rep->hasReadAccess($path, false))
exit;
 
$url = $config->getURL($rep, $path, "log");
$listurl = $config->getURL($rep, $path, "dir");
 
// If there's no revision info, go to the lastest revision for this path
$history = $svnrep->getLog($path, $rev, "", false, 20);
$youngest = $history->entries[0]->rev;
 
// Cachename reflecting full path to and rev for rssfeed. Must end with xml to work
$cachename = strtr(getFullURL($listurl), ":/\\?", "____");
$cachename = $locwebsvnreal.DIRECTORY_SEPARATOR."cache".DIRECTORY_SEPARATOR.$cachename.@$_REQUEST["rev"]."_rssfeed.xml";
 
$rss = new UniversalFeedCreator();
$rss->useCached("RSS2.0", $cachename);
$rss->title = $rep->getDisplayName();
$rss->description = "${lang["RSSFEEDTITLE"]} - $repname";
$rss->link = html_entity_decode(getFullURL($baseurl.$listurl));
$rss->syndicationURL = $rss->link;
$rss->xslStyleSheet = ""; //required for UniversalFeedCreator since 1.7
$rss->cssStyleSheet = ""; //required for UniversalFeedCreator since 1.7
 
//$divbox = "<div>";
//$divfont = "<span>";
 
foreach ($history->entries as $r)
{
$thisrev = $r->rev;
$changes = $r->mods;
$files = count($changes);
 
// Add the trailing slash if we need to (svnlook history doesn't return trailing slashes!)
$rpath = $r->path;
if ($isDir && $rpath{strlen($rpath) - 1} != "/")
$rpath .= "/";
// Find the parent path (or the whole path if it's already a directory)
$pos = strrpos($rpath, "/");
$parent = substr($rpath, 0, $pos + 1);
$url = $config->getURL($rep, $parent, "dir");
$desc = $r->msg;
$item = new FeedItem();
// For the title, we show the first 10 words of the description
$pos = 0;
$len = strlen($desc);
for ($i = 0; $i < 10; $i++)
{
if ($pos >= $len) break;
$pos = strpos($desc, " ", $pos);
if ($pos === FALSE) break;
$pos++;
}
if ($pos !== FALSE)
{
$sdesc = substr($desc, 0, $pos) . "...";
}
else
{
$sdesc = $desc;
}
if ($desc == "") $sdesc = "${lang["REV"]} $thisrev";
$item->title = "$sdesc";
$item->link = html_entity_decode(getFullURL($baseurl."${url}rev=$thisrev&amp;sc=$showchanged"));
$item->description = "<div><strong>${lang["REV"]} $thisrev - ".$r->author."</strong> ($files ${lang["FILESMODIFIED"]})</div><div>".nl2br(create_anchors($desc))."</div>";
 
if ($showchanged)
{
foreach ($changes as $file)
{
switch ($file->action)
{
case "A":
$item->description .= "+ ".$file->path."<br />";
break;
case "M":
$item->description .= "~ ".$file->path."<br />";
break;
case "D":
$item->description .= "-".$file->path."<br />";
break;
}
}
}
 
$item->date = $r->committime;
$item->author = $r->author;
$rss->addItem($item);
}
 
// valid format strings are: RSS0.91, RSS1.0, RSS2.0, PIE0.1, MBOX, OPML
 
// Save the feed
$rss->saveFeed("RSS2.0",$cachename, false);
header("Content-Type: application/xml");
echo $rss->createFeed("RSS2.0");
 
?>
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// rss.php
//
// Creates an rss feed for the given repository number
 
include("include/feedcreator.class.php");
 
require_once("include/setup.inc");
require_once("include/svnlook.inc");
require_once("include/utils.inc");
require_once("include/template.inc");
 
$isDir = (@$_REQUEST["isdir"] == 1)?1:0;
 
$maxmessages = 20;
 
// Find the base URL name
if ($config->multiViews)
{
$baseurl = "";
}
else
{
$baseurl = dirname($_SERVER["PHP_SELF"]);
if ($baseurl != "" && $baseurl != DIRECTORY_SEPARATOR && $baseurl != "\\" && $baseurl != "/" )
$baseurl .= "/";
else
$baseurl = "/";
}
 
$svnrep = new SVNRepository($rep);
 
if ($path == "" || $path{0} != "/")
$ppath = "/".$path;
else
$ppath = $path;
 
// Make sure that the user has full access to the specified directory
if (!$rep->hasReadAccess($path, false))
exit;
 
$url = $config->getURL($rep, $path, "log");
$listurl = $config->getURL($rep, $path, "dir");
 
// If there's no revision info, go to the lastest revision for this path
$history = $svnrep->getLog($path, $rev, "", false, 20);
$youngest = $history->entries[0]->rev;
 
// Cachename reflecting full path to and rev for rssfeed. Must end with xml to work
$cachename = strtr(getFullURL($listurl), ":/\\?", "____");
$cachename = $locwebsvnreal.DIRECTORY_SEPARATOR."cache".DIRECTORY_SEPARATOR.$cachename.@$_REQUEST["rev"]."_rssfeed.xml";
 
$rss = new UniversalFeedCreator();
$rss->useCached("RSS2.0", $cachename);
$rss->title = $rep->getDisplayName();
$rss->description = "${lang["RSSFEEDTITLE"]} - $repname";
$rss->link = html_entity_decode(getFullURL($baseurl.$listurl));
$rss->syndicationURL = $rss->link;
$rss->xslStyleSheet = ""; //required for UniversalFeedCreator since 1.7
$rss->cssStyleSheet = ""; //required for UniversalFeedCreator since 1.7
 
//$divbox = "<div>";
//$divfont = "<span>";
 
foreach ($history->entries as $r)
{
$thisrev = $r->rev;
$changes = $r->mods;
$files = count($changes);
 
// Add the trailing slash if we need to (svnlook history doesn't return trailing slashes!)
$rpath = $r->path;
if ($isDir && $rpath{strlen($rpath) - 1} != "/")
$rpath .= "/";
// Find the parent path (or the whole path if it's already a directory)
$pos = strrpos($rpath, "/");
$parent = substr($rpath, 0, $pos + 1);
$url = $config->getURL($rep, $parent, "dir");
$desc = $r->msg;
$item = new FeedItem();
// For the title, we show the first 10 words of the description
$pos = 0;
$len = strlen($desc);
for ($i = 0; $i < 10; $i++)
{
if ($pos >= $len) break;
$pos = strpos($desc, " ", $pos);
if ($pos === FALSE) break;
$pos++;
}
if ($pos !== FALSE)
{
$sdesc = substr($desc, 0, $pos) . "...";
}
else
{
$sdesc = $desc;
}
if ($desc == "") $sdesc = "${lang["REV"]} $thisrev";
$item->title = "$sdesc";
$item->link = html_entity_decode(getFullURL($baseurl."${url}rev=$thisrev&amp;sc=$showchanged"));
$item->description = "<div><strong>${lang["REV"]} $thisrev - ".$r->author."</strong> ($files ${lang["FILESMODIFIED"]})</div><div>".nl2br(create_anchors($desc))."</div>";
 
if ($showchanged)
{
foreach ($changes as $file)
{
switch ($file->action)
{
case "A":
$item->description .= "+ ".$file->path."<br />";
break;
case "M":
$item->description .= "~ ".$file->path."<br />";
break;
case "D":
$item->description .= "-".$file->path."<br />";
break;
}
}
}
 
$item->date = $r->committime;
$item->author = $r->author;
$rss->addItem($item);
}
 
// valid format strings are: RSS0.91, RSS1.0, RSS2.0, PIE0.1, MBOX, OPML
 
// Save the feed
$rss->saveFeed("RSS2.0",$cachename, false);
header("Content-Type: application/xml");
echo $rss->createFeed("RSS2.0");
 
?>
/WebSVN/templates.txt
1,364 → 1,364
 
THE TEMPLATING SYSTEM
~~~~~~~~~~~~~~~~~~~~~
 
Everyone wants their view onto their SVN repository to fit in with their look
and feel. With WebSVN's templating system this is very possible.
 
To create your own templates, you first need to change your config.inc file to
tell WebSVN where the templates are stored. For example:
 
$config->setTemplatePath("./templates/Standard/");
 
This directory should contain at least the following files:
 
header.tmpl - Header templated included before any other
footer.tmpl - Footer templated included after any other
 
index.tmpl - The main project page template
 
directory.tmpl - Listing of a directory
log.tmple - Log of a directory or file
file.tmpl - Contents of a text file
diff.tmpl - Differences between text files
blame.tmpl - Blame information for a file
 
Each template file should be written in HTML, but is allowed to contain certain
WebSVN controls. There are two control types, commands and variables.
 
 
COMMANDS
~~~~~~~~
 
NOTE: Commands MUST appear on their own line.
 
---
 
[websvn-test:varname]
...
[websvn-else]
...
[websvn-endtest]
 
If the variable is non-0 write out the first part else write out the second
 
---
 
[websvn-startlisting]
...
[websvn-endlisting]
 
 
Used in pages that contain listings of files, logs, etc. Everything between
the controls is repeated for each item in the list
 
---
 
[websvn-defineicons] (used in directory.tmpl only)
...
[websvn-enddefineicons]
...
 
[websvn-treenode]
[websvn-icon]
 
These commands are used to display certain icons next to certain file types in
the directory view.
 
The [websvn-defineicons] block should contain a line for each file type,
defining the HTML to be used for that file type. To define the HTML for a
particular extension use the syntax:
 
.<extension>=<HTML code>
 
There are also some special filetypes:
 
dir=<HTML code> is used for directory icons
diropen=<HTML code> is used for open directory icons
*=<HTML code> is used for all filetypes which have no other definition
 
i-node - | shaped node of the tree view
t-node - T shaped node of the tree view
l-node - L shaped node of the tree view
e-node - Empty node of the tree view
 
Example from the BlueGrey scheme:
 
[websvn-defineicons]
dir=<img align="middle" valign="center" src="[websvn:locwebsvnhttp]/templates/BlueGrey/folder.png" alt="[FOLDER]">
diropen=<img align="middle" valign="center" src="[websvn:locwebsvnhttp]/templates/BlueGrey/folder-open.png" alt="[FOLDER]">
*=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/file.png" alt="[FILE]">
.c=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/filec.png" alt="[C-FILE]">
.h=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/fileh.png" alt="[H-FILE]">
.s=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/files.png" alt="[S-FILE]">
 
i-node=<img align="middle" border="0" width="24" height="26" src="[websvn:locwebsvnhttp]/templates/BlueGrey/i-node.png" alt="[NODE]">
t-node=<img align="middle" border="0" width="24" height="26" src="[websvn:locwebsvnhttp]/templates/BlueGrey/t-node.png" alt="[NODE]">
l-node=<img align="middle" border="0" width="24" height="26" src="[websvn:locwebsvnhttp]/templates/BlueGrey/l-node.png" alt="[NODE]">
e-node=<img align="middle" border="0" width="24" height="26" src="[websvn:locwebsvnhttp]/templates/BlueGrey/e-node.png" alt="[NODE]">
[websvn-enddefineicons]
 
Inside the [websvn-startlisting] block, the command [websvn-treeview] will
output the HTML code defined for the appropriate tree view icon.
[websvn-icon] will output the HTML code defined for the type of the current
file.
 
---
 
[websvn-getlisting] (used in file.tmpl only)
Get the contents of the file being viewed and output it exactly (surrounded
with <PRE> .. </PRE>).
 
VARIABLES
~~~~~~~~~
 
Variables are written in the form [websvn:varname] where varname is the name of
a variable passed to the template. The control is replaced with the variable
required.
 
The variables available are described below for each template.
You may also access the language file using [lang:varname] is order to keep your
templates international!
 
Take special notice of the use of the locwebsvnhttp variable. It should be used
to locate other files and graphics that your templates need. For example:
 
<link href="[websvn:locwebsvnhttp]/templates/tmptname/styles.css" ...
 
You may imagine that simply using . in place should work, however this isn't
the case when MultiViews are turned on. Using this variable gives you a way to
access your template files in all cases.
 
Variables defined for in all scripts
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
locwebsvnhttp - Root of websvn directory
charset - The charset requested by the user
 
projects_form - HTML <form> specification for the projects selection box
projects_select - HTML <select>...</select> specification for the project
options
projects_submit - HTML <input> specification for the projects selection GO
button
projects_endform - HTML </form> specification for the projects selection
box (includes hidden field declarations)
 
lang_form - HTML <form> specification for the language selection box
lang_select - HTML <select>...</select> specification for the language options
lang_submit - HTML <input> specification for the language selection GO button
lang_endform - HTML </form> specification for the language selection box
 
noaccess - True if the user should be blocked from accessing this page due
to insufficient access rights.
 
Variables defined for index.tmpl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
treeview - true if the index should be displayed as a tree of grouped projects
flatview - true if the index should be displayed as a simple list of projects
opentree - true if the tree viewed should be open by default
 
Used in [websvn-startlisting] ... [websvn-endlisting] block of a flat view:
 
projlink - Link to the project
rowparity - Parity of the row (0 or 1). Used to generate striped tables
 
Used in [websvn-startlisting] ... [websvn-endlisting] block of a tree view:
 
isprojlink - This item is a project link
isgrouphead - This item is a group name
rowparity - Parity of the row (0 or 1). Used to generate striped tables
listitem - The item to display
 
Variables defined for directory.tmpl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
restricted - True if the users has restricted access to this directory (to
allow access to a readable directory lower down only)
repname - Name of the repository
rev - Revision being viewed
path - Path of item being logged
author - Author of current revision
date - Date that revision was committed
log - Log message of revision
lastchangedrev - Revision of the last modification to current directory
goyoungestlink - Link to head revision of repository
 
showchanges - 1 if showing changes (for websvn-test)
hidechanges - 1 if hiding changes (for websvn-test)
showchangeslink - Link to page with changes hidden
hidechangeslink - Link to page with changes shown
 
newfilesbr - list of the new files separated by <BR>'s
changedfilesbr - list of the changed files separated by <BR>'s
deletedfilesbr - list of the deleted files separated by <BR>'s
 
newfiles - list of the new files separated by spaces
changedfiles - list of the changed files separated by spaces
deletedfiles - list of the deleted files separated by spaces
 
curdirlinks - List of the path of this directory with links to each one
curdirloglink - Link to the log view of current directory
curdirrsslink - Link to the RSS feed for the current directory
curdirrssanchor - The <a href=...> tag to the RSS feed for the current directory
curdirrsshref - URL of the feed for the current directory (without anchor tag)
curdirdllink - Link to the tarball of current directory
curdircomplink - Link to comparison with previously changed revision
 
allowdownload - True if downloading has been configured
 
compare_form - HTML <form> specification for the comparison form
compare_submit - HTML <input> specification for the comparison button
compare_endform - HTML </form> specification for the comparison form
 
Used in [websvn-startlisting] ... [websvn-endlisting] block:
 
compare_box - HTML checkbox specification for the comparison option
filelink - Link to the file
rowparity - Parity of the row (0 or 1). Used to generate striped tables
fileviewloglink - Link to the log page for the file
fileviewdllink - Link to the tarball of current directory
isDir - true if the current file is a directory (use with [websvn-test:isDir]
to display icons)
rsslink - Link to the RSS feed for this file/directory
rssanchor - The <a href=...> tag to the RSS feed for this file/directory
 
Variables defined for log.tmpl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
action - Action being performed ("Log")
 
repname - Name of the repository
rev - Revision being viewed
path - Path of item being logged
curdirlinks - List of the path of this directory with links to each one
error - Error message when results not available
 
pagelinks - List of list to all the pages of the log
showalllink - Link to show the entire log in one go
 
logsearch_form - HTML <form> specification for the log search box
logsearch_inputbox - HTML <input> specification for the log search box
logsearch_submit - HTML <input> specification for the log search GO button
logsearch_endform - HTML </form> specification for the log search box box
(includes hidden field declarations)
logsearch_clearloglink - Link to unfiltered display (remove current search
criteria)
logsearch_resultsfound - true when there are logs to display
logsearch_nomatches - true when there are no matches for the current request
logsearch_nomorematches - true when there are no further matches to the current
request (but there have been previous pages,
for example)
 
compare_form - HTML <form> specification for the comparison form
compare_submit - HTML <input> specification for the comparison button
compare_endform - HTML </form> specification for the comparison form
 
Used in [websvn-startlisting] ... [websvn-endlisting] block:
 
compare_box - HTML checkbox specification for the comparison option
revpathlink - Link to revision
revauthor - Author of this revision
revage - Age of revision
revlog - Log message of revision
 
 
Variables defined for file.tmpl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
repname - Name of the repository
rev - Revision being viewed
path - Path of item being logged
curdirlinks - List of the path of this directory with links to each one
 
prevdifflink - Link to comparison with previous revision
blamelink - Link to the blame information for this file
fileviewloglink - Link to the log page for the file
 
Note: Use command [websvn-getlisting] to display the listing.
 
 
Variables defined for diff.tmpl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
action - Action being performed ("Diff")
locwebsvnhttp - Root of websvn directory
charset - The charset requested by the user
 
repname - Name of the repository
rev - Revision being viewed
path - Path of item being logged
curdirlinks - List of the path of this directory with links to each one
 
rev1 - Revision of the older file
rev2 - Revision of the newer file
 
showcompactlink - Link to compact view
showalllink - Link to full view
 
Used in [websvn-startlisting] ... [websvn-endlisting] block:
 
rev1lineno / rev2lineno - Line number of the next difference block. Only
defined at the start of the block.
rev2diffclass / rev2diffclass - Class name of the diff block used for colouring
differences. The result is one of:
* diff (no changes)
* diffadded
* diffchanged
* diffdeleted
rev1line / rev2line - The line under comparison
 
Variables defined for blame.tmpl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
locwebsvnhttp - Root of websvn directory
charset - The charset requested by the user
 
repname - Name of the repository
rev - Revision being viewed
path - Path of item being logged
curdirlinks - List of the path of this directory with links to each one
 
Used in [websvn-startlisting] ... [websvn-endlisting] block:
 
lineno - Line number of the line
revision - Revision in which the line changed
author - Last author to modify the line
line - The line itself
 
Variables defined for compare.tmpl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
action - Action being performed ("Path Comparison")
repname - Name of the repository
path1 - First path being compared
rev1 - Revision of first path
path2 - Second path being compared
rev2 - Revision of second path
 
success = true if the comparison succeeded
 
revlink - Link to reverse comparison
 
compare_form - HTML <form> specification for the comparison form
compare_path1input/compare_path2input - HTML specifications for the path input areas
compare_rev1input/compare_rev2input - HTML specifications for the revision input areas
compare_submit - HTML <input> specification for the comparison button
compare_endform - HTML </form> specification for the comparison form
 
Used in [websvn-startlisting] ... [websvn-endlisting] block:
 
newpath - Name of new file under comparison (only defined at start of block)
difflines - Lines changed information for this file. Start of diff lines.
(only defined after newpath)
diffclass - Class name of the diff block used for colouring
differences. The result is one of:
* diff (no changes)
* diffadded
* diffdeleted
line - The line under comparison
enddifflines - End of diff lines
properties - Property changes
endpath - End of current path
 
THE TEMPLATING SYSTEM
~~~~~~~~~~~~~~~~~~~~~
 
Everyone wants their view onto their SVN repository to fit in with their look
and feel. With WebSVN's templating system this is very possible.
 
To create your own templates, you first need to change your config.inc file to
tell WebSVN where the templates are stored. For example:
 
$config->setTemplatePath("./templates/Standard/");
 
This directory should contain at least the following files:
 
header.tmpl - Header templated included before any other
footer.tmpl - Footer templated included after any other
 
index.tmpl - The main project page template
 
directory.tmpl - Listing of a directory
log.tmple - Log of a directory or file
file.tmpl - Contents of a text file
diff.tmpl - Differences between text files
blame.tmpl - Blame information for a file
 
Each template file should be written in HTML, but is allowed to contain certain
WebSVN controls. There are two control types, commands and variables.
 
 
COMMANDS
~~~~~~~~
 
NOTE: Commands MUST appear on their own line.
 
---
 
[websvn-test:varname]
...
[websvn-else]
...
[websvn-endtest]
 
If the variable is non-0 write out the first part else write out the second
 
---
 
[websvn-startlisting]
...
[websvn-endlisting]
 
 
Used in pages that contain listings of files, logs, etc. Everything between
the controls is repeated for each item in the list
 
---
 
[websvn-defineicons] (used in directory.tmpl only)
...
[websvn-enddefineicons]
...
 
[websvn-treenode]
[websvn-icon]
 
These commands are used to display certain icons next to certain file types in
the directory view.
 
The [websvn-defineicons] block should contain a line for each file type,
defining the HTML to be used for that file type. To define the HTML for a
particular extension use the syntax:
 
.<extension>=<HTML code>
 
There are also some special filetypes:
 
dir=<HTML code> is used for directory icons
diropen=<HTML code> is used for open directory icons
*=<HTML code> is used for all filetypes which have no other definition
 
i-node - | shaped node of the tree view
t-node - T shaped node of the tree view
l-node - L shaped node of the tree view
e-node - Empty node of the tree view
 
Example from the BlueGrey scheme:
 
[websvn-defineicons]
dir=<img align="middle" valign="center" src="[websvn:locwebsvnhttp]/templates/BlueGrey/folder.png" alt="[FOLDER]">
diropen=<img align="middle" valign="center" src="[websvn:locwebsvnhttp]/templates/BlueGrey/folder-open.png" alt="[FOLDER]">
*=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/file.png" alt="[FILE]">
.c=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/filec.png" alt="[C-FILE]">
.h=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/fileh.png" alt="[H-FILE]">
.s=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/files.png" alt="[S-FILE]">
 
i-node=<img align="middle" border="0" width="24" height="26" src="[websvn:locwebsvnhttp]/templates/BlueGrey/i-node.png" alt="[NODE]">
t-node=<img align="middle" border="0" width="24" height="26" src="[websvn:locwebsvnhttp]/templates/BlueGrey/t-node.png" alt="[NODE]">
l-node=<img align="middle" border="0" width="24" height="26" src="[websvn:locwebsvnhttp]/templates/BlueGrey/l-node.png" alt="[NODE]">
e-node=<img align="middle" border="0" width="24" height="26" src="[websvn:locwebsvnhttp]/templates/BlueGrey/e-node.png" alt="[NODE]">
[websvn-enddefineicons]
 
Inside the [websvn-startlisting] block, the command [websvn-treeview] will
output the HTML code defined for the appropriate tree view icon.
[websvn-icon] will output the HTML code defined for the type of the current
file.
 
---
 
[websvn-getlisting] (used in file.tmpl only)
Get the contents of the file being viewed and output it exactly (surrounded
with <PRE> .. </PRE>).
 
VARIABLES
~~~~~~~~~
 
Variables are written in the form [websvn:varname] where varname is the name of
a variable passed to the template. The control is replaced with the variable
required.
 
The variables available are described below for each template.
You may also access the language file using [lang:varname] is order to keep your
templates international!
 
Take special notice of the use of the locwebsvnhttp variable. It should be used
to locate other files and graphics that your templates need. For example:
 
<link href="[websvn:locwebsvnhttp]/templates/tmptname/styles.css" ...
 
You may imagine that simply using . in place should work, however this isn't
the case when MultiViews are turned on. Using this variable gives you a way to
access your template files in all cases.
 
Variables defined for in all scripts
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
locwebsvnhttp - Root of websvn directory
charset - The charset requested by the user
 
projects_form - HTML <form> specification for the projects selection box
projects_select - HTML <select>...</select> specification for the project
options
projects_submit - HTML <input> specification for the projects selection GO
button
projects_endform - HTML </form> specification for the projects selection
box (includes hidden field declarations)
 
lang_form - HTML <form> specification for the language selection box
lang_select - HTML <select>...</select> specification for the language options
lang_submit - HTML <input> specification for the language selection GO button
lang_endform - HTML </form> specification for the language selection box
 
noaccess - True if the user should be blocked from accessing this page due
to insufficient access rights.
 
Variables defined for index.tmpl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
treeview - true if the index should be displayed as a tree of grouped projects
flatview - true if the index should be displayed as a simple list of projects
opentree - true if the tree viewed should be open by default
 
Used in [websvn-startlisting] ... [websvn-endlisting] block of a flat view:
 
projlink - Link to the project
rowparity - Parity of the row (0 or 1). Used to generate striped tables
 
Used in [websvn-startlisting] ... [websvn-endlisting] block of a tree view:
 
isprojlink - This item is a project link
isgrouphead - This item is a group name
rowparity - Parity of the row (0 or 1). Used to generate striped tables
listitem - The item to display
 
Variables defined for directory.tmpl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
restricted - True if the users has restricted access to this directory (to
allow access to a readable directory lower down only)
repname - Name of the repository
rev - Revision being viewed
path - Path of item being logged
author - Author of current revision
date - Date that revision was committed
log - Log message of revision
lastchangedrev - Revision of the last modification to current directory
goyoungestlink - Link to head revision of repository
 
showchanges - 1 if showing changes (for websvn-test)
hidechanges - 1 if hiding changes (for websvn-test)
showchangeslink - Link to page with changes hidden
hidechangeslink - Link to page with changes shown
 
newfilesbr - list of the new files separated by <BR>'s
changedfilesbr - list of the changed files separated by <BR>'s
deletedfilesbr - list of the deleted files separated by <BR>'s
 
newfiles - list of the new files separated by spaces
changedfiles - list of the changed files separated by spaces
deletedfiles - list of the deleted files separated by spaces
 
curdirlinks - List of the path of this directory with links to each one
curdirloglink - Link to the log view of current directory
curdirrsslink - Link to the RSS feed for the current directory
curdirrssanchor - The <a href=...> tag to the RSS feed for the current directory
curdirrsshref - URL of the feed for the current directory (without anchor tag)
curdirdllink - Link to the tarball of current directory
curdircomplink - Link to comparison with previously changed revision
 
allowdownload - True if downloading has been configured
 
compare_form - HTML <form> specification for the comparison form
compare_submit - HTML <input> specification for the comparison button
compare_endform - HTML </form> specification for the comparison form
 
Used in [websvn-startlisting] ... [websvn-endlisting] block:
 
compare_box - HTML checkbox specification for the comparison option
filelink - Link to the file
rowparity - Parity of the row (0 or 1). Used to generate striped tables
fileviewloglink - Link to the log page for the file
fileviewdllink - Link to the tarball of current directory
isDir - true if the current file is a directory (use with [websvn-test:isDir]
to display icons)
rsslink - Link to the RSS feed for this file/directory
rssanchor - The <a href=...> tag to the RSS feed for this file/directory
 
Variables defined for log.tmpl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
action - Action being performed ("Log")
 
repname - Name of the repository
rev - Revision being viewed
path - Path of item being logged
curdirlinks - List of the path of this directory with links to each one
error - Error message when results not available
 
pagelinks - List of list to all the pages of the log
showalllink - Link to show the entire log in one go
 
logsearch_form - HTML <form> specification for the log search box
logsearch_inputbox - HTML <input> specification for the log search box
logsearch_submit - HTML <input> specification for the log search GO button
logsearch_endform - HTML </form> specification for the log search box box
(includes hidden field declarations)
logsearch_clearloglink - Link to unfiltered display (remove current search
criteria)
logsearch_resultsfound - true when there are logs to display
logsearch_nomatches - true when there are no matches for the current request
logsearch_nomorematches - true when there are no further matches to the current
request (but there have been previous pages,
for example)
 
compare_form - HTML <form> specification for the comparison form
compare_submit - HTML <input> specification for the comparison button
compare_endform - HTML </form> specification for the comparison form
 
Used in [websvn-startlisting] ... [websvn-endlisting] block:
 
compare_box - HTML checkbox specification for the comparison option
revpathlink - Link to revision
revauthor - Author of this revision
revage - Age of revision
revlog - Log message of revision
 
 
Variables defined for file.tmpl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
repname - Name of the repository
rev - Revision being viewed
path - Path of item being logged
curdirlinks - List of the path of this directory with links to each one
 
prevdifflink - Link to comparison with previous revision
blamelink - Link to the blame information for this file
fileviewloglink - Link to the log page for the file
 
Note: Use command [websvn-getlisting] to display the listing.
 
 
Variables defined for diff.tmpl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
action - Action being performed ("Diff")
locwebsvnhttp - Root of websvn directory
charset - The charset requested by the user
 
repname - Name of the repository
rev - Revision being viewed
path - Path of item being logged
curdirlinks - List of the path of this directory with links to each one
 
rev1 - Revision of the older file
rev2 - Revision of the newer file
 
showcompactlink - Link to compact view
showalllink - Link to full view
 
Used in [websvn-startlisting] ... [websvn-endlisting] block:
 
rev1lineno / rev2lineno - Line number of the next difference block. Only
defined at the start of the block.
rev2diffclass / rev2diffclass - Class name of the diff block used for colouring
differences. The result is one of:
* diff (no changes)
* diffadded
* diffchanged
* diffdeleted
rev1line / rev2line - The line under comparison
 
Variables defined for blame.tmpl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
locwebsvnhttp - Root of websvn directory
charset - The charset requested by the user
 
repname - Name of the repository
rev - Revision being viewed
path - Path of item being logged
curdirlinks - List of the path of this directory with links to each one
 
Used in [websvn-startlisting] ... [websvn-endlisting] block:
 
lineno - Line number of the line
revision - Revision in which the line changed
author - Last author to modify the line
line - The line itself
 
Variables defined for compare.tmpl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
action - Action being performed ("Path Comparison")
repname - Name of the repository
path1 - First path being compared
rev1 - Revision of first path
path2 - Second path being compared
rev2 - Revision of second path
 
success = true if the comparison succeeded
 
revlink - Link to reverse comparison
 
compare_form - HTML <form> specification for the comparison form
compare_path1input/compare_path2input - HTML specifications for the path input areas
compare_rev1input/compare_rev2input - HTML specifications for the revision input areas
compare_submit - HTML <input> specification for the comparison button
compare_endform - HTML </form> specification for the comparison form
 
Used in [websvn-startlisting] ... [websvn-endlisting] block:
 
newpath - Name of new file under comparison (only defined at start of block)
difflines - Lines changed information for this file. Start of diff lines.
(only defined after newpath)
diffclass - Class name of the diff block used for colouring
differences. The result is one of:
* diff (no changes)
* diffadded
* diffdeleted
line - The line under comparison
enddifflines - End of diff lines
properties - Property changes
endpath - End of current path
/WebSVN/wsvn.php
1,161 → 1,161
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// wsvn.php
//
// Glue for MultiViews
 
// --- CONFIGURE THESE VARIABLES ---
 
// Location of websvn directory via HTTP
//
// e.g. For http://servername/websvn use /websvn
//
// Note that wsvn.php need not be in the /websvn directory (and normally isn't).
// If you want to use the root server directory, just use a blank string ('').
#$locwebsvnhttp = "/websvn";
$locwebsvnhttp = '';
 
// Physical location of websvn directory
#$locwebsvnreal = "d:/websvn";
$locwebsvnreal = '/mnt/wsvn';
 
chdir($locwebsvnreal);
 
// --- DON'T CHANGE BELOW HERE ---
 
// this tells files that we are in multiviews if they are unable to access
// the $config variable
if (!defined('WSVN_MULTIVIEWS'))
define('WSVN_MULTIVIEWS', 1);
 
ini_set("include_path", $locwebsvnreal);
 
require_once("include/setup.inc");
require_once("include/svnlook.inc");
 
if (!isset($_REQUEST["sc"]))
$_REQUEST["sc"] = 1;
 
if ($config->multiViews)
{
// If this is a form handling request, deal with it
if (@$_REQUEST["op"] == "form")
{
include("$locwebsvnreal/form.php");
exit;
}
 
$path = @$_SERVER["PATH_INFO"];
 
// Remove initial slash
$path = substr($path, 1);
if (empty($path))
{
include("$locwebsvnreal/index.php");
exit;
}
// Split the path into repository and path elements
// Note: we have to cope with the repository name
// having a slash in it
 
$found = false;
 
foreach ($config->getRepositories() as $rep)
{
$pos = strlen($rep->getDisplayName());
if (strlen($path) < $pos)
continue;
$name = substr($path, 0, $pos);
if (strcasecmp($rep->getDisplayName(), $name) == 0)
{
$tpath = substr($path, $pos);
if ($tpath[0] == "/") {
$found = true;
$path = $tpath;
break;
}
}
}
 
if ($found == false)
{
include("$locwebsvnreal/index.php");
exit;
}
 
createProjectSelectionForm();
$vars["allowdownload"] = $rep->getAllowDownload();
 
// find the operation type
$op = @$_REQUEST["op"];
switch ($op)
{
case "dir":
$file = "listing.php";
break;
case "file":
$file = "filedetails.php";
break;
 
case "log":
$file = "log.php";
break;
 
case "diff":
$file = "diff.php";
break;
 
case "blame":
$file = "blame.php";
break;
 
case "rss":
$file = "rss.php";
break;
case "dl":
$file = "dl.php";
break;
 
case "comp":
$file = "comp.php";
break;
 
default:
if ($path[strlen($path) - 1] == "/")
$file = "listing.php";
else
$file = "filedetails.php";
}
// Now include the file that handles it
include("$locwebsvnreal/$file");
}
else
{
print "<p>MultiViews must be configured in config.inc in order to use this file";
exit;
}
<?php
# vim:et:ts=3:sts=3:sw=3:fdm=marker:
 
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright © 2004-2006 Tim Armes, Matt Sicker
//
// This program 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.
//
// This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// --
//
// wsvn.php
//
// Glue for MultiViews
 
// --- CONFIGURE THESE VARIABLES ---
 
// Location of websvn directory via HTTP
//
// e.g. For http://servername/websvn use /websvn
//
// Note that wsvn.php need not be in the /websvn directory (and normally isn't).
// If you want to use the root server directory, just use a blank string ('').
#$locwebsvnhttp = "/websvn";
$locwebsvnhttp = '';
 
// Physical location of websvn directory
#$locwebsvnreal = "d:/websvn";
$locwebsvnreal = '/home/junx/docs/wsvn';
 
chdir($locwebsvnreal);
 
// --- DON'T CHANGE BELOW HERE ---
 
// this tells files that we are in multiviews if they are unable to access
// the $config variable
if (!defined('WSVN_MULTIVIEWS'))
define('WSVN_MULTIVIEWS', 1);
 
ini_set("include_path", $locwebsvnreal);
 
require_once("include/setup.inc");
require_once("include/svnlook.inc");
 
if (!isset($_REQUEST["sc"]))
$_REQUEST["sc"] = 1;
 
if ($config->multiViews)
{
// If this is a form handling request, deal with it
if (@$_REQUEST["op"] == "form")
{
include("$locwebsvnreal/form.php");
exit;
}
 
$path = @$_SERVER["PATH_INFO"];
 
// Remove initial slash
$path = substr($path, 1);
if (empty($path))
{
include("$locwebsvnreal/index.php");
exit;
}
// Split the path into repository and path elements
// Note: we have to cope with the repository name
// having a slash in it
 
$found = false;
 
foreach ($config->getRepositories() as $rep)
{
$pos = strlen($rep->getDisplayName());
if (strlen($path) < $pos)
continue;
$name = substr($path, 0, $pos);
if (strcasecmp($rep->getDisplayName(), $name) == 0)
{
$tpath = substr($path, $pos);
if ($tpath[0] == "/") {
$found = true;
$path = $tpath;
break;
}
}
}
 
if ($found == false)
{
include("$locwebsvnreal/index.php");
exit;
}
 
createProjectSelectionForm();
$vars["allowdownload"] = $rep->getAllowDownload();
 
// find the operation type
$op = @$_REQUEST["op"];
switch ($op)
{
case "dir":
$file = "listing.php";
break;
case "file":
$file = "filedetails.php";
break;
 
case "log":
$file = "log.php";
break;
 
case "diff":
$file = "diff.php";
break;
 
case "blame":
$file = "blame.php";
break;
 
case "rss":
$file = "rss.php";
break;
case "dl":
$file = "dl.php";
break;
 
case "comp":
$file = "comp.php";
break;
 
default:
if ($path[strlen($path) - 1] == "/")
$file = "listing.php";
else
$file = "filedetails.php";
}
// Now include the file that handles it
include("$locwebsvnreal/$file");
}
else
{
print "<p>MultiViews must be configured in config.inc in order to use this file";
exit;
}