protected function _CachePostCounts(&$Sender) { $Discussion = $Sender->Data('Discussion'); $Comments = $Sender->Data('CommentData'); $UserIDList = array(); if ($Discussion) { $UserIDList[$Discussion->InsertUserID] = 1; } if ($Comments && $Comments->NumRows()) { $Comments->DataSeek(-1); while ($Comment = $Comments->NextRow()) { $UserIDList[$Comment->InsertUserID] = 1; } } $UserPostCounts = array(); if (sizeof($UserIDList)) { /* $PostCounts = Gdn::SQL() ->Select('u.UserID') ->Select('u.CountComments + u.CountDiscussions', FALSE, 'PostCount') ->From('User u') ->WhereIn('UserID', array_keys($UserIDList)) ->Get(); */ $PostCounts = Gdn::Database()->Query(sprintf("\n SELECT \n u.UserID,\n COALESCE(u.CountComments,0) + COALESCE(u.CountDiscussions,0) AS PostCount \n FROM GDN_User u \n WHERE UserID IN (%s)", implode(",", array_keys($UserIDList)))); $PostCounts->DataSeek(-1); while ($UserPostCount = $PostCounts->NextRow()) { $UserPostCounts[$UserPostCount->UserID] = $UserPostCount->PostCount; } } $Sender->SetData('Plugin-PostCount-Counts', $UserPostCounts); }
public function Export() { $this->Permission('Garden.Export'); // This permission doesn't exist, so only users with Admin == '1' will succeed. set_time_limit(60*2); $Ex = new ExportModel(); $Ex->PDO(Gdn::Database()->Connection()); $Ex->Prefix = Gdn::Database()->DatabasePrefix; /// 2. Do the export. /// $Ex->UseCompression = TRUE; $Ex->BeginExport(PATH_ROOT.DS.'uploads'.DS.'export '.date('Y-m-d His').'.txt.gz', 'Vanilla 2.0'); $Ex->ExportTable('User', 'select * from :_User'); // ":_" will be replace by database prefix $Ex->ExportTable('Role', 'select * from :_Role'); $Ex->ExportTable('UserRole', 'select * from :_UserRole'); $Ex->ExportTable('Category', 'select * from :_Category'); $Ex->ExportTable('Discussion', 'select * from :_Discussion'); $Ex->ExportTable('Comment', 'select * from :_Comment'); $Ex->ExportTable('Conversation', 'select * from :_Conversation'); $Ex->ExportTable('UserConversation', 'select * from :_UserConversation'); $Ex->ExportTable('ConversationMessage', 'select * from :_ConversationMessage'); $Ex->EndExport(); }
public function Authenticate() { $ForeignIdentityUrl = C('Garden.Authenticator.AuthenticateURL'); if (!$ForeignIdentityUrl) { return FALSE; } try { $Response = $this->_GetForeignCredentials($ForeignIdentityUrl); if (!$Response) { throw new Exception(); } $SQL = Gdn::Database()->SQL(); $Provider = $SQL->Select('uap.AuthenticationKey, uap.AssociationSecret')->From('UserAuthenticationProvider uap')->Get()->FirstRow(DATASET_TYPE_ARRAY); if (!$Provider) { throw new Exception(); } // Got a response from the remote identity provider $UserEmail = ArrayValue('Email', $Response); $UserName = ArrayValue('Name', $Response); $UserName = trim(preg_replace('/[^a-z0-9-]+/i', '', $UserName)); $AuthResponse = $this->ProcessAuthorizedRequest($Provider['AuthenticationKey'], $UserEmail, $UserName); if ($AuthResponse == Gdn_Authenticator::AUTH_SUCCESS) { Gdn::Request()->WithRoute('DefaultController'); } elseif ($AuthResponse == Gdn_Authenticator::AUTH_PARTIAL) { Redirect(Url('/entry/handshake/proxy', TRUE), 302); } else { Gdn::Request()->WithRoute('DefaultController'); throw new Exception('authentication failed'); } } catch (Exception $e) { // Fallback to defer checking until the next session $this->SetIdentity(-1, FALSE); } }
public static function GetCountSQL($Aggregate, $ParentTable, $ChildTable, $ParentColumnName = '', $ChildColumnName = '', $ParentJoinColumn = '', $ChildJoinColumn = '') { if (!$ParentColumnName) { switch (strtolower($Aggregate)) { case 'count': $ParentColumnName = "Count{$ChildTable}s"; break; case 'max': $ParentColumnName = "Last{$ChildTable}ID"; break; case 'min': $ParentColumnName = "First{$ChildTable}ID"; break; case 'sum': $ParentColumnName = "Sum{$ChildTable}s"; break; } } if (!$ChildColumnName) { $ChildColumnName = $ChildTable . 'ID'; } if (!$ParentJoinColumn) { $ParentJoinColumn = $ParentTable . 'ID'; } if (!$ChildJoinColumn) { $ChildJoinColumn = $ParentJoinColumn; } $Result = "update :_{$ParentTable} p\n set p.{$ParentColumnName} = (\n select {$Aggregate}(c.{$ChildColumnName})\n from :_{$ChildTable} c\n where p.{$ParentJoinColumn} = c.{$ChildJoinColumn})"; $Result = str_replace(':_', Gdn::Database()->DatabasePrefix, $Result); return $Result; }
protected function _GetData() { $Px = Gdn::Database()->DatabasePrefix; $Sql = "show table status where Name in ('{$Px}User', '{$Px}Discussion', '{$Px}Comment')"; $Result = array('User' => 0, 'Discussion' => 0, 'Comment' => 0); foreach ($Result as $Name => $Value) { $Result[$Name] = $this->GetCount($Name); } $this->SetData('Totals', $Result); }
/** * The constructor for this class. Automatically fills $this->ClassName. * * @param string $Database * @todo $Database needs a description. */ public function __construct($Database = NULL) { parent::__construct(); if (is_null($Database)) { $this->Database = Gdn::Database(); } else { $this->Database = $Database; } $this->DatabasePrefix($this->Database->DatabasePrefix); $this->Reset(); }
/** * The constructor for this class. Automatically fills $this->ClassName. * * @param string $Database * @todo $Database needs a description. */ public function __construct($Database = NULL) { $this->ClassName = get_class($this); if (is_null($Database)) { $this->Database = Gdn::Database(); } else { $this->Database = $Database; } $this->DatabasePrefix($this->Database->DatabasePrefix); $this->_Reset(); }
public function LoadTable($Tablename, $Path) { if (!array_key_exists($Tablename, $this->Structures)) { throw new Exception("The table \"{$Tablename}\" is not a valid import table."); } $Path = Gdn::Database()->Connection()->quote($Path); $Tablename = Gdn::Database()->DatabasePrefix . self::TABLE_PREFIX . $Tablename; Gdn::Database()->Query("truncate table {$Tablename};"); $Sql = "load data infile {$Path} into table {$Tablename}\r\ncharacter set utf8\r\ncolumns terminated by ','\r\noptionally enclosed by '\"'\r\nescaped by '\\\\'\r\nlines terminated by '\\n'\r\nignore 1 lines;"; Gdn::Database()->Query($Sql); }
/** * The constructor for this class. Automatically fills $this->ClassName. * * @param string $Database * @todo $Database needs a description. */ public function __construct($Database = NULL) { $this->ClassName = get_class($this); if (is_null($Database)) { $this->Database = Gdn::Database(); } else { $this->Database = $Database; } $this->DatabasePrefix($this->Database->DatabasePrefix); $this->_TableName = ''; $this->_Columns = array(); }
public function Base_AfterBody_Handler($Sender) { $Session = Gdn::Session(); if (!Debug() && !$Session->CheckPermission('Plugins.Debugger.View')) { return; } if (!$Sender->Head) { $Sender->Head = new HeadModule($Sender); } $Sender->Head->AddCss('/plugins/Debugger/style.css'); //$Session = Gdn::Session(); //if ($Session->CheckPermission('Plugins.Debugger.View')) { $String = '<div id="Sql" class="DebugInfo">'; $String .= '<h2>' . T('Debug Information') . '</h2>'; // Add the canonical Url. if (method_exists($Sender, 'CanonicalUrl')) { $CanonicalUrl = htmlspecialchars($Sender->CanonicalUrl(), ENT_COMPAT, 'UTF-8'); $String .= '<div class="CanonicalUrl"><b>' . T('Canonical Url') . "</b>: <a href=\"{$CanonicalUrl}\">{$CanonicalUrl}</a></div>"; } $Database = Gdn::Database(); $SQL = $Database->SQL(); if (!is_null($Database)) { $Queries = $Database->Queries(); $QueryTimes = $Database->QueryTimes(); $String .= '<h3>' . count($Queries) . ' queries in ' . $Database->ExecutionTime() . 's</h3>'; foreach ($Queries as $Key => $QueryInfo) { $Query = $QueryInfo['Sql']; // this is a bit of a kludge. I found that the regex below would mess up when there were incremented named parameters. Ie. it would replace :Param before :Param0, which ended up with some values like "'4'0". if (isset($QueryInfo['Parameters']) && is_array($QueryInfo['Parameters'])) { $tmp = $QueryInfo['Parameters']; $Query = $SQL->ApplyParameters($Query, $tmp); } $String .= $QueryInfo['Method'] . '<small>' . @number_format($QueryTimes[$Key], 6) . 's</small>' . (isset($QueryInfo['Cache']) ? '<div><b>Cache:</b> ' . var_export($QueryInfo['Cache'], TRUE) . '</div>' : '') . '<pre>' . htmlspecialchars($Query) . ';</pre>'; } } $String .= '<h3>Controller Data</h3><pre>'; $String .= self::FormatData($Sender->Data); $String .= '</pre>'; global $Start; $String .= '<h3>Page completed in ' . round(Now() - $_SERVER['REQUEST_TIME'], 4) . 's</h3>'; /* <div> <strong>Application:</strong> ' . $Sender->ApplicationFolder . '; <strong>Controller:</strong> ' . $Sender->ClassName . '; <strong>Method:</strong> ' . $Sender->RequestMethod . '; </div> </div>'; */ $String .= '</div>'; echo $String; //} }
/** * Set or setore database prefix (default empty). * Allow use SqlDriver class for building queries for other databases. * https://github.com/vanillaforums/Garden/pull/1266/files * * @param mixed $Px New prefix * @return NULL. */ function DatabasePrefix($Px = '') { static $ConfigDatabasePrefix; static $Count = 0; $Count++; $Database = Gdn::Database(); if ($ConfigDatabasePrefix === Null) { $ConfigDatabasePrefix = $Database->DatabasePrefix; } if ($Count & 1) { $Database->DatabasePrefix = $Px; } else { $Database->DatabasePrefix = $ConfigDatabasePrefix; } }
public function Setup() { // Got Setup? $Database = Gdn::Database(); $Config = Gdn::Factory(Gdn::AliasConfig); $Drop = C('Skeleton.Version') === FALSE ? TRUE : FALSE; $Explicit = TRUE; $Validation = new Gdn_Validation(); // This is going to be needed by structure.php to validate permission names include PATH_APPLICATIONS . DS . 'skeleton' . DS . 'settings' . DS . 'structure.php'; $ApplicationInfo = array(); include CombinePaths(array(PATH_APPLICATIONS . DS . 'skeleton' . DS . 'settings' . DS . 'about.php')); $Version = ArrayValue('Version', ArrayValue('Skeleton', $ApplicationInfo, array()), 'Undefined'); SaveToConfig('Skeleton.Version', $Version); }
public function Base_Render_Before($Sender) { $Session = Gdn::Session(); if (!$Session->CheckPermission('Garden.Settings.Manage')) { return; } if (!$Sender->Head) { $Sender->Head = new HeadModule($Sender); } $Sender->Head->AddCss('/plugins/Debugger/style.css'); //$Session = Gdn::Session(); //if ($Session->CheckPermission('Plugins.Debugger.View')) { $String = '<div id="Sql">'; $Database = Gdn::Database(); if (!is_null($Database)) { $Queries = $Database->Queries(); $QueryTimes = $Database->QueryTimes(); $String .= '<h3>' . count($Queries) . ' queries in ' . $Database->ExecutionTime() . 's</h3>'; foreach ($Queries as $Key => $QueryInfo) { $Query = $QueryInfo['Sql']; // this is a bit of a kludge. I found that the regex below would mess up when there were incremented named parameters. Ie. it would replace :Param before :Param0, which ended up with some values like "'4'0". if (isset($QueryInfo['Parameters']) && is_array($QueryInfo['Parameters'])) { $tmp = $QueryInfo['Parameters']; arsort($tmp); foreach ($tmp as $Name => $Parameter) { $Pattern = '/(.+)(' . $Name . ')([\\W\\s]*)(.*)/'; $Replacement = "\$1'" . htmlentities($Parameter, ENT_COMPAT, 'UTF-8') . "'\$3\$4"; $Query = preg_replace($Pattern, $Replacement, $Query); } } $String .= '<div>' . $QueryInfo['Method'] . '</div><pre>' . $Query . ';</pre><small>' . number_format($QueryTimes[$Key], 6) . 's</small>'; } } global $Start; $String .= '<h3>Page completed in ' . round(Now() - $_SERVER['REQUEST_TIME'], 4) . 's</h3>'; /* <div> <strong>Application:</strong> ' . $Sender->ApplicationFolder . '; <strong>Controller:</strong> ' . $Sender->ClassName . '; <strong>Method:</strong> ' . $Sender->RequestMethod . '; </div> </div>'; */ $String .= '</div>'; $Sender->AddAsset('Foot', $String); //} }
public function Export() { $Ex = $this->ExportModel; $Ex->PDO(Gdn::Database()->Connection()); $Ex->Prefix = Gdn::Database()->DatabasePrefix; /// 2. Do the export. /// $Ex->UseCompression = TRUE; $Ex->BeginExport(PATH_ROOT . DS . 'uploads' . DS . 'export ' . date('Y-m-d His') . '.txt.gz', 'Vanilla 2.0'); $Ex->ExportTable('User', 'select * from :_User'); // ":_" will be replace by database prefix $Ex->ExportTable('Role', 'select * from :_Role'); $Ex->ExportTable('UserRole', 'select * from :_UserRole'); $Ex->ExportTable('Category', 'select * from :_Category'); $Ex->ExportTable('Discussion', 'select * from :_Discussion'); $Ex->ExportTable('Comment', 'select * from :_Comment'); $Ex->EndExport(); }
/** * Get the number of comments inserted since the given timestamp. * * @since 1.0 * @access public */ public function GetCommentCountSince($DiscussionID, $DateAllViewed) { // Only for members $Session = Gdn::Session(); if (!$Session->IsValid()) { return; } // Validate DiscussionID $DiscussionID = (int) $DiscussionID; if (!$DiscussionID) { throw new Exception('A valid DiscussionID is required in GetCommentCountSince.'); } // Prep DB $Database = Gdn::Database(); $SQL = $Database->SQL(); // Get new comment count return $SQL->From('Comment c')->Where('DiscussionID', $DiscussionID)->Where('DateInserted >', Gdn_Format::ToDateTime($DateAllViewed))->GetCount(); }
public function Base_AfterBody_Handler($Sender) { $Session = Gdn::Session(); if (!$Session->CheckPermission('Garden.Settings.Manage')) { return; } if (!$Sender->Head) { $Sender->Head = new HeadModule($Sender); } $Sender->Head->AddCss('/plugins/Debugger/style.css'); //$Session = Gdn::Session(); //if ($Session->CheckPermission('Plugins.Debugger.View')) { $String = '<div id="Sql">'; $Database = Gdn::Database(); $SQL = $Database->SQL(); if (!is_null($Database)) { $Queries = $Database->Queries(); $QueryTimes = $Database->QueryTimes(); $String .= '<h3>' . count($Queries) . ' queries in ' . $Database->ExecutionTime() . 's</h3>'; foreach ($Queries as $Key => $QueryInfo) { $Query = $QueryInfo['Sql']; // this is a bit of a kludge. I found that the regex below would mess up when there were incremented named parameters. Ie. it would replace :Param before :Param0, which ended up with some values like "'4'0". if (isset($QueryInfo['Parameters']) && is_array($QueryInfo['Parameters'])) { $tmp = $QueryInfo['Parameters']; $Query = $SQL->ApplyParameters($Query, $tmp); } $String .= $QueryInfo['Method'] . '<small>' . @number_format($QueryTimes[$Key], 6) . 's</small>' . '<pre>' . $Query . ';</pre>'; } } global $Start; $String .= '<h3>Page completed in ' . round(Now() - $_SERVER['REQUEST_TIME'], 4) . 's</h3>'; /* <div> <strong>Application:</strong> ' . $Sender->ApplicationFolder . '; <strong>Controller:</strong> ' . $Sender->ClassName . '; <strong>Method:</strong> ' . $Sender->RequestMethod . '; </div> </div>'; */ $String .= '</div>'; echo $String; //} }
/** * Setup the application. * * The methods in setup controllers should not call "Render". Rendering will * be handled by the controller that initiated the setup. This method should * return a boolean value indicating success. * * @return bool True on successful setup */ public function Index() { $Database = Gdn::Database(); $Config = Gdn::Factory(Gdn::AliasConfig); $Drop = Gdn::Config('Conversations.Version') === FALSE ? TRUE : FALSE; $Explicit = TRUE; $Validation = new Gdn_Validation(); // This is going to be needed by structure.php to validate permission names try { include PATH_APPLICATIONS . DS . 'conversations' . DS . 'settings' . DS . 'structure.php'; } catch (Exception $ex) { $this->Form->AddError(strip_tags($ex->getMessage())); } if ($this->Form->ErrorCount() == 0) { $ApplicationInfo = array(); include CombinePaths(array(PATH_APPLICATIONS . DS . 'conversations' . DS . 'settings' . DS . 'about.php')); $Version = ArrayValue('Version', ArrayValue('Conversations', $ApplicationInfo, array()), 'Undefined'); SaveToConfig('Conversations.Version', $Version); } return $this->Form->ErrorCount() > 0 ? FALSE : TRUE; }
public function Structure() { Gdn::Structure()->Table('Discussion'); $QnAExists = Gdn::Structure()->ColumnExists('QnA'); $DateAcceptedExists = Gdn::Structure()->ColumnExists('DateAccepted'); Gdn::Structure()->Column('QnA', array('Unanswered', 'Answered', 'Accepted', 'Rejected'), NULL)->Column('DateAccepted', 'datetime', TRUE)->Column('DateOfAnswer', 'datetime', TRUE)->Set(); Gdn::Structure()->Table('Comment')->Column('QnA', array('Accepted', 'Rejected'), NULL)->Column('DateAccepted', 'datetime', TRUE)->Column('AcceptedUserID', 'int', TRUE)->Set(); Gdn::Structure()->Table('User')->Column('CountAcceptedAnswers', 'int', '0')->Set(); Gdn::SQL()->Replace('ActivityType', array('AllowComments' => '0', 'RouteCode' => 'question', 'Notify' => '1', 'Public' => '0', 'ProfileHeadline' => '', 'FullHeadline' => ''), array('Name' => 'QuestionAnswer'), TRUE); Gdn::SQL()->Replace('ActivityType', array('AllowComments' => '0', 'RouteCode' => 'answer', 'Notify' => '1', 'Public' => '0', 'ProfileHeadline' => '', 'FullHeadline' => ''), array('Name' => 'AnswerAccepted'), TRUE); if ($QnAExists && !$DateAcceptedExists) { // Default the date accepted to the accepted answer's date. $Px = Gdn::Database()->DatabasePrefix; $Sql = "update {$Px}Discussion d set DateAccepted = (select min(c.DateInserted) from {$Px}Comment c where c.DiscussionID = d.DiscussionID and c.QnA = 'Accepted')"; Gdn::SQL()->Query($Sql, 'update'); Gdn::SQL()->Update('Discussion')->Set('DateOfAnswer', 'DateAccepted', FALSE, FALSE)->Put(); Gdn::SQL()->Update('Comment c')->Join('Discussion d', 'c.CommentID = d.DiscussionID')->Set('c.DateAccepted', 'c.DateInserted', FALSE, FALSE)->Set('c.AcceptedUserID', 'd.InsertUserID', FALSE, FALSE)->Where('c.QnA', 'Accepted')->Where('c.DateAccepted', NULL)->Put(); } $this->StructureReactions(); $this->StructureBadges(); }
/** * Get the number of comments inserted since the given timestamp. */ function GetCommentCountSince($DiscussionID, $DateSince) { if (!C('Plugins.AllViewed.Enabled')) return; // Only for members $Session = Gdn::Session(); if(!$Session->IsValid()) return; // Validate DiscussionID $DiscussionID = (int) $DiscussionID; if (!$DiscussionID) throw new Exception('A valid DiscussionID is required in GetCommentCountSince.'); // Prep DB $Database = Gdn::Database(); $SQL = $Database->SQL(); // Get new comment count return $SQL ->Select('c.CommentID') ->From('Comment c') ->Where('DiscussionID = '.$DiscussionID) ->Where("DateInserted > '".$DateSince."'") ->Get() ->Count; }
function Redirect($Destination = FALSE, $StatusCode = NULL) { if (!$Destination) { $Destination = Url(''); } // if (Debug() && $Trace = Trace()) { // Trace("Redirecting to $Destination"); // return; // } // Close any db connections before exit $Database = Gdn::Database(); $Database->CloseConnection(); // Clear out any previously sent content @ob_end_clean(); // assign status code $SendCode = is_null($StatusCode) ? 302 : $StatusCode; // re-assign the location header header("Location: " . Url($Destination), TRUE, $SendCode); // Exit exit; }
/** * Setup database structure for model */ public function Structure() { $Database = Gdn::Database(); $Construct = $Database->Structure(); $Construct->Table('DiscussionPolls'); $Construct->PrimaryKey('PollID')->Column('DiscussionID', 'int', FALSE, 'key')->Column('Text', 'varchar(140)', TRUE)->Column('Open', 'tinyint(1)', '1')->Set(); $Construct->Table('DiscussionPollQuestions'); $Construct->PrimaryKey('QuestionID')->Column('PollID', 'int', FALSE, 'key')->Column('Text', 'varchar(140)')->Column('CountResponses', 'int', '0')->Set(); $Construct->Table('DiscussionPollQuestionOptions'); $Construct->PrimaryKey('OptionID')->Column('QuestionID', 'int', FALSE, 'key')->Column('PollID', 'int', FALSE, 'key')->Column('Text', 'varchar(140)')->Column('CountVotes', 'int', '0')->Set(); $Construct->Table('DiscussionPollAnswers'); $Construct->PrimaryKey('AnswerID')->Column('PollID', 'int', FALSE, 'key')->Column('QuestionID', 'int', FALSE, 'key')->Column('UserID', 'int', FALSE, 'key')->Column('OptionID', 'int', TRUE, 'key')->Set(); $Construct->Table('DiscussionPollAnswerPartial'); $Construct->Column('PollID', 'int', FALSE, 'index.1')->Column('QuestionID', 'int', FALSE)->Column('UserID', 'int', FALSE, 'index.1')->Column('OptionID', 'int', FALSE)->Set(); }
/** * Class constructor. Defines the related database table name. * * @param string $Name An optional parameter that allows you to explicitly define the name of * the table that this model represents. You can also explicitly set this * value with $this->Name. */ public function __construct($Name = '') { if ($Name == '') { $Name = get_class($this); } $this->Database = Gdn::Database(); $this->SQL = $this->Database->SQL(); $this->Validation = new Gdn_Validation(); $this->Name = $Name; parent::__construct(); }
/** * If looking at the root node, make sure it exists and that the * nested set columns exist in the table. * * @since 2.0.15 * @access public */ public function ApplyUpdates() { if (!C('Vanilla.NestedCategoriesUpdate')) { // Add new columns $Construct = Gdn::Database()->Structure(); $Construct->Table('Category')->Column('TreeLeft', 'int', TRUE)->Column('TreeRight', 'int', TRUE)->Column('Depth', 'int', TRUE)->Column('CountComments', 'int', '0')->Column('LastCommentID', 'int', TRUE)->Set(0, 0); // Insert the root node if ($this->SQL->GetWhere('Category', array('CategoryID' => -1))->NumRows() == 0) { $this->SQL->Insert('Category', array('CategoryID' => -1, 'TreeLeft' => 1, 'TreeRight' => 4, 'Depth' => 0, 'InsertUserID' => 1, 'UpdateUserID' => 1, 'DateInserted' => Gdn_Format::ToDateTime(), 'DateUpdated' => Gdn_Format::ToDateTime(), 'Name' => 'Root', 'UrlCode' => '', 'Description' => 'Root of category tree. Users should never see this.')); } // Build up the TreeLeft & TreeRight values. $this->RebuildTree(); SaveToConfig('Vanilla.NestedCategoriesUpdate', 1); } }
function Redirect($Destination) { // Close any db connections before exit $Database = Gdn::Database(); $Database->CloseConnection(); // Clear out any previously sent content @ob_end_clean(); // re-assign the location header header("location: " . Url($Destination)); // Exit exit; }
/** * Automatically executed when application is enabled. * * @since 2.0.0 * @package Vanilla */ public function Setup() { $Database = Gdn::Database(); $Config = Gdn::Factory(Gdn::AliasConfig); $Drop = Gdn::Config('Vanilla.Version') === FALSE ? TRUE : FALSE; $Explicit = TRUE; // Call structure.php to update database $Validation = new Gdn_Validation(); // Needed by structure.php to validate permission names include PATH_APPLICATIONS . DS . 'vanilla' . DS . 'settings' . DS . 'structure.php'; include PATH_APPLICATIONS . DS . 'vanilla' . DS . 'settings' . DS . 'stub.php'; $ApplicationInfo = array(); include CombinePaths(array(PATH_APPLICATIONS . DS . 'vanilla' . DS . 'settings' . DS . 'about.php')); $Version = ArrayValue('Version', ArrayValue('Vanilla', $ApplicationInfo, array()), 'Undefined'); $Save = array('Vanilla.Version' => $Version, 'Routes.DefaultController' => 'discussions'); SaveToConfig($Save); }
public function UpdateProxy() { $Fields = $_POST; foreach ($Fields as $Field => $Value) { if (get_magic_quotes_gpc()) { if (is_array($Value)) { $Count = count($Value); for ($i = 0; $i < $Count; ++$i) { $Value[$i] = stripslashes($Value[$i]); } } else { $Value = stripslashes($Value); } $Fields[$Field] = $Value; } } $UpdateCheckUrl = C('Garden.UpdateCheckUrl', 'http://vanillaforums.org/addons/update'); echo ProxyRequest($UpdateCheckUrl.'?'.http_build_query($Fields)); $Database = Gdn::Database(); $Database->CloseConnection(); }
/** * A custom error handler that displays much more, very useful information when * errors are encountered in Garden. * @param Exception $Exception The exception that was thrown. */ function Gdn_ExceptionHandler($Exception) { try { $ErrorNumber = $Exception->getCode(); $Message = $Exception->getMessage(); $File = $Exception->getFile(); $Line = $Exception->getLine(); if (method_exists($Exception, 'getContext')) { $Arguments = $Exception->getContext(); } else { $Arguments = ''; } $Backtrace = $Exception->getTrace(); // Clean the output buffer in case an error was encountered in-page. @ob_end_clean(); // prevent headers already sent error if (!headers_sent()) { header('Content-Type: text/html; charset=utf-8'); } $SenderMessage = $Message; $SenderObject = 'PHP'; $SenderMethod = 'Gdn_ErrorHandler'; $SenderCode = FALSE; $SenderTrace = $Backtrace; $MessageInfo = explode('|', $Message); $MessageCount = count($MessageInfo); if ($MessageCount == 4) { list($SenderMessage, $SenderObject, $SenderMethod, $SenderCode) = $MessageInfo; } else { if ($MessageCount == 3) { list($SenderMessage, $SenderObject, $SenderMethod) = $MessageInfo; } elseif (function_exists('GetValueR')) { $IsError = GetValueR('0.function', $SenderTrace) == 'Gdn_ErrorHandler'; // not exception $N = $IsError ? '1' : '0'; $SenderMethod = GetValueR($N . '.function', $SenderTrace, $SenderMethod); $SenderObject = GetValueR($N . '.class', $SenderTrace, $SenderObject); } } $SenderMessage = strip_tags($SenderMessage); $Master = FALSE; // The parsed master view $CssPath = FALSE; // The web-path to the css file $ErrorLines = FALSE; // The lines near the error's line # $DeliveryType = defined('DELIVERY_TYPE_ALL') ? DELIVERY_TYPE_ALL : 'ALL'; if (array_key_exists('DeliveryType', $_POST)) { $DeliveryType = $_POST['DeliveryType']; } else { if (array_key_exists('DeliveryType', $_GET)) { $DeliveryType = $_GET['DeliveryType']; } } // Make sure all of the required custom functions and variables are defined. $PanicError = FALSE; // Should we just dump a message and forget about the master view? if (!defined('DS')) { $PanicError = TRUE; } if (!defined('PATH_ROOT')) { $PanicError = TRUE; } if (!defined('APPLICATION')) { define('APPLICATION', 'Garden'); } if (!defined('APPLICATION_VERSION')) { define('APPLICATION_VERSION', 'Unknown'); } $WebRoot = ''; // Try and rollback a database transaction. if (class_exists('Gdn', FALSE)) { $Database = Gdn::Database(); if (is_object($Database)) { $Database->RollbackTransaction(); } } if ($PanicError === FALSE) { // See if we can get the file that caused the error if (is_string($File) && is_numeric($ErrorNumber)) { $ErrorLines = @file($File); } // If this error was encountered during an ajax request, don't bother gettting the css or theme files if ($DeliveryType == DELIVERY_TYPE_ALL) { $CssPaths = array(); // Potential places where the css can be found in the filesystem. $MasterViewPaths = array(); $MasterViewName = 'error.master.php'; $MasterViewCss = 'error.css'; if (class_exists('Gdn', FALSE)) { $CurrentTheme = ''; // The currently selected theme $CurrentTheme = Gdn::Config('Garden.Theme', ''); $MasterViewName = Gdn::Config('Garden.Errors.MasterView', $MasterViewName); $MasterViewCss = substr($MasterViewName, 0, strpos($MasterViewName, '.')); if ($MasterViewCss == '') { $MasterViewCss = 'error'; } $MasterViewCss .= '.css'; if ($CurrentTheme != '') { // Look for CSS in the theme folder: $CssPaths[] = PATH_THEMES . DS . $CurrentTheme . DS . 'design' . DS . $MasterViewCss; // Look for Master View in the theme folder: $MasterViewPaths[] = PATH_THEMES . DS . $CurrentTheme . DS . 'views' . DS . $MasterViewName; } } // Look for CSS in the dashboard design folder. $CssPaths[] = PATH_APPLICATIONS . DS . 'dashboard' . DS . 'design' . DS . $MasterViewCss; // Look for Master View in the dashboard view folder. $MasterViewPaths[] = PATH_APPLICATIONS . DS . 'dashboard' . DS . 'views' . DS . $MasterViewName; $CssPath = FALSE; $Count = count($CssPaths); for ($i = 0; $i < $Count; ++$i) { if (file_exists($CssPaths[$i])) { $CssPath = $CssPaths[$i]; break; } } if ($CssPath !== FALSE) { $CssPath = str_replace(array(PATH_ROOT, DS), array('', '/'), $CssPath); $CssPath = ($WebRoot == '' ? '' : '/' . $WebRoot) . $CssPath; } $MasterViewPath = FALSE; $Count = count($MasterViewPaths); for ($i = 0; $i < $Count; ++$i) { if (file_exists($MasterViewPaths[$i])) { $MasterViewPath = $MasterViewPaths[$i]; break; } } if ($MasterViewPath !== FALSE) { include $MasterViewPath; $Master = TRUE; } } } if ($DeliveryType != DELIVERY_TYPE_ALL) { // This is an ajax request, so dump an error that is more eye-friendly in the debugger echo '<h1>FATAL ERROR IN: ', $SenderObject, '.', $SenderMethod, "();</h1>\n<div class=\"AjaxError\">\"" . $SenderMessage . "\"\n"; if ($SenderCode != '') { echo htmlentities($SenderCode, ENT_COMPAT, 'UTF-8') . "\n"; } if (is_array($ErrorLines) && $Line > -1) { echo "LOCATION: ", $File, "\n"; } $LineCount = count($ErrorLines); $Padding = strlen($Line + 5); for ($i = 0; $i < $LineCount; ++$i) { if ($i > $Line - 6 && $i < $Line + 4) { if ($i == $Line - 1) { echo '>>'; } echo '> ' . str_pad($i + 1, $Padding, " ", STR_PAD_LEFT), ': ', str_replace(array("\n", "\r"), array('', ''), $ErrorLines[$i]), "\n"; } } if (is_array($Backtrace)) { echo "BACKTRACE:\n"; $BacktraceCount = count($Backtrace); for ($i = 0; $i < $BacktraceCount; ++$i) { if (array_key_exists('file', $Backtrace[$i])) { $File = $Backtrace[$i]['file'] . ' ' . $Backtrace[$i]['line']; } echo '[' . $File . ']', ' ', array_key_exists('class', $Backtrace[$i]) ? $Backtrace[$i]['class'] : 'PHP', array_key_exists('type', $Backtrace[$i]) ? $Backtrace[$i]['type'] : '::', $Backtrace[$i]['function'], '();', "\n"; } } echo '</div>'; } else { // If the master view wasn't found, assume a panic state and dump the error. if ($Master === FALSE) { echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-ca"> <head> <title>Fatal Error</title> </head> <body> <h1>Fatal Error in ', $SenderObject, '.', $SenderMethod, '();</h1> <h2>', $SenderMessage, "</h2>\n"; if ($SenderCode != '') { echo '<code>', htmlentities($SenderCode, ENT_COMPAT, 'UTF-8'), "</code>\n"; } if (is_array($ErrorLines) && $Line > -1) { echo '<h3><strong>The error occurred on or near:</strong> ', $File, '</h3> <pre>'; $LineCount = count($ErrorLines); $Padding = strlen($Line + 4); for ($i = 0; $i < $LineCount; ++$i) { if ($i > $Line - 6 && $i < $Line + 4) { echo str_pad($i, $Padding, " ", STR_PAD_LEFT), ': ', htmlentities($ErrorLines[$i], ENT_COMPAT, 'UTF-8'); } } echo "</pre>\n"; } echo '<h2>Need Help?</h2> <p>If you are a user of this website, you can report this message to a website administrator.</p> <p>If you are an administrator of this website, you can get help at the <a href="http://vanillaforums.org/discussions/" target="_blank">Vanilla Community Forums</a>.</p> <h2>Additional information for support personnel:</h2> <ul> <li><strong>Application:</strong> ', APPLICATION, '</li> <li><strong>Application Version:</strong> ', APPLICATION_VERSION, '</li> <li><strong>PHP Version:</strong> ', PHP_VERSION, '</li> <li><strong>Operating System:</strong> ', PHP_OS, "</li>\n"; if (array_key_exists('SERVER_SOFTWARE', $_SERVER)) { echo '<li><strong>Server Software:</strong> ', $_SERVER['SERVER_SOFTWARE'], "</li>\n"; } if (array_key_exists('HTTP_REFERER', $_SERVER)) { echo '<li><strong>Referer:</strong> ', $_SERVER['HTTP_REFERER'], "</li>\n"; } if (array_key_exists('HTTP_USER_AGENT', $_SERVER)) { echo '<li><strong>User Agent:</strong> ', $_SERVER['HTTP_USER_AGENT'], "</li>\n"; } if (array_key_exists('REQUEST_URI', $_SERVER)) { echo '<li><strong>Request Uri:</strong> ', $_SERVER['REQUEST_URI'], "</li>\n"; } echo '</ul> </body> </html>'; } } // Attempt to log an error message no matter what. LogMessage($File, $Line, $SenderObject, $SenderMethod, $SenderMessage, $SenderCode); } catch (Exception $e) { print get_class($e) . " thrown within the exception handler.<br/>Message: " . $e->getMessage() . " in " . $e->getFile() . " on line " . $e->getLine(); exit; } }
public function LookupNonce($TokenKey, $Nonce = NULL) { $NonceData = Gdn::Database()->SQL()->Select('uan.*')->From('UserAuthenticationNonce uan')->Where('uan.Token', $TokenKey)->Get()->FirstRow(DATASET_TYPE_ARRAY); if ($NonceData && (is_null($Nonce) || $NonceData['Nonce'] == $Nonce)) { return $NonceData['Nonce']; } return FALSE; }
/** * Registration that requires approval. * * Events: RegistrationPending * * @access private * @since 2.0.0 */ private function RegisterApproval() { Gdn::UserModel()->AddPasswordStrength($this); // If the form has been posted back... if ($this->Form->IsPostBack()) { // Add validation rules that are not enforced by the model $this->UserModel->DefineSchema(); $this->UserModel->Validation->ApplyRule('Name', 'Username', $this->UsernameError); $this->UserModel->Validation->ApplyRule('TermsOfService', 'Required', T('You must agree to the terms of service.')); $this->UserModel->Validation->ApplyRule('Password', 'Required'); $this->UserModel->Validation->ApplyRule('Password', 'Strength'); $this->UserModel->Validation->ApplyRule('Password', 'Match'); $this->UserModel->Validation->ApplyRule('DiscoveryText', 'Required', 'Tell us why you want to join!'); // $this->UserModel->Validation->ApplyRule('DateOfBirth', 'MinimumAge'); $this->FireEvent('RegisterValidation'); try { $Values = $this->Form->FormValues(); unset($Values['Roles']); $AuthUserID = $this->UserModel->Register($Values); if (!$AuthUserID) { $this->Form->SetValidationResults($this->UserModel->ValidationResults()); } else { // The user has been created successfully, so sign in now. Gdn::Session()->Start($AuthUserID); if ($this->Form->GetFormValue('RememberMe')) { Gdn::Authenticator()->SetIdentity($AuthUserID, TRUE); } // Notification text $Label = T('NewApplicantEmail', 'New applicant:'); $Story = Anchor(Gdn_Format::Text($Label . ' ' . $Values['Name']), ExternalUrl('dashboard/user/applicants')); $this->EventArguments['AuthUserID'] = $AuthUserID; $this->EventArguments['Story'] =& $Story; $this->FireEvent('RegistrationPending'); $this->View = "RegisterThanks"; // Tell the user their application will be reviewed by an administrator. // Grab all of the users that need to be notified. $Data = Gdn::Database()->SQL()->GetWhere('UserMeta', array('Name' => 'Preferences.Email.Applicant'))->ResultArray(); $ActivityModel = new ActivityModel(); foreach ($Data as $Row) { $ActivityModel->Add($AuthUserID, 'Applicant', $Story, $Row['UserID'], '', '/dashboard/user/applicants', 'Only'); } } } catch (Exception $Ex) { $this->Form->AddError($Ex); } } $this->Render(); }
/** * 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. */ public 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.RewriteUrls', '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); // Load the locales for the locale dropdown // $Locale = Gdn::Locale(); // $AvailableLocales = $Locale->GetAvailableLocaleSources(); // $this->LocaleData = array_combine($AvailableLocales, $AvailableLocales); // 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 : RandomString(10); $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) { $ApplicationManager = new Gdn_ApplicationManager(); $Locale = Gdn::Locale(); $Locale->Set($NewLocale, $ApplicationManager->EnabledApplicationFolders(), Gdn::PluginManager()->EnabledPluginFolders(), TRUE); } // Install db structure & basic data. $Database = Gdn::Database(); $Database->Init(); $Drop = FALSE; // Gdn::Config('Garden.Version') === FALSE ? TRUE : 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 rewrite abilities try { $Query = ConcatSep('/', Gdn::Request()->Domain(), Gdn::Request()->WebRoot(), 'dashboard/setup'); $Results = ProxyHead($Query, array(), 3); $CanRewrite = FALSE; if (in_array(ArrayValue('StatusCode', $Results, 404), array(200, 302)) && ArrayValue('X-Garden-Version', $Results, 'None') != 'None') { $CanRewrite = TRUE; } } catch (Exception $e) { // cURL and fsockopen arent supported... guess? $CanRewrite = function_exists('apache_get_modules') && in_array('mod_rewrite', apache_get_modules()) ? TRUE : FALSE; } SaveToConfig(array('Garden.Version' => ArrayValue('Version', GetValue('Dashboard', $ApplicationInfo, array()), 'Undefined'), 'Garden.RewriteUrls' => $CanRewrite, 'Garden.CanProcessImages' => function_exists('gd_info'), 'EnabledPlugins.GettingStarted' => 'GettingStarted', 'EnabledPlugins.HtmLawed' => 'HtmLawed')); } } return $this->Form->ErrorCount() == 0 ? TRUE : FALSE; }