'description|parameters|paraminfo', 'plugin' => '', 'module' => '', 'singletitle' => 'none', 'titletag' => 'h3', 'start' => '', 'limit' => '', 'paramtype' => '', 'showparamtype' => 'n', 'showtopinfo' => 'y' ]; } function getName() { return 'PluginManager'; } function getVersion() { return preg_replace("/[Revision: $]/", '', "\$Revision: 1.11 $"); } function getDescription() { return wikiplugin_pluginmanager_help(); } function run($data, $params) { global $helpurl; $wikilib = TikiLib::lib('wiki'); $tikilib = TikiLib::lib('tiki'); if (! is_dir(PLUGINS_DIR)) { return $this->error('No plugin directory defined'); } if (empty($helpurl)) { $helpurl = 'http://doc.tiki.org/'; } if(empty($sourceurl)) { $sourceurl = 'https://gitlab.com/tikiwiki/tiki/-/blob/master/lib/wiki-plugins/'; } $params = $this->getParams($params); extract($params, EXTR_SKIP); if (! empty($module) && ! empty($plugin)) { return $this->error(tra('Either the module or plugin parameter must be set, but not both.')); } elseif (! empty($module)) { $aPrincipalField = ['field' => 'plugin', 'name' => 'Module']; $helppath = $helpurl . $aPrincipalField['name'] . ' '; $filepath = 'mod-func-'; $modlib = TikiLib::lib('mod'); $aPlugins = $modlib->list_module_files(); $mod = true; $type = ' module'; $plugin = $module; } else { $aPrincipalField = ['field' => 'plugin', 'name' => 'Plugin']; $helppath = $helpurl . $aPrincipalField['name']; $filepath = 'wikiplugin_'; $aPlugins = $wikilib->list_plugins(); $mod = false; $type = ' plugin'; } $all = $aPlugins; //if the user set $module, that setting has now been moved to $plugin so that one code set is used //$aPlugins and $all now has the complete list of plugin or module file names - the code below modifies $aPlugins //if necessary based on user settings if (! empty($plugin)) { if (strpos($plugin, '|') !== false) { $aPlugins = []; $userlist = explode('|', $plugin); foreach ($userlist as $useritem) { $file = $filepath . $useritem . '.php'; $confirm = in_array($file, $all); if ($confirm === false) { return '^' . tr('Plugin Manager error: %0%1 not found', $useritem, $type) . '^'; } else { $aPlugins[] = $file; } } } elseif (strpos($plugin, '-') !== false) { $userrange = explode('-', $plugin); $begin = array_search($filepath . $userrange[0] . '.php', $aPlugins); $end = array_search($filepath . $userrange[1] . '.php', $aPlugins); $beginerror = ''; $enderror = ''; $type2 = $type; if ($begin === false || $end === false) { if ($begin === false) { $beginerror = $userrange[0]; } if ($end === false) { $enderror = $userrange[1]; if (! empty($beginerror)) { $and = ' and '; } else { $and = ''; $type = ''; } } return '^' . tr('Plugin Manager error: %0%1%2%3%4 not found', $beginerror, $type, $and, $enderror, $type2) . '^'; } elseif ($end > $begin) { $aPlugins = array_slice($aPlugins, $begin, $end - $begin + 1); } else { $aPlugins = array_slice($aPlugins, $end, $begin - $end + 1); } } elseif (! empty($limit)) { $begin = array_search($filepath . $plugin . '.php', $aPlugins); if ($begin === false) { return '^' . tr('Plugin Manager error: %0%1 not found', $begin, $type) . '^'; } else { $aPlugins = array_slice($aPlugins, $begin, $limit); } } elseif ($plugin != 'all') { $file = $filepath . $plugin . '.php'; $confirm = in_array($file, $aPlugins); if ($confirm === false) { return '^' . tr('Plugin Manager error: %0%1 not found', $plugin, $type) . '^'; } else { $aPlugins = []; $aPlugins[] = $file; } } } else { if (! empty($start) || ! empty($limit)) { if (! empty($start) && ! empty($limit)) { $aPlugins = array_slice($aPlugins, $start - 1, $limit); } elseif (! empty($start)) { $aPlugins = array_slice($aPlugins, $start - 1); } else { $aPlugins = array_slice($aPlugins, 0, $limit); } } } //Set all data variables needed for separate code used to generate the display table $aData = []; if ($singletitle == 'table' || count($aPlugins) > 1) { foreach ($aPlugins as $sPluginFile) { global $sPlugin, $numparams; if ($mod) { $infoPlugin = get_module_params($sPluginFile); $namepath = $sPlugin; } else { $infoPlugin = get_plugin_info($sPluginFile); $namepath = ucfirst($sPlugin); } if (in_array('description', $info)) { if (isset($infoPlugin['description'])) { if ($numparams > 1) { $aData[$sPlugin]['description']['onekey'] = $infoPlugin['description']; } else { $aData[$sPlugin]['description'] = $infoPlugin['description']; } } else { $aData[$sPlugin]['description'] = ' --- '; } } if (in_array('sourcecode', $info)) { if ($numparams > 1) { $aData[$sPlugin]['sourcecode']['onekey'] = '[' . $sourceurl.$sPluginFile . '|'.tra('Go to the source code').']'; } else { $aData[$sPlugin]['sourcecode'] = '[' . $sourceurl.$sPluginFile . '|'.tra('Go to the source code').']'; } } if (in_array('parameters', $info)) { if ($numparams > 0) { if ($aPrincipalField['field'] == 'plugin' && ! in_array('options', $info) && $numparams > 1) { $aData[$sPlugin][$aPrincipalField['field']]['rowspan'] = $numparams; if (in_array('description', $info)) { $aData[$sPlugin]['description']['rowspan'] = $numparams; } } foreach ($infoPlugin['params'] as $paramname => $param) { if (isset($infoPlugin['params'][$paramname]['description'])) { $paramblock = '~np~' . $infoPlugin['params'][$paramname]['description'] . '~/np~'; } if (isset($param['options']) && is_array($param['options'])) { $paramblock .= '
' . tra('Options:') . ' '; $i = 0; foreach ($param['options'] as $oplist => $opitem) { if (isset($opitem['value'])) { $paramblock .= $opitem['value']; } else { $paramblock .= $opitem['text']; } $paramblock .= ' | '; $i++; } $paramblock = substr($paramblock, 0, -3); } if (isset($infoPlugin['params'][$paramname]['required']) && $infoPlugin['params'][$paramname]['required'] == true) { $aData[$sPlugin]['parameters']['' . $paramname . ''] = $paramblock; } else { $aData[$sPlugin]['parameters']['' . $paramname . ''] = $paramblock; } } } else { $aData[$sPlugin]['parameters']['no parameters'] = '' . tra('n/a') . ''; } } $aData[$sPlugin]['plugin']['plugin'] = '[' . $helppath . $namepath . '|' . ucfirst($sPlugin) . ']'; } // Plugins Loop return PluginsLibUtil::createTable($aData, $info, $aPrincipalField); } else { //Replicates a documentation table for parameters for a single plugin or module //Not using plugin lib table to avoid making custom modifications global $sPlugin, $numparams; $sourcecode = $sourceurl.$aPlugins[0]; if ($mod) { $infoPlugin = get_module_params($aPlugins[0]); $namepath = $sPlugin; } else { $infoPlugin = get_plugin_info($aPlugins[0]); $namepath = ucfirst($sPlugin); } if ($singletitle == 'top') { $title = '<' . $titletag . '>[' . $helppath . $namepath . '|' . ucfirst($sPlugin) . ']'; $title .= $infoPlugin['description'] . '
'; } else { $title = ''; } $headbegin = "\n\t\t" . ''; $cellbegin = "\n\t\t" . ''; $header = "\n\t" . '' . $headbegin . 'Parameters'; $rows = ''; if (isset($numparams) && $numparams > 0) { $header .= $headbegin . tra('Accepted Values') . ''; $header .= $headbegin . tra('Description') . ''; $rowCounter = 1; //sort required params first $reqarray = array_column($infoPlugin['params'], 'required'); $keysarray = array_keys($infoPlugin['params']); $reqarray = array_combine($keysarray, $reqarray); if (count($reqarray) == count($infoPlugin['params'])) { array_multisort($reqarray, SORT_DESC, $infoPlugin['params']); } //add body instructions to the parameter array if (! empty($infoPlugin['body'])) { $body = ['(body of plugin)' => ['description' => $infoPlugin['body']]]; $infoPlugin['params'] = array_merge($body, $infoPlugin['params']); } $count = 1; foreach ($infoPlugin['params'] as $paramname => $paraminfo) { unset($sep, $septext); //check is paramtype filter is set if ( empty($params['paramtype']) || ((empty($paraminfo['doctype']) && ! empty($params['paramtype']) && $params['paramtype'] === 'none') || (! empty($paraminfo['doctype']) && $params['paramtype'] == $paraminfo['doctype'])) ) { $filteredparams[] = $paraminfo; $rows .= "\n\t" . '' . $cellbegin; //Parameters column if (isset($paraminfo['required']) && $paraminfo['required'] == true) { $rows .= '' . $paramname . ''; } elseif ($paramname == '(body of plugin)') { $rows .= tra('(body of plugin)'); } else { $rows .= '' . $paramname . '' ; } if ( isset($params['showparamtype']) && $params['showparamtype'] === 'y' && ! empty($paraminfo['doctype']) ) { $rows .= '
(' . $paraminfo['doctype'] . ')'; } $rows .= ''; //Accepted Values column $rows .= $cellbegin; if (isset($paraminfo['separator'])) { $sep = $paraminfo['separator']; $septext = tr('%0separator:%1 ', '', '') . '' . $paraminfo['separator'] . ''; } else { $sep = '| '; } if (isset($paraminfo['accepted'])) { $rows .= $paraminfo['accepted']; if (isset($septext)) { $rows .= '
' . $septext; } $rows .= ''; } elseif (isset($paraminfo['options'])) { $optcounter = 1; $numoptions = count($paraminfo['options']); foreach ($paraminfo['options'] as $oplist => $opitem) { $rows .= strlen($opitem['value']) == 0 ? tra('(blank)') : $opitem['value']; if ($optcounter < $numoptions) { if ($numoptions > 10) { $rows .= $sep; } else { $rows .= '
'; } } $optcounter++; } if (isset($septext)) { $rows .= '
' . $septext; } $rows .= ''; } elseif (isset($paraminfo['filter'])) { if ($paraminfo['filter'] == 'striptags') { $rows .= tra('any string except for HTML and PHP tags'); } else { $rows .= $paraminfo['filter']; } if (isset($septext)) { $rows .= '
' . $septext; } $rows .= ''; } else { if (isset($septext)) { $rows .= '
' . $septext; } $rows .= ''; } //Description column $rows .= $cellbegin . $paraminfo['description'] . ''; //Default column if ($rowCounter == 1) { $header .= $headbegin . tra('Default') . ''; } if (! isset($paraminfo['default'])) { $paraminfo['default'] = ''; } $rows .= $cellbegin . $paraminfo['default'] . ''; //Since column if ($rowCounter == 1) { $header .= $headbegin . tra('Since') . ''; } $since = ! empty($paraminfo['since']) ? $paraminfo['since'] : ''; $rows .= $cellbegin . $since . ''; $rows .= "\n\t" . ''; $rowCounter++; } } if (! empty($infoPlugin['additional']) && (empty($params['paramtype']) || $params['paramtype'] === 'none')) { $rows .= '' . $infoPlugin['additional'] . ''; } } else { if (! empty($infoPlugin['body'])) { $rows .= "\n\t" . '' . $cellbegin . '' . tra('(body of plugin)') . ' - ' . $infoPlugin['body'] . ''; } $rows .= "\n\t" . '' . $cellbegin . '' . tra('no parameters') . ''; } $header .= "\n\t" . ''; $pluginprefs = ! empty($infoPlugin['prefs']) && $params['showtopinfo'] !== 'n' ? '' . tra('Preferences required:') . ' ' . implode(', ', $infoPlugin['prefs']) . '
' : ''; $title .= isset($infoPlugin['introduced']) && $params['showtopinfo'] !== 'n' ? '' . tr('Introduced in %0', 'Tiki ' . $infoPlugin['introduced']) . '.' : ''; $link .= '[' . $sourcecode . '|'.tra('Go to the source code').']'; $required = ! empty($filteredparams) ? array_column($filteredparams, 'required') : false; $bold = in_array(true, $required) > 0 ? ' ' . tr( 'Required parameters are in%0 %1bold%2', '', '', '.' ) : ''; $sOutput = $title . $bold . '
' . $link . '
' . $pluginprefs . '
' . '' . $header . $rows . '
' . "\n"; return $sOutput; } } function processDescription($sDescription) { $sDescription = str_replace(',', ', ', $sDescription); $sDescription = str_replace('|', '| ', $sDescription); $sDescription = strip_tags(wordwrap($sDescription, 35)); return $sDescription; } } function wikiplugin_pluginmanager_info() { return [ 'name' => tra('Plugin Manager'), 'documentation' => 'PluginPluginManager', 'description' => tra('List wiki plugin or module information for the site'), 'prefs' => [ 'wikiplugin_pluginmanager' ], 'introduced' => 1, 'iconname' => 'plugin', 'params' => [ 'info' => [ 'required' => false, 'name' => tra('Information'), 'description' => tr('Determines what information is shown. Values separated with %0|%1. Ignored when %0singletitle%1 is set to %0top%1 or %0none%1.', '', ''), 'filter' => 'text', 'accepted' => tra('One or more of: description | parameters | paraminfo'), 'default' => 'description | parameters | paraminfo ', 'since' => '1', 'options' => [ ['text' => '', 'value' => ''], ['text' => tra('Description'), 'value' => 'description'], ['text' => tra('Description and Source Code'), 'value' => 'description|sourcecode'], ['text' => tra('Description and Parameters'), 'value' => 'description|parameters'], ['text' => tra('Description & Parameter Info'), 'value' => 'description|paraminfo'], ['text' => tra('Parameters & Parameter Info'), 'value' => 'parameters|paraminfo'], ['text' => tra('All'), 'value' => 'description|parameters|paraminfo'] ] ], 'plugin' => [ 'required' => false, 'name' => tra('Plugin'), 'description' => tr('Name of a plugin (e.g., backlinks), or list separated by %0|%1, or range separated by %0-%1. Single plugin can be used with %0limit%1 parameter.', '', ''), 'filter' => 'text', 'default' => '', 'since' => '5.0', ], 'module' => [ 'required' => false, 'name' => tra('Module'), 'description' => tr('Name of a module (e.g., calendar_new), or list separated by %0|%1, or range separated by %0-%1. Single module can be used with %0limit%1 parameter.', '', ''), 'filter' => 'text', 'default' => '', 'since' => '6.1', ], 'singletitle' => [ 'required' => false, 'name' => tra('Single Title'), 'description' => tr('Set placement of plugin name and description when displaying information for only one plugin'), 'filter' => 'alpha', 'default' => 'none', 'since' => '5.0', 'options' => [ ['text' => tra(''), 'value' => ''], ['text' => tra('Top'), 'value' => 'top'], ['text' => tra('Table'), 'value' => 'table'], ], ], 'titletag' => [ 'required' => false, 'name' => tra('Title Heading'), 'description' => tr('Sets the heading size for the title, e.g., %0h2%1.', '', ''), 'filter' => 'alnum', 'default' => 'h3', 'since' => '5.0', 'advanced' => true, ], 'start' => [ 'required' => false, 'name' => tra('Start'), 'description' => tra('Start with this plugin record number (must be an integer 1 or greater).'), 'filter' => 'digits', 'default' => '', 'since' => '5.0', ], 'limit' => [ 'required' => false, 'name' => tra('Limit'), 'description' => tra('Number of plugins to show. Can be used either with start or plugin as the starting point. Must be an integer 1 or greater.'), 'filter' => 'digits', 'default' => '', 'since' => '5.0', ], 'paramtype' => [ 'required' => false, 'name' => tra('Parameter Type'), 'description' => tr('Only list parameters with this %0doctype%1 setting. Set to %0none%1 to show only parameters without a type setting and the body instructions.', '', ''), 'since' => '15.0', 'filter' => 'alpha', 'default' => '', 'advanced' => true, ], 'showparamtype' => [ 'required' => false, 'name' => tra('Show Parameter Type'), 'description' => tr('Show the parameter %0doctype%1 value.', '', ''), 'since' => '15.0', 'filter' => 'alpha', 'default' => '', 'advanced' => true, 'options' => [ ['text' => '', 'value' => ''], ['text' => tra('Yes'), 'value' => 'y'], ['text' => tra('No'), 'value' => 'n'] ] ], 'showtopinfo' => [ 'required' => false, 'name' => tra('Show Top Info'), 'description' => tr('Show information above the table regarding preferences required and the first version when the plugin became available. Shown by default.'), 'since' => '15.0', 'filter' => 'alpha', 'default' => '', 'advanced' => true, 'options' => [ ['text' => '', 'value' => ''], ['text' => tra('Yes'), 'value' => 'y'], ['text' => tra('No'), 'value' => 'n'] ] ], ], ]; } function get_plugin_info($sPluginFile) { preg_match("/wikiplugin_(.*)\.php/i", $sPluginFile, $match); global $sPlugin, $numparams; $sPlugin = $match[1]; include_once(PLUGINS_DIR . '/' . $sPluginFile); global $tikilib; $parserlib = TikiLib::lib('parser'); $infoPlugin = $parserlib->plugin_info($sPlugin); $numparams = isset($infoPlugin['params']) ? count($infoPlugin['params']) : 0; return $infoPlugin; } function get_module_params($sPluginFile) { preg_match("/mod-func-(.*)\.php/i", $sPluginFile, $match); global $sPlugin, $numparams; $sPlugin = $match[1]; include_once('modules/' . $sPluginFile); $info_func = "module_{$sPlugin}_info"; $infoPlugin = $info_func(); $numparams = isset($infoPlugin['params']) ? count($infoPlugin['params']) : 0; return $infoPlugin; } function wikiplugin_pluginmanager($data, $params) { $plugin = new WikiPluginPluginManager(); return $plugin->run($data, $params); }