From: <lph...@us...> - 2009-01-20 19:16:06
|
Revision: 16335 http://tikiwiki.svn.sourceforge.net/tikiwiki/?rev=16335&view=rev Author: lphuberdeau Date: 2009-01-20 19:15:51 +0000 (Tue, 20 Jan 2009) Log Message: ----------- [MRG] Automatic merge, trunk 16267 to 16333 Modified Paths: -------------- branches/experimental/ui-revamp/_htaccess branches/experimental/ui-revamp/db/tiki.sql branches/experimental/ui-revamp/lib/init/tra.php branches/experimental/ui-revamp/lib/profilelib/installlib.php branches/experimental/ui-revamp/lib/profilelib/profilelib.php branches/experimental/ui-revamp/lib/setup/prefs.php branches/experimental/ui-revamp/lib/smarty_tiki/function.wikistructure.php branches/experimental/ui-revamp/lib/tikiaccesslib.php branches/experimental/ui-revamp/lib/tikilib.php branches/experimental/ui-revamp/lib/trackers/trackerlib.php branches/experimental/ui-revamp/lib/wiki-plugins/wikiplugin_code.php branches/experimental/ui-revamp/lib/wiki-plugins/wikiplugin_toc.php branches/experimental/ui-revamp/lib/wiki-plugins/wikiplugin_trackerlist.php branches/experimental/ui-revamp/styles/darkroom.css branches/experimental/ui-revamp/styles/transitions/2.0to3.0.css branches/experimental/ui-revamp/templates/list_file_gallery.tpl branches/experimental/ui-revamp/templates/module.tpl branches/experimental/ui-revamp/templates/modules/mod-switch_lang.tpl branches/experimental/ui-revamp/templates/tiki-admin-include-profiles.tpl branches/experimental/ui-revamp/templates/tiki-editpage.tpl branches/experimental/ui-revamp/templates/tiki-plugin_trackerlist.tpl branches/experimental/ui-revamp/templates/tracker_item_field_value.tpl branches/experimental/ui-revamp/tests/testfile.txt branches/experimental/ui-revamp/tiki-admin_include_profiles.php branches/experimental/ui-revamp/tiki-admin_tracker_fields.php branches/experimental/ui-revamp/tiki-editpage.php branches/experimental/ui-revamp/tiki-index.php branches/experimental/ui-revamp/tiki-view_tracker_item.php Added Paths: ----------- branches/experimental/ui-revamp/installer/schema/20090120_lost_2.0to3.0.sql branches/experimental/ui-revamp/lib/profilelib/channellib.php branches/experimental/ui-revamp/lib/wiki-plugins/wikiplugin_footnote.php branches/experimental/ui-revamp/lib/wiki-plugins/wikiplugin_footnotearea.php branches/experimental/ui-revamp/lib/wiki-plugins/wikiplugin_mwtable.php branches/experimental/ui-revamp/tiki-channel.php branches/experimental/ui-revamp/tiki-sefurl.php Removed Paths: ------------- branches/experimental/ui-revamp/lib/graph2/ Property Changed: ---------------- branches/experimental/ui-revamp/ branches/experimental/ui-revamp/installer/schema/20081105_calendar_items_allday_update_tiki.sql branches/experimental/ui-revamp/installer/schema/20081211_newsletter_files_tiki.sql branches/experimental/ui-revamp/lib/core/lib/Multilingual/Aligner/BilingualAligner.php branches/experimental/ui-revamp/lib/core/lib/Multilingual/Aligner/SentenceSegmentor.php branches/experimental/ui-revamp/lib/core/lib/Multilingual/Aligner/ShortestPathFinder.php branches/experimental/ui-revamp/lib/core/test/Multilingual/Aligner/AllTests.php branches/experimental/ui-revamp/lib/core/test/Multilingual/Aligner/BilingualAlignerTest.php branches/experimental/ui-revamp/lib/core/test/Multilingual/Aligner/SentenceSegmentorTest.php branches/experimental/ui-revamp/lib/core/test/Multilingual/Aligner/ShortestPathFinderTest.php branches/experimental/ui-revamp/templates/tiki-pagecontrols-tab-header.tpl Property changes on: branches/experimental/ui-revamp ___________________________________________________________________ Modified: svn:mergeinfo - /branches/experimental/declfilter:15787-16031 /trunk:15666-16267 + /branches/experimental/declfilter:15787-16031 /trunk:15666-16333 Modified: branches/experimental/ui-revamp/_htaccess =================================================================== --- branches/experimental/ui-revamp/_htaccess 2009-01-20 19:14:39 UTC (rev 16334) +++ branches/experimental/ui-revamp/_htaccess 2009-01-20 19:15:51 UTC (rev 16335) @@ -95,7 +95,7 @@ # todo add support for all characters allowed in a Wiki name # make sure this is the last rule! RewriteRule ^show:(~?)([-_\+A-Za-z0-9]+)$ tiki-slideshow.php?page=$1$2 [QSA,L] -RewriteRule ^([^/\.]+)$ tiki-index.php?page=$1 [QSA,L] +RewriteRule ^(.+)$ tiki-index.php?page=$1 [QSA,L] # Following one rule added to support &bl "Best Language". SEWilco 2008-07-15 RewriteRule ^([-_\+A-Za-z0-9]+)&bl$ tiki-index.php?page=$1&bl [QSA,L] Modified: branches/experimental/ui-revamp/db/tiki.sql =================================================================== --- branches/experimental/ui-revamp/db/tiki.sql 2009-01-20 19:14:39 UTC (rev 16334) +++ branches/experimental/ui-revamp/db/tiki.sql 2009-01-20 19:15:51 UTC (rev 16335) @@ -2825,6 +2825,7 @@ INSERT INTO users_permissions (permName, permDesc, level, type) VALUES ('tiki_p_edit_categorized', 'Can edit items in categories', 'registered', 'category'); INSERT INTO users_permissions (permName, permDesc, level, type) VALUES ('tiki_p_view_categories', 'Can view categories', 'basic', 'category'); INSERT INTO users_permissions (permName, permDesc, level, type) VALUES ('tiki_p_view_categorized', 'Can view categorized items', 'basic', 'category'); +INSERT INTO users_permissions (permName, permDesc, level, type) VALUES ('tiki_p_search_categorized', 'Can search on objects of this category', 'basic', 'category'); INSERT INTO users_permissions (permName, permDesc, level, type, admin) VALUES ('tiki_p_admin_charts', 'Can admin charts', 'admin', 'charts', 'y'); INSERT INTO users_permissions (permName, permDesc, level, type) VALUES ('tiki_p_autoval_chart_suggestio', 'Autovalidate suggestions', 'editors', 'charts'); Property changes on: branches/experimental/ui-revamp/installer/schema/20081105_calendar_items_allday_update_tiki.sql ___________________________________________________________________ Modified: svn:mergeinfo - /branches/experimental/declfilter/installer/schema/20081105_calendar_items_allday_update.sql:15787-16031 /trunk/installer/schema/20081105_calendar_items_allday_update_tiki.sql:16069-16267 + /branches/experimental/declfilter/installer/schema/20081105_calendar_items_allday_update.sql:15787-16031 /trunk/installer/schema/20081105_calendar_items_allday_update_tiki.sql:16069-16333 Property changes on: branches/experimental/ui-revamp/installer/schema/20081211_newsletter_files_tiki.sql ___________________________________________________________________ Modified: svn:mergeinfo - /trunk/installer/schema/20081211_newsletter_files_tiki.sql:16066-16267 + /trunk/installer/schema/20081211_newsletter_files_tiki.sql:16066-16333 Copied: branches/experimental/ui-revamp/installer/schema/20090120_lost_2.0to3.0.sql (from rev 16333, trunk/installer/schema/20090120_lost_2.0to3.0.sql) =================================================================== --- branches/experimental/ui-revamp/installer/schema/20090120_lost_2.0to3.0.sql (rev 0) +++ branches/experimental/ui-revamp/installer/schema/20090120_lost_2.0to3.0.sql 2009-01-20 19:15:51 UTC (rev 16335) @@ -0,0 +1,6 @@ +#2008-07-24 sylvieg +SET @fgcant=0; +SELECT (@fgcant:=count(*)) FROM users_permissions WHERE permName = 'tiki_p_search_categorized'; +INSERT INTO users_permissions (permName, permDesc, level, type) VALUES ('tiki_p_search_categorized', 'Can search on objects of this category', 'basic', 'category'); +INSERT INTO `users_objectpermissions` (groupName, permName, objectType, objectId) SELECT groupName, 'tiki_p_search_categorized', objectType , objectId FROM `users_objectpe +rmissions` WHERE permName = 'tiki_p_view_categorized' AND @fgcant = 0; \ No newline at end of file Property changes on: branches/experimental/ui-revamp/lib/core/lib/Multilingual/Aligner/BilingualAligner.php ___________________________________________________________________ Modified: svn:mergeinfo - /branches/experimental/declfilter/lib/multilingual/BilingualAligner.php:15787-16031 /trunk/lib/core/lib/Multilingual/Aligner/BilingualAligner.php:16066-16267 + /branches/experimental/declfilter/lib/multilingual/BilingualAligner.php:15787-16031 /trunk/lib/core/lib/Multilingual/Aligner/BilingualAligner.php:16066-16333 Property changes on: branches/experimental/ui-revamp/lib/core/lib/Multilingual/Aligner/SentenceSegmentor.php ___________________________________________________________________ Modified: svn:mergeinfo - /branches/experimental/declfilter/lib/multilingual/SentenceSegmentor.php:15787-16031 /trunk/lib/core/lib/Multilingual/Aligner/SentenceSegmentor.php:16066-16267 + /branches/experimental/declfilter/lib/multilingual/SentenceSegmentor.php:15787-16031 /trunk/lib/core/lib/Multilingual/Aligner/SentenceSegmentor.php:16066-16333 Property changes on: branches/experimental/ui-revamp/lib/core/lib/Multilingual/Aligner/ShortestPathFinder.php ___________________________________________________________________ Modified: svn:mergeinfo - /branches/experimental/declfilter/lib/multilingual/ShortestPathFinder.php:15787-16031 /trunk/lib/core/lib/Multilingual/Aligner/ShortestPathFinder.php:16066-16267 + /branches/experimental/declfilter/lib/multilingual/ShortestPathFinder.php:15787-16031 /trunk/lib/core/lib/Multilingual/Aligner/ShortestPathFinder.php:16066-16333 Property changes on: branches/experimental/ui-revamp/lib/core/test/Multilingual/Aligner/AllTests.php ___________________________________________________________________ Modified: svn:mergeinfo - /branches/experimental/declfilter/lib/multilingual/AllTests.php:15787-16031 /trunk/lib/core/test/Multilingual/Aligner/AllTests.php:16066-16267 + /branches/experimental/declfilter/lib/multilingual/AllTests.php:15787-16031 /trunk/lib/core/test/Multilingual/Aligner/AllTests.php:16066-16333 Property changes on: branches/experimental/ui-revamp/lib/core/test/Multilingual/Aligner/BilingualAlignerTest.php ___________________________________________________________________ Modified: svn:mergeinfo - /branches/experimental/declfilter/lib/multilingual/BilingualAlignerTest.php:15787-16031 /trunk/lib/core/test/Multilingual/Aligner/BilingualAlignerTest.php:16066-16267 + /branches/experimental/declfilter/lib/multilingual/BilingualAlignerTest.php:15787-16031 /trunk/lib/core/test/Multilingual/Aligner/BilingualAlignerTest.php:16066-16333 Property changes on: branches/experimental/ui-revamp/lib/core/test/Multilingual/Aligner/SentenceSegmentorTest.php ___________________________________________________________________ Modified: svn:mergeinfo - /branches/experimental/declfilter/lib/multilingual/SentenceSegmentorTest.php:15787-16031 /trunk/lib/core/test/Multilingual/Aligner/SentenceSegmentorTest.php:16066-16267 + /branches/experimental/declfilter/lib/multilingual/SentenceSegmentorTest.php:15787-16031 /trunk/lib/core/test/Multilingual/Aligner/SentenceSegmentorTest.php:16066-16333 Property changes on: branches/experimental/ui-revamp/lib/core/test/Multilingual/Aligner/ShortestPathFinderTest.php ___________________________________________________________________ Modified: svn:mergeinfo - /trunk/lib/core/test/Multilingual/Aligner/ShortestPathFinderTest.php:16066-16267 + /trunk/lib/core/test/Multilingual/Aligner/ShortestPathFinderTest.php:16066-16333 Modified: branches/experimental/ui-revamp/lib/init/tra.php =================================================================== --- branches/experimental/ui-revamp/lib/init/tra.php 2009-01-20 19:14:39 UTC (rev 16334) +++ branches/experimental/ui-revamp/lib/init/tra.php 2009-01-20 19:15:51 UTC (rev 16335) @@ -14,7 +14,7 @@ if ($content != '') { if ($prefs['lang_use_db'] != 'y') { - global $lang; + global $lang, $tikidomain; if ($lg != "") { if (is_file("lang/$lg/language.php")) { $l = $lg; @@ -35,6 +35,9 @@ if (is_file("lang/$l/custom.php")) { include_once("lang/$l/custom.php"); } + if (!empty($tikidomain) && is_file("lang/$l/$tikidomain/custom.php")) { + include_once("lang/$l/$tikidomain/custom.php"); + } ${"lang_$l"} = $lang; unset($lang); } Copied: branches/experimental/ui-revamp/lib/profilelib/channellib.php (from rev 16333, trunk/lib/profilelib/channellib.php) =================================================================== --- branches/experimental/ui-revamp/lib/profilelib/channellib.php (rev 0) +++ branches/experimental/ui-revamp/lib/profilelib/channellib.php 2009-01-20 19:15:51 UTC (rev 16335) @@ -0,0 +1,64 @@ +<?php + +class Tiki_Profile_ChannelList +{ + private $channels = array(); + + public static function fromConfiguration( $string ) // {{{ + { + $list = new self; + + $string = str_replace( "\r", '', $string ); + $lines = explode( "\n", $string ); + + foreach( $lines as $line ) { + $parts = explode( ',', $line ); + if( count( $parts ) < 3 ) + continue; + elseif( count( $parts ) == 3 ) + $parts[] = 'Admins'; + + $parts = array_map( 'trim', $parts ); + list( $name, $domain, $profile ) = array_slice( $parts, 0, 3 ); + $groups = array_slice( $parts, 3 ); + + $list->channels[ $name ] = array( + 'domain' => $domain, + 'profile' => $profile, + 'groups' => $groups, + ); + } + + return $list; + } // }}} + + function canExecuteChannels( array $channelNames, array $groups ) // {{{ + { + foreach( $channelNames as $channel ) { + if( ! array_key_exists( $channel, $this->channels ) ) + return false; + + // At least one match is required + if( count( array_intersect( $groups, $this->channels[$channel]['groups'] ) ) == 0 ) + return false; + } + + return true; + } // }}} + + function getProfiles( array $channelNames ) // {{{ + { + $profiles = array(); + + foreach( $channelNames as $channelName ) { + $info = $this->channels[$channelName]; + + if( $profile = Tiki_Profile::fromNames( $info['domain'], $info['profile'] ) ) + $profiles[$channelName] = $profile; + } + + return $profiles; + } // }}} +} + +?> Modified: branches/experimental/ui-revamp/lib/profilelib/installlib.php =================================================================== --- branches/experimental/ui-revamp/lib/profilelib/installlib.php 2009-01-20 19:14:39 UTC (rev 16334) +++ branches/experimental/ui-revamp/lib/profilelib/installlib.php 2009-01-20 19:15:51 UTC (rev 16335) @@ -50,7 +50,7 @@ $result = $tikilib->query( "SELECT DISTINCT domain, profile FROM tiki_profile_symbols" ); while( $row = $result->fetchRow() ) - $this->installed[sprintf( "http://%s/tiki-export_wiki_pages.php?page=%s", $row['domain'], urlencode($row['profile']) )] = true; + $this->installed[Tiki_Profile::getProfileKeyFor( $row['domain'], $row['profile'] )] = true; } // }}} function setUserData( $userData ) // {{{ @@ -62,7 +62,7 @@ { // Obtain the list of all required profiles $dependencies = $profile->getRequiredProfiles(true); - $dependencies[$profile->url] = $profile; + $dependencies[$profile->getProfileKey()] = $profile; $referenced = array(); $knownObjects = array(); @@ -71,11 +71,11 @@ // Build the list of dependencies for each profile $short = array(); - foreach( $dependencies as $url => $profile ) + foreach( $dependencies as $key => $profile ) { - $short[$url] = array(); - foreach( $profile->getRequiredProfiles() as $u => $p ) - $short[$url][] = $u; + $short[$key] = array(); + foreach( $profile->getRequiredProfiles() as $k => $p ) + $short[$key][] = $k; foreach( $profile->getNamedObjects() as $o ) $knownObjects[] = Tiki_Profile_Object::serializeNamedObject( $o ); @@ -93,9 +93,9 @@ // Build the list of packages that need to be installed $toSequence = array(); - foreach( $dependencies as $url => $profile ) + foreach( $dependencies as $key => $profile ) if( ! $this->isInstalled( $profile ) ) - $toSequence[] = $url; + $toSequence[] = $key; // Order the packages to make sure all dependencies are met $toInstall = array(); @@ -107,13 +107,13 @@ if( $counter++ > count( $toSequence ) * 2 ) throw new Exception( "Profiles could not be ordered: " . implode( ", ", $toSequence ) ); - $url = reset( $toSequence ); + $key = reset( $toSequence ); // Remove packages that are already scheduled or installed from dependencies - $short[$url] = array_diff( $short[$url], array_keys( $this->installed ), $toInstall ); + $short[$key] = array_diff( $short[$key], array_keys( $this->installed ), $toInstall ); $element = array_shift( $toSequence ); - if( count( $short[$url] ) ) + if( count( $short[$key] ) ) $toSequence[] = $element; else { @@ -124,8 +124,8 @@ $final = array(); // Perform the actual install - foreach( $toInstall as $url ) - $final[] = $dependencies[$url]; + foreach( $toInstall as $key ) + $final[] = $dependencies[$key]; return $final; } // }}} @@ -146,7 +146,7 @@ function isInstalled( Tiki_Profile $profile ) // {{{ { - return array_key_exists( $profile->url, $this->installed ); + return array_key_exists( $profile->getProfileKey(), $this->installed ); } // }}} function isInstallable( Tiki_Profile $profile ) // {{{ @@ -179,7 +179,7 @@ { global $tikilib; - $this->installed[$profile->url] = $profile; + $this->installed[$profile->getProfileKey()] = $profile; foreach( $profile->getObjects() as $object ) $this->getInstallHandler( $object )->install(); @@ -228,6 +228,13 @@ $userlib->remove_object_permission( $groupName, $data['id'], $data['type'], $perm ); } } // }}} + + function forget( Tiki_Profile $profile ) // {{{ + { + $key = $profile->getProfileKey(); + unset($this->installed[$key]); + $profile->removeSymbols(); + } // }}} } abstract class Tiki_Profile_InstallHandler // {{{ @@ -608,6 +615,9 @@ private $name; private $lang; + private $mode = 'create_or_update'; + private $exists; + function fetchData() { if( $this->name ) @@ -623,6 +633,8 @@ $this->lang = $data['lang']; if( array_key_exists( 'content', $data ) ) $this->content = $data['content']; + if( array_key_exists( 'mode', $data ) ) + $this->mode = $data['mode']; } function canInstall() @@ -631,11 +643,37 @@ if( empty( $this->name ) || empty( $this->content ) ) return false; + global $tikilib; + $this->exists = $tikilib->page_exists($this->name); + + switch( $this->mode ) { + case 'create': + if( $this->exists ) + throw new Exception( "Page {$this->name} already exists and profile does not allow update." ); + break; + case 'update': + case 'append': + if( ! $this->exists ) + throw new Exception( "Page {$this->name} does not exist and profile only allows update." ); + break; + case 'create_or_update': + $this->mode = $this->exists ? 'update' : 'create'; + break; + case 'create_or_append': + $this->mode = $this->exists ? 'append' : 'create'; + break; + default: + throw new Exception( "Invalid mode '{$this->mode}' for wiki handler." ); + } + return true; } function _install() { + // Normalize mode + $this->canInstall(); + global $tikilib; $this->fetchData(); $this->replaceReferences( $this->name ); @@ -643,10 +681,27 @@ $this->replaceReferences( $this->content ); $this->replaceReferences( $this->lang ); - if( $tikilib->create_page( $this->name, 0, $this->content, time(), 'Created by profile installer.', 'admin', '0.0.0.0', $this->description, $this->lang ) ) + if( $this->mode == 'create' ) { + if( $tikilib->create_page( $this->name, 0, $this->content, time(), tra('Created by profile installer'), 'admin', '0.0.0.0', $this->description, $this->lang ) ) + return $this->name; + else + return null; + } else { + $info = $tikilib->get_page_info( $this->name, true, true ); + + if( ! $this->description ) + $this->description = $info['description']; + + if( ! $this->lang ) + $this->lang = $info['lang']; + + if( $this->mode == 'append' ) { + $this->content = rtrim( $info['data'] ) . "\n" . trim($this->content) . "\n"; + } + + $tikilib->update_page( $this->name, $this->content, tra('Page updated by profile installer'), 'admin', '0.0.0.0', $this->description, false, $this->lang ); return $this->name; - else - return null; + } } } // }}} Modified: branches/experimental/ui-revamp/lib/profilelib/profilelib.php =================================================================== --- branches/experimental/ui-revamp/lib/profilelib/profilelib.php 2009-01-20 19:14:39 UTC (rev 16334) +++ branches/experimental/ui-revamp/lib/profilelib/profilelib.php 2009-01-20 19:15:51 UTC (rev 16335) @@ -9,7 +9,7 @@ { const SHORT_PATTERN = '/^\$((([\w\.-]+):)?((\w+):))?(\w+)$/'; const LONG_PATTERN = '/\$profileobject:((([\w\.-]+):)?((\w+):))?(\w+)\$/'; - const INFO_REQUEST = '/\$profilerequest:([^\$]+)\$([^\$]+)\$/'; + const INFO_REQUEST = '/\$profilerequest:([^\$\|]+)(\|(\w+))?\$([^\$]+)\$/'; private $url; private $pageUrl; @@ -22,6 +22,7 @@ private $objects = null; private static $known = array(); + private static $resolvePrefix = null; public static function convertLists( $data, $conversion, $prependKey = false ) // {{{ { @@ -59,6 +60,43 @@ return $copy; } // }}} + public static function getProfileKeyFor( $domain, $profile ) // {{{ + { + return $domain . '/' . $profile; + } // }}} + + public static function useUnicityPrefix( $prefix ) // {{{ + { + self::$resolvePrefix = $prefix; + } // }}} + + public static function withPrefix( $profile ) // {{{ + { + if( self::$resolvePrefix ) + return self::$resolvePrefix . ':' . $profile; + else + return $profile; + } // }}} + + private static function getObjectReference( $object, $full = true ) // {{{ + { + // If a prefix was set, attempt to isolate the lookup to the prefix first + if( $full ) { + $withPrefix = $object; + $withPrefix['profile'] = self::withPrefix( $withPrefix['profile'] ); + + if( ! is_null( $ref = self::getObjectReference( $withPrefix, false ) ) ) + return $ref; + } + + $serialized = Tiki_Profile_Object::serializeNamedObject( $object ); + + if( ! isset( self::$known[$serialized] ) ) + self::$known[$serialized] = self::findObjectReference( $object ); + + return self::$known[$serialized]; + } // }}} + private static function findObjectReference( $object ) // {{{ { global $tikilib; @@ -68,16 +106,70 @@ if( $row = $result->fetchRow() ) return $row['value']; + + return null; } // }}} - function __construct( $url ) // {{{ + public static function fromUrl( $url ) // {{{ { - $this->url = $url; + $profile = new self; + $profile->url = $url; - if( $this->analyseMeta( $url ) ) - $this->loadYaml( $url ); + if( $profile->analyseMeta( $url ) ) { + + // Obtain the page export + $content = tiki_get_remote_file( $url ); + $content = html_entity_decode( $content ); + $content = str_replace( "\r", '', $content ); + + // Find content start (strip headers) + $begin = strpos( $content, "\n\n" ); + if( ! $begin ) + return false; + + $content = substr( $content, $begin + 2 ); + + $profile->loadYaml( $content ); + } + + return $profile; } // }}} + public static function fromNames( $domain, $profile ) // {{{ + { + if( strpos( $domain, '://' ) === false ) + $domain = "http://$domain"; + + if( $domain == 'tiki://local' ) { + return self::fromDb( $profile ); + } else { + $url = "$domain/tiki-export_wiki_pages.php?page=" . urlencode( $profile ); + return self::fromUrl( $url ); + } + } // }}} + + public static function fromDb( $pageName ) // {{{ + { + global $tikilib, $wikilib; + require_once 'lib/wiki/wikilib.php'; + + $profile = new self; + $profile->domain = 'tiki://local'; + $profile->profile = $pageName; + $profile->pageUrl = $wikilib->sefurl($pageName); + $profile->url = 'tiki://local/' . urlencode($pageName); + + $info = $tikilib->get_page_info( $pageName ); + $content = html_entity_decode( $info['data'] ); + $profile->loadYaml( $content ); + + return $profile; + } // }}} + + private function __construct() // {{{ + { + } // }}} + function __get( $name ) // {{{ { switch( $name ) @@ -111,17 +203,8 @@ return true; } // }}} - private function loadYaml( $url ) // {{{ + private function loadYaml( $content ) // {{{ { - $content = tiki_get_remote_file( $url ); - $content = html_entity_decode( $content ); - $content = str_replace( "\r", '', $content ); - - $begin = strpos( $content, "\n\n" ); - if( ! $begin ) - return false; - - $content = substr( $content, $begin + 2 ); $this->pageContent = $content; $pos = 0; @@ -251,11 +334,11 @@ foreach( $this->getExternalReferences() as $ext ) { - $url = "http://{$ext['domain']}/tiki-export_wiki_pages.php?page=" . urlencode( $ext['profile'] ); - if( array_key_exists( $url, $known ) || array_key_exists( $url, $profiles ) ) + $key = Tiki_Profile::getProfileKeyFor( $ext['domain'], $ext['profile'] ); + if( array_key_exists( $key, $known ) || array_key_exists( $key, $profiles ) ) continue; - $profiles[$url] = new self( $url ); + $profiles[$key] = self::fromNames( $ext['domain'], $ext['profile'] ); } if( $recursive ) @@ -292,12 +375,7 @@ if( preg_match( self::SHORT_PATTERN, $data, $parts ) ) { $object = $this->convertReference( $parts ); - $serialized = Tiki_Profile_Object::serializeNamedObject( $object ); - - if( ! isset( self::$known[$serialized] ) ) - self::$known[$serialized] = self::findObjectReference( $object ); - - $data = self::$known[$serialized]; + $data = self::getObjectReference( $object ); return; } @@ -308,25 +386,29 @@ foreach( $parts as $row ) { $object = $this->convertReference( $row ); - $serialized = Tiki_Profile_Object::serializeNamedObject( $object ); - if( ! isset( self::$known[$serialized] ) ) - self::$known[$serialized] = self::findObjectReference( $object ); - $needles[] = $row[0]; - $replacements[] = self::$known[$serialized]; + $replacements[] = self::getObjectReference( $object ); } if( preg_match_all( self::INFO_REQUEST, $data, $parts, PREG_SET_ORDER ) ) foreach( $parts as $row ) { - list( $full, $label, $default ) = $row; + list( $full, $label, $junk, $filter, $default ) = $row; if( ! array_key_exists( $label, $suppliedUserData ) ) $value = $default; else $value = $suppliedUserData[$label]; + if( $filter ) + $value = TikiFilter::get($filter)->filter($value); + else + $value = TikiFilter::get('xss')->filter($value); + + if( empty($value) ) + $value = $default; + $needles[] = $full; $replacements[] = $value; } @@ -483,8 +565,18 @@ { global $tikilib; $tikilib->query( "DELETE FROM tiki_profile_symbols WHERE domain = ? AND profile = ?", - array( $this->domain, $this->profile ) ); + array( $this->domain, self::withPrefix($this->profile) ) ); + + $key = self::getProfileKeyFor( $this->domain, self::withPrefix($this->profile) ); + foreach( array_keys(self::$known) as $obj ) + if( strpos( $obj, $key ) === 0 ) + unset(self::$known[$obj]); } // }}} + + function getProfileKey() // {{{ + { + return self::getProfileKeyFor( $this->domain, $this->withPrefix( $this->profile ) ); + } // }}} } class Tiki_Profile_Object @@ -497,7 +589,7 @@ public static function serializeNamedObject( $object ) // {{{ { - return sprintf( "http://%s/%s#%s", $object['domain'], $object['profile'], $object['object'] ); + return sprintf( "%s#%s", Tiki_Profile::getProfileKeyFor($object['domain'], $object['profile']), $object['object'] ); } // }}} public static function getNamedObjects() // {{{ @@ -555,7 +647,7 @@ } $tikilib->query( "INSERT INTO tiki_profile_symbols (domain, profile, object, type, value, named) VALUES(?, ?, ?, ?, ?, ?)", - array( $this->profile->domain, $this->profile->profile, $name, $this->getType(), $this->id, $named ) ); + array( $this->profile->domain, $this->profile->withPrefix($this->profile->profile), $name, $this->getType(), $this->id, $named ) ); } // }}} function getInternalReferences() // {{{ Modified: branches/experimental/ui-revamp/lib/setup/prefs.php =================================================================== --- branches/experimental/ui-revamp/lib/setup/prefs.php 2009-01-20 19:14:39 UTC (rev 16334) +++ branches/experimental/ui-revamp/lib/setup/prefs.php 2009-01-20 19:15:51 UTC (rev 16335) @@ -1145,6 +1145,7 @@ // Tiki Profiles 'profile_sources' => 'http://profiles.tikiwiki.org/profiles', + 'profile_channels' => '', // Minichat 'feature_minichat' => 'n', @@ -1249,14 +1250,11 @@ } } - // Be absolutely sure we have a value for tikiIndex - if ( $modified['tikiIndex'] == '' ) $modified['tikiIndex'] = 'tiki-index.php'; - // Keep some useful sites values available before overriding with user prefs // (they could be used in templates, so we need to set them even for Anonymous) global $user_overrider_prefs; foreach ( $user_overrider_prefs as $uop ) { - $modified['site_'.$uop] = $modified[$uop]; + $modified['site_'.$uop] = isset($modified[$uop])?$modified[$uop]:$defaults[$uop]; } // Assign prefs to the session Modified: branches/experimental/ui-revamp/lib/smarty_tiki/function.wikistructure.php =================================================================== --- branches/experimental/ui-revamp/lib/smarty_tiki/function.wikistructure.php 2009-01-20 19:14:39 UTC (rev 16334) +++ branches/experimental/ui-revamp/lib/smarty_tiki/function.wikistructure.php 2009-01-20 19:15:51 UTC (rev 16335) @@ -1,61 +1,32 @@ -<?php -//copy this file to lib/smarty_tiki -//create a new module and put the following -//{wikistructure id=1 detail=1} -//id for structure id, or page_ref_id -//detail if you only wanna display subbranches of the open node within the structure -// assign your module - - -//this script may only be included - so its better to die if called directly. -if (strpos($_SERVER["SCRIPT_NAME"],basename(__FILE__)) !== false) { - header("location: index.php"); - exit; -} - - -function smarty_function_wikistructure($params, &$smarty) -{ - - global $tikilib, $user, $dbTiki, $structlib; - -extract($params); - -require_once ('lib/structures/structlib.php'); -if (!isset($structlib)) { - $structlib = new StructLib($dbTiki); -} -if (!isset($_REQUEST["page"])) $_REQUEST["page"]=''; -if ($_REQUEST["page"] == '') { -if (isset($_REQUEST["page_ref_id"])) { - // If a structure page has been requested - $page_ref_id = $_REQUEST["page_ref_id"]; -} -} -else { -//Get the structures this page is a member of -if (!isset($structure)) $structure=''; -$structs = $structlib->get_page_structures($_REQUEST["page"],$structure); -//If page is only member of one structure, display if requested -$single_struct = count($structs) == 1; -if ($single_struct) { -$page_ref_id=$structs[0]['req_page_ref_id']; -$_REQUEST["page_ref_id"]=$page_ref_id; -} +<?php +//copy this file to lib/smarty_tiki +//create a new module and put the following +//{wikistructure id=1 detail=1} +//id for structure id, or page_ref_id +//detail if you only wanna display subbranches of the open node within the structure +// assign your module + + +//this script may only be included - so its better to die if called directly. +if (strpos($_SERVER["SCRIPT_NAME"],basename(__FILE__)) !== false) { + header("location: index.php"); + exit; } -if (!isset($channels)) $channels=''; -if (isset($page_ref_id) && isset($detail)) { - $channels.= $structlib->get_toc($page_ref_id,'asc',false,false,'','plain',$_REQUEST["page"]); -} -else { - $channels.= $structlib->get_toc($id,'asc',false,false,'','plain',$_REQUEST["page"]); -} - -return $channels; - -} - - - - -?> + + +function smarty_function_wikistructure($params, &$smarty) { + include_once('lib/wiki-plugins/wikiplugin_toc.php'); + + if (!empty($params['id'])) { + $params['structId'] = $params['id']; + } + $html = wikiplugin_toc('', $params); + $html = str_replace(array('~np~', '~/np~'), '', $html); + return $html; +} + + + + + +?> Modified: branches/experimental/ui-revamp/lib/tikiaccesslib.php =================================================================== --- branches/experimental/ui-revamp/lib/tikiaccesslib.php 2009-01-20 19:14:39 UTC (rev 16334) +++ branches/experimental/ui-revamp/lib/tikiaccesslib.php 2009-01-20 19:15:51 UTC (rev 16335) @@ -261,33 +261,46 @@ return $result; } - //http basic auth headers if no user specified in http header. - if (empty($_SERVER['PHP_AUTH_USER'])) { - $result['header']='y'; - return $result; + if( $this->http_auth() ) { + foreach ($rssrights as $perm) { + if ($GLOBALS[$perm] == 'y') { + // if user/password and the appropriate rights are correct, allow. + return; + } + } } - $user = $_SERVER['PHP_AUTH_USER'] ; + return $result; + } + + function http_auth() + { + global $tikidomain, $userlib, $user, $smarty; + + if (! isset($_SERVER['PHP_AUTH_USER']) ) { + header('WWW-Authenticate: Basic realm="'.$tikidomain.'"'); + header('HTTP/1.0 401 Unauthorized'); + return false; + } + + $attempt = $_SERVER['PHP_AUTH_USER'] ; $pass = $_SERVER['PHP_AUTH_PW'] ; - list($res,$rest)=$userlib->validate_user_tiki($user, $pass, false, false); + list($res,$rest)=$userlib->validate_user_tiki($attempt, $pass, false, false); + if ($res==USER_VALID) { + $user = $attempt; $perms = $userlib->get_user_permissions($user); foreach ($perms as $perm) { - eval('global $' . $perm . ';'); - $$perm = 'y'; + $GLOBALS[$perm] = 'y'; $smarty->assign($perm, 'y'); } - foreach ($rssrights as $perm) { - if ($$perm == 'y') { - // if user/password and the appropriate rights are correct, allow. - return; - } - } - } - //try to (re)authenticate the user - $result['header']='y'; - return $result; + return true; + } else { + header('WWW-Authenticate: Basic realm="'.$tikidomain.'"'); + header('HTTP/1.0 401 Unauthorized'); + return false; + } } function get_accept_types() { Modified: branches/experimental/ui-revamp/lib/tikilib.php =================================================================== --- branches/experimental/ui-revamp/lib/tikilib.php 2009-01-20 19:14:39 UTC (rev 16334) +++ branches/experimental/ui-revamp/lib/tikilib.php 2009-01-20 19:15:51 UTC (rev 16335) @@ -234,8 +234,7 @@ global $userlib; $email = $userlib->get_user_email($user); } - $query = "delete from `tiki_user_watches` where ".$this->convert_binary()." `user`=? and `event`=? and `object`=?"; - $this->query($query,array($user,$event,$object)); + $this->remove_user_watch( $user, $event, $object, $type ); $query = "insert into `tiki_user_watches`(`user`,`event`,`object`,`email`,`type`,`title`,`url`) "; $query.= "values(?,?,?,?,?,?,?)"; $this->query($query,array($user,$event,$object,$email,$type,$title,$url)); @@ -244,8 +243,7 @@ function add_group_watch($group, $event, $object, $type, $title, $url) { - $query = "delete from `tiki_group_watches` where ".$this->convert_binary()." `group`=? and `event`=? and `object`=?"; - $this->query($query,array($group,$event,$object)); + $this->remove_group_watch( $group, $event, $object, $type ); $query = "insert into `tiki_group_watches`(`group`,`event`,`object`,`type`,`title`,`url`) "; $query.= "values(?,?,?,?,?,?)"; $this->query($query,array($group,$event,$object,$type,$title,$url)); @@ -264,14 +262,14 @@ } /*shared*/ - function remove_user_watch($user, $event, $object) { - $query = "delete from `tiki_user_watches` where ".$this->convert_binary()." `user`=? and `event`=? and `object`=?"; - $this->query($query,array($user,$event,$object)); + function remove_user_watch($user, $event, $object, $type = 'wiki page') { + $query = "delete from `tiki_user_watches` where ".$this->convert_binary()." `user`=? and `event`=? and `object`=? and `type` = ?"; + $this->query($query,array($user,$event,$object,$type)); } - function remove_group_watch($group, $event, $object) { - $query = "delete from `tiki_group_watches` where ".$this->convert_binary()." `group`=? and `event`=? and `object`=?"; - $this->query($query,array($group,$event,$object)); + function remove_group_watch($group, $event, $object, $type = 'wiki page') { + $query = "delete from `tiki_group_watches` where ".$this->convert_binary()." `group`=? and `event`=? and `object`=? and `type` = ?"; + $this->query($query,array($group,$event,$object,$type)); } /*shared*/ @@ -4907,9 +4905,9 @@ return $ret; } - function get_page_info($pageName, $retrieve_datas = true) { + function get_page_info($pageName, $retrieve_datas = true, $skipCache = false) { $pageNameEncode = urlencode($pageName); - if ( isset($this->cache_page_info[$pageNameEncode]) + if ( !$skipCache && isset($this->cache_page_info[$pageNameEncode]) && ( ! $retrieve_datas || isset($this->cache_page_info[$pageNameEncode]['data']) ) ) { return $this->cache_page_info[$pageNameEncode]; @@ -5059,7 +5057,7 @@ if( !is_array( $pluginskiplist ) ) $pluginskiplist = array(); - $matcher_fake = array("~pp~","~np~","<pre>","CODE"); + $matcher_fake = array("~pp~","~np~","<pre>"); $matcher = "/\{([A-Z]+)\(|\{([a-z]+)(\s|\})|~pp~|~np~|<[pP][rR][eE]>/"; $plugins = array(); @@ -5192,7 +5190,7 @@ // Closing quote found if( $quote !== false ) { $value = substr( $params_string, 1, $quote - 1 ); - $arguments[$name] = $value; + $arguments[$name] = str_replace( '\"', '"', $value ); $params_string = substr( $params_string, $quote + 1 ); continue; @@ -5348,52 +5346,36 @@ $current_index = ++$plugin_indexes[$plugin_name]; - // We store CODE stuff out of the way too, but then process it as a plugin as well. - if( preg_match( '/^ *\{CODE\(/', $plugin_start ) ) { - $ret = wikiplugin_code($plugin_data, $arguments); + // Handle nested plugins. + $this->parse_first($plugin_data, $preparsed, $noparsed, $options, $real_start_diff + $pos+strlen($plugin_start)); - // Pull the np out. - preg_match( "/~np~(.*)~\/np~/s", $ret, $stuff ); + if( true === $status = $this->plugin_can_execute( $plugin_name, $plugin_data, $arguments ) ) { + $ret = $this->plugin_execute( $plugin_name, $plugin_data, $arguments, $real_start_diff + $pos+strlen($plugin_start), false, $options); + } else { + global $tiki_p_plugin_viewdetail, $tiki_p_plugin_preview, $tiki_p_plugin_approve; + $details = $tiki_p_plugin_viewdetail == 'y' && $status != 'rejected'; + $preview = $tiki_p_plugin_preview == 'y' && $details; + $approve = $tiki_p_plugin_approve == 'y' && $details; - if( count( $stuff ) > 0 ) { - $key = "§".md5($this->genPass())."§"; - $noparsed["key"][] = preg_quote($key); - $noparsed["data"][] = $stuff[1]; - - $ret = preg_replace( "/~np~.*~\/np~/s", $key, $ret ); + if( $status != 'rejected' ) { + $smarty->assign( 'plugin_fingerprint', $status ); + $status = 'pending'; } - } else { - // Handle nested plugins. - $this->parse_first($plugin_data, $preparsed, $noparsed, $options, $real_start_diff + $pos+strlen($plugin_start)); + $smarty->assign( 'plugin_name', $plugin_name ); + $smarty->assign( 'plugin_index', $current_index ); - if( true === $status = $this->plugin_can_execute( $plugin_name, $plugin_data, $arguments ) ) { - $ret = $this->plugin_execute( $plugin_name, $plugin_data, $arguments, $real_start_diff + $pos+strlen($plugin_start), false, $options); - } else { - global $tiki_p_plugin_viewdetail, $tiki_p_plugin_preview, $tiki_p_plugin_approve; - $details = $tiki_p_plugin_viewdetail == 'y' && $status != 'rejected'; - $preview = $tiki_p_plugin_preview == 'y' && $details; - $approve = $tiki_p_plugin_approve == 'y' && $details; + $smarty->assign( 'plugin_status', $status ); + $smarty->assign( 'plugin_details', $details ); + $smarty->assign( 'plugin_preview', $preview ); + $smarty->assign( 'plugin_approve', $approve ); - if( $status != 'rejected' ) { - $smarty->assign( 'plugin_fingerprint', $status ); - $status = 'pending'; - } + $smarty->assign( 'plugin_body', $plugin_data ); + $smarty->assign( 'plugin_args', $arguments ); - $smarty->assign( 'plugin_name', $plugin_name ); - $smarty->assign( 'plugin_index', $current_index ); - - $smarty->assign( 'plugin_status', $status ); - $smarty->assign( 'plugin_details', $details ); - $smarty->assign( 'plugin_preview', $preview ); - $smarty->assign( 'plugin_approve', $approve ); - - $smarty->assign( 'plugin_body', $plugin_data ); - $smarty->assign( 'plugin_args', $arguments ); - - $ret = '~np~' . $smarty->fetch('tiki-plugin_blocked.tpl') . '~/np~'; - } + $ret = '~np~' . $smarty->fetch('tiki-plugin_blocked.tpl') . '~/np~'; } + //echo '<pre>'; debug_print_backtrace(); echo '</pre>'; if( $this->plugin_is_editable( $plugin_name ) && (empty($options['print']) || !$options['print']) ) { include_once('lib/smarty_tiki/function.icon.php'); @@ -5412,7 +5394,7 @@ . ', ' . json_encode($arguments) . ', ' - . json_encode(trim($plugin_data)) + . json_encode(trim(TikiLib::htmldecode($plugin_data))) . ", event.target); } ); } ); @@ -7259,6 +7241,7 @@ } function invalidate_cache($page) { + unset( $this->cache_page_info[urlencode($page)] ); $query = "update `tiki_pages` set `cache_timestamp`=? where `pageName`=?"; $this->query($query, array(0,$page) ); } @@ -7761,7 +7744,7 @@ // run through all the language codes: if (isset($short) && $short == "y") { foreach ($languages as $lc) { - if ( !is_array($prefs['available_languages'] ) || (!$all and in_array($lc,$prefs['available_languages']))) { + if ( empty($prefs['available_languages'] ) || (!$all and in_array($lc,$prefs['available_languages']))) { if (isset($langmapping[$lc])) $formatted[] = array('value' => $lc, 'name' => $langmapping[$lc][0]); else Modified: branches/experimental/ui-revamp/lib/trackers/trackerlib.php =================================================================== --- branches/experimental/ui-revamp/lib/trackers/trackerlib.php 2009-01-20 19:14:39 UTC (rev 16334) +++ branches/experimental/ui-revamp/lib/trackers/trackerlib.php 2009-01-20 19:15:51 UTC (rev 16335) @@ -645,6 +645,7 @@ // Do we need a numerical sort on the field ? $field = $this->get_tracker_field($asort_mode); switch ($field['type']) { + case 'C': case 'q': case 'n': $numsort = true; break; Modified: branches/experimental/ui-revamp/lib/wiki-plugins/wikiplugin_code.php =================================================================== --- branches/experimental/ui-revamp/lib/wiki-plugins/wikiplugin_code.php 2009-01-20 19:14:39 UTC (rev 16334) +++ branches/experimental/ui-revamp/lib/wiki-plugins/wikiplugin_code.php 2009-01-20 19:15:51 UTC (rev 16335) @@ -146,14 +146,14 @@ $pre_style = 'overflow:auto;'; } - $out = '<pre class="codelisting" dir="'.( (isset($rtl) && $rtl == 1) ? 'rtl' : 'ltr').'" style="'.$pre_style.'">' + $out = '~np~<pre class="codelisting" dir="'.( (isset($rtl) && $rtl == 1) ? 'rtl' : 'ltr').'" style="'.$pre_style.'">~/np~' .(( $parse_wiki ) ? '' : '~np~') .$out .(( $parse_wiki ) ? '' : '~/np~') - .'</pre>'; + .'~np~</pre>~/np~'; if ( isset($caption) ) { - $out = '<div class="codecaption">'.$caption.'</div>'.$out; + $out = '~np~<div class="codecaption">~/np~'.$caption.'~np~</div>~/np~'.$out; } return $out; Copied: branches/experimental/ui-revamp/lib/wiki-plugins/wikiplugin_footnote.php (from rev 16333, trunk/lib/wiki-plugins/wikiplugin_footnote.php) =================================================================== --- branches/experimental/ui-revamp/lib/wiki-plugins/wikiplugin_footnote.php (rev 0) +++ branches/experimental/ui-revamp/lib/wiki-plugins/wikiplugin_footnote.php 2009-01-20 19:15:51 UTC (rev 16335) @@ -0,0 +1,24 @@ +<?php +/* by robferguson + * + * FOOTNOTE plugin. Inserts a superscripted number where the plugin is written starting with one and counting up as the additional footnotes are added. + * + * Syntax: + * + * {FOOTNOTE()/} + */ +function wikiplugin_footnote_help() { + return tra("Inserts a superscripted footnote number next to text and takes in footnote as parameter").":<br />~np~{FOOTNOTE()}insert footnote here{FOOTNOTE}~/np~"; +} + +function wikiplugin_footnote($data, $params) { + + extract ($params,EXTR_SKIP); + $GLOBALS["footnoteCount"]++; + $footnoteCount = $GLOBALS["footnoteCount"]; + $GLOBALS["footnotesData"][] = $data; + return "{SUP()}$footnoteCount{SUP}"; +} +?> + + Copied: branches/experimental/ui-revamp/lib/wiki-plugins/wikiplugin_footnotearea.php (from rev 16333, trunk/lib/wiki-plugins/wikiplugin_footnotearea.php) =================================================================== --- branches/experimental/ui-revamp/lib/wiki-plugins/wikiplugin_footnotearea.php (rev 0) +++ branches/experimental/ui-revamp/lib/wiki-plugins/wikiplugin_footnotearea.php 2009-01-20 19:15:51 UTC (rev 16335) @@ -0,0 +1,24 @@ +<?php +/* by robferguson + * + * FOOTNOTEAREA plugin. Inserts a section for collected footnotes created with the FOOTNOTES plugin . + * + * Syntax: + * + * {FOOTNOTEAREA()/} + */ +function wikiplugin_footnotearea_help() { + return tra("Inserts a section for collected footnotes within the wiki page").":<br />~np~{FOOTNOTEAREA()/}~/np~"; +} + +function wikiplugin_footnotearea($data, $params) { + + extract ($params,EXTR_SKIP); + foreach($GLOBALS["footnotesData"] as $key => $value){ + $footnoteOuput .= "<sup>". ($key + 1) ."</sup>".$value."<br />"; + } + return "<div style=\"border-top:2px solid #999;float:left;min-width:300px;font-size:11px;\">$footnoteOuput</div>"; +} +?> + + Copied: branches/experimental/ui-revamp/lib/wiki-plugins/wikiplugin_mwtable.php (from rev 16333, trunk/lib/wiki-plugins/wikiplugin_mwtable.php) =================================================================== --- branches/experimental/ui-revamp/lib/wiki-plugins/wikiplugin_mwtable.php (rev 0) +++ branches/experimental/ui-revamp/lib/wiki-plugins/wikiplugin_mwtable.php 2009-01-20 19:15:51 UTC (rev 16335) @@ -0,0 +1,370 @@ +<?php +// +// Written by bil...@we... January 2009 +// +// Amended by bil...@we... January 2009 +// Included styling of <col> elements (not supported by MediaWiki syntax). +// Include styling of <caption>. +// Corrected parsing of html attributes in $data. +// Corrected setting of default wiki classes. +// +// Description: +// Displays a table using (sort of) MediaWiki syntax. +// MWTable doesn't support things like templates or the !row heading syntax. +// <col> styling overcomes the latter to a degree but, for cross-browser +// consistency, you are limited to by HTML to border=, background=, width= +// and visibility=. You can also use span= so that a <col> definition can +// apply to adjacent columns. <tr> and <td> styling overrides <col>. +// +// As the code base was FANCYTABLE, it seemed fair to keep odd/even styling in. +// If a class is not specified for an element and fancy=false +// then 'wikitable' or 'wikicell' is used as appropriate. +// +// Parameters: +// fancy = true | false (default is false) +// wiki_classes = true | false (default is true) +// +// Note: wiki classes (wikitable and wikicell) and fancy classes (odd and even) +// do not work together so fancy takes precedence. +// +// Usage: +// Optionally, first line (prior to |) contains html attributes for <table>. +// Optionally, next line can specify a <caption>; line starts |+ followed by +// optional html attributes that end with a | followed by the caption text. +// Optionally, html attributes for <col> elements can be specified next on +// one or more lines starting with a ?. +// Each column's attributes start on a new line with ? or on the same line +// preceeded by ?? and become a <col>. +// Optionally, column headings can be specified next on one or more lines +// starting with a !. +// Each column heading starts on a new line with ! or on the same line +// preceeded by !!. Optional html attributes for <th> end with a | +// followed by heading text that becomes the text of a <th>. +// Each row, including the first, starts on a new line with |-, +// optionally followed by html attributes for <tr> +// Each cell starts on a new line with | or on the same line preceeded by ||. +// Optional html attributes for <td> end with a | followed by the cell text +// (so data for one cell can have 1 or 2 | characters. Any other | +// characters are assumed to be part of the cell text.) +// +// Example 1: The minimalist approach +// {MWTABLE()} +// |- +// |Bill +// |The little house +// |- +// |Carol || The big house +// {MWTABLE} +// +// Example 2: Most of the bells and whistles +// {MWTABLE( wiki_classes=false )} style="width:50%", class="myclass" +// |+style="font-style:italic;"|My caption +// ? width="30%;" ?? style="background-color:yellow;" +// ! style="background-color:grey;"| Name +// ! Address +// |- style="background-color: red" +// | style="color: blue;" | Bill +// | The little house +// |- +// | Carol || The big house +// {MWTABLE} +// + +function wikiplugin_mwtable_help() { + return tra("Displays the data using (sort of) MediaWiki syntax"). + ":<br />~np~{MWTABLE(fancy=>true|false,wiki_classes=>true|false)}".tra("data")."{MWTABLE}~/np~"; +} + +function wikiplugin_mwtable_info() { + return array( + 'name' => tra('MWTable'), + 'documentation' => 'PluginMWTable', + 'description' => tra("Displays a table using MediaWiki syntax"), + 'prefs' => array( 'wikiplugin_mwtable' ), + 'body' => tra('URL'), + 'validate' => 'all', + 'params' => array( + 'fancy' => array( + 'safe' => true, + 'required' => false, + 'name' => tra('fancy'), + 'description' => tra('true|false'), + ), + 'wiki_classes' => array( + 'safe' => true, + 'required' => false, + 'name' => tra('wiki_classes'), + 'description' => tra('true|false'), + ), + ), + ); +} + +function wikiplugin_mwtable($data, $params) { + global $tikilib; + + // Parse the parameters + extract ($params,EXTR_SKIP); + if (isset($fancy) and $fancy=="true") { + $fancy = true; + } else { + $fancy = false; + } + if (isset($wiki_classes) and $wiki_classes=="false") { + $wiki_classes = false; + } else { + $wiki_classes = true; + } + + // set class constants + $default_class_table = "normal"; + $default_class_heading = ""; + $default_class_td_odd = ""; + $default_class_td_odd = ""; + if ($fancy) { + $default_class_table = "normal"; + $default_class_heading = "heading"; + $default_class_td_odd = "odd"; + $default_class_td_even = "even"; + } else if ($wiki_classes) { + $default_class_table = "wikitable"; + $default_class_td_odd = "wikicell"; + $default_class_td_even = "wikicell"; + } + + // soe = start-of-element; eoe = end-of-element + // set the start position + $soe = 0; + + // <table>: prefix = start-of-string, suffix = "\n" + $suffix = "\n"; + $eoe = strpos($data, $suffix); + + // we only have attributes + $element = substr($data, $soe, $eoe - strlen($suffix)); + $attributes = _get_attributes($element); + + _check_class_attribute($attributes,$default_class_table); + + $wret .= _output_tag_with_attributes("table",$attributes,true); + + // move soe - skip terminating suffix + $soe = $eoe + strlen($suffix); + // <table>: end (of start tag) + + // <caption>: prefix = "|+", suffix = "\n" + $prefix = "|+"; + $suffix = "\n"; + if (substr($data, $soe, strlen($prefix))==$prefix) { + $eoe = strpos($data, $suffix, $soe); + $element = substr($data, $soe + strlen($prefix), + $eoe - $soe - strlen($prefix) - strlen($suffix)); + if (strpos($element, "|")) { + // attributes present + list($attribs, $text) = explode("|", $element, 2); + $attributes = _get_attributes($attribs); + $wret .= _output_tag_with_attributes("caption",$attributes,true); + $wret .= trim($text); + } else { + $wret .= "<caption>".trim($element); + } + $wret .= "</caption>\n"; + // move soe - skip terminating suffix + $soe = $eoe + strlen($suffix); + } + // <caption>: end + + // <col>: prefix = "?", suffix = "!" or "|-" + $prefix = "?"; + $suffix = "!"; + if (substr($data, $soe, strlen($prefix))==$prefix) { + // the end of the column data is the start of the headings + // or the start of the rows + $pos_headings = strpos($data, "!", $soe); + $pos_rows = strpos($data, "|-", $soe); + if ($pos_headings) { + //assume if headings present they precede any row + $eoe = $pos_headings; + } else { + // assume element delimited by first row + $suffix = "|-"; + $eoe = $pos_rows; + } + $element = substr($data, $soe + strlen($prefix), + $eoe - $soe - strlen($prefix) - strlen($suffix)); + + // convert "??" to "\n?" to simplify splitting + $element = str_replace("??", "\n?", $element); + + $columns = explode("?", $element); + foreach ($columns as $column) { + // we only have attributes + $attributes = _get_attributes($column); + $wret .= _output_tag_with_attributes("col",$attributes,true,true); + } + + // move soe - keep terminating string + $soe = $eoe; + } + // <col>: end + + // <th>: prefix = "!", suffix = "|-" + $prefix = "!"; + $suffix = "|-"; + if (substr($data, $soe, strlen($prefix))==$prefix) { + // the end of the heading data is the start of the first row + $eoe = strpos($data, "|-", $soe); + $element = substr($data, $soe + strlen($prefix), + $eoe - $soe - strlen($prefix) - strlen($suffix)); + + // convert "!!" to "\n!" to simplify splitting + $element = str_replace("!!", "\n!", $element); + + $columns = explode("!", $element); + $wret .= "<tr>\n"; + foreach ($columns as $column) { + // each column can have attributes and/or text + if (strpos($column, "|")) { + list($attribs, $text) = explode("|", $column, 2); + $attributes = _get_attributes($attribs); + _check_class_attribute($attributes,$default_class_headings); + $wret .= _output_tag_with_attributes("th",$attributes); + $wret .= trim($text); + } else { + // only one part so use as heading + $wret .= "<th>".trim($column); + } + $wret .= "</th>\n"; + } + $wret .= "</tr>\n"; + + // move soe - keep terminating "|-" + $soe = $eoe; + } + // <th>: end + + // <tr>: prefix = "|-", suffix = "|-" or end-of-data + // skip over prefix for first row + $prefix = "|-"; + $rows = explode($prefix, substr($data, $soe + strlen($prefix))); + + $row_is_odd = true; + foreach ($rows as $row) { + // each row + if ($row_is_odd) { + $default_class_td = $default_class_td_odd; + } else { + $default_class_td = $default_class_td_even; + } + $row_is_odd = !$row_is_odd; + + // the end of row attributes is the end of the line/start of cell + $suffix = "\n|"; + $eoe = strpos($row, $suffix); + $attribs = substr($row, 0, $eoe - strlen($suffix)); + $attributes = _get_attributes($attribs); + $wret .= _output_tag_with_attributes("tr",$attributes,true); + + // extract just the data for the cells - skip prefix of first cell + $soe = $eoe + strlen($suffix); + $row_cells = substr($row, $soe); + + // the cells + $prefix = "\n|"; + + // convert "||" to "\n|" to simplify splitting + $row_cells = str_replace("||", $prefix, $row_cells); + + // get cells - skip over prefix of first cell + $cells = explode($prefix, $row_cells); + foreach ($cells as $cell) { + if (strpos($cell, "|")) { + list($attribs, $text) = explode("|", $cell, 2); + $attributes = _get_attributes($attribs); + } else { + // only one part so use as text + $attributes = array(); + $text = $cell; + } + _check_class_attribute($attributes,$default_class_td); + $wret .= _output_tag_with_attributes("td",$attributes); + $wret .= trim($text); + + // end of cell + $wret .= "</td>\n"; + } + // end the row + $wret .= "</tr>\n"; + } + + // End the table + $wret .= "</table>\n"; + + return $wret; +} + +// We need a function to parse attributes as wiki syntax rules do +// funny things to the data. +// % needs to be enclosed in double-quotes to not be a dynamic variable +// double-quotes have become " which is no good for an html attribute +// +// Return an associative array where value has had any delimiters removed. + +function _get_attributes($string) { + $attributes = array(); + $cur_pos = 0; + + while ($cur_pos < strlen($string)) { + // identify key + if (preg_match("/\s*(\w+)=/",$string,$matches,PREG_OFFSET_CAPTURE,$cur_pos)) { + $cur_pos += strlen($matches[0][0]); // skip whole pattern + $key = $matches[1][0]; // just store key + // identify value: + // use # as start/end character inclusion of / in value + if (preg_match("#([(")\"'\w:;%-/\.]+)(?=\s|\Z)#",$string,$matches,PREG_OFFSET_CAPTURE,$cur_pos)) { + $cur_pos += strlen($matches[0][0]); // skip whole pattern + $value = $matches[1][0]; // just store value + // remove delimiters (quote or double-quote if present) + $value = str_replace("'", "", $value); + $value = str_replace(""", "", $value); + } else { + $value = substr($string,$cur_pos); + $cur_pos = strlen($string); + } + $attributes[$key] = $value; + } else { + $cur_pos = strlen($string); + } + } + return $attributes; +} + +// If terminate_tag==False return in the form <tag attribute="value"> +// If terminate_tag==True return in the form <tag attribute="value"/> +// The latter is only applicable to a few tags like <col>. +function _output_tag_with_attributes($tag,$attributes,$newline = False, + $terminate_tag = False) { + $output = "<".$tag; + if (sizeof($attributes)) { + foreach($attributes as $key=>$value) { + $output .= " ".$key."=\"".$value."\""; + } + } + if ($terminate_tag) $output .= "/"; + $output .= ">"; + if ($newline) $output .= "\n"; + return $output; +} + +// Check the class element. +// if $add... [truncated message content] |