1<?php 2// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project 3// 4// All Rights Reserved. See copyright.txt for details and a complete list of authors. 5// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details. 6// $Id$ 7 8function wikiplugin_module_info() 9{ 10 global $lang; 11 12 $modlib = TikiLib::lib('mod'); 13 $cachelib = TikiLib::lib('cache'); 14 15 if (! $modules_options = $cachelib->getSerialized('module_list_for_plugin' . $lang)) { 16 $all_modules = $modlib->get_all_modules(); 17 $all_modules_info = array_combine($all_modules, array_map([ $modlib, 'get_module_info' ], $all_modules)); 18 uasort($all_modules_info, 'compare_names'); 19 $modules_options = []; 20 foreach ($all_modules_info as $module => $module_info) { 21 $modules_options[] = ['text' => $module_info['name'] . ' (' . $module . ')', 'value' => $module]; 22 } 23 24 $cachelib->cacheItem('module_list_for_plugin' . $lang, serialize($modules_options)); 25 } 26 27 return [ 28 'name' => tra('Module'), 29 'documentation' => 'PluginModule', 30 'description' => tra('Display a module'), 31 'prefs' => [ 'wikiplugin_module' ], 32 'validate' => 'all', 33 'format' => 'html', 34 'iconname' => 'module', 35 'introduced' => 1, 36 'extraparams' => true, 37 'tags' => [ 'basic' ], 38 'params' => [ 39 'module' => [ 40 'required' => true, 41 'name' => tra('Module Name'), 42 'description' => tra('Module name as known in Tiki'), 43 'since' => '1', 44 'default' => '', 45 'filter' => 'text', 46 'options' => $modules_options, 47 ], 48 'notitle' => [ 49 'required' => false, 50 'name' => tra('No Title'), 51 'description' => tr('Select Yes (%0y%1) to hide the title (default is to show the title)', '<code>', '</code>'), 52 'since' => '3.0', 53 'options' => [ 54 ['text' => '', 'value' => ''], 55 ['text' => tra('Yes'), 'value' => 'y'], 56 ['text' => tra('No'), 'value' => 'n'], 57 ], 58 'filter' => 'alpha', 59 'advanced' => true, 60 ], 61 'title' => [ 62 'name' => tra('Module Title'), 63 'description' => tr( 64 'Title to display at the top of the box, assuming No Title is not set to Yes (%0y%1).', 65 '<code>', 66 '</code>' 67 ), 68 'since' => '1', 69 'filter' => 'text', 70 'advanced' => true, 71 ], 72 'float' => [ 73 'required' => false, 74 'name' => tra('Float'), 75 'description' => tra('Align the module to the left or right on the page allowing other elements to align against it'), 76 'since' => '1', 77 'default' => '', 78 'filter' => 'word', 79 'advanced' => true, 80 'options' => [ 81 ['text' => '', 'value' => ''], 82 ['text' => 'No Float', 'value' => 'nofloat'], 83 ['text' => tra('Left'), 'value' => 'left'], 84 ['text' => tra('Right'), 'value' => 'right'] 85 ] 86 ], 87 'max' => [ 88 'required' => false, 89 'name' => tra('Max'), 90 'description' => tr('Number of rows (default: %010%1)', '<code>', '</code>'), 91 'since' => '1', 92 'default' => 10, 93 'filter' => 'digits', 94 'advanced' => true, 95 ], 96 'np' => [ 97 'required' => false, 98 'name' => tra('Parse'), 99 'description' => tra('Parse wiki syntax.') . ' ' . tra('Default:') . ' ' . tra('No'), 100 'since' => '1', 101 'default' => '1', 102 'filter' => 'digits', 103 'options' => [ 104 ['text' => '', 'value' => ''], 105 ['text' => tra('Yes'), 'value' => '0'], 106 ['text' => tra('No'), 'value' => '1'], 107 ], 108 'advanced' => true, 109 ], 110 'nobox' => [ 111 'name' => tra('No Box'), 112 'description' => 'y|n ' . tra('Show only the content with no title or borders, etc. around the content.'), 113 'since' => '9.0', 114 'section' => 'appearance', 115 'filter' => 'alpha', 116 'advanced' => true, 117 'options' => [ 118 ['text' => '', 'value' => ''], 119 ['text' => tra('Yes'), 'value' => 'y'], 120 ['text' => tra('No'), 'value' => 'n'] 121 ] 122 ], 123 'decoration' => [ 124 'required' => false, 125 'name' => tra('Title, background, etc'), 126 'description' => tra('Show module title (heading) background, etc. (default is to show them)'), 127 'since' => '1', 128 'advanced' => true, 129 'filter' => 'digits', 130 'options' => [ 131 ['text' => '', 'value' => ''], 132 ['text' => tra('Yes'), 'value' => '1'], 133 ['text' => tra('No'), 'value' => '0'], 134 ] 135 ], 136 'flip' => [ 137 'required' => false, 138 'name' => tra('Flip'), 139 'description' => tra('Add ability to show/hide the content of the module (default is the site admin 140 setting for modules)'), 141 'since' => '1', 142 'section' => 'appearance', 143 'filter' => 'digits', 144 'options' => [ 145 ['text' => '', 'value' => ''], 146 ['text' => tra('Yes'), 'value' => '1'], 147 ['text' => tra('No'), 'value' => '0'], 148 ], 149 'advanced' => true, 150 ], 151 'bgcolor' => [ 152 'required' => false, 153 'name' => tra('Title Background'), 154 'description' => tr( 155 'Override the background color for the title (if the title is shown). The value 156 can be a color name (ex: %0bgcolor="blue"%1) or a hexadecimal value (ex: %0bgcolor="#FFEBCD"%1)', 157 '<code>', 158 '</code>' 159 ), 160 'since' => '9.0', 161 'default' => '', 162 'filter' => 'text', 163 'advanced' => true, 164 ], 165 'module_style' => [ 166 'required' => false, 167 'name' => tra('Module Style'), 168 'description' => tr( 169 'Inline CSS for the containing div element, for example, %0max-width:80%%1', 170 '<code>', 171 '</code>' 172 ), 173 'since' => '9.0', 174 'filter' => 'text', 175 'accepted' => tra('Valid CSS styling'), 176 'default' => '', 177 'advanced' => true, 178 ], 179 'style' => [ 180 'name' => tra('Style'), 181 'description' => tra('CSS styling for the module data itself.'), 182 'since' => '9.0', 183 'filter' => 'text', 184 'section' => 'appearance', 185 'accepted' => tra('Valid CSS styling'), 186 'advanced' => true, 187 ], 188 'topclass' => [ 189 'name' => tra('Containing Class'), 190 'description' => tra('Custom CSS class of div around the module.'), 191 'since' => '9.0', 192 'filter' => 'text', 193 'section' => 'appearance', 194 'accepted' => tra('Valid CSS class'), 195 'advanced' => true, 196 ], 197 'class' => [ 198 'name' => tra('Class'), 199 'description' => tra('Custom CSS class.'), 200 'since' => '9.0', 201 'section' => 'appearance', 202 'filter' => 'text', 203 'accepted' => tra('Valid CSS class'), 204 'advanced' => true, 205 ], 206 'category' => [ 207 'name' => tra('Category'), 208 'description' => tra('Module displayed depending on category. Multiple category ids or names can be 209 separated by semi-colons.'), 210 'since' => '9.0', 211 'section' => 'visibility', 212 'separator' => ';', 213 'filter' => 'alnum', 214 'advanced' => true, 215 ], 216 'nocategory' => [ 217 'name' => tra('No Category'), 218 'description' => tra('Module hidden depending on category. Multiple category ids or names can be 219 separated by semi-colons. This takes precedence over the category parameter above.'), 220 'since' => '9.0', 221 'section' => 'visibility', 222 'separator' => ';', 223 'filter' => 'alnum', 224 'advanced' => true, 225 ], 226 'perspective' => [ 227 'name' => tra('Perspective'), 228 'description' => tra('Only display the module if in one of the listed perspective IDs. Semi-colon 229 separated.'), 230 'since' => '9.0', 231 'separator' => ';', 232 'filter' => 'digits', 233 'section' => 'visibility', 234 'advanced' => true, 235 ], 236 'lang' => [ 237 'name' => tra('Language'), 238 'description' => tra('Module only applicable for the specified languages. Languages are defined as two 239 character language codes. Multiple values can be separated by semi-colons.'), 240 'since' => '9.0', 241 'separator' => ';', 242 'filter' => 'lang', 243 'section' => 'visibility', 244 'advanced' => true, 245 ], 246 'section' => [ 247 'name' => tra('Section'), 248 'description' => tra('Module only applicable for the specified sections. Multiple values can be 249 separated by semi-colons.'), 250 'since' => '9.0', 251 'separator' => ';', 252 'filter' => 'text', 253 'section' => 'visibility', 254 'advanced' => true, 255 ], 256 'page' => [ 257 'name' => tra('Page Filter'), 258 'description' => tra('Module only applicable on the specified page names. Multiple values can be 259 separated by semi-colons.'), 260 'since' => '9.0', 261 'separator' => ';', 262 'filter' => 'pagename', 263 'section' => 'visibility', 264 'advanced' => true, 265 ], 266 'nopage' => [ 267 'name' => tra('No Page'), 268 'description' => tra('Module not applicable on the specified page names. Multiple values can be 269 separated by semi-colons.'), 270 'since' => '9.0', 271 'separator' => ';', 272 'filter' => 'pagename', 273 'section' => 'visibility', 274 'advanced' => true, 275 ], 276 'theme' => [ 277 'name' => tra('Theme'), 278 'description' => tr('Module enabled or disabled depending on the theme file name (e.g. 279 %0thenews.css%1). Specified themes can be either included or excluded. Theme names prefixed by %0!%1 280 are in the exclusion list. Multiple values can be separated by semi-colons.', '<code>', '</code>'), 281 'since' => '9.0', 282 'separator' => ';', 283 'filter' => 'themename', 284 'section' => 'visibility', 285 'advanced' => true, 286 ], 287 'creator' => [ 288 'name' => tra('Creator'), 289 'description' => tr('Module only available based on the relationship of the user with the wiki page. 290 Either only creators (%0y%1) or only non-creators (%0n%1) will see the module.', '<code>', '</code>'), 291 'since' => '9.0', 292 'filter' => 'alpha', 293 'section' => 'visibility', 294 'advanced' => true, 295 ], 296 'contributor' => [ 297 'name' => tra('Contributor'), 298 'description' => tra( 299 'Module only available based on the relationship of the user with the wiki page. 300 Either only contributors (%0y%1) or only non-contributors (%0n%1) will see the module.', 301 '<code>', 302 '</code>' 303 ), 304 'since' => '9.0', 305 'filter' => 'alpha', 306 'section' => 'visibility', 307 'advanced' => true, 308 ], 309 ] 310 ]; 311} 312 313function wikiplugin_module($data, $params) 314{ 315 static $instance = 0; 316 317 $out = ''; 318 319 extract($params, EXTR_SKIP); 320 321 if (! isset($float)) { 322 $float = 'nofloat'; 323 } 324 325 if (! isset($max)) { 326 if (! isset($rows)) { 327 $max = 10; // default value 328 } else { 329 $max = $rows; // rows=> used instead of max=> ? 330 } 331 } 332 333 if (! isset($np)) { 334 $np = '1'; 335 } 336 337 if (! isset($module) or ! $module) { 338 $out = '<form class="box" id="modulebox">'; 339 340 $out .= '<br /><select name="choose">'; 341 $out .= '<option value="">' . tra('Please choose a module') . '</option>'; 342 $out .= '<option value="" style="background-color:#bebebe;">' . tra('to be used as argument') . '</option>'; 343 $out .= '<option value="" style="background-color:#bebebe;">{MODULE(module=>name_of_module)}</option>'; 344 $handle = opendir('modules'); 345 346 while ($file = readdir($handle)) { 347 if ((substr($file, 0, 4) == "mod-") and (substr($file, -4, 4) == ".php")) { 348 $mod = substr(substr(basename($file), 4), 0, -4); 349 350 $out .= "<option value=\"$mod\">$mod</option>"; 351 } 352 } 353 354 $out .= '</select></form>'; 355 } else { 356 $instance++; 357 if (empty($moduleId)) { 358 $moduleId = 'wikiplugin_' . $instance; 359 } 360 361 $module_reference = [ 362 'moduleId' => $moduleId, 363 'name' => $module, 364 'params' => $params, 365 'rows' => $max, 366 'position' => '_wp_', 367 'ord' => $instance, 368 'cache_time' => 0, 369 ]; 370 371 if (! empty($module_style)) { 372 $module_reference['module_style'] = $module_style; 373 } 374 375 $modlib = TikiLib::lib('mod'); 376 $out = $modlib->execute_module($module_reference); 377 } 378 379 if ($out) { 380 if ($float != 'nofloat') { 381 $data = "<div style='float: $float;'>$out</div>"; 382 } else { 383 $data = "<div>$out</div>"; 384 } 385 } else { 386 // Display error message 387 $data = "<div class=\"alert alert-danger\" role=\"alert\"><button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-label=\"" . tra("Close") . "\"><span aria-hidden=\"true\">×</span></button>" . tra("Sorry, no such module") . "<br><b>$module</b></div>" . $data; 388 } 389 390 if ($module == 'register') { 391 // module register (maybe others too?) adds ~np~ to plugin output so remove them 392 $data = preg_replace('/~[\/]?np~/ms', '', $data); 393 } 394 return $data; 395} 396