Update of /cvsroot/phpwiki/phpwiki/lib In directory usw-pr-cvs1:/tmp/cvs-serv26187/lib Modified Files: FileFinder.php PageList.php Request.php Template.php Theme.php WikiDB.php WikiPlugin.php WikiUser.php config.php display.php interwiki.php main.php stdlib.php Log Message: LANG still broken, working on better locale handling. improved PageList: added checkbox, sortby added <?plugin-head for FrameInclude and RedirectTo fixed some minor UserPreferences quirks solidified templates added PhpWeather added a new generic WikiAdminSelect to simulate the commandline: work with sets of pages, pass the request to underlying WikiAdmin* plugins Index: FileFinder.php =================================================================== RCS file: /cvsroot/phpwiki/phpwiki/lib/FileFinder.php,v retrieving revision 1.7 retrieving revision 1.8 diff -u -2 -b -p -d -r1.7 -r1.8 --- FileFinder.php 22 Jan 2002 03:12:59 -0000 1.7 +++ FileFinder.php 27 Aug 2002 21:51:31 -0000 1.8 @@ -5,7 +5,15 @@ /** * A class for finding files. + * + * This should really provided by pear. We don't want really to mess around + * with all the lousy systems. (WindowsNT, Win95, Mac, VMS, ...) + * But pear has only System and File, which do nothing. + * Anyway, in good PHP style we ignore the rest of the world and try to behave + * as on unix only. That means we use / as pathsep in all our constants. */ class FileFinder { + var $_pathsep, $_path; + /** * Constructor. @@ -14,4 +22,5 @@ class FileFinder */ function FileFinder ($path = false) { + $this->_pathsep = $this->_get_syspath_separator(); if ($path === false) $path = $this->_get_include_path(); @@ -31,5 +40,5 @@ class FileFinder } elseif ( ($dir = $this->_search_path($file)) ) { - return "$dir/$file"; + return $dir . $this->_use_path_separator($dir) . $file; } @@ -62,12 +71,50 @@ class FileFinder /** + * The system-dependent path-separator character. + * UNIX: / + * Windows: \ + * Mac: : + * + * @access private + * @return string path_separator. + */ + function _get_syspath_separator () { + if (isWindows()) return '\\'; // anyway: we support only WinNT and use / + elseif (isMac()) return ':'; // MacOsX is / + // VMS or LispM is really weird, we ignore it. + else return '/'; + } + + /** + * The path-separator character of the given path. + * Windows accepts / also, but gets confused with mixed path_separators, + * e.g "C:\Apache\phpwiki/locale/button" + * > dir C:\Apache\phpwiki/locale/button => + * Parameterformat nicht korrekt - "locale" + * So if there's any \\ in the path, either fix them to / (not in Win95!) + * or use \\ for ours. + * + * @access private + * @return string path_separator. + */ + function _use_path_separator ($path) { + if (isWindows()) { + return (strstr('\\',$path)) ? '\\' : '/'; + } else { + return $this->_get_syspath_separator(); + } + } + + /** * Determine if path is absolute. * * @access private * @param $path string Path. - * @return bool True iff path is absolute. + * @return bool True if path is absolute. */ function _is_abs($path) { - return ereg('^/', $path); + if (ereg('^/', $path)) return true; + elseif (isWindows() and (eregi('^[a-z]:[/\\]', $path))) return true; + else return false; } @@ -94,5 +141,5 @@ class FileFinder function _search_path ($file) { foreach ($this->_path as $dir) { - if (file_exists("$dir/$file")) + if (file_exists($dir . $this->_use_path_separator($dir) . $file)) return $dir; } @@ -103,10 +150,13 @@ class FileFinder * The system-dependent path-separator character. On UNIX systems, * this character is ':'; on Win32 systems it is ';'. + * Fixme: + * On Mac it cannot be : because this is the seperator there! * * @access private * @return string path_separator. */ - function _get_path_separator () { - return preg_match('/^Windows/', php_uname()) ? ';' : ':'; + function _get_ini_separator () { + return isWindows() ? ';' : ':'; + // return preg_match('/^Windows/', php_uname()) } @@ -121,5 +171,5 @@ class FileFinder if (empty($path)) $path = '.'; - return explode($this->_get_path_separator(), $path); + return explode($this->_get_ini_separator(), $path); } @@ -150,5 +200,37 @@ class FileFinder * put it here, as it seems to work-around the bug. */ - ini_set('include_path', implode($this->_get_path_separator(), $path)); + ini_set('include_path', implode($this->_get_ini_separator(), $path)); + } + + // Return all the possible shortened locale specifiers for the given locale. + // Most specific first. + // de_DE.iso8859-1@euro => de_DE.iso8859-1, de_DE, de + // This code might needed somewhere else also. + function locale_versions ($lang) { + // Try less specific versions of the locale + $langs[] = $lang; + foreach (array('@', '.', '_') as $sep) { + if ( ($tail = strchr($lang, $sep)) ) + $langs[] = substr($lang, 0, -strlen($tail)); + } + } + + /** + * Try to figure out the appropriate value for $LANG. + * + *@access private + *@return string The value of $LANG. + */ + function _get_lang() { + if (!empty($GLOBALS['LANG'])) + return $GLOBALS['LANG']; + + foreach (array('LC_ALL', 'LC_MESSAGES', 'LC_RESPONSES', 'LANG') as $var) { + $lang = getenv($var); + if (!empty($lang)) + return $lang; + } + + return "C"; } } @@ -182,6 +264,8 @@ class PearFileFinder * this parameter blank. */ - function PearFileFinder ($path = false) { - $this->FileFinder(array('/usr/share/php4', + function PearFileFinder ($path = array()) { + $this->FileFinder(array_merge( + $path, + array('/usr/share/php4', '/usr/share/php', '/usr/lib/php4', @@ -191,5 +275,7 @@ class PearFileFinder '/usr/local/lib/php4', '/usr/local/lib/php', - '/System/Library/PHP')); + '/System/Library/PHP', + '/Apache/pear' // Windows + ))); } } @@ -219,40 +305,13 @@ class LocalizedFileFinder assert(!empty($lang)); - // A locale can be, e.g. de_DE.iso8859-1@euro. - // Try less specific versions of the locale: - $langs[] = $lang; - foreach (array('@', '.', '_') as $sep) { - if ( ($tail = strchr($lang, $sep)) ) - $langs[] = substr($lang, 0, -strlen($tail)); - } - - foreach ($langs as $lang) { + if ($locales = $this->locale_versions($lang)) + foreach ($locales as $lang) { + if ($lang == 'C') $lang='en'; foreach ($include_path as $dir) { $path[] = "$dir/locale/$lang"; } } - $this->FileFinder(array_merge($path, $include_path)); } - - /** - * Try to figure out the appropriate value for $LANG. - * - *@access private - *@return string The value of $LANG. - */ - function _get_lang() { - if (!empty($GLOBALS['LANG'])) - return $GLOBALS['LANG']; - - foreach (array('LC_ALL', 'LC_MESSAGES', 'LC_RESPONSES', 'LANG') as $var) { - $lang = getenv($var); - if (!empty($lang)) - return $lang; - } - - return "C"; - } - } @@ -275,4 +334,5 @@ class LocalizedButtonFinder */ function LocalizedButtonFinder () { + global $Theme; $include_path = $this->_get_include_path(); $path = array(); @@ -280,20 +340,12 @@ class LocalizedButtonFinder $lang = $this->_get_lang(); assert(!empty($lang)); + assert(!empty($Theme)); - // A locale can be, e.g. de_DE.iso8859-1@euro. - // Try less specific versions of the locale: - $langs[] = $lang; - foreach (array('@', '.', '_') as $sep) { - if ( ($tail = strchr($lang, $sep)) ) - $langs[] = substr($lang, 0, -strlen($tail)); - } + $langs = $this->locale_versions($lang); foreach ($langs as $lang) { + if ($lang == 'C') $lang='en'; foreach ($include_path as $dir) { - // FIXME: sorry I know this is ugly but don't know yet what else to do - if ($lang=='C') - $lang='en'; - $path[] = "$dir/themes/".THEME."/buttons/$lang"; - + $path[] = $Theme->file("buttons/$lang"); } } @@ -302,23 +354,20 @@ class LocalizedButtonFinder } - /** - * Try to figure out the appropriate value for $LANG. - * - *@access private - *@return string The value of $LANG. - */ - function _get_lang() { - if (!empty($GLOBALS['LANG'])) - return $GLOBALS['LANG']; +} - foreach (array('LC_ALL', 'LC_MESSAGES', 'LC_RESPONSES', 'LANG') as $var) { - $lang = getenv($var); - if (!empty($lang)) - return $lang; - } +function isWindows() { + //return preg_match('/^Windows/', php_uname()); + return (substr(PHP_OS,0,3) == 'WIN'); +} - return "en"; - } +// So far not supported. This has really ugly pathname semantics +// :path is relative, Desktop:path (I think) is absolute. Please fix this someone +function isMac() { + return (substr(PHP_OS,0,3) == 'MAC'); // not tested! +} +// probably not needed, same behaviour as on unix. +function isCygwin() { + return (substr(PHP_OS,0,6) == 'CYGWIN'); } Index: PageList.php =================================================================== RCS file: /cvsroot/phpwiki/phpwiki/lib/PageList.php,v retrieving revision 1.38 retrieving revision 1.39 diff -u -2 -b -p -d -r1.38 -r1.39 --- PageList.php 24 Feb 2002 17:59:40 -0000 1.38 +++ PageList.php 27 Aug 2002 21:51:31 -0000 1.39 @@ -4,10 +4,9 @@ * This library relieves some work for these plugins: * - * AllPages, BackLinks, LikePages, Mostpopular, TitleSearch + * AllPages, BackLinks, LikePages, Mostpopular, TitleSearch and more * * It also allows dynamic expansion of those plugins to include more * columns in their output. * - * * Column 'info=' arguments: * @@ -23,4 +22,5 @@ * * 'all' All columns will be displayed. This argument must appear alone. + * 'checkbox' A selectable checkbox appears at the left. * * FIXME: In this refactoring I have un-implemented _ctime, _cauthor, and @@ -29,6 +29,13 @@ * database. If lots of revisions have been made to a page, it's more than likely * that some older revisions (include revision 1) have been cleaned (deleted). + * + * FIXME: + * The 'sortby' option is handled here correctly, but at the backends at + * the page iterator not yet. + * + * TODO: sortby, limit, offset, rows arguments for multiple pages/multiple rows. */ class _PageList_Column_base { + function _PageList_Column_base ($default_heading, $align = false) { $this->_heading = $default_heading; @@ -39,5 +46,5 @@ class _PageList_Column_base { } - function format ($page_handle, &$revision_handle) { + function format ($pagelist, $page_handle, &$revision_handle) { return HTML::td($this->_tdattr, NBSP, @@ -51,6 +58,19 @@ class _PageList_Column_base { function heading () { - return HTML::td(array('align' => 'center'), - NBSP, HTML::u($this->_heading), NBSP); + if (in_array($this->_field,array('pagename','mtime','hits'))) { + // asc or desc: +pagename, -pagename + $sortby = '+' . $this->_field; + if ($sorted = $GLOBALS['request']->getArg('sortby')) { + // flip order + if ($sorted == '+' . $this->_field) + $sortby = '-' . $this->_field; + elseif ($sorted == '-' . $this->_field) + $sortby = '+' . $this->_field; + } + $s = HTML::a(array('href' => $GLOBALS['request']->GetURLtoSelf(array('sortby' => $sortby)),'class' => 'pagetitle', 'title' => sprintf(_("Sort by %s"),$this->_field)), NBSP, HTML::u($this->_heading), NBSP); + } else { + $s = HTML(NBSP, HTML::u($this->_heading), NBSP); + } + return HTML::td(array('align' => 'center'),$s); } }; @@ -92,4 +112,30 @@ class _PageList_Column_bool extends _Pag }; +class _PageList_Column_checkbox extends _PageList_Column { + function _PageList_Column_checkbox ($field, $default_heading, $name='p') { + $this->_name = $name; + $this->_PageList_Column($field, $default_heading, 'center'); + } + function _getValue ($pagelist, $page_handle, &$revision_handle) { + $pagename = $page_handle->getName(); + if (!empty($pagelist->_selected[$pagename])) { + return HTML::input(array('type' => 'checkbox', + 'name' => $this->_name . "[$pagename]", + 'value' => $pagename, + 'checked' => '1')); + } else { + return HTML::input(array('type' => 'checkbox', + 'name' => $this->_name . "[$pagename]", + 'value' => $pagename)); + } + } + function format ($pagelist, $page_handle, &$revision_handle) { + return HTML::td($this->_tdattr, + NBSP, + $this->_getValue(&$pagelist, $page_handle, &$revision_handle), + NBSP); + } +}; + class _PageList_Column_time extends _PageList_Column { function _PageList_Column_time ($field, $default_heading) { @@ -131,4 +177,6 @@ class _PageList_Column_author extends _P class _PageList_Column_pagename extends _PageList_Column_base { + var $_field = 'pagename'; + function _PageList_Column_pagename () { $this->_PageList_Column_base(_("Page Name")); @@ -155,6 +203,8 @@ class PageList { var $_pagename_seen = false; var $_types = array(); + var $_options = array(); + var $_selected = array(); - function PageList ($columns = false, $exclude = false) { + function PageList ($columns = false, $exclude = false, $options = false) { if ($columns == 'all') { $this->_initAvailableColumns(); @@ -165,7 +215,13 @@ class PageList { if (!is_array($columns)) $columns = explode(',', $columns); - foreach ($columns as $col) + if (in_array('all',$columns)) { // e.g. 'checkbox,all' + $this->_initAvailableColumns(); + $columns = array_merge($columns,array_keys($this->_types)); + $columns = array_diff($columns,array('all')); + } + foreach ($columns as $col) { $this->_addColumn($col); } + } $this->_addColumn('pagename'); @@ -176,4 +232,5 @@ class PageList { } + $this->_options = $options; $this->_messageIfEmpty = _("<no matches>"); } @@ -204,6 +261,13 @@ class PageList { function addPage ($page_handle) { + if (is_string($page_handle)) { + if (in_array($page_handle, $this->_excluded_pages)) + return; // exclude page. + $dbi = $GLOBALS['request']->getDbh(); + $page_handle = $dbi->getPage($page_handle); + } else { if (in_array($page_handle->getName(), $this->_excluded_pages)) return; // exclude page. + } $group = (int)(count($this->_rows) / $this->_group_rows); @@ -214,5 +278,5 @@ class PageList { $row = HTML::tr(array('class' => $class)); foreach ($this->_columns as $col) - $row->pushContent($col->format($page_handle, $revision_handle)); + $row->pushContent($col->format(&$this, $page_handle, $revision_handle)); } else { @@ -230,4 +294,9 @@ class PageList { } + function addPageList (&$list) { + reset ($list); + while ($page = next($list)) + $this->addPage($page); + } function getContent() { @@ -260,5 +329,8 @@ class PageList { $this->_types = - array('pagename' + array( + 'checkbox' + => new _PageList_Column_checkbox('p', _("Selected")), + 'pagename' => new _PageList_Column_pagename, @@ -297,9 +369,4 @@ class PageList { $this->_columns_seen[$column] = true; - - - - - if (strstr($column, ':')) list ($column, $heading) = explode(':', $column, 2); @@ -330,4 +397,5 @@ class PageList { $row = HTML::tr(); foreach ($this->_columns as $col) { + // Todo: add links to resort the table $row->pushContent($col->heading()); $table_summary[] = $col->_heading; @@ -356,4 +424,26 @@ class PageList { }; +/* List pages with checkboxes to select from. + * Todo: All, None jscript buttons. + */ + +class PageList_Selectable +extends PageList { + + function PageList_Selectable ($columns=false, $exclude=false) { + PageList::PageList($columns,$exclude); + } + + function addPageList ($array) { + while (list($pagename,$selected) = each($array)) { + if ($selected) $this->addPageSelected($pagename); + $this->addPage($pagename); + } + } + + function addPageSelected ($pagename) { + $this->_selected[$pagename] = 1; + } +} // (c-file-style: "gnu") Index: Request.php =================================================================== RCS file: /cvsroot/phpwiki/phpwiki/lib/Request.php,v retrieving revision 1.15 retrieving revision 1.16 diff -u -2 -b -p -d -r1.15 -r1.16 --- Request.php 24 Aug 2002 13:18:56 -0000 1.15 +++ Request.php 27 Aug 2002 21:51:31 -0000 1.16 @@ -67,11 +67,25 @@ class Request { } + function debugVars() { + $array = array(); + foreach (array('start_debug','debug_port','debug_no_cache') as $key) { + if (isset($GLOBALS['HTTP_GET_VARS'][$key])) + $array[$key] = $GLOBALS['HTTP_GET_VARS'][$key]; + } + return $array; + } + + // Well oh well. Do we really want to pass POST params back as GET? - function getURLtoSelf($args = false) { + function getURLtoSelf($args = false, $exclude = array()) { $get_args = $this->args; if ($args) $get_args = array_merge($get_args, $args); if (DEBUG) - $get_args = array_merge($get_args, $GLOBALS['HTTP_GET_VARS']); + $get_args = array_merge($get_args, $this->debugVars()); + + foreach ($exclude as $ex) { + if (!empty($get_args[$ex])) unset($get_args[$ex]); + } $pagename = $get_args['pagename']; Index: Template.php =================================================================== RCS file: /cvsroot/phpwiki/phpwiki/lib/Template.php,v retrieving revision 1.40 retrieving revision 1.41 diff -u -2 -b -p -d -r1.40 -r1.41 --- Template.php 23 Aug 2002 22:10:16 -0000 1.40 +++ Template.php 27 Aug 2002 21:51:31 -0000 1.41 @@ -211,12 +211,19 @@ function GeneratePage($content, $title, $request->setArg('framesrc',false); } else { - // This is a hack but, it works fast enough... so beware of spaces - // The other possibility would be to redirect to an action=FrameInclude + // Early plugin-head check: + // head plugins must consist of a single line at the VERY FIRST LINE in the content. + // This is a hack, but it works fast enough. if ($page_revision and $text = &$page_revision->getPackedContent() and - strstr($text, '<?plugin FrameInclude')) { + strstr($text, '<?plugin-head')) + { + $loader = new WikiPluginLoader(); + // CheckMe! + return $loader->expandPI('<\?plugin-head\s+(?!\S)',$request); + /* // the return of FrameInclude: $plugin = TransformText($page_revision); $args['FRAMESET'] = $plugin->_content[0]; printXML(new Template('frameset', $request, $args)); + */ } else { printXML(new Template('html', $request, $args)); @@ -246,5 +253,5 @@ function GeneratePageasXML($content, $ti $HTML_DUMP = true; - $html = asXML(new Template('top-htmldump', $request, $args)); + $html = asXML(new Template('htmldump', $request, $args)); $HIDE_TOOLBARS = false; Index: Theme.php =================================================================== RCS file: /cvsroot/phpwiki/phpwiki/lib/Theme.php,v retrieving revision 1.51 retrieving revision 1.52 diff -u -2 -b -p -d -r1.51 -r1.52 --- Theme.php 24 Aug 2002 13:18:56 -0000 1.51 +++ Theme.php 27 Aug 2002 21:51:31 -0000 1.52 @@ -149,6 +149,4 @@ function Button ($action, $label = false - - class Theme { var $HTML_DUMP_SUFFIX = ''; @@ -460,4 +458,6 @@ class Theme { // //////////////////////////////////////////////////////////////// + var $_imageAliases = array(); + var $_imageAlt = array(); /** @@ -467,4 +467,11 @@ class Theme { function addImageAlias ($alias, $image_name) { $this->_imageAliases[$alias] = $image_name; + } + + function addImageAlt ($alias, $alt_text) { + $this->_imageAlt[$alias] = $alt_text; + } + function getImageAlt ($alias) { + return $this->_imageAlt[$alias]; } Index: WikiDB.php =================================================================== RCS file: /cvsroot/phpwiki/phpwiki/lib/WikiDB.php,v retrieving revision 1.13 retrieving revision 1.14 diff -u -2 -b -p -d -r1.13 -r1.14 --- WikiDB.php 24 Aug 2002 13:18:56 -0000 1.13 +++ WikiDB.php 27 Aug 2002 21:51:31 -0000 1.14 @@ -721,4 +721,9 @@ class WikiDB_Page } + // special handling of sensitive pref data or upgrades from older versions: + if ($key == 'pref') { + if (!empty($newval['userid'])) unset($newval['userid']); + //if ($GLOBALS['user']->isAdmin()) unset($newval['passwd']); + } $cache->update_pagedata($pagename, array($key => $newval)); } @@ -1061,4 +1066,34 @@ class WikiDB_PageIterator $this->_pages->free(); } + + // Not yet used. + function setSortby ($arg = false) { + if (!$arg) { + $arg = @$_GET['sortby']; + if ($arg) { + $sortby = substr($arg,1); + $order = substr($arg,0,1)=='+' ? 'ASC' : 'DESC'; + } + } + if (is_array($arg)) { // array('mtime' => 'desc') + $sortby = $arg[0]; + $order = $arg[1]; + } else { + $sortby = $arg; + $order = 'ASC'; + } + // available column types to sort by: + // todo: we must provide access methods for the generic dumb/iterator + $this->_types = explode(',','pagename,mtime,hits,version,author,locked,minor,markup'); + if (in_array($sortby,$this->_types)) + $this->_options['sortby'] = $sortby; + else + trigger_error(fmt("Argument %s '%s' ignored",'sortby',$sortby), E_USER_WARNING); + if (in_array(strtoupper($order),'ASC','DESC')) + $this->_options['order'] = strtoupper($order); + else + trigger_error(fmt("Argument %s '%s' ignored",'order',$order), E_USER_WARNING); + } + }; @@ -1269,7 +1304,4 @@ class WikiDB_cache * or we might even be able to update the entries. * - * Group: list of userid's in a special WikiDB_Page - * WikiDB_Page: owner.group permission_flag in page metadata - * * FIXME: This was written before we stored prefs as %pagedata, so */ @@ -1285,4 +1317,5 @@ extends WikiUser } + /* function getPreferences() { // external prefs override internal ones? @@ -1297,4 +1330,5 @@ extends WikiUser return WikiUser::setPreferences(); } + */ function exists() { @@ -1313,5 +1347,5 @@ extends WikiUser function checkPassword($passwd) { - return $this->_authdb->pwcheck($passwd); + return $this->_authdb->pwcheck($this->userid, $passwd); } @@ -1322,5 +1356,5 @@ extends WikiUser return; } - return $this->_authdb->changePass($passwd); + return $this->_authdb->changePass($this->userid, $passwd); } @@ -1337,4 +1371,5 @@ extends WikiDB var $group_members = false, $user_groups = false; var $pref_update = false, $pref_select = false; + var $_dbh; function WikiAuthDB($DBAuthParams) { @@ -1342,40 +1377,74 @@ extends WikiDB $this->$key = $value; } + if (!$this->auth_dsn) { + trigger_error(_("no \$DBAuthParams['dsn'] provided"), E_USER_ERROR); + return false; + } + // compare auth DB to the existing page DB. reuse if it's on the same database. + if (isa($this->_backend, 'WikiDB_backend_PearDB') and + $this->_backend->_dsn == $this->auth_dsn) { + $this->_dbh = &$this->_backend->_dbh; + return $this->_backend; + } + include_once("lib/WikiDB/SQL.php"); + return new WikiDB_SQL($DBAuthParams); + } + + function param_missing ($param) { + trigger_error(sprintf(_("No \$DBAuthParams['%s'] provided."), $param), E_USER_ERROR); + return; } function getPrefs($prefs) { if ($this->pref_select) { - trigger_error(sprintf("WikiAuthDB->getPrefs() not yet written for '%s'", - $this->_userid), E_USER_WARNING); + $statement = $this->_backend->Prepare($this->pref_select); + return unserialize($this->_backend->Execute($statement, + $prefs->get('userid'))); } else { - trigger_error(sprintf("WikiAuthDB->getPrefs() not defined for '%s'", - $this->_userid), E_USER_ERROR); - } + param_missing('pref_select'); return false; } + } + function setPrefs($prefs) { if ($this->pref_write) { - trigger_error(sprintf("WikiAuthDB->setPrefs() not allowed for '%s'", - $this->_userid), E_USER_ERROR); + $statement = $this->_backend->Prepare($this->pref_write); + return $this->_backend->Execute($statement, + $prefs->get('userid'), serialize($prefs->_prefs)); } else { - trigger_error(sprintf("WikiAuthDB->setPrefs() not yet written for '%s'", - $this->_userid), E_USER_WARNING); - } + param_missing('pref_write'); return false; } + } + function createUser ($pref) { - trigger_error(sprintf("WikiAuthDB->createUser() not yet written for '%s'", - $this->_userid), E_USER_WARNING); + if ($this->user_create) { + $statement = $this->_backend->Prepare($this->user_create); + return $this->_backend->Execute($statement, + $prefs->get('userid'), serialize($prefs->_prefs)); + } else { + param_missing('user_create'); return false; } - function exists() { - trigger_error(sprintf("WikiAuthDB->exists() not yet written for '%s'", - $this->_userid), E_USER_WARNING); + } + + function exists($userid) { + if ($this->user_check) { + $statement = $this->_backend->Prepare($this->user_check); + return $this->_backend->Execute($statement, $prefs->get('userid')); + } else { + param_missing('user_check'); return false; } - function pwcheck($pass) { - trigger_error(sprintf("WikiAuthDB->pwcheck() not yet written for '%s'", - $this->_userid), E_USER_WARNING); + } + + function pwcheck($userid, $pass) { + if ($this->auth_check) { + $statement = $this->_backend->Prepare($this->auth_check); + return $this->_backend->Execute($statement, $userid, $pass); + } else { + param_missing('auth_check'); return false; + } } } Index: WikiPlugin.php =================================================================== RCS file: /cvsroot/phpwiki/phpwiki/lib/WikiPlugin.php,v retrieving revision 1.23 retrieving revision 1.24 diff -u -2 -b -p -d -r1.23 -r1.24 --- WikiPlugin.php 19 Aug 2002 11:32:29 -0000 1.23 +++ WikiPlugin.php 27 Aug 2002 21:51:31 -0000 1.24 @@ -5,5 +5,5 @@ class WikiPlugin { function getDefaultArguments() { - return array(); + return array('description' => $this->getDescription()); } @@ -241,5 +241,5 @@ class WikiPluginLoader { function expandPI($pi, $request) { - if (!preg_match('/^\s*<\?(plugin(?:-form|-link)?)\s+(\w+)\s*(.*?)\s*\?>\s*$/s', $pi, $m)) + if (!preg_match('/^\s*<\?(plugin(?:-form|-link|-head)?)\s+(\w+)\s*(.*?)\s*\?>\s*$/s', $pi, $m)) return $this->_error(sprintf("Bad %s", 'PI')); @@ -253,4 +253,5 @@ class WikiPluginLoader { switch ($pi_name) { case 'plugin': + case 'plugin-head': // FIXME: change API for run() (no $dbi needed). $dbi = $request->getDbh(); Index: WikiUser.php =================================================================== RCS file: /cvsroot/phpwiki/phpwiki/lib/WikiUser.php,v retrieving revision 1.19 retrieving revision 1.20 diff -u -2 -b -p -d -r1.19 -r1.20 --- WikiUser.php 24 Aug 2002 22:09:14 -0000 1.19 +++ WikiUser.php 27 Aug 2002 21:51:31 -0000 1.20 @@ -18,5 +18,5 @@ define('WIKIAUTH_FORBIDDEN', 11); // Com $UserPreferences = array( - 'userid' => new _UserPreference(''), + 'userid' => new _UserPreference(''), // really store this also? 'passwd' => new _UserPreference(''), 'email' => new _UserPreference(''), @@ -196,5 +196,5 @@ class WikiUser { // WikiDB_User DB/File Authentification from $DBAuthParams // Check if we have the user. If not try other methods. - if (ALLOW_USER_LOGIN and !empty($passwd)) { + if (ALLOW_USER_LOGIN) { // and !empty($passwd)) { $request = $this->_request; // first check if the user is known @@ -250,5 +250,5 @@ class WikiUser { // and get the preferences from the db or page. if (!($prefs = $this->_request->getCookieVar('WIKI_PREFS2'))) - $prefs = $this->_request->getSessionVar('wiki_prefs'); + $prefs = $this->request->getSessionVar('wiki_prefs'); if (!$this->_userid and !empty($GLOBALS['HTTP_COOKIE_VARS']['WIKI_ID'])) { @@ -266,4 +266,6 @@ class WikiUser { // No cookies anymore for all prefs, only the userid. // PHP creates a session cookie in memory, which is much more efficient. + // + // Return the number of changed entries? function setPreferences($prefs, $id_only = false) { // update the id @@ -275,10 +277,22 @@ class WikiUser { // We must ensure that any password is encrypted. // We don't need any plaintext password. - if (! $id_only and $this->isSignedIn() and ($homepage = $this->homePage())) { - if ($this->isAdmin()) - $prefs->set('passwd',''); // this is already stored in index.php, + if (! $id_only ) { + if ($this->isSignedIn()) { + if ($this->isAdmin()) $prefs->set('passwd',''); // this is already stored in index.php, // and it might be plaintext! well oh well + if ($homepage = $this->homePage()) { $homepage->set('pref',serialize($prefs->_prefs)); + return sizeof($prefs->_prefs); + } else { + trigger_error('No homepage for user found. Creating one...', E_USER_WARNING); + $this->createHomepage($prefs); + //$homepage->set('pref',serialize($prefs->_prefs)); + return sizeof($prefs->_prefs); } + } else { + trigger_error('you must be signed in',E_USER_WARNING); + } + } + return 0; } @@ -366,10 +380,10 @@ class WikiUser { if (empty($prefs->_prefs['passwd'])) // not stored in the page // allow empty passwords? At least store a '*' then. - // try other backend + // try other backend. hmm. $stored_passwd = $this->tryAuthBackends($this->_userid); if (empty($stored_passwd)) { - trigger_error(sprintf(_("WikiUser backend problem: Old UserPage %s. No password to check against! Update your UserPreferences."), $this->_userid), E_USER_NOTICE); + trigger_error(sprintf(_("Old UserPage %s without stored password updated with empty password. Set a password in your UserPreferences."), $this->_userid), E_USER_NOTICE); + $prefs->set('passwd','*'); return true; - //return false; } if ($stored_passwd == '*') @@ -532,6 +546,6 @@ class UserPreferences { break; case 'lang': - $LANG = ($value == 'en') ? 'C' : $value; update_locale ($LANG); + $GLOBALS['LANG'] = $value; break; } Index: config.php =================================================================== RCS file: /cvsroot/phpwiki/phpwiki/lib/config.php,v retrieving revision 1.60 retrieving revision 1.61 diff -u -2 -b -p -d -r1.60 -r1.61 --- config.php 23 Aug 2002 18:29:29 -0000 1.60 +++ config.php 27 Aug 2002 21:51:31 -0000 1.61 @@ -31,5 +31,6 @@ function FindFile ($file, $missing_okay if (!isset($finder)) $finder = new FileFinder; - return $finder->findFile($file, $missing_okay); + $s = $finder->findFile($file, $missing_okay); + return $s; } @@ -69,11 +70,27 @@ if (!function_exists ('bindtextdomain')) return gettext($text); } + + if ( ($lcfile = FindLocalizedFile("LC_MESSAGES/phpwiki.php", 'missing_ok')) ) { + include($lcfile); + } } // Setup localisation +// This is currently broken, after trying to enable dynamic UserPreferences +// on the language. function update_locale ($LANG) { - if ($LANG == 'en') - $LANG = 'C'; - setlocale(LC_ALL, "$LANG"); + //return; + global $locale, $LC_ALL, $language_locales; + if (empty($language_locales[$LANG])) + $LC_ALL = $LANG; + else + $LC_ALL = $language_locales[$LANG]; + if (empty($LC_ALL)) + $LC_ALL = $LANG; + + // Fixme: Currently we just check the dirs under locale for all + // available languages, but with setlocale we must use the long form, + // like 'de_DE','nl_NL', 'es_MX', 'es_AR', 'fr_FR'. For Windows maybe even 'german'. + setlocale(LC_ALL, $LC_ALL); if (!function_exists ('bindtextdomain')) { @@ -82,4 +99,7 @@ function update_locale ($LANG) { } } else { + if (empty($language_locales[$LANG])) { + trigger_error(_("Dynamically changing the language not (yet) available on this locale"), E_USER_NOTICE); + } // Setup localisation bindtextdomain ("phpwiki", FindFile("locale")); @@ -88,5 +108,30 @@ function update_locale ($LANG) { } -update_locale ($LANG); +//update_locale ($LANG); + + if (empty($language_locales[$LANG])) + $LC_ALL = $LANG; + else + $LC_ALL = $language_locales[$LANG]; + if (empty($LC_ALL)) + $LC_ALL = $LANG; + + // Fixme: Currently we just check the dirs under locale for all + // available languages, but with setlocale we must use the long form, + // like 'de_DE','nl_NL', 'es_MX', 'es_AR', 'fr_FR'. For Windows maybe even 'german'. + setlocale(LC_ALL, $LC_ALL); + + if (!function_exists ('bindtextdomain')) { + if ( ($lcfile = FindLocalizedFile("LC_MESSAGES/phpwiki.php", 'missing_ok')) ) { + include($lcfile); + } + } else { + if (empty($language_locales[$LANG])) { + trigger_error(_("Dynamically changing the language not (yet) available on this locale"), E_USER_NOTICE); + } + // Setup localisation + bindtextdomain ("phpwiki", FindFile("locale")); + textdomain ("phpwiki"); + } Index: display.php =================================================================== RCS file: /cvsroot/phpwiki/phpwiki/lib/display.php,v retrieving revision 1.35 retrieving revision 1.36 diff -u -2 -b -p -d -r1.35 -r1.36 --- display.php 23 Aug 2002 18:29:30 -0000 1.35 +++ display.php 27 Aug 2002 21:51:31 -0000 1.36 @@ -93,5 +93,5 @@ function displayPage(&$request, $tmpl = $last_page = array_pop($pages); // deletes last element from array as side-effect $pagetitle = HTML::span(HTML::a(array('href' => WikiURL($pages[0]), - //'class' => 'backlinks' + 'class' => 'pagetitle' ), split_pagename($pages[0] . SUBPAGE_SEPARATOR))); Index: interwiki.php =================================================================== RCS file: /cvsroot/phpwiki/phpwiki/lib/interwiki.php,v retrieving revision 1.21 retrieving revision 1.22 diff -u -2 -b -p -d -r1.21 -r1.22 --- interwiki.php 24 Aug 2002 13:18:56 -0000 1.21 +++ interwiki.php 27 Aug 2002 21:51:31 -0000 1.22 @@ -85,4 +85,5 @@ class InterWikiMap { } + // Fixme! function _getMapFromFile ($filename) { if (defined('WARN_NONPUBLIC_INTERWIKIMAP') and WARN_NONPUBLIC_INTERWIKIMAP) { @@ -90,5 +91,8 @@ class InterWikiMap { trigger_error( $error_html, E_USER_NOTICE ); } - + if (!file_exists($filename)) { + $finder = new FileFinder(); + $filename = $finder->findFile(INTERWIKI_MAP_FILE); + } @$fd = fopen ($filename, "rb"); @$data = fread ($fd, filesize($filename)); Index: main.php =================================================================== RCS file: /cvsroot/phpwiki/phpwiki/lib/main.php,v retrieving revision 1.70 retrieving revision 1.71 diff -u -2 -b -p -d -r1.70 -r1.71 --- main.php 24 Aug 2002 13:18:56 -0000 1.70 +++ main.php 27 Aug 2002 21:51:31 -0000 1.71 @@ -274,4 +274,5 @@ class WikiRequest extends Request { case 'viewsource': case 'diff': + case 'select': return WIKIAUTH_ANON; Index: stdlib.php =================================================================== RCS file: /cvsroot/phpwiki/phpwiki/lib/stdlib.php,v retrieving revision 1.115 retrieving revision 1.116 diff -u -2 -b -p -d -r1.115 -r1.116 --- stdlib.php 24 Aug 2002 13:18:56 -0000 1.115 +++ stdlib.php 27 Aug 2002 21:51:31 -0000 1.116 @@ -1,3 +1,3 @@ -<?php rcs_id('$Id$'); +<?php //rcs_id('$Id$'); /* @@ -27,4 +27,8 @@ __vsprintf ($fmt, $args) better_srand($seed = '') + count_all($arg) + isSubPage($pagename) + subPageSlice($pagename, $pos) + explodePageList($input, $perm = false) function: LinkInterWikiLink($link, $linktext) @@ -460,13 +464,22 @@ function split_pagename ($page) { $RE[$key] = pcre_fix_posix_classes($val); } - - foreach ($RE as $regexp) + if (isSubPage($page)) { + $pages = explode(SUBPAGE_SEPARATOR,$page); + $new_page = $pages[0] ? split_pagename($pages[0]) : ''; + for ($i=1; $i < sizeof($pages); $i++) { + $new_page .= (SUBPAGE_SEPARATOR . ($pages[$i] ? split_pagename($pages[$i]) : '')); + } + return $new_page; + } else { + foreach ($RE as $regexp) { $page = preg_replace($regexp, '\1円 \2円', $page); + } return $page; + } } function NoSuchRevision (&$request, $page, $version) { $html = HTML(HTML::h2(_("Revision Not Found")), - HTML::p(fmt("I'm sorry. Version %d of %s is not in my database.", + HTML::p(fmt("I'm sorry. Version %d of %s is not in the database.", $version, WikiLink($page, 'auto')))); include_once('lib/Template.php'); @@ -661,10 +674,16 @@ class fileSet { function _filenameSelector($filename) { - // Default selects all filenames, override as needed. + if (! $this->_pattern) return true; + else { + return glob_match ($this->_pattern, $filename, $this->_case); + } } - function fileSet($directory) { + function fileSet($directory, $filepattern = false) { $this->_fileList = array(); + $this->_pattern = $filepattern; + $this->_case = !isWindows(); + $this->_pathsep = '/'; if (empty($directory)) { @@ -682,5 +701,5 @@ class fileSet { while ($filename = readdir($dir_handle)) { - if ($filename[0] == '.' || filetype("$dir/$filename") != 'file') + if ($filename[0] == '.' || filetype($dir . $this->_pathsep . $filename) != 'file') continue; if ($this->_filenameSelector($filename)) { @@ -694,4 +713,73 @@ class fileSet { }; +// File globbing + +// expands a list containing regex's to its matching entries +class ListRegexExpand { + var $match, $list, $index, $case_sensitive; + function ListRegexExpand (&$list, $match, $case_sensitive = true) { + $this->match = $match; + $this->list = &$list; + $this->case_sensitive = $case_sensitive; + } + function listMatchCallback ($item, $key) { + if (preg_match('/' . $this->match . ($this->case_sensitive ? '/' : '/i'), $item)) { + unset($this->list[$this->index]); + $this->list[] = $item; + } + } + function expandRegex ($index, &$pages) { + $this->index = $index; + array_walk($pages, array($this, 'listMatchCallback')); + return $this->list; + } +} + +// convert fileglob to regex style +function glob_to_pcre ($glob) { + $re = preg_replace('/\./', '\\.', $glob); + $re = preg_replace(array('/\*/','/\?/'), array('.*','.'), $glob); + if (!preg_match('/^[\?\*]/',$glob)) + $re = '^' . $re; + if (!preg_match('/[\?\*]$/',$glob)) + $re = $re . '$'; + return $re; +} + +function glob_match ($glob, $against, $case_sensitive = true) { + return preg_match('/' . glob_to_pcre($glob) . ($case_sensitive ? '/' : '/i'), $against); +} + +function explodeList($input, $allnames, $glob_style = true, $case_sensitive = true) { + $list = explode(',',$input); + // expand wildcards from list of $allnames + if (preg_match('/[\?\*]/',$input)) { + for ($i = 0; $i <= sizeof($list); $i++) { + $f = $list[$i]; + if (preg_match('/[\?\*]/',$f)) { + reset($allnames); + $expand = new ListRegexExpand(&$list, $glob_style ? glob_to_pcre($f) : $f, $case_sensitive); + $expand->expandRegex($i, &$allnames); + } + } + } + return $list; +} + +// echo implode(":",explodeList("Test*",array("xx","Test1","Test2"))); + +function explodePageList($input, $perm = false) { + $list = explode(',',$input); + // expand wildcards from list of all pages + if (preg_match('/[\?\*]/',$input)) { + $dbi = $GLOBALS['request']->_dbi; + $allPagehandles = $dbi->getAllPages($perm); + while ($pagehandle = $allPagehandles->next()) { + $allPages[] = $pagehandle->getName(); + } + return explodeList($input, &$allPages); + } + return $list; +} // Class introspections