Get a configuration setting for the application.
public static config ( string $Name = false, mixed $Default = false ) : Gdn_Configuration | mixed | ||
$Name | string | The name of the configuration setting. Settings in different sections are seperated by a dot ('.') |
$Default | mixed | The result to return if the configuration setting is not found. |
Результат | Gdn_Configuration | mixed | The configuration setting. |
/** * Returns an array of all folder names within the source folder or FALSE * if SourceFolder does not exist. * * @param string $SourceFolder */ public static function folders($SourceFolders) { if (!is_array($SourceFolders)) { $SourceFolders = array($SourceFolders); } $BlackList = Gdn::config('Garden.FolderBlacklist'); if (!is_array($BlackList)) { $BlackList = array('.', '..'); } $Result = array(); foreach ($SourceFolders as $SourceFolder) { if ($DirectoryHandle = opendir($SourceFolder)) { while (($Item = readdir($DirectoryHandle)) !== false) { $SubFolder = combinePaths(array($SourceFolder, $Item)); if (!in_array($Item, $BlackList) && is_dir($SubFolder)) { $Result[] = $Item; } } closedir($DirectoryHandle); } } if (count($Result) == 0) { return false; } return $Result; }
/** * */ public function __construct() { $this->Dispatcher = new Gdn_Dispatcher(); $EnabledApplications = Gdn::config('EnabledApplications'); $this->Dispatcher->enabledApplicationFolders($EnabledApplications); $this->Dispatcher->passProperty('EnabledApplications', $EnabledApplications); }
/** * Get list of conversations. * * Events: BeforeGet. * * @since 2.0.0 * @access public * * @param int $ViewingUserID Unique ID of current user. * @param int $Offset Number to skip. * @param int $Limit Maximum to return. * @return Gdn_DataSet SQL results. */ public function get($ViewingUserID, $Offset = '0', $Limit = '') { if ($Limit == '') { $Limit = Gdn::config('Conversations.Conversations.PerPage', 30); } $Offset = !is_numeric($Offset) || $Offset < 0 ? 0 : $Offset; // Grab the base list of conversations. $Data = $this->SQL->select('c.*')->select('uc.CountReadMessages')->select('uc.LastMessageID', '', 'UserLastMessageID')->from('UserConversation uc')->join('Conversation c', 'uc.ConversationID = c.ConversationID')->where('uc.UserID', $ViewingUserID)->where('uc.Deleted', 0)->orderBy('c.DateUpdated', 'desc')->limit($Limit, $Offset)->get()->resultArray(); $this->joinLastMessages($Data); return $Data; }
/** * Get messages by conversation. * * Events: BeforeGet. * * @since 2.0.0 * @access public * * @param int $ConversationID Unique ID of conversation being viewed. * @param int $ViewingUserID Unique ID of current user. * @param int $Offset Number to skip. * @param int $Limit Maximum to return. * @param array $Wheres SQL conditions. * @return Gdn_DataSet SQL results. */ public function get($ConversationID, $ViewingUserID, $Offset = '0', $Limit = '', $Wheres = '') { if ($Limit == '') { $Limit = Gdn::config('Conversations.Messages.PerPage', 50); } $Offset = !is_numeric($Offset) || $Offset < 0 ? 0 : $Offset; if (is_array($Wheres)) { $this->SQL->where($Wheres); } $this->fireEvent('BeforeGet'); return $this->SQL->select('cm.*')->select('iu.Name', '', 'InsertName')->select('iu.Email', '', 'InsertEmail')->select('iu.Photo', '', 'InsertPhoto')->from('ConversationMessage cm')->join('Conversation c', 'cm.ConversationID = c.ConversationID')->join('UserConversation uc', 'c.ConversationID = uc.ConversationID and uc.UserID = ' . $ViewingUserID, 'left')->join('User iu', 'cm.InsertUserID = iu.UserID', 'left')->beginWhereGroup()->where('uc.DateCleared is null')->orWhere('uc.DateCleared <', 'cm.DateInserted', true, false)->endWhereGroup()->where('cm.ConversationID', $ConversationID)->orderBy('cm.DateInserted', 'asc')->limit($Limit, $Offset)->get(); }
/** * Statistics setup & configuration. * * @since 2.0.17 * @access public */ public function index() { $this->permission('Garden.Settings.Manage'); $this->addSideMenu('dashboard/statistics'); //$this->addJsFile('statistics.js'); $this->title(t('Vanilla Statistics')); $this->enableSlicing($this); if ($this->Form->authenticatedPostBack()) { $Flow = true; if ($Flow && $this->Form->getFormValue('Reregister')) { Gdn::Statistics()->register(); } if ($Flow && $this->Form->getFormValue('Save')) { Gdn::installationID($this->Form->getFormValue('InstallationID')); Gdn::installationSecret($this->Form->getFormValue('InstallationSecret')); $this->informMessage(t("Your settings have been saved.")); } if ($Flow && $this->Form->getFormValue('AllowLocal')) { saveToConfig('Garden.Analytics.AllowLocal', true); } if ($Flow && $this->Form->getFormValue('Allow')) { saveToConfig('Garden.Analytics.Enabled', true); } if ($Flow && $this->Form->getFormValue('ClearCredentials')) { Gdn::installationID(false); Gdn::installationSecret(false); Gdn::statistics()->Tick(); $Flow = false; } } else { $this->Form->setValue('InstallationID', Gdn::installationID()); $this->Form->setValue('InstallationSecret', Gdn::installationSecret()); } $AnalyticsEnabled = Gdn_Statistics::checkIsEnabled(); if ($AnalyticsEnabled) { $ConfFile = Gdn::config()->defaultPath(); $this->setData('ConfWritable', $ConfWritable = is_writable($ConfFile)); if (!$ConfWritable) { $AnalyticsEnabled = false; } } $this->setData('AnalyticsEnabled', $AnalyticsEnabled); $NotifyMessage = Gdn::get('Garden.Analytics.Notify', false); $this->setData('NotifyMessage', $NotifyMessage); if ($NotifyMessage !== false) { Gdn::set('Garden.Analytics.Notify', null); } $this->render(); }
public function settingsController_PostUrl_create($Sender, $args) { $Sender->permission('Garden.Settings.Manage'); $Cf = new ConfigurationModule($Sender); if (c('Plugins.PostUrl.Display1') == "") { Gdn::config()->set('Plugins.PostUrl.Display1', "from: %post_url%", false, false); } $Description = '<p>可接受下列占位符号,该符号和wordpress兼容: <br />%site_url% - the URI of your site<br />%site_name% - the name of your site<br />%post_url% - the URI of the post where the text is displayed<br />%post_title% - the title of the post where the text is displayed</p>'; $Cf->initialize(array('Plugins.PostUrl.ItemName1' => array('LabelCode' => '版权名称一', 'Control' => 'TextBox', 'Description' => "该字段用于发布话题时选择方便记忆"), 'Plugins.PostUrl.Display1' => array('LabelCode' => '版权信息一', 'Control' => 'TextBox', 'Description' => $Description, 'Items' => array(), 'Options' => array("MultiLine" => true, "rows" => "20", "cols" => 30)), 'Plugins.PostUrl.ItemName2' => array('LabelCode' => '<hr /><br />版权名称二', 'Control' => 'TextBox', 'Description' => "该字段用于发布话题时选择方便记忆"), 'Plugins.PostUrl.Display2' => array('LabelCode' => '版权信息二', 'Control' => 'TextBox', 'Options' => array("MultiLine" => true, "rows" => "20", "cols" => 30)), 'Plugins.PostUrl.ItemName3' => array('LabelCode' => '<hr /><br />版权名称三', 'Control' => 'TextBox', 'Description' => "该字段用于发布话题时选择方便记忆"), 'Plugins.PostUrl.Display3' => array('LabelCode' => '版权信息三', 'Control' => 'TextBox', 'Options' => array("MultiLine" => true, "rows" => "20", "cols" => 30)), 'Plugins.PostUrl.Default' => array('LabelCode' => '默认版权信息', 'Control' => 'DropDown', 'Description' => "没有选择或者历史文章将会使用该设定", 'Items' => array(0 => '', 1 => '版权一', 2 => '版权二', 3 => '版权三'), 'Options' => array('Value' => c('Plugins.PostUrl.Default'))))); $c = Gdn::controller(); $c->addJsFile('settings.js', 'plugins/CDNManager'); $Sender->addSideMenu(); $Sender->setData('Title', t('Add Post Url')); $Cf->renderAll(); }
public function settingsController_cdnmanager_create($Sender, $args) { $Sender->permission('Garden.Settings.Manage'); $Cf = new ConfigurationModule($Sender); if (c('Plugins.CDNManager.CDNSources') == "") { $defaultCDNValue = "jquery.js = \"http://libs.baidu.com/jquery/1.10.2/jquery.min.js\"\r\njquery-ui.js = \"http://apps.bdimg.com/libs/jqueryui/1.10.4/jquery-ui.min.js\""; Gdn::config()->set('Plugins.CDNManager.CDNSources', $defaultCDNValue, false, false); } $Cf->initialize(array('Plugins.CDNManager.CDNSources' => array('LabelCode' => 'CDN使用源列表', 'Control' => 'TextBox', 'Options' => array('MultiLine' => true, 'rows' => 20, 'cols' => 50), 'Description' => '<p>输入需要用CDN加速的文件和对应的地址,如jquery等国内国外都有开放的CDN源,也可申请<font color="red"><a href="https://portal.qiniu.com/signup?code=3lcqpvqtedfma" target="_blank">七牛</a></font>免费的空间来加速您的网站,<a href="https://portal.qiniu.com/signup?code=3lcqpvqtedfma" target="_blank">点击这里免费申请七牛加速空间</a></p> <p><small><strong> </strong> </small></p>', 'Items' => array()))); $c = Gdn::controller(); $c->addJsFile('settings.js', 'plugins/CDNManager'); $Sender->addSideMenu(); $Sender->setData('Title', t('CDN源设置')); $Cf->renderAll(); }
/** * Advanced settings. * * Allows setting configuration values via form elements. * * @since 2.0.0 * @access public */ public function advanced() { // Check permission $this->permission('Garden.Settings.Manage'); // Load up config options we'll be setting $Validation = new Gdn_Validation(); $ConfigurationModel = new Gdn_ConfigurationModel($Validation); $ConfigurationModel->setField(array('Vanilla.Discussions.PerPage', 'Vanilla.Comments.AutoRefresh', 'Vanilla.Comments.PerPage', 'Garden.Html.AllowedElements', 'Vanilla.Archive.Date', 'Vanilla.Archive.Exclude', 'Garden.EditContentTimeout', 'Vanilla.AdminCheckboxes.Use', 'Vanilla.Discussions.SortField' => 'd.DateLastComment', 'Vanilla.Discussions.UserSortField', 'Vanilla.Comment.MaxLength', 'Vanilla.Comment.MinLength')); // 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.Discussions.PerPage', 'Required'); $ConfigurationModel->Validation->applyRule('Vanilla.Discussions.PerPage', 'Integer'); $ConfigurationModel->Validation->applyRule('Vanilla.Comments.AutoRefresh', 'Integer'); $ConfigurationModel->Validation->applyRule('Vanilla.Comments.PerPage', 'Required'); $ConfigurationModel->Validation->applyRule('Vanilla.Comments.PerPage', 'Integer'); $ConfigurationModel->Validation->applyRule('Vanilla.Archive.Date', 'Date'); $ConfigurationModel->Validation->applyRule('Garden.EditContentTimeout', 'Integer'); $ConfigurationModel->Validation->applyRule('Vanilla.Comment.MaxLength', 'Required'); $ConfigurationModel->Validation->applyRule('Vanilla.Comment.MaxLength', 'Integer'); // Grab old config values to check for an update. $ArchiveDateBak = Gdn::config('Vanilla.Archive.Date'); $ArchiveExcludeBak = (bool) Gdn::config('Vanilla.Archive.Exclude'); // Save new settings $Saved = $this->Form->save(); if ($Saved) { $ArchiveDate = Gdn::config('Vanilla.Archive.Date'); $ArchiveExclude = (bool) Gdn::config('Vanilla.Archive.Exclude'); if ($ArchiveExclude != $ArchiveExcludeBak || $ArchiveExclude && $ArchiveDate != $ArchiveDateBak) { $DiscussionModel = new DiscussionModel(); $DiscussionModel->UpdateDiscussionCount('All'); } $this->informMessage(t("Your changes have been saved.")); } } $this->addSideMenu('vanilla/settings/advanced'); $this->addJsFile('settings.js'); $this->title(t('Advanced Forum Settings')); // Render default view (settings/advanced.php) $this->render(); }
/** * Class constructor * * @param object $Sender */ public function __construct($Sender = '', $ApplicationFolder = false) { if (!$Sender) { $Sender = Gdn::controller(); } if (is_object($Sender)) { $this->_ApplicationFolder = $Sender->ApplicationFolder; $this->_ThemeFolder = $Sender->Theme; } else { $this->_ApplicationFolder = 'dashboard'; $this->_ThemeFolder = Gdn::config('Garden.Theme'); } if ($ApplicationFolder !== false) { $this->_ApplicationFolder = $ApplicationFolder; } if (is_object($Sender)) { $this->_Sender = $Sender; } parent::__construct(); }
/** * Default all drafts view: chronological by time saved. * * @since 2.0.0 * @access public * * @param int $Offset Number of drafts to skip. */ public function index($Offset = '0') { Gdn_Theme::section('DiscussionList'); // Setup head $this->permission('Garden.SignIn.Allow'); $this->addJsFile('jquery.gardenmorepager.js'); $this->addJsFile('discussions.js'); $this->title(t('My Drafts')); // Validate $Offset if (!is_numeric($Offset) || $Offset < 0) { $Offset = 0; } // Set criteria & get drafts data $Limit = Gdn::config('Vanilla.Discussions.PerPage', 30); $Session = Gdn::session(); $Wheres = array('d.InsertUserID' => $Session->UserID); $this->DraftData = $this->DraftModel->getByUser($Session->UserID, $Offset, $Limit); $CountDrafts = $this->DraftModel->getCountByUser($Session->UserID); // Build a pager $PagerFactory = new Gdn_PagerFactory(); $this->Pager = $PagerFactory->GetPager('MorePager', $this); $this->Pager->MoreCode = 'More drafts'; $this->Pager->LessCode = 'Newer drafts'; $this->Pager->ClientID = 'Pager'; $this->Pager->configure($Offset, $Limit, $CountDrafts, 'drafts/%1$s'); // Deliver JSON data if necessary if ($this->_DeliveryType != DELIVERY_TYPE_ALL) { $this->setJson('LessRow', $this->Pager->toString('less')); $this->setJson('MoreRow', $this->Pager->toString('more')); $this->View = 'drafts'; } // Add modules $this->addModule('DiscussionFilterModule'); $this->addModule('NewDiscussionModule'); $this->addModule('CategoriesModule'); $this->addModule('BookmarkedModule'); // Render default view (drafts/index.php) $this->render(); }
/** * Gets an array of all of the enabled applications. * * @return array */ public function enabledApplications() { if (!is_array($this->enabledApplications)) { $EnabledApplications = Gdn::config('EnabledApplications', array('Dashboard' => 'dashboard')); // Add some information about the applications to the array. foreach ($EnabledApplications as $Name => $Folder) { $EnabledApplications[$Name] = array('Folder' => $Folder); //$EnabledApplications[$Name]['Version'] = Gdn::Config($Name.'.Version', ''); $EnabledApplications[$Name]['Version'] = ''; $EnabledApplications[$Name]['Index'] = $Name; // Get the application version from it's about file. $AboutPath = PATH_APPLICATIONS . '/' . strtolower($Name) . '/settings/about.php'; if (file_exists($AboutPath)) { $ApplicationInfo = array(); include $AboutPath; $EnabledApplications[$Name]['Version'] = GetValueR("{$Name}.Version", $ApplicationInfo, ''); } } $this->enabledApplications = $EnabledApplications; } return $this->enabledApplications; }
/** * Create different sizes of user photos. */ public function processAvatars() { $UploadImage = new Gdn_UploadImage(); $UserData = $this->SQL->select('u.Photo')->from('User u')->get(); foreach ($UserData->result() as $User) { try { $Image = PATH_ROOT . DS . 'uploads' . DS . str_replace('userpics', 'attachments', $User->Photo); // Check extension length $ImageExtension = strlen(pathinfo($Image, PATHINFO_EXTENSION)); $ImageBaseName = pathinfo($Image, PATHINFO_BASENAME) + 1; if (!file_exists($Image)) { rename(substr($Image, 0, -$ImageExtension), $Image); } // Make sure the avatars folder exists. if (!file_exists(PATH_ROOT . '/uploads/userpics')) { mkdir(PATH_ROOT . '/uploads/userpics'); } // Save the uploaded image in profile size if (!file_exists(PATH_ROOT . '/uploads/userpics/p' . $ImageBaseName)) { $UploadImage->SaveImageAs($Image, PATH_ROOT . '/uploads/userpics/p' . $ImageBaseName, Gdn::config('Garden.Profile.MaxHeight', 1000), Gdn::config('Garden.Profile.MaxWidth', 250)); } // Save the uploaded image in preview size /*if (!file_exists(PATH_ROOT.'/uploads/userpics/t'.$ImageBaseName)) $UploadImage->SaveImageAs( $Image, PATH_ROOT.'/uploads/userpics/t'.$ImageBaseName, Gdn::config('Garden.Preview.MaxHeight', 100), Gdn::config('Garden.Preview.MaxWidth', 75) );*/ // Save the uploaded image in thumbnail size $ThumbSize = Gdn::config('Garden.Thumbnail.Size', 40); if (!file_exists(PATH_ROOT . '/uploads/userpics/n' . $ImageBaseName)) { $UploadImage->SaveImageAs($Image, PATH_ROOT . '/uploads/userpics/n' . $ImageBaseName, $ThumbSize, $ThumbSize, true); } } catch (Exception $ex) { } } }
/** * The initialize method is called by the dispatcher after the constructor * has completed, objects have been passed along, assets have been * retrieved, and before the requested method fires. Use it in any extended * controller to do things like loading script and CSS into the head. */ public function initialize() { if (in_array($this->SyndicationMethod, array(SYNDICATION_ATOM, SYNDICATION_RSS))) { $this->_Headers['Content-Type'] = 'text/xml; charset=' . c('Garden.Charset', 'utf-8'); } if (is_object($this->Menu)) { $this->Menu->Sort = Gdn::config('Garden.Menu.Sort'); } $ResolvedPath = strtolower(combinePaths(array(Gdn::dispatcher()->application(), Gdn::dispatcher()->ControllerName, Gdn::dispatcher()->ControllerMethod))); $this->ResolvedPath = $ResolvedPath; $this->FireEvent('Initialize'); }
/** * Retrieves a configuration setting. * * @param string|bool $Name The name of the configuration setting. * Settings in different sections are separated by dots. * @param mixed $Default The result to return if the configuration setting is not found. * @return mixed The configuration setting. * @see Gdn::config() */ function config($Name = false, $Default = false) { return Gdn::config($Name, $Default); }
/** * Send password email. * * @param $UserID * @param $Password * @throws Exception */ public function sendPasswordEmail($UserID, $Password) { $Session = Gdn::session(); $Sender = $this->getID($Session->UserID); $User = $this->getID($UserID); $AppTitle = Gdn::config('Garden.Title'); $Email = new Gdn_Email(); $Email->subject(sprintf(t('[%s] Password Reset'), $AppTitle)); $Email->to($User->Email); $Data = array(); $Data['User'] = arrayTranslate((array) $User, array('Name', 'Email')); $Data['Sender'] = arrayTranslate((array) $Sender, array('Name', 'Email')); $Data['Title'] = $AppTitle; $EmailFormat = t('EmailPassword'); if (strpos($EmailFormat, '{') !== false) { $Message = formatString($EmailFormat, $Data); } else { $Message = sprintf($EmailFormat, $User->Name, $Sender->Name, $AppTitle, ExternalUrl('/'), $Password, $User->Email); } $Message = $this->_addEmailHeaderFooter($Message, $Data); $Email->message($Message); $Email->send(); }
/** * Returns the xhtml for the opening of the form (the form tag and all * hidden elements). * * @param array $Attributes An associative array of attributes for the form tag. Here is a list of * "special" attributes and their default values: * * Attribute Options Default * ---------------------------------------- * method get,post post * action [any url] [The current url] * ajax TRUE,FALSE FALSE * * @return string * * @todo check that missing DataObject parameter */ public function open($Attributes = array()) { // if ($this->InputPrefix) // Trace($this->InputPrefix, 'InputPrefix'); if (!is_array($Attributes)) { $Attributes = array(); } $Return = '<form'; if ($this->InputPrefix != '' || array_key_exists('id', $Attributes)) { $Return .= $this->_idAttribute($this->InputPrefix, $Attributes); } // Method $MethodFromAttributes = arrayValueI('method', $Attributes); $this->Method = $MethodFromAttributes === false ? $this->Method : $MethodFromAttributes; // Action $ActionFromAttributes = arrayValueI('action', $Attributes); if ($this->Action == '') { $this->Action = url(); } $this->Action = $ActionFromAttributes === false ? $this->Action : $ActionFromAttributes; if (strcasecmp($this->Method, 'get') == 0) { // The path is not getting passed on get forms so put them in hidden fields. $Action = strrchr($this->Action, '?'); $Exclude = val('Exclude', $Attributes, array()); if ($Action !== false) { $this->Action = substr($this->Action, 0, -strlen($Action)); parse_str(trim($Action, '?'), $Query); $Hiddens = ''; foreach ($Query as $Key => $Value) { if (in_array($Key, $Exclude)) { continue; } $Key = Gdn_Format::form($Key); $Value = Gdn_Format::form($Value); $Hiddens .= "\n<input type=\"hidden\" name=\"{$Key}\" value=\"{$Value}\" />"; } } } $Return .= ' method="' . $this->Method . '"' . ' action="' . $this->Action . '"' . $this->_attributesToString($Attributes) . ">\n<div>\n"; if (isset($Hiddens)) { $Return .= $Hiddens; } // Postback Key - don't allow it to be posted in the url (prevents csrf attacks & hijacks) if ($this->Method != "get") { $Session = Gdn::session(); $Return .= $this->hidden('TransientKey', array('value' => $Session->transientKey())); // Also add a honeypot if Forms.HoneypotName has been defined $HoneypotName = Gdn::config('Garden.Forms.HoneypotName'); if ($HoneypotName) { $Return .= $this->hidden($HoneypotName, array('Name' => $HoneypotName, 'style' => "display: none;")); } } // Render all other hidden inputs that have been defined $Return .= $this->getHidden(); return $Return; }
/** * Takes a set of form data ($Form->_PostValues), validates them, and * inserts or updates them to the configuration file. * * @param array $FormPostValues An associative array of $Field => $Value pairs that represent data posted * from the form in the $_POST or $_GET collection. */ public function save($FormPostValues, $Live = false) { // Fudge your way through the schema application. This will allow me to // force the validation object to expect the fieldnames contained in // $this->Data. $this->Validation->setSchema($this->Data); // Validate the form posted values if ($this->Validation->validate($FormPostValues)) { // Merge the validation fields and the forced settings into a single array $Settings = $this->Validation->validationFields(); if (is_array($this->_ForceSettings)) { $Settings = mergeArrays($Settings, $this->_ForceSettings); } $SaveResults = saveToConfig($Settings); // If the Live flag is true, set these in memory too if ($SaveResults && $Live) { Gdn::config()->set($Settings, true); } return $SaveResults; } else { return false; } }
/** * Updates the CountDiscussions value on the category based on the CategoryID * being saved. * * @since 2.0.0 * @access public * * @param int $CategoryID Unique ID of category we are updating. */ public function updateDiscussionCount($CategoryID, $Discussion = false) { $DiscussionID = val('DiscussionID', $Discussion, false); if (strcasecmp($CategoryID, 'All') == 0) { $Exclude = (bool) Gdn::config('Vanilla.Archive.Exclude'); $ArchiveDate = Gdn::config('Vanilla.Archive.Date'); $Params = array(); $Where = ''; if ($Exclude && $ArchiveDate) { $Where = 'where d.DateLastComment > :ArchiveDate'; $Params[':ArchiveDate'] = $ArchiveDate; } // Update all categories. $Sql = "update :_Category c\n left join (\n select\n d.CategoryID,\n coalesce(count(d.DiscussionID), 0) as CountDiscussions,\n coalesce(sum(d.CountComments), 0) as CountComments\n from :_Discussion d\n {$Where}\n group by d.CategoryID\n ) d\n on c.CategoryID = d.CategoryID\n set\n c.CountDiscussions = coalesce(d.CountDiscussions, 0),\n c.CountComments = coalesce(d.CountComments, 0)"; $Sql = str_replace(':_', $this->Database->DatabasePrefix, $Sql); $this->Database->query($Sql, $Params, 'DiscussionModel_UpdateDiscussionCount'); } elseif (is_numeric($CategoryID)) { $this->SQL->select('d.DiscussionID', 'count', 'CountDiscussions')->select('d.CountComments', 'sum', 'CountComments')->from('Discussion d')->where('d.CategoryID', $CategoryID); $this->AddArchiveWhere(); $Data = $this->SQL->get()->firstRow(); $CountDiscussions = (int) GetValue('CountDiscussions', $Data, 0); $CountComments = (int) GetValue('CountComments', $Data, 0); $CacheAmendment = array('CountDiscussions' => $CountDiscussions, 'CountComments' => $CountComments); if ($DiscussionID) { $CacheAmendment = array_merge($CacheAmendment, array('LastDiscussionID' => $DiscussionID, 'LastCommentID' => null, 'LastDateInserted' => val('DateInserted', $Discussion))); } $CategoryModel = new CategoryModel(); $CategoryModel->setField($CategoryID, $CacheAmendment); $CategoryModel->SetRecentPost($CategoryID); } }
/** * Select view/method to be used for registration (from config). * * @access protected * @since 2.0.0 * * @return string Method name. */ protected function _registrationView() { $RegistrationMethod = Gdn::config('Garden.Registration.Method'); if (!in_array($RegistrationMethod, array('Closed', 'Basic', 'Captcha', 'Approval', 'Invitation', 'Connect'))) { $RegistrationMethod = 'Basic'; } return 'Register' . $RegistrationMethod; }
/** * Display discussion page starting with a particular comment. * * @since 2.0.0 * @access public * * @param int $CommentID Unique comment ID */ public function comment($CommentID) { // Get the discussionID $Comment = $this->CommentModel->getID($CommentID); if (!$Comment) { throw notFoundException('Comment'); } $DiscussionID = $Comment->DiscussionID; // Figure out how many comments are before this one $Offset = $this->CommentModel->getOffset($Comment); $Limit = Gdn::config('Vanilla.Comments.PerPage', 30); $PageNumber = pageNumber($Offset, $Limit, true); $this->setData('Page', $PageNumber); $this->View = 'index'; $this->index($DiscussionID, 'x', $PageNumber); }
/** * * * @return bool|null * @throws Exception */ public function save() { if (!$this->Dirty) { return null; } $this->EventArguments['ConfigDirty'] =& $this->Dirty; $this->EventArguments['ConfigNoSave'] = false; $this->EventArguments['ConfigType'] = $this->Type; $this->EventArguments['ConfigSource'] = $this->Source; $this->EventArguments['ConfigData'] = $this->Settings; $this->fireEvent('BeforeSave'); if ($this->EventArguments['ConfigNoSave']) { $this->Dirty = false; return true; } // Check for and fire callback if one exists if ($this->Callback && is_callable($this->Callback)) { $CallbackOptions = array(); if (!is_array($this->CallbackOptions)) { $this->CallbackOptions = array(); } $CallbackOptions = array_merge($CallbackOptions, $this->CallbackOptions, array('ConfigDirty' => $this->Dirty, 'ConfigType' => $this->Type, 'ConfigSource' => $this->Source, 'ConfigData' => $this->Settings, 'SourceObject' => $this)); $ConfigSaved = call_user_func($this->Callback, $CallbackOptions); if ($ConfigSaved) { $this->Dirty = false; return true; } } switch ($this->Type) { case 'file': if (empty($this->Source)) { trigger_error(errorMessage('You must specify a file path to be saved.', 'Configuration', 'Save'), E_USER_ERROR); } $CheckWrite = $this->Source; if (!file_exists($CheckWrite)) { $CheckWrite = dirname($CheckWrite); } if (!is_writable($CheckWrite)) { throw new Exception(sprintf(t("Unable to write to config file '%s' when saving."), $this->Source)); } $Group = $this->Group; $Data =& $this->Settings; ksort($Data); // Check for the case when the configuration is the group. if (is_array($Data) && count($Data) == 1 && array_key_exists($Group, $Data)) { $Data = $Data[$Group]; } // Do a sanity check on the config save. if ($this->Source == Gdn::config()->defaultPath()) { // Log root config changes try { $LogData = $this->Initial; $LogData['_New'] = $this->Settings; LogModel::insert('Edit', 'Configuration', $LogData); } catch (Exception $Ex) { } if (!isset($Data['Database'])) { if ($Pm = Gdn::pluginManager()) { $Pm->EventArguments['Data'] = $Data; $Pm->EventArguments['Backtrace'] = debug_backtrace(); $Pm->fireEvent('ConfigError'); } return false; } } // Write config data to string format, ready for saving $FileContents = Gdn_Configuration::format($Data, array('VariableName' => $Group, 'WrapPHP' => true, 'ByLine' => true)); if ($FileContents === false) { trigger_error(errorMessage('Failed to define configuration file contents.', 'Configuration', 'Save'), E_USER_ERROR); } // Save to cache if we're into that sort of thing $FileKey = sprintf(Gdn_Configuration::CONFIG_FILE_CACHE_KEY, $this->Source); if ($this->Configuration && $this->Configuration->caching() && Gdn::cache()->type() == Gdn_Cache::CACHE_TYPE_MEMORY && Gdn::cache()->activeEnabled()) { $CachedConfigData = Gdn::cache()->store($FileKey, $Data, array(Gdn_Cache::FEATURE_NOPREFIX => true, Gdn_Cache::FEATURE_EXPIRY => 3600)); } $TmpFile = tempnam(PATH_CONF, 'config'); $Result = false; if (file_put_contents($TmpFile, $FileContents) !== false) { chmod($TmpFile, 0775); $Result = rename($TmpFile, $this->Source); } if ($Result) { if (function_exists('apc_delete_file')) { // This fixes a bug with some configurations of apc. @apc_delete_file($this->Source); } elseif (function_exists('opcache_invalidate')) { @opcache_invalidate($this->Source); } } $this->Dirty = false; return $Result; break; case 'json': case 'array': case 'string': /** * How would these even save? String config data must be handled by * an event hook or callback, if at all. */ $this->Dirty = false; return false; break; } }
/** * * * @param $InvitationID * @throws Exception */ public function send($InvitationID) { $Invitation = $this->GetByInvitationID($InvitationID); $Session = Gdn::session(); if ($Invitation === false) { throw new Exception(t('ErrorRecordNotFound')); } elseif ($Session->UserID != $Invitation->SenderUserID) { throw new Exception(t('InviteErrorPermission', t('ErrorPermission'))); } else { // Some information for the email $RegistrationUrl = ExternalUrl("entry/registerinvitation/{$Invitation->Code}"); $AppTitle = Gdn::config('Garden.Title'); $Email = new Gdn_Email(); $Email->subject(sprintf(t('[%s] Invitation'), $AppTitle)); $Email->to($Invitation->Email); $Email->message(sprintf(t('EmailInvitation'), $Invitation->SenderName, $AppTitle, $RegistrationUrl)); $Email->send(); } }
/** * * * @throws Exception */ private function _loadRoutes() { $Routes = Gdn::config('Routes', array()); $this->EventArguments['Routes'] =& $Routes; $this->fireEvent("BeforeLoadRoutes"); foreach ($Routes as $Key => $Destination) { $Route = $this->_decodeRouteKey($Key); $RouteData = $this->_parseRoute($Destination); $this->Routes[$Route] = array_merge(array('Route' => $Route, 'Key' => $Key, 'Reserved' => in_array($Route, $this->ReservedRoutes)), $RouteData); } $this->fireEvent("AfterLoadRoutes"); }
/** * Check minimum requirements for Garden. * * @since 2.0.0 * @access private * @return bool Whether platform passes requirement check. */ private function _checkPrerequisites() { // Make sure we are running at least PHP 5.1 if (version_compare(phpversion(), ENVIRONMENT_PHP_VERSION) < 0) { $this->Form->addError(sprintf(t('You are running PHP version %1$s. Vanilla requires PHP %2$s or greater. You must upgrade PHP before you can continue.'), phpversion(), ENVIRONMENT_PHP_VERSION)); } // Make sure PDO is available if (!class_exists('PDO')) { $this->Form->addError(t('You must have the PDO module enabled in PHP in order for Vanilla to connect to your database.')); } if (!defined('PDO::MYSQL_ATTR_USE_BUFFERED_QUERY')) { $this->Form->addError(t('You must have the MySQL driver for PDO enabled in order for Vanilla to connect to your database.')); } // Make sure that the correct filesystem permissions are in place. $PermissionProblem = false; // Make sure the appropriate folders are writable. $ProblemDirectories = array(); if (!is_readable(PATH_CONF) || !isWritable(PATH_CONF)) { $ProblemDirectories[] = PATH_CONF; } if (!is_readable(PATH_UPLOADS) || !isWritable(PATH_UPLOADS)) { $ProblemDirectories[] = PATH_UPLOADS; } if (!is_readable(PATH_CACHE) || !isWritable(PATH_CACHE)) { $ProblemDirectories[] = PATH_CACHE; } if (file_exists(PATH_CACHE . '/Smarty/compile') && (!is_readable(PATH_CACHE . '/Smarty/compile') || !isWritable(PATH_CACHE . '/Smarty/compile'))) { $ProblemDirectories[] = PATH_CACHE . '/Smarty/compile'; } // Display our permission errors. if (count($ProblemDirectories) > 0) { $PermissionProblem = true; $PermissionError = t('Some folders don\'t have correct permissions.', '<p>These folders must be readable and writable by the web server:</p>'); $PermissionHelp = '<pre>' . implode("\n", $ProblemDirectories) . '</pre>'; $this->Form->addError($PermissionError . $PermissionHelp); } // Make sure the config folder is writable. if (!$PermissionProblem) { $ConfigFile = Gdn::config()->defaultPath(); if (file_exists($ConfigFile)) { // Make sure the config file is writable. if (!is_readable($ConfigFile) || !isWritable($ConfigFile)) { $this->Form->addError(sprintf(t('Your configuration file does not have the correct permissions. PHP needs to be able to read and write to this file: <code>%s</code>'), $ConfigFile)); $PermissionProblem = true; } } else { // Make sure the config file can be created. if (!is_writeable(dirname($ConfigFile))) { $this->Form->addError(sprintf(t('Your configuration file cannot be created. PHP needs to be able to create this file: <code>%s</code>'), $ConfigFile)); $PermissionProblem = true; } } } // Make sure the cache folder is writable if (!$PermissionProblem) { if (!file_exists(PATH_CACHE . '/Smarty')) { mkdir(PATH_CACHE . '/Smarty'); } if (!file_exists(PATH_CACHE . '/Smarty/cache')) { mkdir(PATH_CACHE . '/Smarty/cache'); } if (!file_exists(PATH_CACHE . '/Smarty/compile')) { mkdir(PATH_CACHE . '/Smarty/compile'); } } return $this->Form->errorCount() == 0 ? true : false; }
/** * Send password email. * * @param int $UserID * @param string $Password */ public function sendPasswordEmail($UserID, $Password) { $Session = Gdn::session(); $Sender = $this->getID($Session->UserID); $User = $this->getID($UserID); $AppTitle = Gdn::config('Garden.Title'); $Email = new Gdn_Email(); $Email->subject('[' . $AppTitle . '] ' . t('Reset Password')); $Email->to($User->Email); $greeting = formatString(t('Hello %s!'), val('Name', $User)); $message = '<p>' . $greeting . ' ' . sprintf(t('%s has reset your password at %s.'), val('Name', $Sender), $AppTitle) . ' ' . t('Find your account information below.') . '<br></p>' . '<p>' . sprintf(t('%s: %s'), t('Email'), val('Email', $User)) . '<br>' . sprintf(t('%s: %s'), t('Password'), $Password) . '</p>'; $emailTemplate = $Email->getEmailTemplate()->setTitle(t('Reset Password'))->setMessage($message)->setButton(externalUrl('/'), t('Access the Site')); $Email->setEmailTemplate($emailTemplate); try { $Email->send(); } catch (Exception $e) { if (debug()) { throw $e; } } }
/** * Load the basics of the current environment * * The purpose of this method is to consolidate all the various environment information into one * array under a set of common names, thereby removing the tedium of figuring out which superglobal * and key combination contain the requested information each time it is needed. * * @return void */ protected function _loadEnvironment() { $this->_environmentElement('ConfigWebRoot', Gdn::config('Garden.WebRoot')); $this->_environmentElement('ConfigStripUrls', Gdn::config('Garden.StripWebRoot', false)); if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) { $Host = $_SERVER['HTTP_X_FORWARDED_HOST']; } elseif (isset($_SERVER['HTTP_HOST'])) { $Host = $_SERVER['HTTP_HOST']; } else { $Host = val('SERVER_NAME', $_SERVER); } // The host can have the port passed in, remove it here if it exists $HostParts = explode(':', $Host, 2); $Host = $HostParts[0]; $RawPort = null; if (count($HostParts) > 1) { $RawPort = $HostParts[1]; } $this->requestHost($Host); $this->requestMethod(isset($_SERVER['REQUEST_METHOD']) ? val('REQUEST_METHOD', $_SERVER) : 'CONSOLE'); // Request IP // Loadbalancers if ($TestIP = val('HTTP_X_CLUSTER_CLIENT_IP', $_SERVER)) { $IP = $TestIP; } elseif ($TestIP = val('HTTP_CLIENT_IP', $_SERVER)) { $IP = $TestIP; } elseif ($TestIP = val('HTTP_X_FORWARDED_FOR', $_SERVER)) { $IP = $TestIP; } else { $IP = val('REMOTE_ADDR', $_SERVER); } if (strpos($IP, ',') !== false) { $Matched = preg_match_all('/([\\d]{1,3}\\.[\\d]{1,3}\\.[\\d]{1,3}\\.[\\d]{1,3})(?:, )?/i', $IP, $Matches); // If we found matching IPs if ($Matched) { $IPs = $Matches[1]; $IP = $IPs[0]; // Fallback } else { $remoteAddr = val('REMOTE_ADDR', $_SERVER); if (strpos($remoteAddr, ',') !== false) { $remoteAddr = substr($remoteAddr, 0, strpos($remoteAddr, ',')); } $IP = $remoteAddr; } } $IP = forceIPv4($IP); $this->requestAddress($IP); // Request Scheme $Scheme = 'http'; // Webserver-originated SSL if (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') { $Scheme = 'https'; } // Loadbalancer-originated (and terminated) SSL if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https') { $Scheme = 'https'; } // Varnish $OriginalProto = val('HTTP_X_ORIGINALLY_FORWARDED_PROTO', $_SERVER, null); if (!is_null($OriginalProto)) { $Scheme = $OriginalProto; } $this->requestScheme($Scheme); if (isset($_SERVER['SERVER_PORT'])) { $Port = $_SERVER['SERVER_PORT']; } elseif ($RawPort) { $Port = $RawPort; } else { if ($Scheme === 'https') { $Port = 443; } else { $Port = 80; } } $this->port($Port); if (is_array($_GET)) { $Get = false; if ($Get === false) { $Get =& $_GET; } if (!is_array($Get)) { $Original = array(); parse_str($Get, $Original); safeParseStr($Get, $Get, $Original); } if (!empty($_SERVER['X_REWRITE'])) { $Path = $_SERVER['PATH_INFO']; } elseif (isset($Get['_p'])) { $Path = $Get['_p']; unset($_GET['_p']); } elseif (isset($Get['p'])) { $Path = $Get['p']; unset($_GET['p']); } else { $Path = ''; } $this->RequestURI($Path); } $PossibleScriptNames = array(); if (isset($_SERVER['SCRIPT_NAME'])) { $PossibleScriptNames[] = $_SERVER['SCRIPT_NAME']; } if (isset($_ENV['SCRIPT_NAME'])) { $PossibleScriptNames[] = $_ENV['SCRIPT_NAME']; } if (PHP_SAPI === 'cgi' && isset($_ENV['SCRIPT_URL'])) { $PossibleScriptNames[] = $_ENV['SCRIPT_URL']; } if (isset($_SERVER['SCRIPT_FILENAME'])) { $PossibleScriptNames[] = $_SERVER['SCRIPT_FILENAME']; } if (isset($_SERVER['ORIG_SCRIPT_NAME'])) { $PossibleScriptNames[] = $_SERVER['ORIG_SCRIPT_NAME']; } $this->requestFolder(''); $TrimURI = trim($this->requestURI(), '/'); foreach ($PossibleScriptNames as $ScriptName) { $Script = basename($ScriptName); $this->requestScript($Script); $Folder = substr($ScriptName, 0, 0 - strlen($Script)); $TrimFolder = trim($Folder, '/'); $TrimScript = trim($Script, '/'); if (isset($_SERVER['DOCUMENT_ROOT'])) { $DocumentRoot = $_SERVER['DOCUMENT_ROOT']; } else { $AbsolutePath = str_replace("\\", "/", realpath($Script)); $DocumentRoot = substr($AbsolutePath, 0, strpos($AbsolutePath, $ScriptName)); } if (!$DocumentRoot) { continue; } $TrimRoot = rtrim($DocumentRoot); $RealFolder = str_replace($TrimRoot, '', $Folder); if (!empty($RealFolder)) { $this->requestFolder(ltrim($RealFolder, '/')); break; } } }
/** * Configuration of registration settings. * * Events: BeforeRegistrationUpdate * * @since 2.0.0 * @access public * @param string $RedirectUrl Where to send user after registration. */ public function registration($RedirectUrl = '') { $this->permission('Garden.Settings.Manage'); $this->addSideMenu('dashboard/settings/registration'); $this->addJsFile('registration.js'); $this->title(t('Registration')); // Create a model to save configuration settings $Validation = new Gdn_Validation(); $ConfigurationModel = new Gdn_ConfigurationModel($Validation); $registrationOptions = array('Garden.Registration.Method' => 'Captcha', 'Garden.Registration.InviteExpiration', 'Garden.Registration.ConfirmEmail'); if ($manageCaptcha = c('Garden.Registration.ManageCaptcha', true)) { $registrationOptions[] = 'Garden.Registration.CaptchaPrivateKey'; $registrationOptions[] = 'Garden.Registration.CaptchaPublicKey'; } $this->setData('_ManageCaptcha', $manageCaptcha); $ConfigurationModel->setField($registrationOptions); // Set the model on the forms. $this->Form->setModel($ConfigurationModel); // Load roles with sign-in permission $RoleModel = new RoleModel(); $this->RoleData = $RoleModel->getByPermission('Garden.SignIn.Allow'); $this->setData('_Roles', array_column($this->RoleData->resultArray(), 'Name', 'RoleID')); // Get currently selected InvitationOptions $this->ExistingRoleInvitations = Gdn::config('Garden.Registration.InviteRoles'); if (is_array($this->ExistingRoleInvitations) === false) { $this->ExistingRoleInvitations = array(); } // Get the currently selected Expiration Length $this->InviteExpiration = Gdn::config('Garden.Registration.InviteExpiration', ''); // Registration methods. $this->RegistrationMethods = array('Captcha' => "New users fill out a simple form and are granted access immediately.", 'Approval' => "New users are reviewed and approved by an administrator (that's you!).", 'Invitation' => "Existing members send invitations to new members.", 'Connect' => "New users are only registered through SSO plugins."); // Options for how many invitations a role can send out per month. $this->InvitationOptions = array('0' => t('None'), '1' => '1', '2' => '2', '5' => '5', '-1' => t('Unlimited')); // Options for when invitations should expire. $this->InviteExpirationOptions = array('1 week' => t('1 week after being sent'), '2 weeks' => t('2 weeks after being sent'), '1 month' => t('1 month after being sent'), 'FALSE' => t('never')); if ($this->Form->authenticatedPostBack() === false) { $this->Form->setData($ConfigurationModel->Data); } else { // Define some validation rules for the fields being saved $ConfigurationModel->Validation->applyRule('Garden.Registration.Method', 'Required'); // Define the Garden.Registration.RoleInvitations setting based on the postback values $InvitationRoleIDs = $this->Form->getValue('InvitationRoleID'); $InvitationCounts = $this->Form->getValue('InvitationCount'); $this->ExistingRoleInvitations = arrayCombine($InvitationRoleIDs, $InvitationCounts); $ConfigurationModel->forceSetting('Garden.Registration.InviteRoles', $this->ExistingRoleInvitations); // Event hook $this->EventArguments['ConfigurationModel'] =& $ConfigurationModel; $this->fireEvent('BeforeRegistrationUpdate'); // Save! if ($this->Form->save() !== false) { $this->informMessage(t("Your settings have been saved.")); if ($RedirectUrl != '') { $this->RedirectUrl = $RedirectUrl; } } } $this->render(); }
/** * Record when the various actions are taken. * * 1. If the user edits the registration settings. * * @param $Step * @throws Exception */ public function saveStep($Step) { if (Gdn::config($Step, '') != '1') { saveToConfig($Step, '1'); } // If all of the steps are now completed, disable this plugin if (Gdn::config('Plugins.GettingStarted.Registration', '0') == '1' && Gdn::config('Plugins.GettingStarted.Plugins', '0') == '1' && Gdn::config('Plugins.GettingStarted.Categories', '0') == '1' && Gdn::config('Plugins.GettingStarted.Profile', '0') == '1' && Gdn::config('Plugins.GettingStarted.Discussion', '0') == '1') { Gdn::pluginManager()->disablePlugin('GettingStarted'); } }
/** * Insert or update core data about the comment. * * Events: BeforeSaveComment, AfterSaveComment. * * @since 2.0.0 * @access public * * @param array $FormPostValues Data from the form model. * @return int $CommentID */ public function save($FormPostValues) { $Session = Gdn::session(); // Define the primary key in this model's table. $this->defineSchema(); // Add & apply any extra validation rules: $this->Validation->applyRule('Body', 'Required'); $this->Validation->addRule('MeAction', 'function:ValidateMeAction'); $this->Validation->applyRule('Body', 'MeAction'); $MaxCommentLength = Gdn::config('Vanilla.Comment.MaxLength'); if (is_numeric($MaxCommentLength) && $MaxCommentLength > 0) { $this->Validation->SetSchemaProperty('Body', 'Length', $MaxCommentLength); $this->Validation->applyRule('Body', 'Length'); } $MinCommentLength = c('Vanilla.Comment.MinLength'); if ($MinCommentLength && is_numeric($MinCommentLength)) { $this->Validation->SetSchemaProperty('Body', 'MinLength', $MinCommentLength); $this->Validation->addRule('MinTextLength', 'function:ValidateMinTextLength'); $this->Validation->applyRule('Body', 'MinTextLength'); } // Validate $CommentID and whether this is an insert $CommentID = val('CommentID', $FormPostValues); $CommentID = is_numeric($CommentID) && $CommentID > 0 ? $CommentID : false; $Insert = $CommentID === false; if ($Insert) { $this->AddInsertFields($FormPostValues); } else { $this->AddUpdateFields($FormPostValues); } // Prep and fire event $this->EventArguments['FormPostValues'] =& $FormPostValues; $this->EventArguments['CommentID'] = $CommentID; $this->fireEvent('BeforeSaveComment'); // Validate the form posted values if ($this->validate($FormPostValues, $Insert)) { // If the post is new and it validates, check for spam if (!$Insert || !$this->CheckForSpam('Comment')) { $Fields = $this->Validation->SchemaValidationFields(); $Fields = RemoveKeyFromArray($Fields, $this->PrimaryKey); if ($Insert === false) { // Log the save. LogModel::LogChange('Edit', 'Comment', array_merge($Fields, array('CommentID' => $CommentID))); // Save the new value. $this->SerializeRow($Fields); $this->SQL->put($this->Name, $Fields, array('CommentID' => $CommentID)); } else { // Make sure that the comments get formatted in the method defined by Garden. if (!val('Format', $Fields) || c('Garden.ForceInputFormatter')) { $Fields['Format'] = Gdn::config('Garden.InputFormatter', ''); } // Check for spam $Spam = SpamModel::IsSpam('Comment', $Fields); if ($Spam) { return SPAM; } // Check for approval $ApprovalRequired = CheckRestriction('Vanilla.Approval.Require'); if ($ApprovalRequired && !val('Verified', Gdn::session()->User)) { $DiscussionModel = new DiscussionModel(); $Discussion = $DiscussionModel->getID(val('DiscussionID', $Fields)); $Fields['CategoryID'] = val('CategoryID', $Discussion); LogModel::insert('Pending', 'Comment', $Fields); return UNAPPROVED; } // Create comment. $this->SerializeRow($Fields); $CommentID = $this->SQL->insert($this->Name, $Fields); } if ($CommentID) { $this->EventArguments['CommentID'] = $CommentID; $this->EventArguments['Insert'] = $Insert; // IsNewDiscussion is passed when the first comment for new discussions are created. $this->EventArguments['IsNewDiscussion'] = val('IsNewDiscussion', $FormPostValues); $this->fireEvent('AfterSaveComment'); } } } // Update discussion's comment count $DiscussionID = val('DiscussionID', $FormPostValues); $this->UpdateCommentCount($DiscussionID, array('Slave' => false)); return $CommentID; }
Gdn::factoryInstall(Gdn::AliasPluginManager, 'Gdn_PluginManager', '', Gdn::FactorySingleton, [Gdn::addonManager()]); // Start the addons, plugins, and applications. Gdn::addonManager()->startAddonsByKey(c('EnabledPlugins'), Addon::TYPE_ADDON); Gdn::addonManager()->startAddonsByKey(c('EnabledApplications'), Addon::TYPE_ADDON); Gdn::addonManager()->startAddonsByKey(array_keys(c('EnabledLocales', [])), Addon::TYPE_LOCALE); $currentTheme = c(!isMobile() ? 'Garden.Theme' : 'Garden.MobileTheme', 'default'); Gdn::addonManager()->startAddonsByKey([$currentTheme], Addon::TYPE_THEME); // Load the configurations for enabled addons. foreach (Gdn::addonManager()->getEnabled() as $addon) { /* @var Addon $addon */ if ($configPath = $addon->getSpecial('config')) { Gdn::config()->load($addon->path($configPath)); } } // Re-apply loaded user settings. Gdn::config()->overlayDynamic(); /** * Bootstrap Late * * All configurations are loaded, as well as the Application, Plugin and Theme * managers. */ if (file_exists(PATH_CONF . '/bootstrap.late.php')) { require_once PATH_CONF . '/bootstrap.late.php'; } if (c('Debug')) { debug(true); } Gdn_Cache::trace(debug()); /** * Factory Services