/** * Reload the locale system. */ public function refresh() { $LocalName = $this->current(); $ApplicationWhiteList = Gdn::applicationManager()->enabledApplicationFolders(); $PluginWhiteList = Gdn::pluginManager()->enabledPluginFolders(); $ForceRemapping = true; $this->set($LocalName, $ApplicationWhiteList, $PluginWhiteList, $ForceRemapping); }
/** * Creates and renders an instance of a module. * * @param string $Module * @param string $AppFolder * @param string $DeliveryType * @throws NotFoundException */ public function index($Module, $AppFolder = '', $DeliveryType = '') { if (!$DeliveryType) { $this->deliveryType(DELIVERY_TYPE_VIEW); } $ModuleClassExists = class_exists($Module); if ($ModuleClassExists) { // Make sure that the class implements Gdn_IModule $ReflectionClass = new ReflectionClass($Module); if ($ReflectionClass->implementsInterface("Gdn_IModule")) { // Check any incoming app folder against real application list. $appWhitelist = Gdn::applicationManager()->enabledApplicationFolders(); // Set the proper application folder on this controller so that things render properly. if ($AppFolder && in_array($AppFolder, $appWhitelist)) { $this->ApplicationFolder = $AppFolder; } else { $Filename = str_replace('\\', '/', substr($ReflectionClass->getFileName(), strlen(PATH_ROOT))); // Figure our the application folder for the module. $Parts = explode('/', trim($Filename, '/')); if ($Parts[0] == 'applications' && in_array($Parts[1], $appWhitelist)) { $this->ApplicationFolder = $Parts[1]; } } $ModuleInstance = new $Module($this); $ModuleInstance->Visible = true; $WhiteList = array('Limit', 'Help'); foreach ($this->Request->get() as $Key => $Value) { if (in_array($Key, $WhiteList)) { // Set a sane max limit for this open-ended way of calling modules. if ($Key == 'Limit' && $Value > 200) { throw new Exception(t('Invalid limit.'), 400); } $ModuleInstance->{$Key} = $Value; } } $this->setData('_Module', $ModuleInstance); $this->render('Index', false, 'dashboard'); return; } } throw notFoundException(htmlspecialchars($Module)); }
/** * Attach mappings for vanilla extension folders. * * @param string $ExtensionType The type of extension to map. * This should be one of: CONTEXT_THEME, CONTEXT_PLUGIN, CONTEXT_APPLICATION. */ public static function attach($ExtensionType) { switch ($ExtensionType) { case self::CONTEXT_APPLICATION: if (Gdn::applicationManager() instanceof Gdn_ApplicationManager) { $EnabledApplications = Gdn::applicationManager()->enabledApplicationFolders(); foreach ($EnabledApplications as $EnabledApplication) { self::attachApplication($EnabledApplication); } } break; case self::CONTEXT_PLUGIN: if (Gdn::pluginManager() instanceof Gdn_PluginManager) { foreach (Gdn::pluginManager()->searchPaths() as $SearchPath => $SearchPathName) { if ($SearchPathName === true || $SearchPathName == 1) { $SearchPathName = md5($SearchPath); } // If we have already loaded the plugin manager, use its internal folder list if (Gdn::pluginManager()->started()) { $Folders = Gdn::pluginManager()->enabledPluginFolders($SearchPath); foreach ($Folders as $PluginFolder) { $FullPluginPath = combinePaths(array($SearchPath, $PluginFolder)); self::registerMap(self::MAP_LIBRARY, self::CONTEXT_PLUGIN, $FullPluginPath, array('SearchSubfolders' => true, 'Extension' => $SearchPathName, 'Structure' => Gdn_Autoloader_Map::STRUCTURE_SPLIT, 'SplitTopic' => strtolower($PluginFolder), 'PreWarm' => true)); } $PluginMap = self::getMap(self::MAP_LIBRARY, self::CONTEXT_PLUGIN); if ($PluginMap && !$PluginMap->mapIsOnDisk()) { Gdn::pluginManager()->forceAutoloaderIndex(); } } } } break; case self::CONTEXT_THEME: break; } }
/** * * * @param $PluginName * @param $Validation * @param bool $Setup * @param string $EnabledPluginValueIndex * @return bool * @throws Exception * @throws Gdn_UserException */ public function enablePlugin($PluginName, $Validation, $Setup = false, $EnabledPluginValueIndex = 'Folder') { // Check that the plugin is in AvailablePlugins... $PluginInfo = $this->getPluginInfo($PluginName); // Couldn't load the plugin info. if (!$PluginInfo) { return false; } // Check to see if the plugin is already enabled. if (array_key_exists($PluginName, $this->enabledPlugins())) { throw new Gdn_UserException(T('The plugin is already enabled.')); } $this->testPlugin($PluginName, $Validation, $Setup); if (is_object($Validation) && count($Validation->results()) > 0) { return false; } // Write enabled state to config SaveToConfig("EnabledPlugins.{$PluginName}", true); Logger::event('addon_enabled', LogLevel::NOTICE, 'The {addonName} plugin was enabled.', array('addonName' => $PluginName)); $this->EnabledPlugins[$PluginName] = true; $PluginClassName = GetValue('ClassName', $PluginInfo); $this->registerPlugin($PluginClassName); Gdn::locale()->set(Gdn::locale()->current(), Gdn::applicationManager()->enabledApplicationFolders(), $this->enabledPluginFolders(), true); $this->EventArguments['AddonName'] = $PluginName; $this->fireEvent('AddonEnabled'); return true; }
/** * The summary of all settings available. * * The menu items displayed here are collected from each application's * application controller and all plugin's definitions. * * @since 2.0.0 * @access public */ public function index() { $this->ApplicationFolder = 'dashboard'; $this->MasterView = 'setup'; // Fatal error if Garden has already been installed. $Installed = c('Garden.Installed'); if ($Installed) { throw new Gdn_UserException('Vanilla is installed!', 409); } if (!$this->_checkPrerequisites()) { $this->View = 'prerequisites'; } else { $this->View = 'configure'; // Make sure the user has copied the htaccess file over. if (!file_exists(PATH_ROOT . '/.htaccess')) { $this->setData('NoHtaccess', true); if ($this->Form->isPostBack()) { $htaccessAction = $this->Form->getFormValue('HtaccessAction'); switch ($htaccessAction) { case 'skip': break; case 'dist': $htaccessCopied = copy(PATH_ROOT . '/.htaccess.dist', PATH_ROOT . '/.htaccess'); if ($htaccessCopied === false) { $this->Form->addError(t('Unable to copy .htaccess.dist to .htaccess.', 'Unable to copy .htaccess.dist to .htaccess. You may need to manually copy this file.')); } break; default: $this->Form->addError(t('You are missing Vanilla\'s .htaccess file.', 'You are missing an <b>.htaccess</b> file. This file can be automatically created from Vanilla\'s <b>.htaccess.dist</b>. However, it may not have been copied if you are using FTP to upload your files because this file is hidden. Make sure you\'ve copied the <b>.htaccess.dist</b> file before continuing.')); } } } $ApplicationManager = Gdn::applicationManager(); // Need to go through all of the setups for each application. Garden, if ($this->configure() && $this->Form->isPostBack()) { // Get list of applications to enable during install // Override by creating the config and adding this setting before install begins $AppNames = c('Garden.Install.Applications', array('Conversations', 'Vanilla')); try { // Step through the available applications, enabling each of them. foreach ($AppNames as $AppName) { $Validation = new Gdn_Validation(); $ApplicationManager->RegisterPermissions($AppName, $Validation); $ApplicationManager->EnableApplication($AppName, $Validation); } Gdn::pluginManager()->start(true); } catch (Exception $ex) { $this->Form->addError($ex); } if ($this->Form->errorCount() == 0) { // Save a variable so that the application knows it has been installed. // Now that the application is installed, select a more user friendly error page. $Config = array('Garden.Installed' => true); saveToConfig($Config); $this->setData('Installed', true); $this->fireAs('UpdateModel')->fireEvent('AfterStructure'); $this->fireEvent('Installed'); // Go to the dashboard. if ($this->deliveryType() === DELIVERY_TYPE_ALL) { redirect('/settings/gettingstarted'); } } elseif ($this->deliveryType() === DELIVERY_TYPE_DATA) { $maxCode = 0; $messages = array(); foreach ($this->Form->errors() as $row) { list($code, $message) = $row; $maxCode = max($maxCode, $code); $messages[] = $message; } throw new Gdn_UserException(implode(' ', $messages), $maxCode); } } } $this->render(); }
/** * * * @param null $AddonCode * @param bool $Explicit * @param bool $Drop * @throws Exception */ public function runStructure($AddonCode = null, $Explicit = false, $Drop = false) { // Get the structure files for all of the enabled applications. $ApplicationManager = new Gdn_ApplicationManager(); $Apps = $ApplicationManager->enabledApplications(); $AppNames = consolidateArrayValuesByKey($Apps, 'Folder'); $Paths = array(); foreach ($Apps as $Key => $AppInfo) { $Path = PATH_APPLICATIONS . "/{$AppInfo['Folder']}/settings/structure.php"; if (file_exists($Path)) { $Paths[] = $Path; } Gdn::applicationManager()->registerPermissions($Key, $this->Validation); } // Execute the structures. $Database = Gdn::database(); $SQL = Gdn::sql(); $Structure = Gdn::structure(); foreach ($Paths as $Path) { include $Path; } // Execute the structures for all of the plugins. $PluginManager = Gdn::pluginManager(); $Registered = $PluginManager->registeredPlugins(); foreach ($Registered as $ClassName => $Enabled) { if (!$Enabled) { continue; } try { $Plugin = $PluginManager->getPluginInstance($ClassName, Gdn_PluginManager::ACCESS_CLASSNAME); if (method_exists($Plugin, 'Structure')) { trace("{$ClassName}->Structure()"); $Plugin->structure(); } } catch (Exception $Ex) { // Do nothing, plugin wouldn't load/structure. if (Debug()) { throw $Ex; } } } $this->fireEvent('AfterStructure'); }
/** * Generate an e-tag for the application from the versions of all of its enabled applications/plugins. * * @return string etag **/ public static function eTag() { $data = []; $data['vanilla-core-' . APPLICATION_VERSION] = true; $plugins = Gdn::pluginManager()->enabledPlugins(); foreach ($plugins as $info) { $data[strtolower("{$info['Index']}-plugin-{$info['Version']}")] = true; } $applications = Gdn::applicationManager()->enabledApplications(); foreach ($applications as $info) { $data[strtolower("{$info['Index']}-app-{$info['Version']}")] = true; } // Add the desktop theme version. $info = Gdn::themeManager()->getThemeInfo(Gdn::themeManager()->desktopTheme()); if (!empty($info)) { $version = val('Version', $info, 'v0'); $data[strtolower("{$info['Index']}-theme-{$version}")] = true; if (Gdn::controller()->Theme && Gdn::controller()->ThemeOptions) { $filenames = valr('Styles.Value', Gdn::controller()->ThemeOptions); $data[$filenames] = true; } } // Add the mobile theme version. $info = Gdn::themeManager()->getThemeInfo(Gdn::themeManager()->mobileTheme()); if (!empty($info)) { $version = val('Version', $info, 'v0'); $data[strtolower("{$info['Index']}-theme-{$version}")] = true; } Gdn::pluginManager()->EventArguments['ETagData'] =& $data; $suffix = ''; Gdn::pluginManager()->EventArguments['Suffix'] =& $suffix; Gdn::pluginManager()->fireAs('AssetModel')->fireEvent('GenerateETag'); unset(Gdn::pluginManager()->EventArguments['ETagData']); ksort($data); $result = substr(md5(implode(',', array_keys($data))), 0, 8) . $suffix; return $result; }
/** * Returns a complete list of all enabled applications & plugins. This list * can act as a namespace list for permissions. * * @return array */ public function getAllowedPermissionNamespaces() { $ApplicationManager = Gdn::applicationManager(); $EnabledApplications = $ApplicationManager->EnabledApplications(); $PluginNamespaces = array(); foreach (Gdn::pluginManager()->EnabledPlugins() as $Plugin) { if (!array_key_exists('RegisterPermissions', $Plugin) || !is_array($Plugin['RegisterPermissions'])) { continue; } foreach ($Plugin['RegisterPermissions'] as $Index => $PermissionName) { if (is_string($Index)) { $PermissionName = $Index; } $Namespace = substr($PermissionName, 0, strrpos($PermissionName, '.')); $PluginNamespaces[$Namespace] = true; } } $Result = array_merge(array_keys($EnabledApplications), array_keys($PluginNamespaces)); if (in_array('Dashboard', $Result)) { $Result[] = 'Garden'; } return $Result; }
/** * Returns the name of the enabled application based on $ApplicationFolder. * * @param string The application folder related to the application name you want to return. */ public function enabledApplication($ApplicationFolder = '') { if ($ApplicationFolder == '') { $ApplicationFolder = $this->_ApplicationFolder; } if (strpos($ApplicationFolder, 'plugins/') === 0) { $Plugin = StringBeginsWith($ApplicationFolder, 'plugins/', false, true); if (array_key_exists($Plugin, Gdn::pluginManager()->availablePlugins())) { return $Plugin; } return false; } else { foreach (Gdn::applicationManager()->availableApplications() as $ApplicationName => $ApplicationInfo) { if (val('Folder', $ApplicationInfo, false) === $ApplicationFolder) { $EnabledApplication = $ApplicationName; $this->EventArguments['EnabledApplication'] = $EnabledApplication; $this->fireEvent('AfterEnabledApplication'); return $EnabledApplication; } } } return false; }
unset($Gdn_Path); unset($Hooks_Path); // Themes startup Gdn::themeManager()->start(); Gdn_Autoloader::attach(Gdn_Autoloader::CONTEXT_THEME); // Plugins startup Gdn::pluginManager()->start(); Gdn_Autoloader::attach(Gdn_Autoloader::CONTEXT_PLUGIN); /** * Locales * * Install any custom locales provided by applications and plugins, and set up * the locale management system. */ // Load the Garden locale system $Gdn_Locale = new Gdn_Locale(c('Garden.Locale', 'en'), Gdn::applicationManager()->enabledApplicationFolders(), Gdn::pluginManager()->enabledPluginFolders()); Gdn::factoryInstall(Gdn::AliasLocale, 'Gdn_Locale', null, Gdn::FactorySingleton, $Gdn_Locale); unset($Gdn_Locale); require_once PATH_LIBRARY_CORE . '/functions.validation.php'; // Start Authenticators Gdn::authenticator()->startAuthenticator(); /** * Bootstrap After * * After the bootstrap has finished loading, this hook allows developers a last * chance to customize Garden's runtime environment before the actual request * is handled. */ if (file_exists(PATH_ROOT . '/conf/bootstrap.after.php')) { require_once PATH_ROOT . '/conf/bootstrap.after.php'; }
public function enableApplication($addonName, $filter) { if (!Gdn::request()->isAuthenticatedPostBack(true)) { throw new Exception('Requires POST', 405); } $this->permission('Garden.Settings.Manage'); $applicationManager = Gdn::applicationManager(); $action = 'none'; if ($filter == 'disabled') { $action = 'SlideUp'; } $addon = Gdn::addonManager()->lookupAddon($addonName); try { $applicationManager->checkRequirements($addonName); $this->informMessage(sprintf(t('%s Enabled.'), val('name', $addon->getInfo(), t('Application')))); } catch (Exception $e) { $this->Form->addError(strip_tags($e->getMessage())); } if ($this->Form->errorCount() == 0) { $validation = new Gdn_Validation(); $applicationManager->registerPermissions($addonName, $validation); $applicationManager->enableApplication($addonName, $validation); $this->Form->setValidationResults($validation->results()); } $this->handleAddonToggle($addonName, $addon->getInfo(), 'applications', true, $filter, $action); }
/** * Resolve relative static resources into full paths * * This method is used to translate CSS, Js and Template relative file lists * into absolute paths. * * Element values should conform to the following format: * * [] => array( * 'FileName' => // filename (relative, absolute, or URL) * 'AppFolder' => // optional application folder to target (default controller app) * ); * * @param array $resourceList * @param string $stub * @param array $options Optional. List of check options. * - 'GlobalLibrary' // Check $Stub/library in global section * - 'StripRoot' // Strip PATH_ROOT from final results * - 'CDNS' // List of external CDN replacements * @param array $checkLocations Optional. List of locations to check. * - 'themes' * - 'plugins' * - 'applications' * - 'global' */ public static function resolveStaticResources($resourceList, $stub, $options = null, $checkLocations = null) { // All locations by default if (!is_array($checkLocations)) { $checkLocations = array('themes', 'plugins', 'applications', 'global'); } // Default options $defaultOptions = array('GlobalLibrary' => true, 'StripRoot' => true, 'CDNS' => array(), 'AutoVersion' => true); if (!is_array($options)) { $options = array(); } $options = array_merge($defaultOptions, $options); // Parse options $checkGlobalLibrary = val('GlobalLibrary', $options); $stripRoot = val('StripRoot', $options); $autoDetectVersion = val('AutoVersion', $options); // See if we're allowing any CDN replacements $CDNs = val('CDNS', $options, array()); // Pre-get controller info $controllerAppFolder = false; $controllerTheme = false; if (Gdn::Controller() instanceof Gdn_Controller) { $controllerAppFolder = Gdn::controller()->ApplicationFolder; $controllerTheme = Gdn::controller()->Theme; } $fileList = array(); foreach ($resourceList as $index => $resourceInfo) { $resourceFile = $resourceInfo['FileName']; $resourceFolder = val('AppFolder', $resourceInfo); $resourceOptions = (array) val('Options', $resourceInfo, false); if ($resourceFile === false) { if (!$resourceOptions) { continue; } $rawCSS = val('Css', $resourceOptions, false); if (!$rawCSS) { continue; } $cssHash = md5($rawCSS); $fileList[$resourceFolder] = array('options' => $resourceOptions); continue; } $skipFileCheck = false; // Resolve CDN resources if (array_key_exists($resourceFile, $CDNs)) { $resourceFile = $CDNs[$resourceFile]; } if (strpos($resourceFile, '//') !== false) { // This is a link to an external file. $skipFileCheck = true; $testPaths = array($resourceFile); } elseif (strpos($resourceFile, '/') === 0) { // A direct path to the file was given. $testPaths = array(paths(PATH_ROOT, $resourceFile)); } elseif (strpos($resourceFile, '~') === 0) { $skipFileCheck = true; $resourceFile = substr($resourceFile, 1); $testPaths = array(paths(PATH_ROOT, $resourceFile)); } else { // Relative path $appFolder = val('AppFolder', $resourceInfo, false); if ($appFolder == '') { $appFolder = $controllerAppFolder; } if ($appFolder == 'false') { $appFolder = false; } // Resources can come from: // - a theme // - an application // - a plugin // - global garden resource-specific folder // - global garden resource-specific library folder $testPaths = array(); // Theme if (in_array('themes', $checkLocations) && $controllerTheme) { // Application-specific theme override if ($appFolder) { $testPaths[] = paths(PATH_THEMES, $controllerTheme, $appFolder, $stub, $resourceFile); } // Garden-wide theme override $testPaths[] = paths(PATH_THEMES, $controllerTheme, $stub, $resourceFile); } // Application or plugin $isPluginFolder = stringBeginsWith(trim($appFolder, '/'), 'plugins/', true, false); if ($isPluginFolder) { $pluginFolder = stringBeginsWith(trim($appFolder, '/'), 'plugins/', true, true); } if (in_array('plugins', $checkLocations) && $isPluginFolder) { // Plugin $testPaths[] = paths(PATH_PLUGINS, $pluginFolder, $stub, $resourceFile); $testPaths[] = paths(PATH_PLUGINS, $pluginFolder, $resourceFile); } if (in_array('applications', $checkLocations) && !$isPluginFolder) { // Application if ($appFolder) { $testPaths[] = paths(PATH_APPLICATIONS, $appFolder, $stub, $resourceFile); } // Dashboard app is added by default if ($appFolder != 'dashboard') { $testPaths[] = paths(PATH_APPLICATIONS, 'dashboard', $stub, $resourceFile); } } if (in_array('global', $checkLocations)) { // Global folder. eg. root/js/ $testPaths[] = paths(PATH_ROOT, $stub, $resourceFile); if ($checkGlobalLibrary) { // Global library folder. eg. root/js/library/ $testPaths[] = paths(PATH_ROOT, $stub, 'library', $resourceFile); } } } // Find the first file that matches the path. $resourcePath = false; if (!$skipFileCheck) { foreach ($testPaths as $glob) { $paths = safeGlob($glob); if (is_array($paths) && count($paths) > 0) { $resourcePath = $paths[0]; break; } } // Get version $version = val('Version', $resourceInfo, false); // If a path was matched, make sure it has a version if ($resourcePath && !$version && $autoDetectVersion) { // Theme file if (!$version && preg_match('`themes/([^/]+)/`i', $resourcePath, $matches)) { $themeName = $matches[1]; $themeInfo = Gdn::themeManager()->getThemeInfo($themeName); $version = val('Version', $themeInfo); $versionSource = "theme {$themeName}"; } // Plugin file if (!$version && preg_match('`plugins/([^/]+)/`i', $resourcePath, $matches)) { $pluginName = $matches[1]; $pluginInfo = Gdn::pluginManager()->getPluginInfo($pluginName, Gdn_PluginManager::ACCESS_PLUGINNAME); $version = val('Version', $pluginInfo); $versionSource = "plugin {$pluginName}"; } // Application file if (!$version && preg_match('`applications/([^/]+)/`i', $resourcePath, $matches)) { $applicationName = $matches[1]; $applicationInfo = Gdn::applicationManager()->getApplicationInfo($applicationName); $version = val('Version', $applicationInfo); $versionSource = "app {$applicationName}"; } } } else { $version = null; } // Global file if (!$version) { $version = APPLICATION_VERSION; } // If a path was succesfully matched if ($resourcePath !== false || $skipFileCheck) { // We enact SkipFileCheck for virtual paths, targeting controllers // perhaps, or full URLs from the CDN resolver. if ($skipFileCheck) { $resourcePath = array_pop($testPaths); } // Strip PATH_ROOT from absolute path $resourceResolved = $resourcePath; if ($stripRoot) { $resourceResolved = str_replace(array(PATH_ROOT, DS), array('', '/'), $resourcePath); } // Bring options into response structure $resource = array('path' => $resourcePath); $resourceOptions = (array) val('Options', $resourceInfo, array()); touchValue('version', $resource, $version); if ($resourceOptions) { touchValue('options', $resource, $resourceOptions); } $fileList[$resourceResolved] = $resource; } } return $fileList; }
/** * Display flood control options. * * @since 2.0.0 * @access public */ public function floodControl() { // Check permission $this->permission('Garden.Settings.Manage'); // Display options $this->title(t('Flood Control')); $this->addSideMenu('vanilla/settings/floodcontrol'); // Check to see if Conversation is enabled. $IsConversationsEnabled = Gdn::applicationManager()->checkApplication('Conversations'); $ConfigurationFields = array('Vanilla.Discussion.SpamCount', 'Vanilla.Discussion.SpamTime', 'Vanilla.Discussion.SpamLock', 'Vanilla.Comment.SpamCount', 'Vanilla.Comment.SpamTime', 'Vanilla.Comment.SpamLock'); if ($IsConversationsEnabled) { $ConfigurationFields = array_merge($ConfigurationFields, array('Conversations.Conversation.SpamCount', 'Conversations.Conversation.SpamTime', 'Conversations.Conversation.SpamLock', 'Conversations.ConversationMessage.SpamCount', 'Conversations.ConversationMessage.SpamTime', 'Conversations.ConversationMessage.SpamLock')); } // Load up config options we'll be setting $Validation = new Gdn_Validation(); $ConfigurationModel = new Gdn_ConfigurationModel($Validation); $ConfigurationModel->setField($ConfigurationFields); // Set the model on the form. $this->Form->setModel($ConfigurationModel); // If seeing the form for the first time... if ($this->Form->authenticatedPostBack() === false) { // Apply the config settings to the form. $this->Form->setData($ConfigurationModel->Data); } else { // Define some validation rules for the fields being saved $ConfigurationModel->Validation->applyRule('Vanilla.Discussion.SpamCount', 'Required'); $ConfigurationModel->Validation->applyRule('Vanilla.Discussion.SpamCount', 'Integer'); $ConfigurationModel->Validation->applyRule('Vanilla.Discussion.SpamTime', 'Required'); $ConfigurationModel->Validation->applyRule('Vanilla.Discussion.SpamTime', 'Integer'); $ConfigurationModel->Validation->applyRule('Vanilla.Discussion.SpamLock', 'Required'); $ConfigurationModel->Validation->applyRule('Vanilla.Discussion.SpamLock', 'Integer'); $ConfigurationModel->Validation->applyRule('Vanilla.Comment.SpamCount', 'Required'); $ConfigurationModel->Validation->applyRule('Vanilla.Comment.SpamCount', 'Integer'); $ConfigurationModel->Validation->applyRule('Vanilla.Comment.SpamTime', 'Required'); $ConfigurationModel->Validation->applyRule('Vanilla.Comment.SpamTime', 'Integer'); $ConfigurationModel->Validation->applyRule('Vanilla.Comment.SpamLock', 'Required'); $ConfigurationModel->Validation->applyRule('Vanilla.Comment.SpamLock', 'Integer'); if ($IsConversationsEnabled) { $ConfigurationModel->Validation->applyRule('Conversations.Conversation.SpamCount', 'Required'); $ConfigurationModel->Validation->applyRule('Conversations.Conversation.SpamCount', 'Integer'); $ConfigurationModel->Validation->applyRule('Conversations.Conversation.SpamTime', 'Required'); $ConfigurationModel->Validation->applyRule('Conversations.Conversation.SpamTime', 'Integer'); $ConfigurationModel->Validation->applyRule('Conversations.Conversation.SpamLock', 'Required'); $ConfigurationModel->Validation->applyRule('Conversations.Conversation.SpamLock', 'Integer'); $ConfigurationModel->Validation->applyRule('Conversations.ConversationMessage.SpamCount', 'Required'); $ConfigurationModel->Validation->applyRule('Conversations.ConversationMessage.SpamCount', 'Integer'); $ConfigurationModel->Validation->applyRule('Conversations.ConversationMessage.SpamTime', 'Required'); $ConfigurationModel->Validation->applyRule('Conversations.ConversationMessage.SpamTime', 'Integer'); $ConfigurationModel->Validation->applyRule('Conversations.ConversationMessage.SpamLock', 'Required'); $ConfigurationModel->Validation->applyRule('Conversations.ConversationMessage.SpamLock', 'Integer'); } if ($this->Form->save() !== false) { $this->informMessage(t("Your changes have been saved.")); } } // Render default view $this->render(); }
/** * Get a version string for a given asset. * * @param string $destination The path of the asset. * @param string|null $version A known version for the asset or **null** to grab it from the addon's info array. * @return string Returns a version string. */ function assetVersion($destination, $version = null) { static $gracePeriod = 90; // Figure out which version to put after the asset. if (is_null($version)) { $version = APPLICATION_VERSION; if (preg_match('`^/([^/]+)/([^/]+)/`', $destination, $matches)) { $type = $matches[1]; $key = $matches[2]; static $themeVersion = null; switch ($type) { case 'plugins': $pluginInfo = Gdn::pluginManager()->getPluginInfo($key); $version = val('Version', $pluginInfo, $version); break; case 'applications': $applicationInfo = Gdn::applicationManager()->getApplicationInfo(ucfirst($key)); $version = val('Version', $applicationInfo, $version); break; case 'themes': if ($themeVersion === null) { $themeInfo = Gdn::themeManager()->getThemeInfo(Theme()); if ($themeInfo !== false) { $themeVersion = val('Version', $themeInfo, $version); } else { $themeVersion = $version; } } $version = $themeVersion; break; } } } // Add a timestamp component to the version if available. if ($timestamp = c('Garden.Deployed')) { $graced = $timestamp + $gracePeriod; if (time() >= $graced) { $timestamp = $graced; } $version .= '.' . dechex($timestamp); } return $version; }
/** * Takes the path to an asset (image, js file, css file, etc) and prepends the web root. * * @param string $Destination The path to the asset. * @param boolean $WithDomain Whether or not to include the domain. * @param boolean $AddVersion Whether or not to add a cache-busting querystring parameter to the URL. * @param string $Version Forced version, skips auto-lookup. * @return string Returns the URL to the asset. */ function asset($Destination = '', $WithDomain = false, $AddVersion = false, $Version = null) { $Destination = str_replace('\\', '/', $Destination); if (IsUrl($Destination)) { $Result = $Destination; } else { $Result = Gdn::request()->urlDomain($WithDomain) . Gdn::request()->assetRoot() . '/' . ltrim($Destination, '/'); } if ($AddVersion) { if (strpos($Result, '?') === false) { $Result .= '?'; } else { $Result .= '&'; } // Figure out which version to put after the asset. if (is_null($Version)) { $Version = APPLICATION_VERSION; if (preg_match('`^/([^/]+)/([^/]+)/`', $Destination, $Matches)) { $Type = $Matches[1]; $Key = $Matches[2]; static $ThemeVersion = null; switch ($Type) { case 'plugins': $PluginInfo = Gdn::pluginManager()->getPluginInfo($Key); $Version = val('Version', $PluginInfo, $Version); break; case 'applications': $AppInfo = Gdn::applicationManager()->getApplicationInfo(ucfirst($Key)); $Version = val('Version', $AppInfo, $Version); break; case 'themes': if ($ThemeVersion === null) { $ThemeInfo = Gdn::themeManager()->getThemeInfo(Theme()); if ($ThemeInfo !== false) { $ThemeVersion = val('Version', $ThemeInfo, $Version); } else { $ThemeVersion = $Version; } } $Version = $ThemeVersion; break; } } } $Result .= 'v=' . urlencode($Version); } return $Result; }
/** * * * @param $Path * @param bool $Text * @param null $Format * @param array $Options * @return mixed|null|string */ public static function link($Path, $Text = false, $Format = null, $Options = array()) { $Session = Gdn::session(); $Class = val('class', $Options, ''); $WithDomain = val('WithDomain', $Options); $Target = val('Target', $Options, ''); if ($Target == 'current') { $Target = trim(url('', true), '/ '); } if (is_null($Format)) { $Format = '<a href="%url" class="%class">%text</a>'; } switch ($Path) { case 'activity': touchValue('Permissions', $Options, 'Garden.Activity.View'); break; case 'category': $Breadcrumbs = Gdn::controller()->data('Breadcrumbs'); if (is_array($Breadcrumbs) && count($Breadcrumbs) > 0) { $Last = array_pop($Breadcrumbs); $Path = val('Url', $Last); $DefaultText = val('Name', $Last, T('Back')); } else { $Path = '/'; $DefaultText = c('Garden.Title', T('Back')); } if (!$Text) { $Text = $DefaultText; } break; case 'dashboard': $Path = 'dashboard/settings'; touchValue('Permissions', $Options, array('Garden.Settings.Manage', 'Garden.Settings.View')); if (!$Text) { $Text = t('Dashboard'); } break; case 'home': $Path = '/'; if (!$Text) { $Text = t('Home'); } break; case 'inbox': $Path = 'messages/inbox'; touchValue('Permissions', $Options, 'Garden.SignIn.Allow'); if (!$Text) { $Text = t('Inbox'); } if ($Session->isValid() && $Session->User->CountUnreadConversations) { $Class = trim($Class . ' HasCount'); $Text .= ' <span class="Alert">' . $Session->User->CountUnreadConversations . '</span>'; } if (!$Session->isValid() || !Gdn::applicationManager()->checkApplication('Conversations')) { $Text = false; } break; case 'forumroot': $Route = Gdn::router()->getDestination('DefaultForumRoot'); if (is_null($Route)) { $Path = '/'; } else { $Path = combinePaths(array('/', $Route)); } break; case 'profile': touchValue('Permissions', $Options, 'Garden.SignIn.Allow'); if (!$Text && $Session->isValid()) { $Text = $Session->User->Name; } if ($Session->isValid() && $Session->User->CountNotifications) { $Class = trim($Class . ' HasCount'); $Text .= ' <span class="Alert">' . $Session->User->CountNotifications . '</span>'; } break; case 'user': $Path = 'profile'; touchValue('Permissions', $Options, 'Garden.SignIn.Allow'); if (!$Text && $Session->isValid()) { $Text = $Session->User->Name; } break; case 'photo': $Path = 'profile'; TouchValue('Permissions', $Options, 'Garden.SignIn.Allow'); if (!$Text && $Session->isValid()) { $IsFullPath = strtolower(substr($Session->User->Photo, 0, 7)) == 'http://' || strtolower(substr($Session->User->Photo, 0, 8)) == 'https://'; $PhotoUrl = $IsFullPath ? $Session->User->Photo : Gdn_Upload::url(changeBasename($Session->User->Photo, 'n%s')); $Text = img($PhotoUrl, array('alt' => $Session->User->Name)); } break; case 'drafts': TouchValue('Permissions', $Options, 'Garden.SignIn.Allow'); if (!$Text) { $Text = t('My Drafts'); } if ($Session->isValid() && $Session->User->CountDrafts) { $Class = trim($Class . ' HasCount'); $Text .= ' <span class="Alert">' . $Session->User->CountDrafts . '</span>'; } break; case 'discussions/bookmarked': TouchValue('Permissions', $Options, 'Garden.SignIn.Allow'); if (!$Text) { $Text = t('My Bookmarks'); } if ($Session->isValid() && $Session->User->CountBookmarks) { $Class = trim($Class . ' HasCount'); $Text .= ' <span class="Count">' . $Session->User->CountBookmarks . '</span>'; } break; case 'discussions/mine': TouchValue('Permissions', $Options, 'Garden.SignIn.Allow'); if (!$Text) { $Text = t('My Discussions'); } if ($Session->isValid() && $Session->User->CountDiscussions) { $Class = trim($Class . ' HasCount'); $Text .= ' <span class="Count">' . $Session->User->CountDiscussions . '</span>'; } break; case 'register': if (!$Text) { $Text = t('Register'); } $Path = registerUrl($Target); break; case 'signin': case 'signinout': // The destination is the signin/signout toggle link. if ($Session->isValid()) { if (!$Text) { $Text = T('Sign Out'); } $Path = signOutUrl($Target); $Class = concatSep(' ', $Class, 'SignOut'); } else { if (!$Text) { $Text = t('Sign In'); } $Path = signInUrl($Target); if (signInPopup() && strpos(Gdn::Request()->Url(), 'entry') === false) { $Class = concatSep(' ', $Class, 'SignInPopup'); } } break; } if ($Text == false && strpos($Format, '%text') !== false) { return ''; } if (val('Permissions', $Options) && !$Session->checkPermission($Options['Permissions'], false)) { return ''; } $Url = Gdn::request()->url($Path, $WithDomain); if ($TK = val('TK', $Options)) { if (in_array($TK, array(1, 'true'))) { $TK = 'TransientKey'; } $Url .= (strpos($Url, '?') === false ? '?' : '&') . $TK . '=' . urlencode(Gdn::session()->transientKey()); } if (strcasecmp(trim($Path, '/'), Gdn::request()->path()) == 0) { $Class = concatSep(' ', $Class, 'Selected'); } // Build the final result. $Result = $Format; $Result = str_replace('%url', $Url, $Result); $Result = str_replace('%text', $Text, $Result); $Result = str_replace('%class', $Class, $Result); return $Result; }
/** * Application Gateway. * * @copyright 2009-2016 Vanilla Forums Inc. * @license http://www.opensource.org/licenses/gpl-2.0.php GNU GPL v2 * @package Core * @since 2.0 */ if (PHP_VERSION_ID < 50400) { die("Vanilla requires PHP 5.4 or greater."); } define('APPLICATION', 'Vanilla'); define('APPLICATION_VERSION', '2.2.101.7'); // Report and track all errors. error_reporting(E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR); ini_set('display_errors', 0); ini_set('track_errors', 1); ob_start(); // Define the constants we need to get going. define('DS', '/'); define('PATH_ROOT', getcwd()); // Include the bootstrap to configure the framework. require_once PATH_ROOT . '/bootstrap.php'; // Create and configure the dispatcher. $dispatcher = Gdn::dispatcher(); $enabledApplications = Gdn::applicationManager()->enabledApplicationFolders(); $dispatcher->enabledApplicationFolders($enabledApplications); $dispatcher->passProperty('EnabledApplications', $enabledApplications); // Process the request. $dispatcher->start(); $dispatcher->dispatch();