*
* array('action' => 'diff', 'previous' => 'author') *
false
.
*/
function addImageAlias ($alias, $image_name) {
// fall back to the PhpWiki-supplied image if not found
if ($this->_findFile("images/$image_name", true))
$this->_imageAliases[$alias] = $image_name;
}
function addImageAlt ($alias, $alt_text) {
$this->_imageAlt[$alias] = $alt_text;
}
function getImageAlt ($alias) {
return $this->_imageAlt[$alias];
}
function getImageURL ($image) {
$aliases = &$this->_imageAliases;
if (isset($aliases[$image])) {
$image = $aliases[$image];
if (!$image)
return false;
}
// If not extension, default to .png.
if (!preg_match('/\.\w+$/', $image))
$image .= '.png';
// FIXME: this should probably be made to fall back
// automatically to .gif, .jpg.
// Also try .gif before .png if browser doesn't like png.
$path = $this->_findData("images/$image", 'missing okay');
if (!$path) // search explicit images/ or button/ links also
return $this->_findData("$image", 'missing okay');
else
return $path;
}
function setLinkIcon($proto, $image = false) {
if (!$image)
$image = $proto;
$this->_linkIcons[$proto] = $image;
}
function getLinkIconURL ($proto) {
$icons = &$this->_linkIcons;
if (!empty($icons[$proto]))
return $this->getImageURL($icons[$proto]);
elseif (!empty($icons['*']))
return $this->getImageURL($icons['*']);
return false;
}
function addButtonAlias ($text, $alias = false) {
$aliases = &$this->_buttonAliases;
if (is_array($text))
$aliases = array_merge($aliases, $text);
elseif ($alias === false)
unset($aliases[$text]);
else
$aliases[$text] = $alias;
}
function getButtonURL ($text) {
$aliases = &$this->_buttonAliases;
if (isset($aliases[$text]))
$text = $aliases[$text];
$qtext = urlencode($text);
$url = $this->_findButton("$qtext.png");
if ($url && strstr($url, '%')) {
$url = preg_replace('|([^/]+)$|e', 'urlencode("\\1")', $url);
}
if (!$url) {// Jeff complained about png not supported everywhere. This is not PC
$url = $this->_findButton("$qtext.gif");
if ($url && strstr($url, '%')) {
$url = preg_replace('|([^/]+)$|e', 'urlencode("\\1")', $url);
}
}
return $url;
}
function _findButton ($button_file) {
if (!isset($this->_button_path))
$this->_button_path = $this->_getButtonPath();
foreach ($this->_button_path as $dir) {
$path = "$this->_theme/$dir/$button_file";
if (file_exists($this->_path . $path))
return defined('DATA_PATH') ? DATA_PATH . "/$path" : $path;
}
return false;
}
function _getButtonPath () {
$button_dir = $this->file("buttons");
if (!file_exists($button_dir) || !is_dir($button_dir))
return array();
$path = array('buttons');
$dir = dir($button_dir);
while (($subdir = $dir->read()) !== false) {
if ($subdir[0] == '.')
continue;
if (is_dir("$button_dir/$subdir"))
$path[] = "buttons/$subdir";
}
$dir->close();
return $path;
}
////////////////////////////////////////////////////////////////
//
// Button style
//
////////////////////////////////////////////////////////////////
function makeButton ($text, $url, $class = false) {
// FIXME: don't always try for image button?
// Special case: URLs like 'submit:preview' generate form
// submission buttons.
if (preg_match('/^submit:(.*)$/', $url, $m))
return $this->makeSubmitButton($text, $m[1], $class);
$imgurl = $this->getButtonURL($text);
if ($imgurl)
return new ImageButton($text, $url, $class, $imgurl);
else
return new Button($text, $url, $class);
}
function makeSubmitButton ($text, $name, $class = false) {
$imgurl = $this->getButtonURL($text);
if ($imgurl)
return new SubmitImageButton($text, $name, $class, $imgurl);
else
return new SubmitButton($text, $name, $class);
}
/**
* Make button to perform action.
*
* This constructs a button which performs an action on the
* currently selected version of the current page.
* (Or anotherpage or version, if you want...)
*
* @param $action string The action to perform (e.g. 'edit', 'lock').
* This can also be the name of an "action page" like 'LikePages'.
* Alternatively you can give a hash of query args to be applied
* to the page.
*
* @param $label string Textual label for the button. If left empty,
* a suitable name will be guessed.
*
* @param $page_or_rev mixed The page to link to. This can be
* given as a string (the page name), a WikiDB_Page object, or as
* WikiDB_PageRevision object. If given as a WikiDB_PageRevision
* object, the button will link to a specific version of the
* designated page, otherwise the button links to the most recent
* version of the page.
*
* @return object A Button object.
*/
function makeActionButton ($action, $label = false, $page_or_rev = false) {
extract($this->_get_name_and_rev($page_or_rev));
if (is_array($action)) {
$attr = $action;
$action = isset($attr['action']) ? $attr['action'] : 'browse';
}
else
$attr['action'] = $action;
$class = is_safe_action($action) ? 'wikiaction' : 'wikiadmin';
if (!$label)
$label = $this->_labelForAction($action);
if ($version)
$attr['version'] = $version;
if ($action == 'browse')
unset($attr['action']);
return $this->makeButton($label, WikiURL($pagename, $attr), $class);
}
/**
* Make a "button" which links to a wiki-page.
*
* These are really just regular WikiLinks, possibly
* disguised (e.g. behind an image button) by the theme.
*
* This method should probably only be used for links
* which appear in page navigation bars, or similar places.
*
* Use linkExistingWikiWord, or LinkWikiWord for normal links.
*
* @param $page_or_rev mixed The page to link to. This can be
* given as a string (the page name), a WikiDB_Page object, or as
* WikiDB_PageRevision object. If given as a WikiDB_PageRevision
* object, the button will link to a specific version of the
* designated page, otherwise the button links to the most recent
* version of the page.
*
* @return object A Button object.
*/
function makeLinkButton ($page_or_rev, $label = false) {
extract($this->_get_name_and_rev($page_or_rev));
$args = $version ? array('version' => $version) : false;
return $this->makeButton($label ? $label : $this->maybeSplitWikiWord($pagename),
WikiURL($pagename, $args), 'wiki');
}
function _get_name_and_rev ($page_or_rev) {
$version = false;
if (empty($page_or_rev)) {
global $request;
$pagename = $request->getArg("pagename");
$version = $request->getArg("version");
}
elseif (is_object($page_or_rev)) {
if (isa($page_or_rev, 'WikiDB_PageRevision')) {
$rev = $page_or_rev;
$page = $rev->getPage();
$version = $rev->getVersion();
}
else {
$page = $page_or_rev;
}
$pagename = $page->getName();
}
else {
$pagename = (string) $page_or_rev;
}
return compact('pagename', 'version');
}
function _labelForAction ($action) {
switch ($action) {
case 'edit': return _("Edit");
case 'diff': return _("Diff");
case 'logout': return _("Sign Out");
case 'login': return _("Sign In");
case 'lock': return _("Lock Page");
case 'unlock': return _("Unlock Page");
case 'remove': return _("Remove Page");
default:
// I don't think the rest of these actually get used.
// 'setprefs'
// 'upload' 'dumpserial' 'loadfile' 'zip'
// 'save' 'browse'
return gettext(ucfirst($action));
}
}
//----------------------------------------------------------------
var $_buttonSeparator = "\n | ";
function setButtonSeparator($separator) {
$this->_buttonSeparator = $separator;
}
function getButtonSeparator() {
return $this->_buttonSeparator;
}
////////////////////////////////////////////////////////////////
//
// CSS
//
// Notes:
//
// Based on testing with Galeon 1.2.7 (Mozilla 1.2):
// Automatic media-based style selection (via tags) only
// seems to work for the default style, not for alternate styles.
//
// Doing
//
//
//
//
// works to make it so that the printer style sheet get used
// automatically when printing (or print-previewing) a page
// (but when only when the default style is selected.)
//
// Attempts like:
//
//
//
//
// Result in two "Modern" choices when trying to select alternate style.
// If one selects the first of those choices, one gets phpwiki-modern
// both when browsing and printing. If one selects the second "Modern",
// one gets no CSS when browsing, and phpwiki-printer when printing.
//
// The Real Fix?
// =============
//
// We should probably move to doing the media based style
// switching in the CSS files themselves using, e.g.:
//
// @import url(print.css) print;
//
////////////////////////////////////////////////////////////////
function _CSSlink($title, $css_file, $media, $is_alt = false) {
// Don't set title on default style. This makes it clear to
// the user which is the default (i.e. most supported) style.
$link = HTML::link(array('rel' => $is_alt ? 'alternate stylesheet' : 'stylesheet',
'type' => 'text/css',
'charset' => CHARSET,
'href' => $this->_findData($css_file)));
if ($is_alt)
$link->setAttr('title', $title);
if ($media)
$link->setAttr('media', $media);
return $link;
}
/** Set default CSS source for this theme.
*
* To set styles to be used for different media, pass a
* hash for the second argument, e.g.
*
* $theme->setDefaultCSS('default', array('' => 'normal.css',
* 'print' => 'printer.css'));
*
* If you call this more than once, the last one called takes
* precedence as the default style.
*
* @param string $title Name of style (currently ignored, unless
* you call this more than once, in which case, some of the style
* will become alternate (rather than default) styles, and then their
* titles will be used.
*
* @param mixed $css_files Name of CSS file, or hash containing a mapping
* between media types and CSS file names. Use a key of '' (the empty string)
* to set the default CSS for non-specified media. (See above for an example.)
*/
function setDefaultCSS ($title, $css_files) {
if (!is_array($css_files))
$css_files = array('' => $css_files);
// Add to the front of $this->_css
unset($this->_css[$title]);
$this->_css = array_merge(array($title => $css_files), $this->_css);
}
/** Set alternate CSS source for this theme.
*
* @param string $title Name of style.
* @param string $css_files Name of CSS file.
*/
function addAlternateCSS ($title, $css_files) {
if (!is_array($css_files))
$css_files = array('' => $css_files);
$this->_css[$title] = $css_files;
}
/**
* @return string HTML for CSS.
*/
function getCSS () {
$css = array();
$is_alt = false;
foreach ($this->_css as $title => $css_files) {
ksort($css_files); // move $css_files[''] to front.
foreach ($css_files as $media => $css_file) {
$css[] = $this->_CSSlink($title, $css_file, $media, $is_alt);
if ($is_alt) break;
}
$is_alt = true;
}
return HTML($css);
}
function findTemplate ($name) {
return $this->_path . $this->_findFile("templates/$name.tmpl");
}
};
/**
* A class representing a clickable "button".
*
* In it's simplest (default) form, a "button" is just a link associated
* with some sort of wiki-action.
*/
class Button extends HtmlElement {
/** Constructor
*
* @param $text string The text for the button.
* @param $url string The url (href) for the button.
* @param $class string The CSS class for the button.
*/
function Button ($text, $url, $class = false) {
global $request;
$this->HtmlElement('a', array('href' => $url));
if ($class)
$this->setAttr('class', $class);
if ($request->getArg('frame'))
$this->setAttr('target', '_top');
$this->pushContent($GLOBALS['Theme']->maybeSplitWikiWord($text));
}
};
/**
* A clickable image button.
*/
class ImageButton extends Button {
/** Constructor
*
* @param $text string The text for the button.
* @param $url string The url (href) for the button.
* @param $class string The CSS class for the button.
* @param $img_url string URL for button's image.
* @param $img_attr array Additional attributes for the <img> tag.
*/
function ImageButton ($text, $url, $class, $img_url, $img_attr = false) {
$this->HtmlElement('a', array('href' => $url));
if ($class)
$this->setAttr('class', $class);
if (!is_array($img_attr))
$img_attr = array();
$img_attr['src'] = $img_url;
$img_attr['alt'] = $text;
$img_attr['class'] = 'wiki-button';
$img_attr['border'] = 0;
$this->pushContent(HTML::img($img_attr));
}
};
/**
* A class representing a form submit button.
*/
class SubmitButton extends HtmlElement {
/** Constructor
*
* @param $text string The text for the button.
* @param $name string The name of the form field.
* @param $class string The CSS class for the button.
*/
function SubmitButton ($text, $name = false, $class = false) {
$this->HtmlElement('input', array('type' => 'submit',
'value' => $text));
if ($name)
$this->setAttr('name', $name);
if ($class)
$this->setAttr('class', $class);
}
};
/**
* A class representing an image form submit button.
*/
class SubmitImageButton extends SubmitButton {
/** Constructor
*
* @param $text string The text for the button.
* @param $name string The name of the form field.
* @param $class string The CSS class for the button.
* @param $img_url string URL for button's image.
* @param $img_attr array Additional attributes for the <img> tag.
*/
function SubmitImageButton ($text, $name = false, $class = false, $img_url) {
$this->HtmlElement('input', array('type' => 'image',
'src' => $img_url,
'value' => $text,
'alt' => $text));
if ($name)
$this->setAttr('name', $name);
if ($class)
$this->setAttr('class', $class);
}
};
// $Log: not supported by cvs2svn $
// Revision 1.69 2003/12/05 01:32:28 carstenklapp
// New feature: Easier to run multiple wiks off of one set of code. Name
// your logo and signature image files "YourWikiNameLogo.png" and
// "YourWikiNameSignature.png" and put them all into
// themes/default/images. YourWikiName should match what is defined as
// WIKI_NAME in index.php. In case the image is not found, the default
// shipped with PhpWiki will be used.
//
// Revision 1.68 2003/03/04 01:53:30 dairiki
// Inconsequential decrufting.
//
// Revision 1.67 2003/02/26 03:40:22 dairiki
// New action=create. Essentially the same as action=edit, except that if the
// page already exists, it falls back to action=browse.
//
// This is for use in the "question mark" links for unknown wiki words
// to avoid problems and confusion when following links from stale pages.
// (If the "unknown page" has been created in the interim, the user probably
// wants to view the page before editing it.)
//
// Revision 1.66 2003/02/26 00:10:26 dairiki
// More/better/different checks for bad page names.
//
// Revision 1.65 2003/02/24 22:41:57 dairiki
// Fix stupid typo.
//
// Revision 1.64 2003/02/24 22:06:14 dairiki
// Attempts to fix auto-selection of printer CSS when printing.
// See new comments lib/Theme.php for more details.
// Also see SF patch #669563.
//
// Revision 1.63 2003/02/23 03:37:05 dairiki
// Stupid typo/bug fix.
//
// Revision 1.62 2003/02/21 04:14:52 dairiki
// New WikiLink type 'if_known'. This gives linkified name if page
// exists, otherwise, just plain text.
//
// Revision 1.61 2003/02/18 21:52:05 dairiki
// Fix so that one can still link to wiki pages with # in their names.
// (This was made difficult by the introduction of named tags, since
// '[Page #1]' is now a link to anchor '1' in page 'Page'.
//
// Now the ~ escape for page names should work: [Page ~#1].
//
// Revision 1.60 2003/02/15 01:59:47 dairiki
// Theme::getCSS(): Add Default-Style HTTP(-eqiv) header in attempt
// to fix default stylesheet selection on some browsers.
// For details on the Default-Style header, see:
// http://home.dairiki.org/docs/html4/present/styles.html#h-14.3.2
//
// Revision 1.59 2003/01/04 22:30:16 carstenklapp
// New: display a "Never edited." message instead of an invalid epoch date.
//
// (c-file-style: "gnu")
// Local Variables:
// mode: php
// tab-width: 8
// c-basic-offset: 4
// c-hanging-comment-ender-p: nil
// indent-tabs-mode: nil
// End:
?>