Index: trunk/extensions/Widgets/WidgetRenderer.php |
— | — | @@ -0,0 +1,193 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Class holding functions for displaying widgets. |
| 5 | + */ |
| 6 | + |
| 7 | +if ( !defined( 'MEDIAWIKI' ) ) { |
| 8 | + echo "This file is not a valid entry point."; |
| 9 | + exit( 1 ); |
| 10 | +} |
| 11 | + |
| 12 | +class WidgetRenderer { |
| 13 | + |
| 14 | +public static function renderWidget ( &$parser, $widgetName ) { |
| 15 | + global $IP; |
| 16 | + |
| 17 | + $smarty = new Smarty; |
| 18 | + $smarty->left_delimiter = '<!--{'; |
| 19 | + $smarty->right_delimiter = '}-->'; |
| 20 | + $smarty->compile_dir = "$IP/extensions/Widgets/compiled_templates/"; |
| 21 | + |
| 22 | + // registering custom Smarty plugins |
| 23 | + $smarty->plugins_dir[] = "$IP/extensions/Widgets/smarty_plugins/"; |
| 24 | + |
| 25 | + $smarty->security = true; |
| 26 | + $smarty->security_settings = array( |
| 27 | + 'IF_FUNCS' => array( |
| 28 | + 'is_array', |
| 29 | + 'isset', |
| 30 | + 'array', |
| 31 | + 'list', |
| 32 | + 'count', |
| 33 | + 'sizeof', |
| 34 | + 'in_array', |
| 35 | + 'true', |
| 36 | + 'false', |
| 37 | + 'null' |
| 38 | + ), |
| 39 | + 'MODIFIER_FUNCS' => array( 'validate' ) |
| 40 | + ); |
| 41 | + |
| 42 | + // register the resource name "db" |
| 43 | + $smarty->register_resource( |
| 44 | + 'wiki', |
| 45 | + array( |
| 46 | + 'WidgetRenderer::wiki_get_template', |
| 47 | + 'WidgetRenderer::wiki_get_timestamp', |
| 48 | + 'WidgetRenderer::wiki_get_secure', |
| 49 | + 'WidgetRenderer::wiki_get_trusted' |
| 50 | + ) |
| 51 | + ); |
| 52 | + |
| 53 | + $params = func_get_args(); |
| 54 | + array_shift( $params ); # first one is parser - we don't need it |
| 55 | + array_shift( $params ); # second one is widget name |
| 56 | + |
| 57 | + $params_tree = array(); |
| 58 | + |
| 59 | + foreach ( $params as $param ) { |
| 60 | + $pair = explode('=', $param, 2); |
| 61 | + |
| 62 | + if ( count( $pair ) == 2 ) { |
| 63 | + $key = trim($pair[0]); |
| 64 | + $val = trim($pair[1]); |
| 65 | + } else { |
| 66 | + $key = $param; |
| 67 | + $val = true; |
| 68 | + } |
| 69 | + |
| 70 | + if ( $val == 'false' ) { |
| 71 | + $val = false; |
| 72 | + } |
| 73 | + |
| 74 | + /* If the name of the parameter has object notation |
| 75 | + |
| 76 | + a.b.c.d |
| 77 | + |
| 78 | + then we assign stuff to hash of hashes, not scalar |
| 79 | + |
| 80 | + */ |
| 81 | + $keys = explode( '.', $key ); |
| 82 | + |
| 83 | + // $subtree will be moved from top to the bottom and at the end will point to the last level |
| 84 | + $subtree =& $params_tree; |
| 85 | + |
| 86 | + // go throught all the keys but last one |
| 87 | + $last_key = array_pop( $keys ); |
| 88 | + |
| 89 | + foreach ( $keys as $subkey ) { |
| 90 | + // if next level of subtree doesn't exist yet, create an empty one |
| 91 | + if ( !array_key_exists( $subkey, $subtree ) ) { |
| 92 | + $subtree[$subkey] = array(); |
| 93 | + } |
| 94 | + |
| 95 | + // move to the lower level |
| 96 | + $subtree =& $subtree[$subkey]; |
| 97 | + } |
| 98 | + |
| 99 | + // last portion of the key points to itself |
| 100 | + if ( isset( $subtree[$last_key] ) ) { |
| 101 | + // if already an array, push into it, otherwise, convert into array first |
| 102 | + if ( !is_array( $subtree[$last_key] ) ) { |
| 103 | + $subtree[$last_key] = array( $subtree[$last_key] ); |
| 104 | + } |
| 105 | + |
| 106 | + $subtree[$last_key][] = $val; |
| 107 | + } else { |
| 108 | + // doesn't exist yet, just setting a value |
| 109 | + $subtree[$last_key] = $val; |
| 110 | + } |
| 111 | + } |
| 112 | + |
| 113 | + $smarty->assign( $params_tree ); |
| 114 | + |
| 115 | + try { |
| 116 | + $output = $smarty->fetch( "wiki:$widgetName" ); |
| 117 | + } catch ( Exception $e ) { |
| 118 | + wfLoadExtensionMessages( 'Widgets' ); |
| 119 | + return '<div class=\"error\">' . wfMsgExt( 'widgets-desc', array( 'parsemag' ), htmlentities($widgetName) ) . '</div>'; |
| 120 | + } |
| 121 | + |
| 122 | + // Hide the widget from the parser |
| 123 | + $output = 'ENCODED_CONTENT '.base64_encode($output).' END_ENCODED_CONTENT'; |
| 124 | + return $output; |
| 125 | +} |
| 126 | + |
| 127 | +public static function processEncodedWidgetOutput( &$out, &$text ) { |
| 128 | + // Find all hidden content and restore to normal |
| 129 | + $text = preg_replace( |
| 130 | + '/ENCODED_CONTENT ([0-9a-zA-Z\/+]+=*)* END_ENCODED_CONTENT/esm', |
| 131 | + 'base64_decode("$1")', |
| 132 | + $text |
| 133 | + ); |
| 134 | + |
| 135 | + return true; |
| 136 | +} |
| 137 | + |
| 138 | + // the following four functions are all registered with Smarty |
| 139 | + public static function wiki_get_template( $widgetName, &$widgetCode, &$smarty_obj ) { |
| 140 | + global $wgWidgetsUseFlaggedRevs; |
| 141 | + |
| 142 | + $widgetTitle = Title::newFromText($widgetName, NS_WIDGET); |
| 143 | + if ( $widgetTitle && $widgetTitle->exists() ) { |
| 144 | + if ($wgWidgetsUseFlaggedRevs) |
| 145 | + { |
| 146 | + $flaggedWidgetArticle = FlaggedArticle::getTitleInstance( $widgetTitle ); |
| 147 | + $flaggedWidgetArticleRevision = $flaggedWidgetArticle->getStableRev(); |
| 148 | + if ($flaggedWidgetArticleRevision) |
| 149 | + { |
| 150 | + $widgetCode = $flaggedWidgetArticleRevision->getRevText(); |
| 151 | + } |
| 152 | + else |
| 153 | + { |
| 154 | + $widgetCode = ''; |
| 155 | + } |
| 156 | + } |
| 157 | + else |
| 158 | + { |
| 159 | + $widgetArticle = new Article( $widgetTitle, 0 ); |
| 160 | + $widgetCode = $widgetArticle->getContent(); |
| 161 | + } |
| 162 | + |
| 163 | + // Remove <noinclude> sections and <includeonly> tags from form definition |
| 164 | + $widgetCode = StringUtils::delimiterReplace( '<noinclude>', '</noinclude>', '', $widgetCode ); |
| 165 | + $widgetCode = strtr( $widgetCode, array( '<includeonly>' => '', '</includeonly>' => '' ) ); |
| 166 | + |
| 167 | + return true; |
| 168 | + } else { |
| 169 | + return false; |
| 170 | + } |
| 171 | + } |
| 172 | + |
| 173 | + public static function wiki_get_timestamp( $widgetName, &$widgetTimestamp, &$smarty_obj ) { |
| 174 | + $widgetTitle = Title::newFromText( $widgetName, NS_WIDGET ); |
| 175 | + if ($widgetTitle && $widgetTitle->exists()) { |
| 176 | + $widgetArticle = new Article( $widgetTitle, 0 ); |
| 177 | + $widgetTimestamp = $widgetArticle->getTouched(); |
| 178 | + |
| 179 | + return true; |
| 180 | + } else { |
| 181 | + return false; |
| 182 | + } |
| 183 | + } |
| 184 | + |
| 185 | + public static function wiki_get_secure( $tpl_name, &$smarty_obj ) { |
| 186 | + // assume all templates are secure |
| 187 | + return true; |
| 188 | + } |
| 189 | + |
| 190 | + public static function wiki_get_trusted( $tpl_name, &$smarty_obj ) { |
| 191 | + // not used for templates |
| 192 | + } |
| 193 | + |
| 194 | +} |
Index: trunk/extensions/Widgets/Widgets.php |
— | — | @@ -16,7 +16,7 @@ |
17 | 17 | 'path' => __FILE__, |
18 | 18 | 'name' => 'Widgets', |
19 | 19 | 'descriptionmsg' => 'widgets-desc', |
20 | | - 'version' => '0.9.1-dev', |
| 20 | + 'version' => '0.9.1', |
21 | 21 | 'author' => '[http://www.sergeychernyshev.com Sergey Chernyshev]', |
22 | 22 | 'url' => 'http://www.mediawiki.org/wiki/Extension:Widgets' |
23 | 23 | ); |
— | — | @@ -51,6 +51,7 @@ |
52 | 52 | // Initialize Smarty |
53 | 53 | require_once( $dir . 'smarty/Smarty.class.php' ); |
54 | 54 | $wgExtensionMessagesFiles['Widgets'] = $dir . 'Widgets.i18n.php'; |
| 55 | +$wgAutoloadClasses['WidgetRenderer'] = $dir . 'WidgetRenderer.php'; |
55 | 56 | |
56 | 57 | if( defined('MW_SUPPORTS_LOCALISATIONCACHE') ) { |
57 | 58 | $wgExtensionMessagesFiles['WidgetsMagic'] = $dir . 'Widgets.i18n.magic.php'; |
— | — | @@ -73,124 +74,11 @@ |
74 | 75 | $wgHooks['ParserAfterTidy'][] = 'processEncodedWidgetOutput'; |
75 | 76 | |
76 | 77 | function widgetParserFunctions( &$parser ) { |
77 | | - $parser->setFunctionHook( 'widget', 'renderWidget' ); |
| 78 | + $parser->setFunctionHook( 'widget', array( 'WidgetRenderer', 'renderWidget' ) ); |
78 | 79 | |
79 | 80 | return true; |
80 | 81 | } |
81 | 82 | |
82 | | -function renderWidget ( &$parser, $widgetName ) { |
83 | | - global $IP; |
84 | | - |
85 | | - $smarty = new Smarty; |
86 | | - $smarty->left_delimiter = '<!--{'; |
87 | | - $smarty->right_delimiter = '}-->'; |
88 | | - $smarty->compile_dir = "$IP/extensions/Widgets/compiled_templates/"; |
89 | | - |
90 | | - // registering custom Smarty plugins |
91 | | - $smarty->plugins_dir[] = "$IP/extensions/Widgets/smarty_plugins/"; |
92 | | - |
93 | | - $smarty->security = true; |
94 | | - $smarty->security_settings = array( |
95 | | - 'IF_FUNCS' => array( |
96 | | - 'is_array', |
97 | | - 'isset', |
98 | | - 'array', |
99 | | - 'list', |
100 | | - 'count', |
101 | | - 'sizeof', |
102 | | - 'in_array', |
103 | | - 'true', |
104 | | - 'false', |
105 | | - 'null' |
106 | | - ), |
107 | | - 'MODIFIER_FUNCS' => array( 'validate' ) |
108 | | - ); |
109 | | - |
110 | | - // register the resource name "db" |
111 | | - $smarty->register_resource( |
112 | | - 'wiki', |
113 | | - array( |
114 | | - 'wiki_get_template', |
115 | | - 'wiki_get_timestamp', |
116 | | - 'wiki_get_secure', |
117 | | - 'wiki_get_trusted' |
118 | | - ) |
119 | | - ); |
120 | | - |
121 | | - $params = func_get_args(); |
122 | | - array_shift( $params ); # first one is parser - we don't need it |
123 | | - array_shift( $params ); # second one is widget name |
124 | | - |
125 | | - $params_tree = array(); |
126 | | - |
127 | | - foreach ( $params as $param ) { |
128 | | - $pair = explode('=', $param, 2); |
129 | | - |
130 | | - if ( count( $pair ) == 2 ) { |
131 | | - $key = trim($pair[0]); |
132 | | - $val = trim($pair[1]); |
133 | | - } else { |
134 | | - $key = $param; |
135 | | - $val = true; |
136 | | - } |
137 | | - |
138 | | - if ( $val == 'false' ) { |
139 | | - $val = false; |
140 | | - } |
141 | | - |
142 | | - /* If the name of the parameter has object notation |
143 | | - |
144 | | - a.b.c.d |
145 | | - |
146 | | - then we assign stuff to hash of hashes, not scalar |
147 | | - |
148 | | - */ |
149 | | - $keys = explode( '.', $key ); |
150 | | - |
151 | | - // $subtree will be moved from top to the bottom and at the end will point to the last level |
152 | | - $subtree =& $params_tree; |
153 | | - |
154 | | - // go throught all the keys but last one |
155 | | - $last_key = array_pop( $keys ); |
156 | | - |
157 | | - foreach ( $keys as $subkey ) { |
158 | | - // if next level of subtree doesn't exist yet, create an empty one |
159 | | - if ( !array_key_exists( $subkey, $subtree ) ) { |
160 | | - $subtree[$subkey] = array(); |
161 | | - } |
162 | | - |
163 | | - // move to the lower level |
164 | | - $subtree =& $subtree[$subkey]; |
165 | | - } |
166 | | - |
167 | | - // last portion of the key points to itself |
168 | | - if ( isset( $subtree[$last_key] ) ) { |
169 | | - // if already an array, push into it, otherwise, convert into array first |
170 | | - if ( !is_array( $subtree[$last_key] ) ) { |
171 | | - $subtree[$last_key] = array( $subtree[$last_key] ); |
172 | | - } |
173 | | - |
174 | | - $subtree[$last_key][] = $val; |
175 | | - } else { |
176 | | - // doesn't exist yet, just setting a value |
177 | | - $subtree[$last_key] = $val; |
178 | | - } |
179 | | - } |
180 | | - |
181 | | - $smarty->assign( $params_tree ); |
182 | | - |
183 | | - try { |
184 | | - $output = $smarty->fetch( "wiki:$widgetName" ); |
185 | | - } catch ( Exception $e ) { |
186 | | - wfLoadExtensionMessages( 'Widgets' ); |
187 | | - return '<div class=\"error\">' . wfMsgExt( 'widgets-desc', array( 'parsemag' ), htmlentities($widgetName) ) . '</div>'; |
188 | | - } |
189 | | - |
190 | | - // Hide the widget from the parser |
191 | | - $output = 'ENCODED_CONTENT '.base64_encode($output).' END_ENCODED_CONTENT'; |
192 | | - return $output; |
193 | | -} |
194 | | - |
195 | 83 | function processEncodedWidgetOutput( &$out, &$text ) { |
196 | 84 | // Find all hidden content and restore to normal |
197 | 85 | $text = preg_replace( |
— | — | @@ -215,59 +103,3 @@ |
216 | 104 | $wgNamespaceProtection[NS_WIDGET] = array( 'editwidgets' ); |
217 | 105 | } |
218 | 106 | } |
219 | | - |
220 | | -// put these function somewhere in your application |
221 | | -function wiki_get_template( $widgetName, &$widgetCode, &$smarty_obj ) { |
222 | | - global $wgWidgetsUseFlaggedRevs; |
223 | | - |
224 | | - $widgetTitle = Title::newFromText($widgetName, NS_WIDGET); |
225 | | - if ( $widgetTitle && $widgetTitle->exists() ) { |
226 | | - if ($wgWidgetsUseFlaggedRevs) |
227 | | - { |
228 | | - $flaggedWidgetArticle = FlaggedArticle::getTitleInstance( $widgetTitle ); |
229 | | - $flaggedWidgetArticleRevision = $flaggedWidgetArticle->getStableRev(); |
230 | | - if ($flaggedWidgetArticleRevision) |
231 | | - { |
232 | | - $widgetCode = $flaggedWidgetArticleRevision->getRevText(); |
233 | | - } |
234 | | - else |
235 | | - { |
236 | | - $widgetCode = ''; |
237 | | - } |
238 | | - } |
239 | | - else |
240 | | - { |
241 | | - $widgetArticle = new Article( $widgetTitle, 0 ); |
242 | | - $widgetCode = $widgetArticle->getContent(); |
243 | | - } |
244 | | - |
245 | | - // Remove <noinclude> sections and <includeonly> tags from form definition |
246 | | - $widgetCode = StringUtils::delimiterReplace( '<noinclude>', '</noinclude>', '', $widgetCode ); |
247 | | - $widgetCode = strtr( $widgetCode, array( '<includeonly>' => '', '</includeonly>' => '' ) ); |
248 | | - |
249 | | - return true; |
250 | | - } else { |
251 | | - return false; |
252 | | - } |
253 | | -} |
254 | | - |
255 | | -function wiki_get_timestamp( $widgetName, &$widgetTimestamp, &$smarty_obj ) { |
256 | | - $widgetTitle = Title::newFromText( $widgetName, NS_WIDGET ); |
257 | | - if ($widgetTitle && $widgetTitle->exists()) { |
258 | | - $widgetArticle = new Article( $widgetTitle, 0 ); |
259 | | - $widgetTimestamp = $widgetArticle->getTouched(); |
260 | | - |
261 | | - return true; |
262 | | - } else { |
263 | | - return false; |
264 | | - } |
265 | | -} |
266 | | - |
267 | | -function wiki_get_secure( $tpl_name, &$smarty_obj ) { |
268 | | - // assume all templates are secure |
269 | | - return true; |
270 | | -} |
271 | | - |
272 | | -function wiki_get_trusted( $tpl_name, &$smarty_obj ) { |
273 | | - // not used for templates |
274 | | -} |