function test_implode_with_and() { $this->assertEqual(implode_with_and(array()), ''); $this->assertEqual(implode_with_and(array('one')), 'one'); $this->assertEqual(implode_with_and(array('one', 'two')), 'one & two'); $this->assertEqual(implode_with_and(array('one', 'two', 'three')), 'one, two & three'); }
echo format_to_output(T_('Reset'), 'formvalue'); ?> " class="ResetButton"> <p class="note"> <?php $restrictNotes = array(); // Get list of recognized file types (others are not allowed to get uploaded) // dh> because FiletypeCache/DataObjectCache has no interface for getting a list, this dirty query seems less dirty to me. $allowed_extensions = $DB->get_col('SELECT ftyp_extensions FROM T_filetypes WHERE ftyp_allowed != 0'); $allowed_extensions = implode(' ', $allowed_extensions); // implode with space, ftyp_extensions can hold many, separated by space // into array: $allowed_extensions = preg_split('~\\s+~', $allowed_extensions, -1, PREG_SPLIT_NO_EMPTY); // readable: $allowed_extensions = implode_with_and($allowed_extensions); $restrictNotes[] = '<strong>' . T_('Allowed file extensions') . '</strong>: ' . $allowed_extensions; if ($Settings->get('upload_maxkb')) { // We want to restrict on file size: $restrictNotes[] = '<strong>' . T_('Maximum allowed file size') . '</strong>: ' . bytesreadable($Settings->get('upload_maxkb') * 1024); } echo implode('<br />', $restrictNotes) . '<br />'; ?> </p> </div> </td> </tr> </tbody> </table>
/** * Validate dependencies of a Plugin. * * @param Plugin * @param string Mode of check: either 'enable' or 'disable' * @return array The key 'note' holds an array of notes (recommendations), the key 'error' holds a list * of messages for dependency errors. */ function validate_dependencies(&$Plugin, $mode) { global $DB, $app_name; global $app_version; $msgs = array(); if ($mode == 'disable') { // Check the whole list of installed plugins if they depend on our Plugin or it's (set of) events. $required_by_plugin = array(); // a list of plugin classnames that require our poor Plugin foreach ($this->sorted_IDs as $validate_against_ID) { if ($validate_against_ID == $Plugin->ID) { // the plugin itself continue; } $against_Plugin =& $this->get_by_ID($validate_against_ID); if ($against_Plugin->status != 'enabled') { // The plugin is not enabled (this check is needed when checking deps with the Plugins_admin class) continue; } $deps = $against_Plugin->GetDependencies(); if (empty($deps['requires'])) { // has no dependencies continue; } if (!empty($deps['requires']['plugins'])) { foreach ($deps['requires']['plugins'] as $l_req_plugin) { if (!is_array($l_req_plugin)) { $l_req_plugin = array($l_req_plugin, 0); } if ($Plugin->classname == $l_req_plugin[0]) { // our plugin is required by this one, check if it is the only instance if ($this->count_regs($Plugin->classname) < 2) { $required_by_plugin[] = $against_Plugin->classname; } } } } if (!empty($deps['requires']['events_by_one'])) { foreach ($deps['requires']['events_by_one'] as $req_events) { // Get a list of plugins that provide all the events $provided_by = array_keys($this->get_list_by_all_events($req_events)); if (in_array($Plugin->ID, $provided_by) && count($provided_by) < 2) { // we're the only Plugin which provides this set of events $msgs['error'][] = sprintf(T_('The events %s are required by %s (ID %d).'), implode_with_and($req_events), $against_Plugin->classname, $against_Plugin->ID); } } } if (!empty($deps['requires']['events'])) { foreach ($deps['requires']['events'] as $req_event) { // Get a list of plugins that provide all the events $provided_by = array_keys($this->get_list_by_event($req_event)); if (in_array($Plugin->ID, $provided_by) && count($provided_by) < 2) { // we're the only Plugin which provides this event $msgs['error'][] = sprintf(T_('The event %s is required by %s (ID %d).'), $req_event, $against_Plugin->classname, $against_Plugin->ID); } } } // TODO: We might also handle the 'recommends' and add it to $msgs['note'] } if (!empty($required_by_plugin)) { // Prepend the message to the beginning, because it's the most restrictive (IMHO) $required_by_plugin = array_unique($required_by_plugin); if (!isset($msgs['error'])) { $msgs['error'] = array(); } array_unshift($msgs['error'], sprintf(T_('The plugin is required by the following plugins: %s.'), implode_with_and($required_by_plugin))); } return $msgs; } // mode 'enable': $deps = $Plugin->GetDependencies(); if (empty($deps)) { return array(); } foreach ($deps as $class => $dep_list) { if (!is_array($dep_list)) { // Invalid format: "throw" error (needs not translation) return array('error' => array('GetDependencies() did not return array of arrays. Please contact the plugin developer.')); } foreach ($dep_list as $type => $type_params) { switch ($type) { case 'events_by_one': foreach ($type_params as $sub_param) { if (!is_array($sub_param)) { // Invalid format: "throw" error (needs not translation) return array('error' => array('GetDependencies() did not return array of arrays for "events_by_one". Please contact the plugin developer.')); } if (!$this->are_events_available($sub_param, true)) { if ($class == 'recommends') { $msgs['note'][] = sprintf(T_('The plugin recommends a plugin which provides all of the following events: %s.'), implode_with_and($sub_param)); } else { $msgs['error'][] = sprintf(T_('The plugin requires a plugin which provides all of the following events: %s.'), implode_with_and($sub_param)); } } } break; case 'events': if (!$this->are_events_available($type_params, false)) { if ($class == 'recommends') { $msgs['note'][] = sprintf(T_('The plugin recommends plugins which provide the events: %s.'), implode_with_and($type_params)); } else { $msgs['error'][] = sprintf(T_('The plugin requires plugins which provide the events: %s.'), implode_with_and($type_params)); } } break; case 'plugins': if (!is_array($type_params)) { // Invalid format: "throw" error (needs not translation) return array('error' => array('GetDependencies() did not return array of arrays for "plugins". Please contact the plugin developer.')); } foreach ($type_params as $plugin_req) { if (!is_array($plugin_req)) { $plugin_req = array($plugin_req, '0'); } elseif (!isset($plugin_req[1])) { $plugin_req[1] = '0'; } if ($versions = $DB->get_col(' SELECT plug_version FROM T_plugins WHERE plug_classname = ' . $DB->quote($plugin_req[0]) . ' AND plug_status = "enabled"')) { // Clean up version from CVS Revision prefix/suffix: $versions[] = $plugin_req[1]; $clean_versions = preg_replace(array('~^(CVS\\s+)?\\$' . 'Revision:\\s*~i', '~\\s*\\$$~'), '', $versions); $clean_req_ver = array_pop($clean_versions); usort($clean_versions, 'version_compare'); $clean_oldest_enabled = array_shift($clean_versions); if (version_compare($clean_oldest_enabled, $clean_req_ver, '<')) { // at least one instance of the installed plugins is not the current version $msgs['error'][] = sprintf(T_('The plugin requires at least version %s of the plugin %s, but you have %s.'), $plugin_req[1], $plugin_req[0], $clean_oldest_enabled); } } else { // no plugin existing if ($class == 'recommends') { $recommends[] = $plugin_req[0]; } else { $requires[] = $plugin_req[0]; } } } if (!empty($requires)) { $msgs['error'][] = sprintf(T_('The plugin requires the plugins: %s.'), implode_with_and($requires)); } if (!empty($recommends)) { $msgs['note'][] = sprintf(T_('The plugin recommends to install the plugins: %s.'), implode_with_and($recommends)); } break; case 'app_min': // min b2evo version: if (!version_compare($app_version, $type_params, '>=')) { if ($class == 'recommends') { $msgs['note'][] = sprintf(T_('The plugin recommends version %s of %s (%s is installed). Think about upgrading.'), $type_params, $app_name, $app_version); } else { $msgs['error'][] = sprintf(T_('The plugin requires version %s of %s, but %s is installed.'), $type_params, $app_name, $app_version); } } break; case 'api_min': // obsolete since 1.9: continue; default: // Unknown depency type, throw an error: $msgs['error'][] = sprintf(T_('Unknown dependency type (%s). This probably means that the plugin is not compatible and you have to upgrade your %s installation.'), $type, $app_name); } } } return $msgs; }
/** * Return a string with upload restrictions ( allowed extensions, max file size ) */ function get_upload_restriction() { global $DB, $Settings, $current_User; $restrictNotes = array(); if (is_logged_in(false)) { $condition = $current_User->check_perm('files', 'all') ? '' : 'ftyp_allowed <> "admin"'; } else { $condition = 'ftyp_allowed = "any"'; } if (!empty($condition)) { $condition = ' WHERE ' . $condition; } // Get list of recognized file types (others are not allowed to get uploaded) // dh> because FiletypeCache/DataObjectCache has no interface for getting a list, this dirty query seems less dirty to me. $allowed_extensions = $DB->get_col('SELECT ftyp_extensions FROM T_filetypes' . $condition); $allowed_extensions = implode(' ', $allowed_extensions); // implode with space, ftyp_extensions can hold many, separated by space // into array: $allowed_extensions = preg_split('~\\s+~', $allowed_extensions, -1, PREG_SPLIT_NO_EMPTY); // readable: $allowed_extensions = implode_with_and($allowed_extensions); $restrictNotes[] = '<strong>' . T_('Allowed file extensions') . '</strong>: ' . $allowed_extensions; if ($Settings->get('upload_maxkb')) { // We want to restrict on file size: $restrictNotes[] = '<strong>' . T_('Maximum allowed file size') . '</strong>: ' . bytesreadable($Settings->get('upload_maxkb') * 1024); } return implode('<br />', $restrictNotes) . '<br />'; }