public function base_render_before($sender) { // Bail out if we're in the dashboard if (inSection('Dashboard')) { return; } // Fetch the currently enabled locale (en by default) $locale = Gdn::locale()->current(); $sender->setData('locale', $locale); $sender->Head->addCss('./themes/custom/design/extra.css'); }
/** * Returns Captcha HTML & adds translations to document head. * * @return string */ public function captcha() { // Google whitelist $Whitelist = array('ar', 'bg', 'ca', 'zh-CN', 'zh-TW', 'hr', 'cs', 'da', 'nl', 'en-GB', 'en', 'fil', 'fi', 'fr', 'fr-CA', 'de', 'de-AT', 'de-CH', 'el', 'iw', 'hi', 'hu', 'id', 'it', 'ja', 'ko', 'lv', 'lt', 'no', 'fa', 'pl', 'pt', 'pt-BR', 'pt-PT', 'ro', 'ru', 'sr', 'sk', 'sl', 'es', 'es-419', 'sv', 'th', 'tr', 'uk', 'vi'); // reCAPTCHA Options $Options = array('custom_translations' => array('instructions_visual' => t("Type the text:"), 'instructions_audio' => t("Type what you hear:"), 'play_again' => t("Play the sound again"), 'cant_hear_this' => t("Download the sounds as MP3"), 'visual_challenge' => t("Get a visual challenge"), 'audio_challenge' => t("Get an audio challenge"), 'refresh_btn' => t("Get a new challenge"), 'help_btn' => t("Help"), 'incorrect_try_again' => t("Incorrect. Try again."))); // Use our current locale against the whitelist. $Language = Gdn::locale()->language(); if (!in_array($Language, $Whitelist)) { $Language = in_array(Gdn::locale()->Locale, $Whitelist) ? Gdn::locale()->Locale : false; } if ($Language) { $Options['lang'] = $Language; } // Add custom translation strings as JSON. Gdn::controller()->Head->addString('<script type="text/javascript">var RecaptchaOptions = ' . json_encode($Options) . ';</script>'); require_once PATH_LIBRARY . '/vendors/recaptcha/functions.recaptchalib.php'; return recaptcha_get_html(c('Garden.Registration.CaptchaPublicKey'), null, Gdn::request()->scheme() == 'https'); }
/** * Allows the configuration of basic setup information in Garden. This * should not be functional after the application has been set up. * * @since 2.0.0 * @access public * @param string $RedirectUrl Where to send user afterward. */ private function configure($RedirectUrl = '') { // Create a model to save configuration settings $Validation = new Gdn_Validation(); $ConfigurationModel = new Gdn_ConfigurationModel($Validation); $ConfigurationModel->setField(array('Garden.Locale', 'Garden.Title', 'Garden.WebRoot', 'Garden.Cookie.Salt', 'Garden.Cookie.Domain', 'Database.Name', 'Database.Host', 'Database.User', 'Database.Password', 'Garden.Registration.ConfirmEmail', 'Garden.Email.SupportName')); // Set the models on the forms. $this->Form->setModel($ConfigurationModel); // If seeing the form for the first time... if (!$this->Form->isPostback()) { // Force the webroot using our best guesstimates $ConfigurationModel->Data['Database.Host'] = 'localhost'; $this->Form->setData($ConfigurationModel->Data); } else { // Define some validation rules for the fields being saved $ConfigurationModel->Validation->applyRule('Database.Name', 'Required', 'You must specify the name of the database in which you want to set up Vanilla.'); // Let's make some user-friendly custom errors for database problems $DatabaseHost = $this->Form->getFormValue('Database.Host', '~~Invalid~~'); $DatabaseName = $this->Form->getFormValue('Database.Name', '~~Invalid~~'); $DatabaseUser = $this->Form->getFormValue('Database.User', '~~Invalid~~'); $DatabasePassword = $this->Form->getFormValue('Database.Password', '~~Invalid~~'); $ConnectionString = GetConnectionString($DatabaseName, $DatabaseHost); try { $Connection = new PDO($ConnectionString, $DatabaseUser, $DatabasePassword); } catch (PDOException $Exception) { switch ($Exception->getCode()) { case 1044: $this->Form->addError(t('The database user you specified does not have permission to access the database. Have you created the database yet? The database reported: <code>%s</code>'), strip_tags($Exception->getMessage())); break; case 1045: $this->Form->addError(t('Failed to connect to the database with the username and password you entered. Did you mistype them? The database reported: <code>%s</code>'), strip_tags($Exception->getMessage())); break; case 1049: $this->Form->addError(t('It appears as though the database you specified does not exist yet. Have you created it yet? Did you mistype the name? The database reported: <code>%s</code>'), strip_tags($Exception->getMessage())); break; case 2005: $this->Form->addError(t("Are you sure you've entered the correct database host name? Maybe you mistyped it? The database reported: <code>%s</code>"), strip_tags($Exception->getMessage())); break; default: $this->Form->addError(sprintf(t('ValidateConnection'), strip_tags($Exception->getMessage()))); break; } } $ConfigurationModel->Validation->applyRule('Garden.Title', 'Required'); $ConfigurationFormValues = $this->Form->formValues(); if ($ConfigurationModel->validate($ConfigurationFormValues) !== true || $this->Form->errorCount() > 0) { // Apply the validation results to the form(s) $this->Form->setValidationResults($ConfigurationModel->validationResults()); } else { $Host = array_shift(explode(':', Gdn::request()->requestHost())); $Domain = Gdn::request()->domain(); // Set up cookies now so that the user can be signed in. $ExistingSalt = c('Garden.Cookie.Salt', false); $ConfigurationFormValues['Garden.Cookie.Salt'] = $ExistingSalt ? $ExistingSalt : betterRandomString(16, 'Aa0'); $ConfigurationFormValues['Garden.Cookie.Domain'] = ''; // Don't set this to anything by default. # Tim - 2010-06-23 // Additional default setup values. $ConfigurationFormValues['Garden.Registration.ConfirmEmail'] = true; $ConfigurationFormValues['Garden.Email.SupportName'] = $ConfigurationFormValues['Garden.Title']; $ConfigurationModel->save($ConfigurationFormValues, true); // If changing locale, redefine locale sources: $NewLocale = 'en-CA'; // $this->Form->getFormValue('Garden.Locale', false); if ($NewLocale !== false && Gdn::config('Garden.Locale') != $NewLocale) { $Locale = Gdn::locale(); $Locale->set($NewLocale); } // Install db structure & basic data. $Database = Gdn::database(); $Database->init(); $Drop = false; $Explicit = false; try { include PATH_APPLICATIONS . DS . 'dashboard' . DS . 'settings' . DS . 'structure.php'; } catch (Exception $ex) { $this->Form->addError($ex); } if ($this->Form->errorCount() > 0) { return false; } // Create the administrative user $UserModel = Gdn::userModel(); $UserModel->defineSchema(); $UsernameError = t('UsernameError', 'Username can only contain letters, numbers, underscores, and must be between 3 and 20 characters long.'); $UserModel->Validation->applyRule('Name', 'Username', $UsernameError); $UserModel->Validation->applyRule('Name', 'Required', t('You must specify an admin username.')); $UserModel->Validation->applyRule('Password', 'Required', t('You must specify an admin password.')); $UserModel->Validation->applyRule('Password', 'Match'); $UserModel->Validation->applyRule('Email', 'Email'); if (!($AdminUserID = $UserModel->SaveAdminUser($ConfigurationFormValues))) { $this->Form->setValidationResults($UserModel->validationResults()); } else { // The user has been created successfully, so sign in now. saveToConfig('Garden.Installed', true, array('Save' => false)); Gdn::session()->start($AdminUserID, true); saveToConfig('Garden.Installed', false, array('Save' => false)); } if ($this->Form->errorCount() > 0) { return false; } // Assign some extra settings to the configuration file if everything succeeded. $ApplicationInfo = array(); include CombinePaths(array(PATH_APPLICATIONS . DS . 'dashboard' . DS . 'settings' . DS . 'about.php')); // Detect Internet connection for CDNs $Disconnected = !(bool) @fsockopen('ajax.googleapis.com', 80); saveToConfig(array('Garden.Version' => val('Version', val('Dashboard', $ApplicationInfo, array()), 'Undefined'), 'Garden.Cdns.Disable' => $Disconnected, 'Garden.CanProcessImages' => function_exists('gd_info'), 'EnabledPlugins.GettingStarted' => 'GettingStarted', 'EnabledPlugins.HtmLawed' => 'HtmLawed')); } } return $this->Form->errorCount() == 0 ? true : false; }
/** * Request password reset. * * @access public * @since 2.0.0 */ public function passwordRequest() { Gdn::locale()->setTranslation('Email', t(UserModel::signinLabelCode())); if ($this->Form->isPostBack() === true) { $this->Form->validateRule('Email', 'ValidateRequired'); if ($this->Form->errorCount() == 0) { try { $Email = $this->Form->getFormValue('Email'); if (!$this->UserModel->passwordRequest($Email)) { $this->Form->setValidationResults($this->UserModel->validationResults()); Logger::event('password_reset_failure', Logger::INFO, 'Can\'t find account associated with email/username {Input}.', array('Input' => $Email)); } } catch (Exception $ex) { $this->Form->addError($ex->getMessage()); } if ($this->Form->errorCount() == 0) { $this->Form->addError('Success!'); $this->View = 'passwordrequestsent'; Logger::event('password_reset_request', Logger::INFO, '{Input} has been sent a password reset email.', array('Input' => $Email)); } } else { if ($this->Form->errorCount() == 0) { $this->Form->addError("Couldn't find an account associated with that email/username."); Logger::event('password_reset_failure', Logger::INFO, 'Can\'t find account associated with email/username {Input}.', array('Input' => $this->Form->getValue('Email'))); } } } $this->render(); }
/** * Manage list of locales. * * @since 2.0.0 * @access public * @param string $Op 'enable' or 'disable' * @param string $LocaleKey Unique ID of locale to be modified. * @param string $TransientKey Security token. */ public function locales($Op = null, $LocaleKey = null, $TransientKey = null) { $this->permission('Garden.Settings.Manage'); $this->title(t('Locales')); $this->addSideMenu('dashboard/settings/locales'); $this->addJsFile('addons.js'); $LocaleModel = new LocaleModel(); // Get the available locale packs. $AvailableLocales = $LocaleModel->availableLocalePacks(); // Get the enabled locale packs. $EnabledLocales = $LocaleModel->enabledLocalePacks(); // Check to enable/disable a locale. if ($TransientKey && Gdn::session()->validateTransientKey($TransientKey) || $this->Form->authenticatedPostBack()) { if ($Op) { $Refresh = false; switch (strtolower($Op)) { case 'enable': $Locale = val($LocaleKey, $AvailableLocales); if (!is_array($Locale)) { $this->Form->addError('@' . sprintf(t('The %s locale pack does not exist.'), htmlspecialchars($LocaleKey)), 'LocaleKey'); } elseif (!isset($Locale['Locale'])) { $this->Form->addError('ValidateRequired', 'Locale'); } else { saveToConfig("EnabledLocales.{$LocaleKey}", $Locale['Locale']); $EnabledLocales[$LocaleKey] = $Locale['Locale']; $Refresh = true; } break; case 'disable': RemoveFromConfig("EnabledLocales.{$LocaleKey}"); unset($EnabledLocales[$LocaleKey]); $Refresh = true; break; } // Set default locale field if just doing enable/disable $this->Form->setValue('Locale', Gdn_Locale::canonicalize(c('Garden.Locale', 'en'))); } elseif ($this->Form->authenticatedPostBack()) { // Save the default locale. saveToConfig('Garden.Locale', $this->Form->getFormValue('Locale')); $Refresh = true; $this->informMessage(t("Your changes have been saved.")); } if ($Refresh) { Gdn::locale()->refresh(); redirect('/settings/locales'); } } elseif (!$this->Form->isPostBack()) { $this->Form->setValue('Locale', Gdn_Locale::canonicalize(c('Garden.Locale', 'en'))); } // Check for the default locale warning. $DefaultLocale = Gdn_Locale::canonicalize(c('Garden.Locale')); if ($DefaultLocale !== 'en') { $LocaleFound = false; $MatchingLocales = array(); foreach ($AvailableLocales as $Key => $LocaleInfo) { $Locale = val('Locale', $LocaleInfo); if ($Locale == $DefaultLocale) { $MatchingLocales[] = val('Name', $LocaleInfo, $Key); } if (val($Key, $EnabledLocales) == $DefaultLocale) { $LocaleFound = true; } } $this->setData('DefaultLocale', $DefaultLocale); $this->setData('DefaultLocaleWarning', !$LocaleFound); $this->setData('MatchingLocalePacks', htmlspecialchars(implode(', ', $MatchingLocales))); } $this->setData('AvailableLocales', $AvailableLocales); $this->setData('EnabledLocales', $EnabledLocales); $this->setData('Locales', $LocaleModel->availableLocales()); $this->render(); }
/** * Display reCAPTCHA entry field. * * THIS METHOD ECHOS DATA * * @param Gdn_Form $sender * @return string */ public function gdn_form_captcha_handler($sender) { if (!$this->getPrivateKey() || !$this->getPublicKey()) { echo '<div class="Warning">' . t('reCAPTCHA has not been set up by the site administrator in registration settings. This is required to register.') . '</div>'; } // Google whitelist https://developers.google.com/recaptcha/docs/language $whitelist = ['ar', 'bg', 'ca', 'zh-CN', 'zh-TW', 'hr', 'cs', 'da', 'nl', 'en-GB', 'en', 'fil', 'fi', 'fr', 'fr-CA', 'de', 'de-AT', 'de-CH', 'el', 'iw', 'hi', 'hu', 'id', 'it', 'ja', 'ko', 'lv', 'lt', 'no', 'fa', 'pl', 'pt', 'pt-BR', 'pt-PT', 'ro', 'ru', 'sr', 'sk', 'sl', 'es', 'es-419', 'sv', 'th', 'tr', 'uk', 'vi']; // Use our current locale against the whitelist. $language = Gdn::locale()->language(); if (!in_array($language, $whitelist)) { $language = in_array(Gdn::locale()->Locale, $whitelist) ? Gdn::locale()->Locale : false; } Gdn::controller()->Head->addScript('https://www.google.com/recaptcha/api.js?hl=' . $language); $attributes = array('class' => 'g-recaptcha', 'data-sitekey' => $this->getPublicKey(), 'data-theme' => c('Recaptcha.Theme', 'light')); // see https://developers.google.com/recaptcha/docs/display for details $this->EventArguments['Attributes'] =& $attributes; $this->fireEvent('BeforeCaptcha'); echo '<div ' . attribute($attributes) . '></div>'; }
/** * Translates a code into the selected locale's definition. * * @param string $Code The code related to the language-specific definition. * @param string $Default The default value to be displayed if the translation code is not found. * @return string The translated string or $Code if there is no value in $Default. */ public static function translate($Code, $Default = false) { $Locale = Gdn::locale(); if ($Locale) { return $Locale->translate($Code, $Default); } else { return $Default; } }
<?php /* Gdn_Controller $this */ $this->fireAs('dashboard')->fireEvent('render'); ?> <!DOCTYPE html> <html lang="<?php echo htmlspecialchars(Gdn::locale()->Locale); ?> "> <head> <?php $this->renderAsset('Head'); ?> <!-- Robots should not see the dashboard, but tell them not to index it just in case. --> <meta name="robots" content="noindex,nofollow"> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body id="<?php echo htmlspecialchars($BodyIdentifier); ?> " class="<?php echo $this->CssClass; ?> "> <?php $this->renderAsset('Symbols'); // TODO: Pull this asset out elsewhere Gdn_Theme::assetBegin('DashboardUserDropDown'); $user = Gdn::session()->User; $rm = new RoleModel();
/** * Temporarily enable a locale pack without installing it/ * * @param string $LocaleKey The key of the folder. * @throws NotFoundException */ public function testLocale($LocaleKey) { $Available = $this->availableLocalePacks(); if (!isset($Available[$LocaleKey])) { throw notFoundException('Locale'); } // Grab all of the definition files from the locale. $Paths = SafeGlob(PATH_ROOT . "/locales/{$LocaleKey}/*.php"); // Unload the dynamic config Gdn::locale()->unload(); // Load each locale file, checking for errors foreach ($Paths as $Path) { Gdn::locale()->load($Path, false); } }
/** * Manage list of locales. * * @since 2.0.0 * @access public * @param string $Op 'enable' or 'disable' * @param string $LocaleKey Unique ID of locale to be modified. * @param string $TransientKey Security token. */ public function locales($Op = null, $LocaleKey = null) { $this->permission('Garden.Settings.Manage'); $this->title(t('Locales')); $this->setHighlightRoute('dashboard/settings/locales'); $this->addJsFile('addons.js'); $LocaleModel = new LocaleModel(); // Get the available locale packs. $AvailableLocales = $LocaleModel->availableLocalePacks(); // Get the enabled locale packs. $EnabledLocales = $LocaleModel->enabledLocalePacks(); // Check to enable/disable a locale. if ($this->Form->authenticatedPostBack() && !$Op) { // Save the default locale. saveToConfig('Garden.Locale', $this->Form->getFormValue('Locale')); $this->informMessage(t("Your changes have been saved.")); Gdn::locale()->refresh(); redirect('/settings/locales'); } else { $this->Form->setValue('Locale', Gdn_Locale::canonicalize(c('Garden.Locale', 'en'))); } if ($Op) { switch (strtolower($Op)) { case 'enable': $this->enableLocale($LocaleKey, val($LocaleKey, $AvailableLocales), $EnabledLocales); break; case 'disable': $this->disableLocale($LocaleKey, val($LocaleKey, $AvailableLocales), $EnabledLocales); } } // Check for the default locale warning. $DefaultLocale = Gdn_Locale::canonicalize(c('Garden.Locale')); if ($DefaultLocale !== 'en') { $LocaleFound = false; $MatchingLocales = array(); foreach ($AvailableLocales as $Key => $LocaleInfo) { $Locale = val('Locale', $LocaleInfo); if ($Locale == $DefaultLocale) { $MatchingLocales[] = val('Name', $LocaleInfo, $Key); } if (val($Key, $EnabledLocales) == $DefaultLocale) { $LocaleFound = true; } } $this->setData('DefaultLocale', $DefaultLocale); $this->setData('DefaultLocaleWarning', !$LocaleFound); $this->setData('MatchingLocalePacks', htmlspecialchars(implode(', ', $MatchingLocales))); } // Remove all hidden locales, unless they are enabled. $AvailableLocales = array_filter($AvailableLocales, function ($locale) use($EnabledLocales) { return !val('Hidden', $locale) || isset($EnabledLocales[val('Index', $locale)]); }); $this->setData('AvailableLocales', $AvailableLocales); $this->setData('EnabledLocales', $EnabledLocales); $this->setData('Locales', $LocaleModel->availableLocales()); $this->render(); }
/** * * * @param string $Path * @param Gdn_Controller $Controller */ public function init($Path, $Controller) { $Smarty = $this->smarty(); // Get a friendly name for the controller. $ControllerName = get_class($Controller); if (StringEndsWith($ControllerName, 'Controller', true)) { $ControllerName = substr($ControllerName, 0, -10); } // Get an ID for the body. $BodyIdentifier = strtolower($Controller->ApplicationFolder . '_' . $ControllerName . '_' . Gdn_Format::alphaNumeric(strtolower($Controller->RequestMethod))); $Smarty->assign('BodyID', htmlspecialchars($BodyIdentifier)); //$Smarty->assign('Config', Gdn::Config()); // Assign some information about the user. $Session = Gdn::session(); if ($Session->isValid()) { $User = array('Name' => htmlspecialchars($Session->User->Name), 'Photo' => '', 'CountNotifications' => (int) val('CountNotifications', $Session->User, 0), 'CountUnreadConversations' => (int) val('CountUnreadConversations', $Session->User, 0), 'SignedIn' => true); $Photo = $Session->User->Photo; if ($Photo) { if (!isUrl($Photo)) { $Photo = Gdn_Upload::url(changeBasename($Photo, 'n%s')); } } else { $Photo = UserModel::getDefaultAvatarUrl($Session->User); } $User['Photo'] = $Photo; } else { $User = false; /*array( 'Name' => '', 'CountNotifications' => 0, 'SignedIn' => FALSE);*/ } $Smarty->assign('User', $User); // Make sure that any datasets use arrays instead of objects. foreach ($Controller->Data as $Key => $Value) { if ($Value instanceof Gdn_DataSet) { $Controller->Data[$Key] = $Value->resultArray(); } elseif ($Value instanceof stdClass) { $Controller->Data[$Key] = (array) $Value; } } $BodyClass = val('CssClass', $Controller->Data, '', true); $Sections = Gdn_Theme::section(null, 'get'); if (is_array($Sections)) { foreach ($Sections as $Section) { $BodyClass .= ' Section-' . $Section; } } $Controller->Data['BodyClass'] = $BodyClass; // Set the current locale for themes to take advantage of. $Locale = Gdn::locale()->Locale; $CurrentLocale = array('Key' => $Locale, 'Lang' => str_replace('_', '-', Gdn::locale()->language(true))); if (class_exists('Locale')) { $CurrentLocale['Language'] = Locale::getPrimaryLanguage($Locale); $CurrentLocale['Region'] = Locale::getRegion($Locale); $CurrentLocale['DisplayName'] = Locale::getDisplayName($Locale, $Locale); $CurrentLocale['DisplayLanguage'] = Locale::getDisplayLanguage($Locale, $Locale); $CurrentLocale['DisplayRegion'] = Locale::getDisplayRegion($Locale, $Locale); } $Smarty->assign('CurrentLocale', $CurrentLocale); $Smarty->assign('Assets', (array) $Controller->Assets); // 2016-07-07 Linc: Request used to return blank for homepage. // Now it returns defaultcontroller. This restores BC behavior. $isHomepage = val('isHomepage', $Controller->Data); $Path = $isHomepage ? "" : Gdn::request()->path(); $Smarty->assign('Path', $Path); $Smarty->assign('Homepage', $isHomepage); // true/false // Assign the controller data last so the controllers override any default data. $Smarty->assign($Controller->Data); $security = new SmartySecurityVanilla($Smarty); $security->php_handling = Smarty::PHP_REMOVE; $security->allow_constants = false; $security->allow_super_globals = false; $security->streams = null; $security->setPhpFunctions(array_merge($security->php_functions, ['array', 'category', 'checkPermission', 'inSection', 'inCategory', 'ismobile', 'multiCheckPermission', 'getValue', 'setValue', 'url', 'useragenttype'])); $security->php_modifiers = array_merge($security->php_functions, array('sprintf')); $Smarty->enableSecurity($security); }
/** * Disable an application. * * @param string $applicationName The name of the application to disable. * @throws \Exception Throws an exception if the application can't be disabled. */ public function disableApplication($applicationName) { // 1. Check to make sure that this application is allowed to be disabled $ApplicationInfo = (array) arrayValueI($applicationName, $this->availableApplications(), array()); $applicationName = $ApplicationInfo['Index']; if (!val('AllowDisable', $ApplicationInfo, true)) { throw new Exception(sprintf(t('You cannot disable the %s application.'), $applicationName)); } // 2. Check to make sure that no other enabled applications rely on this one foreach ($this->enabledApplications() as $CheckingName => $CheckingInfo) { $RequiredApplications = val('RequiredApplications', $CheckingInfo, false); if (is_array($RequiredApplications) && array_key_exists($applicationName, $RequiredApplications) === true) { throw new Exception(sprintf(t('You cannot disable the %1$s application because the %2$s application requires it in order to function.'), $applicationName, $CheckingName)); } } // 3. Check to make sure that no other enabled plugins rely on this one $DependendPlugins = array(); foreach (Gdn::pluginManager()->enabledPlugins() as $CheckingName => $CheckingInfo) { $RequiredApplications = val('RequiredApplications', $CheckingInfo, false); if (is_array($RequiredApplications) && array_key_exists($applicationName, $RequiredApplications) === true) { $DependendPlugins[] = $CheckingName; } } if (!empty($DependendPlugins)) { throw new Exception(sprintf(t('You cannot disable the %1$s application because the following plugins require it in order to function: %2$s'), $applicationName, implode(', ', $DependendPlugins))); } // 2. Disable it removeFromConfig("EnabledApplications.{$applicationName}"); Logger::event('addon_disabled', Logger::NOTICE, 'The {addonName} application was disabled.', array('addonName' => $applicationName)); // Clear the object caches. Gdn_Autoloader::smartFree(Gdn_Autoloader::CONTEXT_APPLICATION, $ApplicationInfo); // Redefine the locale manager's settings $Locale->Set($CurrentLocale, $EnabledApps, $EnabledPlugins, true); $Locale = Gdn::locale(); $Locale->set($Locale->current(), $this->enabledApplicationFolders(), Gdn::pluginManager()->enabledPluginFolders(), true); $this->EventArguments['AddonName'] = $applicationName; Gdn::pluginManager()->callEventHandlers($this, 'ApplicationManager', 'AddonDisabled'); }
/** * Disable a plugin. * * @param string $pluginName The name of the plugin. * @return bool * @throws Exception */ public function disablePlugin($pluginName) { $addon = $this->addonManager->lookupAddon($pluginName); if (!$addon) { return false; } $pluginClassName = $addon->getPluginClass(); $pluginName = $addon->getRawKey(); $enabled = $this->addonManager->isEnabled($pluginName, Addon::TYPE_ADDON); try { $this->addonManager->checkDependants($addon, true); } catch (\Exception $ex) { throw new Gdn_UserException($ex->getMessage(), 400); } // 2. Perform necessary hook action $this->pluginHook($pluginName, self::ACTION_DISABLE, true); // 3. Disable it. saveToConfig("EnabledPlugins.{$pluginName}", false); $this->addonManager->stopAddon($addon); // 4. Unregister the plugin properly. $this->unregisterPlugin($pluginClassName); if ($enabled) { Logger::event('addon_disabled', Logger::INFO, 'The {addonName} plugin was disabled.', array('addonName' => $pluginName)); } // Redefine the locale manager's settings $Locale->Set($CurrentLocale, $EnabledApps, $EnabledPlugins, TRUE); Gdn::locale()->refresh(); $this->EventArguments['AddonName'] = $pluginName; $this->fireEvent('AddonDisabled'); return true; }
/** * * * @param $PluginName * @return bool * @throws Exception */ public function disablePlugin($PluginName) { // Get the plugin and make sure its name is the correct case. $Plugin = $this->getPluginInfo($PluginName); if ($Plugin) { $PluginName = $Plugin['Index']; } Gdn_Autoloader::smartFree(Gdn_Autoloader::CONTEXT_PLUGIN, $Plugin); $enabled = $this->isEnabled($PluginName); // 1. Check to make sure that no other enabled plugins rely on this one // Get all available plugins and compile their requirements foreach ($this->enabledPlugins() as $CheckingName => $Trash) { $CheckingInfo = $this->getPluginInfo($CheckingName); $RequiredPlugins = ArrayValue('RequiredPlugins', $CheckingInfo, false); if (is_array($RequiredPlugins) && array_key_exists($PluginName, $RequiredPlugins) === true) { throw new Exception(sprintf(T('You cannot disable the %1$s plugin because the %2$s plugin requires it in order to function.'), $PluginName, $CheckingName)); } } // 2. Perform necessary hook action $this->pluginHook($PluginName, self::ACTION_DISABLE, true); // 3. Disable it. SaveToConfig("EnabledPlugins.{$PluginName}", false); unset($this->EnabledPlugins[$PluginName]); if ($enabled) { Logger::event('addon_disabled', LogLevel::NOTICE, 'The {addonName} plugin was disabled.', array('addonName' => $PluginName)); } // Redefine the locale manager's settings $Locale->Set($CurrentLocale, $EnabledApps, $EnabledPlugins, TRUE); Gdn::locale()->refresh(); $this->EventArguments['AddonName'] = $PluginName; $this->fireEvent('AddonDisabled'); return true; }
/** * * * @param $ThemeName * @param bool $IsMobile * @return bool * @throws Exception */ public function enableTheme($ThemeName, $IsMobile = false) { // Make sure to run the setup $this->testTheme($ThemeName); // Set the theme. $ThemeInfo = $this->getThemeInfo($ThemeName); $ThemeFolder = val('Folder', $ThemeInfo, ''); $oldTheme = $IsMobile ? c('Garden.MobileTheme', 'mobile') : c('Garden.Theme', 'default'); if ($ThemeFolder == '') { throw new Exception(t('The theme folder was not properly defined.')); } else { $Options = valr("{$ThemeName}.Options", $this->AvailableThemes()); if ($Options) { if ($IsMobile) { saveToConfig(array('Garden.MobileTheme' => $ThemeName, 'Garden.MobileThemeOptions.Name' => valr("{$ThemeName}.Name", $this->availableThemes(), $ThemeFolder))); } else { saveToConfig(array('Garden.Theme' => $ThemeName, 'Garden.ThemeOptions.Name' => valr("{$ThemeName}.Name", $this->availableThemes(), $ThemeFolder))); } } else { if ($IsMobile) { saveToConfig('Garden.MobileTheme', $ThemeName); removeFromConfig('Garden.MobileThemeOptions'); } else { saveToConfig('Garden.Theme', $ThemeName); removeFromConfig('Garden.ThemeOptions'); } } } if ($oldTheme !== $ThemeName) { $this->themeHook($ThemeName, self::ACTION_ENABLE, true); Logger::event('theme_changed', Logger::NOTICE, 'The {themeType} theme changed from {oldTheme} to {newTheme}.', array('themeType' => $IsMobile ? 'mobile' : 'desktop', 'oldTheme' => $oldTheme, 'newTheme' => $ThemeName)); } // Tell the locale cache to refresh itself. Gdn::locale()->refresh(); return true; }
/** * * * @param $Path * @param $Controller */ public function init($Path, $Controller) { $Smarty = $this->smarty(); // Get a friendly name for the controller. $ControllerName = get_class($Controller); if (StringEndsWith($ControllerName, 'Controller', true)) { $ControllerName = substr($ControllerName, 0, -10); } // Get an ID for the body. $BodyIdentifier = strtolower($Controller->ApplicationFolder . '_' . $ControllerName . '_' . Gdn_Format::alphaNumeric(strtolower($Controller->RequestMethod))); $Smarty->assign('BodyID', $BodyIdentifier); //$Smarty->assign('Config', Gdn::Config()); // Assign some information about the user. $Session = Gdn::session(); if ($Session->isValid()) { $User = array('Name' => $Session->User->Name, 'Photo' => '', 'CountNotifications' => (int) val('CountNotifications', $Session->User, 0), 'CountUnreadConversations' => (int) val('CountUnreadConversations', $Session->User, 0), 'SignedIn' => true); $Photo = $Session->User->Photo; if ($Photo) { if (!IsUrl($Photo)) { $Photo = Gdn_Upload::Url(ChangeBasename($Photo, 'n%s')); } } else { if (function_exists('UserPhotoDefaultUrl')) { $Photo = UserPhotoDefaultUrl($Session->User, 'ProfilePhoto'); } elseif ($ConfigPhoto = C('Garden.DefaultAvatar')) { $Photo = Gdn_Upload::url($ConfigPhoto); } else { $Photo = Asset('/applications/dashboard/design/images/defaulticon.png', true); } } $User['Photo'] = $Photo; } else { $User = false; /*array( 'Name' => '', 'CountNotifications' => 0, 'SignedIn' => FALSE);*/ } $Smarty->assign('User', $User); // Make sure that any datasets use arrays instead of objects. foreach ($Controller->Data as $Key => $Value) { if ($Value instanceof Gdn_DataSet) { $Controller->Data[$Key] = $Value->resultArray(); } elseif ($Value instanceof stdClass) { $Controller->Data[$Key] = (array) $Value; } } $BodyClass = val('CssClass', $Controller->Data, '', true); $Sections = Gdn_Theme::section(null, 'get'); if (is_array($Sections)) { foreach ($Sections as $Section) { $BodyClass .= ' Section-' . $Section; } } $Controller->Data['BodyClass'] = $BodyClass; // Set the current locale for themes to take advantage of. $Locale = Gdn::locale()->Locale; $CurrentLocale = array('Key' => $Locale, 'Lang' => str_replace('_', '-', $Locale)); if (class_exists('Locale')) { $CurrentLocale['Language'] = Locale::getPrimaryLanguage($Locale); $CurrentLocale['Region'] = Locale::getRegion($Locale); $CurrentLocale['DisplayName'] = Locale::getDisplayName($Locale, $Locale); $CurrentLocale['DisplayLanguage'] = Locale::getDisplayLanguage($Locale, $Locale); $CurrentLocale['DisplayRegion'] = Locale::getDisplayRegion($Locale, $Locale); } $Smarty->assign('CurrentLocale', $CurrentLocale); $Smarty->assign('Assets', (array) $Controller->Assets); $Smarty->assign('Path', Gdn::request()->path()); // Assign the controller data last so the controllers override any default data. $Smarty->assign($Controller->Data); $Smarty->Controller = $Controller; // for smarty plugins $Smarty->security = true; $Smarty->security_settings['IF_FUNCS'] = array_merge($Smarty->security_settings['IF_FUNCS'], array('Category', 'CheckPermission', 'InSection', 'InCategory', 'MultiCheckPermission', 'GetValue', 'SetValue', 'Url')); $Smarty->security_settings['MODIFIER_FUNCS'] = array_merge($Smarty->security_settings['MODIFIER_FUNCS'], array('sprintf')); $Smarty->secure_dir = array($Path); }
/** * * * @param SettingsController $sender * @param array $Args */ protected function settings_addEdit($sender, $Args) { $sender->addJsFile('jsconnect-settings.js', 'plugins/jsconnect'); $client_id = $sender->Request->get('client_id'); Gdn::locale()->setTranslation('AuthenticationKey', 'Client ID'); Gdn::locale()->setTranslation('AssociationSecret', 'Secret'); Gdn::locale()->setTranslation('AuthenticateUrl', 'Authentication Url'); /* @var Gdn_Form $form */ $form = $sender->Form; $model = new Gdn_AuthenticationProviderModel(); $form->setModel($model); $generate = false; if ($form->authenticatedPostBack()) { if ($form->getFormValue('Generate') || $sender->Request->post('Generate')) { $generate = true; $key = mt_rand(); $secret = md5(mt_rand()); $sender->setFormSaved(false); } else { $form->validateRule('AuthenticationKey', 'ValidateRequired'); $form->validateRule('AuthenticationKey', 'regex:`^[a-z0-9_-]+$`i', T('The client id must contain only letters, numbers and dashes.')); $form->validateRule('AssociationSecret', 'ValidateRequired'); $form->validateRule('AuthenticateUrl', 'ValidateRequired'); $form->setFormValue('AuthenticationSchemeAlias', 'jsconnect'); if ($form->save(['ID' => $client_id])) { $sender->RedirectUrl = url('/settings/jsconnect'); } } } else { if ($client_id) { $provider = self::getProvider($client_id); touchValue('Trusted', $provider, 1); } else { $provider = array(); } $form->setData($provider); } // Set up the form controls for editing the connection. $hashTypes = hash_algos(); $hashTypes = array_combine($hashTypes, $hashTypes); $controls = ['AuthenticationKey' => ['LabelCode' => 'Client ID', 'Description' => t('The client ID uniquely identifies the site.', 'The client ID uniquely identifies the site. You can generate a new ID with the button at the bottom of this page.')], 'AssociationSecret' => ['LabelCode' => 'Secret', 'Description' => t('The secret secures the sign in process.', 'The secret secures the sign in process. Do <b>NOT</b> give the secret out to anyone.')], 'Name' => ['LabelCode' => 'Site Name', 'Description' => t('Enter a short name for the site.', 'Enter a short name for the site. This is displayed on the signin buttons.')], 'AuthenticateUrl' => ['LabelCode' => 'Authentication URL', 'Description' => t('The location of the JSONP formatted authentication data.')], 'SignInUrl' => ['LabelCode' => 'Sign In URL', 'Description' => t('The url that users use to sign in.') . ' ' . t('Use {target} to specify a redirect.')], 'RegisterUrl' => ['LabelCode' => 'Registration URL', 'Description' => t('The url that users use to register for a new account.')], 'SignOutUrl' => ['LabelCode' => 'Sign Out URL', 'Description' => t('The url that users use to sign out of your site.')], 'Trusted' => ['Control' => 'toggle', 'LabelCode' => 'This is trusted connection and can sync roles & permissions.'], 'IsDefault' => ['Control' => 'toggle', 'LabelCode' => 'Make this connection your default signin method.'], 'Advanced' => ['Control' => 'callback', 'Callback' => function ($form) { return subheading(t('Advanced')); }], 'HashType' => ['Control' => 'dropdown', 'LabelCode' => 'Hash Algorithm', 'Items' => $hashTypes, 'Description' => T('Choose md5 if you\'re not sure what to choose.', "You can select a custom hash algorithm to sign your requests. The hash algorithm must also be used in your client library. Choose md5 if you're not sure what to choose."), 'Options' => ['Default' => 'md5']], 'TestMode' => ['Control' => 'toggle', 'LabelCode' => 'This connection is in test-mode.']]; $sender->setData('_Controls', $controls); $sender->setData('Title', sprintf(T($client_id ? 'Edit %s' : 'Add %s'), T('Connection'))); // Throw a render event as this plugin so that handlers can call our methods. Gdn::pluginManager()->callEventHandlers($this, __CLASS__, 'addedit', 'render'); if ($generate && $sender->deliveryType() === DELIVERY_TYPE_VIEW) { $sender->setJson('AuthenticationKey', $key); $sender->setJson('AssociationSecret', $secret); $sender->render('Blank', 'Utility', 'Dashboard'); } else { $sender->render('Settings_AddEdit', '', 'plugins/jsconnect'); } }