public function BuildCategorySiteMap($UrlCode, &$Urls) { $Category = CategoryModel::Categories($UrlCode); if (!$Category) { throw NotFoundException(); } // Get the min/max dates for the sitemap. $Row = Gdn::SQL()->Select('DateInserted', 'min', 'MinDate')->Select('DateInserted', 'max', 'MaxDate')->From('Discussion')->Where('CategoryID', $Category['CategoryID'])->Get()->FirstRow(DATASET_TYPE_ARRAY); if ($Row) { $From = strtotime('first day of this month 00:00:00', strtotime($Row['MaxDate'])); $To = strtotime('first day of this month 00:00:00', strtotime($Row['MinDate'])); if (!$From || !$To) { $From = -1; $To = 0; } } else { $From = -1; $To = 0; } $Now = time(); for ($i = $From; $i >= $To; $i = strtotime('-1 month', $i)) { $Url = array('Loc' => Url('/categories/archives/' . rawurlencode($Category['UrlCode'] ? $Category['UrlCode'] : $Category['CategoryID']) . '/' . gmdate('Y-m', $i), TRUE), 'LastMod' => '', 'ChangeFreq' => ''); $LastMod = strtotime('last day of this month', $i); if ($LastMod > $Now) { $LastMod = $Now; } $Url['LastMod'] = gmdate('c', $LastMod); $Urls[] = $Url; } // If there are no links then just link to the category. if (count($Urls) === 0) { $Url = array('Loc' => CategoryUrl($Category), 'LastMode' => '', 'ChangeFreq' => ''); $Urls[] = $Url; } }
public function Page($Reference) { $PageModel = new PageModel(); $Page = $PageModel->GetFullID($Reference); if (!$Page) { throw NotFoundException(); } $this->Page = $Page; if ($this->Head) { SetMetaTags($Page, $this); if ($Page->CustomCss) { $CustomCss = "\n" . $Page->CustomCss; if (!StringBeginsWith(trim($CustomCss), '<style', True)) { $CustomCss = Wrap($CustomCss, 'style', array('type' => 'text/css')); } $this->Head->AddString($CustomCss); } if ($Page->CustomJs) { $CustomJs = $Page->CustomJs; if (!StringBeginsWith(trim($CustomJs), '<script', True)) { $CustomJs = Wrap($CustomJs, 'script', array('type' => 'text/javascript')); } $this->Head->AddString($CustomJs); } } if ($Page->SectionID) { $this->Section = BuildNode($Page, 'Section'); $this->SectionID = $Page->SectionID; CandyHooks::AddModules($this, $this->Section); } $this->FireEvent('ContentPage'); if ($Page->View) { $this->View = $this->FetchViewLocation($this->View, False, False, False); } if (!$this->View) { $this->View = $this->FetchViewLocation('view', 'page', '', False); if (!$this->View) { $this->View = 'default'; } } $this->Title($Page->Title); $this->SetData('Content', $Page, True); $this->EventArguments['Format'] =& $Page->Format; $this->EventArguments['Body'] =& $Page->Body; $this->FireEvent('BeforeBodyFormat'); $this->ContentBodyHtml = Gdn_Format::To($Page->Body, $Page->Format); $Doc = PqDocument($this->ContentBodyHtml); $Header = $Doc->Find('h1'); $CountH1 = count($Header); if ($CountH1 == 0) { $this->SetData('Headline', Gdn_Format::Text($Page->Title)); } elseif ($CountH1 == 1) { $this->SetData('Headline', $Header->Text()); $Header->Remove(); $this->ContentBodyHtml = $Doc->Html(); } // $this->AddModule('PageInfoModule'); $this->Render(); }
public function UserController_TempBan_Create($Sender, $Args) { $Sender->Permission('Garden.Moderation.Manage'); $UserID = (int) GetValue('0', $Args); $Unban = (bool) GetValue('1', $Args); $User = Gdn::UserModel()->GetID($UserID, DATASET_TYPE_ARRAY); if (!$User) { throw NotFoundException($User); } $UserModel = Gdn::UserModel(); if ($Sender->Form->AuthenticatedPostBack()) { if ($Unban) { $UserModel->Unban($UserID, array('RestoreContent' => $Sender->Form->GetFormValue('RestoreContent'))); } else { $Minutes = $Sender->Form->GetValue('TempBanPeriodMinutes'); $Hours = $Sender->Form->GetValue('TempBanPeriodHours'); $Days = $Sender->Form->GetValue('TempBanPeriodDays'); $Months = $Sender->Form->GetValue('TempBanPeriodMonths'); $Years = $Sender->Form->GetValue('TempBanPeriodYears'); if (!(empty($Minutes) && empty($Hours) && empty($Days) && empty($Months) && empty($Years))) { $AutoExpirePeriod = Gdn_Format::ToDateTime(strtotime("+{$Years} years {$Months} months {$Days} days {$Hours} hours {$Minutes} minutes")); } else { $Sender->Form->AddError('ValidateRequired', 'Ban Period'); } if (!ValidateRequired($Sender->Form->GetFormValue('Reason'))) { $Sender->Form->AddError('ValidateRequired', 'Reason'); } if ($Sender->Form->GetFormValue('Reason') == 'Other' && !ValidateRequired($Sender->Form->GetFormValue('ReasonText'))) { $Sender->Form->AddError('ValidateRequired', 'Reason Text'); } if ($Sender->Form->ErrorCount() == 0) { if ($Sender->Form->GetFormValue('Reason') == 'Other') { $Reason = $Sender->Form->GetFormValue('ReasonText'); } else { $Reason = $Sender->Form->GetFormValue('Reason'); } Gdn::Locale()->SetTranslation('HeadlineFormat.Ban', FormatString('{RegardingUserID,You} banned {ActivityUserID,you} until {BanExpire, date}.', array('BanExpire' => $AutoExpirePeriod))); $UserModel->Ban($UserID, array('Reason' => $Reason)); $UserModel->SetField($UserID, 'BanExpire', $AutoExpirePeriod); } } if ($Sender->Form->ErrorCount() == 0) { // Redirect after a successful save. if ($Sender->Request->Get('Target')) { $Sender->RedirectUrl = $Sender->Request->Get('Target'); } else { $Sender->RedirectUrl = Url(UserUrl($User)); } } } $Sender->SetData('User', $User); $Sender->AddSideMenu(); $Sender->Title($Unban ? T('Unban User') : T('Temporary Ban User')); if ($Unban) { $Sender->View = 'Unban'; } else { $Sender->View = $this->ThemeView('tempban'); } $Sender->Render(); }
/** * Creates and renders an instance of a module. */ public function Index($Module, $AppFolder = '') { $ModuleClassExists = class_exists($Module); if ($ModuleClassExists) { // Make sure that the class implements Gdn_IModule $ReflectionClass = new ReflectionClass($Module); if ($ReflectionClass->implementsInterface("Gdn_IModule")) { // Set the proper application folder on this controller so that things render properly. if ($AppFolder) { $this->ApplicationFolder = $AppFolder; } else { $Filename = str_replace('\\', '/', substr($ReflectionClass->getFileName(), strlen(PATH_ROOT))); // Figure our the application folder for the module. $Parts = explode('/', trim($Filename, '/')); if ($Parts[0] == 'applications') { $this->ApplicationFolder = $Parts[1]; } } $ModuleInstance = new $Module($this); $this->SetData('_Module', $ModuleInstance); $this->Render('Index', FALSE, 'dashboard'); return; } } throw NotFoundException($Module); }
/** * A standard 404 File Not Found error message is delivered when this action * is encountered. */ public function FileNotFound() { if ($this->DeliveryMethod() == DELIVERY_METHOD_XHTML) { $this->Render(); } else { $this->RenderException(NotFoundException()); } }
/** * A standard 404 File Not Found error message is delivered when this action * is encountered. * * @since 2.0.0 * @access public */ public function FileNotFound() { if ($this->DeliveryMethod() == DELIVERY_METHOD_XHTML) { header("HTTP/1.0 404", TRUE, 404); $this->Render(); } else { $this->RenderException(NotFoundException()); } }
/** * Handle discussion option menu bump action. */ public function DiscussionController_Bump_Create($Sender, $Args) { $Sender->Permission('Garden.Moderation.Manage'); // Get discussion $DiscussionID = $Sender->Request->Get('discussionid'); $Discussion = $Sender->DiscussionModel->GetID($DiscussionID); if (!$Discussion) { throw NotFoundException('Discussion'); } // Update DateLastComment & redirect $Sender->DiscussionModel->SetProperty($DiscussionID, 'DateLastComment', Gdn_Format::ToDateTime()); Redirect(DiscussionUrl($Discussion)); }
/** * Handle discussion option menu NoIndex action (simple toggle). */ public function DiscussionController_NoIndex_Create($Sender, $Args) { $Sender->Permission(array('Garden.Moderation.Manage', 'Garden.Curation.Manage'), FALSE); // Get discussion $DiscussionID = $Sender->Request->Get('discussionid'); $Discussion = $Sender->DiscussionModel->GetID($DiscussionID); if (!$Discussion) { throw NotFoundException('Discussion'); } // Toggle NoIndex $NoIndex = GetValue('NoIndex', $Discussion) ? 0 : 1; // Update DateLastComment & redirect $Sender->DiscussionModel->SetProperty($DiscussionID, 'NoIndex', $NoIndex); Redirect(DiscussionUrl($Discussion)); }
/** * A standard 404 File Not Found error message is delivered when this action * is encountered. * * @since 2.0.0 * @access public */ public function FileNotFound() { $this->RemoveCssFile('admin.css'); $this->AddCssFile('style.css'); $this->MasterView = 'default'; if ($this->Data('ViewPaths')) { Trace($this->Data('ViewPaths'), 'View Paths'); } if ($this->DeliveryMethod() == DELIVERY_METHOD_XHTML) { header("HTTP/1.0 404", TRUE, 404); $this->Render(); } else { $this->RenderException(NotFoundException()); } }
/** * Show some facets about a specific badge * * @param int $BadgeID * @param string $Slug * @throws NotFoundException */ public function Detail($BadgeID, $Slug = NULL) { $UserID = Gdn::Session()->UserID; $Badge = $this->BadgeModel->GetByID($BadgeID); $AwardCount = $this->BadgeAwardModel->GetCount($BadgeID); $UserBadgeAward = $this->BadgeAwardModel->Exists($UserID, $BadgeID); $RecentAwards = $this->BadgeAwardModel->GetRecent($BadgeID); if (!$Badge) { throw NotFoundException('Badge'); } $this->SetData('AwardCount', $AwardCount); $this->SetData('RecentAwards', $RecentAwards); $this->SetData('UserBadgeAward', $UserBadgeAward); $this->SetData('Badge', $Badge); $this->Title(T('Yaga.Badge.View') . $Badge->Name); $this->Render(); }
/** * A standard 404 File Not Found error message is delivered when this action * is encountered. * * @since 2.0.0 * @access public */ public function FileNotFound() { $this->RemoveCssFile('admin.css'); $this->AddCssFile('style.css'); $this->MasterView = 'default'; $this->CssClass = 'SplashMessage NoPanel'; if ($this->Data('ViewPaths')) { Trace($this->Data('ViewPaths'), 'View Paths'); } $this->SetData('_NoMessages', TRUE); Gdn_Theme::Section('Error'); if ($this->DeliveryMethod() == DELIVERY_METHOD_XHTML) { safeHeader("HTTP/1.0 404", TRUE, 404); $this->Render(); } else { $this->RenderException(NotFoundException()); } }
public function Enable($Plugin) { $this->Permission('Garden.Settings.Manage'); $Connections = $this->GetConnections(); if (!array_key_exists($Plugin, $Connections)) { throw NotFoundException('SocialConnect Plugin'); } Gdn::PluginManager()->EnablePlugin($Plugin, NULL); $Connections = $this->GetConnections(); $Connection = GetValue($Plugin, $Connections); require_once $this->FetchViewLocation('connection_functions'); ob_start(); WriteConnection($Connection); $Row = ob_get_clean(); $this->JsonTarget("#Provider_{$Connection['Index']}", $Row); $this->InformMessage(T("Plugin enabled.")); unset($this->Data['Connections']); $this->Render('blank', 'utility'); }
/** * A standard 404 File Not Found error message is delivered when this action * is encountered. * * @since 2.0.0 * @access public */ public function fileNotFound() { $this->removeCssFile('admin.css'); $this->addCssFile('style.css'); $this->addCssFile('vanillicon.css', 'static'); $this->MasterView = 'default'; $this->CssClass = 'SplashMessage NoPanel'; if ($this->data('ViewPaths')) { trace($this->data('ViewPaths'), 'View Paths'); } $this->setData('_NoMessages', true); Gdn_Theme::section('Error'); if ($this->deliveryMethod() == DELIVERY_METHOD_XHTML) { safeHeader("HTTP/1.0 404", true, 404); $this->render(); } else { $this->RenderException(NotFoundException()); } }
/** * Handle discussion option menu Change Author action. */ public function discussionController_author_create($Sender) { $DiscussionID = $Sender->Request->get('discussionid'); $Discussion = $Sender->DiscussionModel->getID($DiscussionID); if (!$Discussion) { throw NotFoundException('Discussion'); } // Check edit permission $Sender->permission('Vanilla.Discussions.Edit', true, 'Category', $Discussion->PermissionCategoryID); if ($Sender->Form->authenticatedPostBack()) { // Change the author $Name = $Sender->Form->getFormValue('Author', ''); $UserModel = new UserModel(); if (trim($Name) != '') { $User = $UserModel->getByUsername(trim($Name)); if (is_object($User)) { if ($Discussion->InsertUserID == $User->UserID) { $Sender->Form->addError('That user is already the discussion author.'); } else { // Change discussion InsertUserID $Sender->DiscussionModel->setField($DiscussionID, 'InsertUserID', $User->UserID); // Update users' discussion counts $Sender->DiscussionModel->updateUserDiscussionCount($Discussion->InsertUserID); $Sender->DiscussionModel->updateUserDiscussionCount($User->UserID, true); // Increment // Go to the updated discussion redirect(discussionUrl($Discussion)); } } else { $Sender->Form->addError('No user with that name was found.'); } } } else { // Form to change the author $Sender->setData('Title', $Discussion->Name); } $Sender->render('changeauthor', '', 'plugins/AuthorSelector'); }
public function UserController_Warning_Create($Sender, $Args) { $Sender->Permission('Garden.Moderation.Manage'); $UserID = (int) GetValue('0', $Args); $User = Gdn::UserModel()->GetID($UserID); if (!$User) { throw NotFoundException($User); } if ($Sender->Form->AuthenticatedPostBack()) { $Type = $Sender->Form->GetValue('Warning'); $Reason = $Sender->Form->GetValue('Reason'); if (empty($Type) || !in_array($Type, $this->WarnLevel)) { $Sender->Form->AddError('ValidateRequired', 'Warn Level'); } if (empty($Reason)) { $Sender->Form->AddError('ValidateRequired', 'Reason'); } if ($Sender->Form->ErrorCount() == 0) { Gdn::UserModel()->SetMeta($UserID, array('Warnings.' . time() => Gdn_Format::Serialize(array('Type' => $Type, 'Reason' => $Reason)))); Gdn::UserModel()->SaveAttribute($UserID, 'WarnLevel', $Type); // get those notification sent $this->SaveActivity($User, $Type, $Reason); // Redirect after a successful save. if ($Sender->Request->Get('Target')) { $Sender->RedirectUrl = $Sender->Request->Get('Target'); } else { $Sender->RedirectUrl = Url(UserUrl($User)); } } } $Sender->SetData('User', $User); $Sender->SetData('WarnLevel', array_combine($this->WarnLevel, array_map(array($this, 'WarnLevelFormat'), $this->WarnLevel))); $Sender->AddSideMenu(); $Sender->Title(T('Warning.Warn', 'Warn')); $Sender->View = $this->ThemeView('warning'); $Sender->Render(); }
/** * Creates and renders an instance of a module. */ public function Index($Module, $AppFolder = '', $DeliveryType = '') { if (!$DeliveryType) { $this->DeliveryType(DELIVERY_TYPE_VIEW); } $ModuleClassExists = class_exists($Module); if ($ModuleClassExists) { // Make sure that the class implements Gdn_IModule $ReflectionClass = new ReflectionClass($Module); if ($ReflectionClass->implementsInterface("Gdn_IModule")) { // Set the proper application folder on this controller so that things render properly. if ($AppFolder) { $this->ApplicationFolder = $AppFolder; } else { $Filename = str_replace('\\', '/', substr($ReflectionClass->getFileName(), strlen(PATH_ROOT))); // Figure our the application folder for the module. $Parts = explode('/', trim($Filename, '/')); if ($Parts[0] == 'applications') { $this->ApplicationFolder = $Parts[1]; } } $ModuleInstance = new $Module($this); $ModuleInstance->Visible = TRUE; $WhiteList = array('Limit', 'Help'); foreach ($this->Request->Get() as $Key => $Value) { if (in_array($Key, $WhiteList)) { $ModuleInstance->{$Key} = $Value; } } $this->SetData('_Module', $ModuleInstance); $this->Render('Index', FALSE, 'dashboard'); return; } } throw NotFoundException($Module); }
/** * Enable a locale pack without installing it to the config or mappings. * * @param string $LocaleKey The key of the folder. */ 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"); foreach ($Paths as $Path) { Gdn::Locale()->Load($Path); } }
/** * Confirm email address is valid via sent code. * * @access public * @since 2.0.0 * * @param int $UserID * @param string $EmailKey Authenticate with unique, 1-time code sent via email. */ public function EmailConfirm($UserID, $EmailKey = '') { $User = $this->UserModel->GetID($UserID); if (!$User) { throw NotFoundException('User'); } $EmailConfirmed = $this->UserModel->ConfirmEmail($User, $EmailKey); $this->Form->SetValidationResults($this->UserModel->ValidationResults()); if ($EmailConfirmed) { $UserID = GetValue('UserID', $User); Gdn::Session()->Start($UserID); } $this->SetData('EmailConfirmed', $EmailConfirmed); $this->SetData('Email', $User->Email); $this->Render(); }
protected function _DiscussionOptions($Sender, $DiscussionID) { $Sender->Form = new Gdn_Form(); $Discussion = $Sender->DiscussionModel->GetID($DiscussionID); if (!$Discussion) { throw NotFoundException('Discussion'); } // Both '' and 'Discussion' denote a discussion type of discussion. if (!GetValue('Type', $Discussion)) { SetValue('Type', $Discussion, 'Discussion'); } if ($Sender->Form->IsPostBack()) { $Sender->DiscussionModel->SetField($DiscussionID, 'Type', $Sender->Form->GetFormValue('Type')); // $Form = new Gdn_Form(); $Sender->Form->SetValidationResults($Sender->DiscussionModel->ValidationResults()); // if ($Sender->DeliveryType() == DELIVERY_TYPE_ALL || $Redirect) // $Sender->RedirectUrl = Gdn::Controller()->Request->PathAndQuery(); Gdn::Controller()->JsonTarget('', '', 'Refresh'); } else { $Sender->Form->SetData($Discussion); } $Sender->SetData('Discussion', $Discussion); $Sender->SetData('_Types', array('Question' => '@' . T('Question Type', 'Question'), 'Discussion' => '@' . T('Discussion Type', 'Discussion'))); $Sender->SetData('Title', T('Q&A Options')); $Sender->Render('DiscussionOptions', '', 'plugins/QnA'); }
/** * Fetches the location of a view into a string and returns it. Returns * false on failure. * * @param string $View The name of the view to fetch. If not specified, it will use the value * of $this->View. If $this->View is not specified, it will use the value * of $this->RequestMethod (which is defined by the dispatcher class). * @param string $ControllerName The name of the controller that owns the view if it is not $this. * - If the controller name is FALSE then the name of the current controller will be used. * - If the controller name is an empty string then the view will be looked for in the base views folder. * @param string $ApplicationFolder The name of the application folder that contains the requested controller if it is not $this->ApplicationFolder. */ public function fetchViewLocation($View = '', $ControllerName = false, $ApplicationFolder = false, $ThrowError = true) { // Accept an explicitly defined view, or look to the method that was called on this controller if ($View == '') { $View = $this->View; } if ($View == '') { $View = $this->RequestMethod; } if ($ControllerName === false) { $ControllerName = $this->ControllerName; } if (StringEndsWith($ControllerName, 'controller', true)) { $ControllerName = substr($ControllerName, 0, -10); } if (strtolower(substr($ControllerName, 0, 4)) == 'gdn_') { $ControllerName = substr($ControllerName, 4); } if (!$ApplicationFolder) { $ApplicationFolder = $this->ApplicationFolder; } //$ApplicationFolder = strtolower($ApplicationFolder); $ControllerName = strtolower($ControllerName); if (strpos($View, DS) === false) { // keep explicit paths as they are. $View = strtolower($View); } // If this is a syndication request, append the method to the view if ($this->SyndicationMethod == SYNDICATION_ATOM) { $View .= '_atom'; } elseif ($this->SyndicationMethod == SYNDICATION_RSS) { $View .= '_rss'; } $LocationName = concatSep('/', strtolower($ApplicationFolder), $ControllerName, $View); $ViewPath = val($LocationName, $this->_ViewLocations, false); if ($ViewPath === false) { // Define the search paths differently depending on whether or not we are in a plugin or application. $ApplicationFolder = trim($ApplicationFolder, '/'); if (stringBeginsWith($ApplicationFolder, 'plugins/')) { $KeyExplode = explode('/', $ApplicationFolder); $PluginName = array_pop($KeyExplode); $PluginInfo = Gdn::pluginManager()->getPluginInfo($PluginName); $BasePath = val('SearchPath', $PluginInfo); $ApplicationFolder = val('Folder', $PluginInfo); } else { $BasePath = PATH_APPLICATIONS; $ApplicationFolder = strtolower($ApplicationFolder); } $SubPaths = array(); // Define the subpath for the view. // The $ControllerName used to default to '' instead of FALSE. // This extra search is added for backwards-compatibility. if (strlen($ControllerName) > 0) { $SubPaths[] = "views/{$ControllerName}/{$View}"; } else { $SubPaths[] = "views/{$View}"; $SubPaths[] = 'views/' . stringEndsWith($this->ControllerName, 'Controller', true, true) . "/{$View}"; } // Views come from one of four places: $ViewPaths = array(); // 1. An explicitly defined path to a view if (strpos($View, DS) !== false && stringBeginsWith($View, PATH_ROOT)) { $ViewPaths[] = $View; } if ($this->Theme) { // 2. Application-specific theme view. eg. /path/to/application/themes/theme_name/app_name/views/controller_name/ foreach ($SubPaths as $SubPath) { $ViewPaths[] = PATH_THEMES . "/{$this->Theme}/{$ApplicationFolder}/{$SubPath}.*"; // $ViewPaths[] = CombinePaths(array(PATH_THEMES, $this->Theme, $ApplicationFolder, 'views', $ControllerName, $View . '.*')); } // 3. Garden-wide theme view. eg. /path/to/application/themes/theme_name/views/controller_name/ foreach ($SubPaths as $SubPath) { $ViewPaths[] = PATH_THEMES . "/{$this->Theme}/{$SubPath}.*"; //$ViewPaths[] = CombinePaths(array(PATH_THEMES, $this->Theme, 'views', $ControllerName, $View . '.*')); } } // 4. Application/plugin default. eg. /path/to/application/app_name/views/controller_name/ foreach ($SubPaths as $SubPath) { $ViewPaths[] = "{$BasePath}/{$ApplicationFolder}/{$SubPath}.*"; //$ViewPaths[] = CombinePaths(array(PATH_APPLICATIONS, $ApplicationFolder, 'views', $ControllerName, $View . '.*')); } // Find the first file that matches the path. $ViewPath = false; foreach ($ViewPaths as $Glob) { $Paths = safeGlob($Glob); if (is_array($Paths) && count($Paths) > 0) { $ViewPath = $Paths[0]; break; } } //$ViewPath = Gdn_FileSystem::Exists($ViewPaths); $this->_ViewLocations[$LocationName] = $ViewPath; } // echo '<div>['.$LocationName.'] RETURNS ['.$ViewPath.']</div>'; if ($ViewPath === false && $ThrowError) { Gdn::dispatcher()->passData('ViewPaths', $ViewPaths); throw NotFoundException('View'); // trigger_error(ErrorMessage("Could not find a '$View' view for the '$ControllerName' controller in the '$ApplicationFolder' application.", $this->ClassName, 'FetchViewLocation'), E_USER_ERROR); } return $ViewPath; }
public function addTag($id = null) { if (!$this->request->is('post')) { throw new MethodNotAllowedException('You don\'t have permission to do that.'); } $tag_id = $this->request->data['Event']['tag']; $id = $this->request->data['Event']['id']; $this->Event->recurisve = -1; $event = $this->Event->read(array('id', 'org', 'orgc', 'distribution'), $id); // org should allow to tag too, so that an event that gets pushed can be tagged locally by the owning org if ($this->Auth->user('org') !== $event['Event']['org'] && $this->Auth->user('org') !== $event['Event']['orgc'] && $event['Event']['distribution'] == 0 || !$this->userRole['perm_tagger'] && !$this->_isSiteAdmin()) { throw new MethodNotAllowedException('You don\'t have permission to do that.'); } $this->Event->EventTag->Tag->id = $tag_id; if (!$this->Event->EventTag->Tag->exists()) { throw NotFoundException('Invalid tag.'); } $found = $this->Event->EventTag->find('first', array('conditions' => array('event_id' => $id, 'tag_id' => $tag_id), 'recursive' => -1)); $this->autoRender = false; if (!empty($found)) { return new CakeResponse(array('body' => json_encode(array('saved' => false, 'errors' => 'Tag is already attached to this event.')), 'status' => 200)); //$this->Session->setFlash('Tag already assigned to this event.'); //$this->redirect(array('action' => 'view', $id)); } $this->Event->EventTag->create(); if ($this->Event->EventTag->save(array('event_id' => $id, 'tag_id' => $tag_id))) { return new CakeResponse(array('body' => json_encode(array('saved' => true, 'success' => 'Tag added.')), 'status' => 200)); } else { return new CakeResponse(array('body' => json_encode(array('saved' => false, 'errors' => 'Tag could not be added.')), 'status' => 200)); } }
/** * Convert various forms of querystring limit/offset, page, limit/range to database limit/offset. * * @param string $offsetOrPage The page query in one of the following formats: * - p<x>: Get page x. * - <x>-<y>: This is a range viewing records x through y. * - <x>lim<n>: This is a limit/offset pair. * - <x>: This is a limit where offset is given in the next parameter. * @param int $limitOrPageSize The page size or limit. * @param bool $throw Whether or not to throw an error if the {@link $offsetOrPage} is too high. * @return array Returns an array in the form: `[$offset, $limit]`. * @throws Exception Throws a 404 exception if the {@link $offsetOrPage} is too high and {@link $throw} is true. */ function offsetLimit($offsetOrPage = '', $limitOrPageSize = '', $throw = false) { $limitOrPageSize = is_numeric($limitOrPageSize) ? (int) $limitOrPageSize : 50; if (is_numeric($offsetOrPage)) { $Offset = (int) $offsetOrPage; $Limit = $limitOrPageSize; } elseif (preg_match('/p(\\d+)/i', $offsetOrPage, $Matches)) { $Page = $Matches[1]; $Offset = $limitOrPageSize * ($Page - 1); $Limit = $limitOrPageSize; } elseif (preg_match('/(\\d+)-(\\d+)/', $offsetOrPage, $Matches)) { $Offset = $Matches[1] - 1; $Limit = $Matches[2] - $Matches[1] + 1; } elseif (preg_match('/(\\d+)lim(\\d*)/i', $offsetOrPage, $Matches)) { $Offset = (int) $Matches[1]; $Limit = (int) $Matches[2]; if (!is_numeric($Limit)) { $Limit = $limitOrPageSize; } } elseif (preg_match('/(\\d+)lin(\\d*)/i', $offsetOrPage, $Matches)) { $Offset = $Matches[1] - 1; $Limit = (int) $Matches[2]; if (!is_numeric($Limit)) { $Limit = $limitOrPageSize; } } elseif ($offsetOrPage && $throw) { // Some unrecognized page string was passed. throw NotFoundException(); } else { $Offset = 0; $Limit = $limitOrPageSize; } if ($Offset < 0) { $Offset = 0; } if ($Limit < 0) { $Limit = 50; } return array($Offset, $Limit); }
/** * Default all discussions view: chronological by most recent comment. * * @since 2.0.0 * @access public * * @param int $Page Multiplied by PerPage option to determine offset. */ public function Index($Page = FALSE) { // Figure out which discussions layout to choose (Defined on "Homepage" settings page). $Layout = C('Vanilla.Discussions.Layout'); switch ($Layout) { case 'table': if ($this->SyndicationMethod == SYNDICATION_NONE) { $this->View = 'table'; } break; default: // $this->View = 'index'; break; } Gdn_Theme::Section('DiscussionList'); // Determine offset from $Page list($Offset, $Limit) = OffsetLimit($Page, C('Vanilla.Discussions.PerPage', 30)); $Page = PageNumber($Offset, $Limit); // Allow page manipulation $this->EventArguments['Page'] =& $Page; $this->EventArguments['Offset'] =& $Offset; $this->EventArguments['Limit'] =& $Limit; $this->FireEvent('AfterPageCalculation'); // Set canonical URL $this->CanonicalUrl(Url(ConcatSep('/', 'discussions', PageNumber($Offset, $Limit, TRUE, FALSE)), TRUE)); // We want to limit the number of pages on large databases because requesting a super-high page can kill the db. $MaxPages = C('Vanilla.Discussions.MaxPages'); if ($MaxPages && $Page > $MaxPages) { throw NotFoundException(); } // Setup head. if (!$this->Data('Title')) { $Title = C('Garden.HomepageTitle'); $DefaultControllerRoute = val('Destination', Gdn::Router()->GetRoute('DefaultController')); if ($Title && $DefaultControllerRoute == 'discussions') { $this->Title($Title, ''); } else { $this->Title(T('Recent Discussions')); } } if (!$this->Description()) { $this->Description(C('Garden.Description', NULL)); } if ($this->Head) { $this->Head->AddRss(Url('/discussions/feed.rss', TRUE), $this->Head->Title()); } // Add modules $this->AddModule('DiscussionFilterModule'); $this->AddModule('NewDiscussionModule'); $this->AddModule('CategoriesModule'); $this->AddModule('BookmarkedModule'); $this->SetData('Breadcrumbs', array(array('Name' => T('Recent Discussions'), 'Url' => '/discussions'))); // Set criteria & get discussions data $this->SetData('Category', FALSE, TRUE); $DiscussionModel = new DiscussionModel(); $DiscussionModel->Watching = TRUE; // Get Discussion Count $CountDiscussions = $DiscussionModel->GetCount(); if ($MaxPages) { $CountDiscussions = min($MaxPages * $Limit, $CountDiscussions); } $this->SetData('CountDiscussions', $CountDiscussions); // Get Announcements $this->AnnounceData = $Offset == 0 ? $DiscussionModel->GetAnnouncements() : FALSE; $this->SetData('Announcements', $this->AnnounceData !== FALSE ? $this->AnnounceData : array(), TRUE); // Get Discussions $this->DiscussionData = $DiscussionModel->GetWhere(FALSE, $Offset, $Limit); $this->SetData('Discussions', $this->DiscussionData, TRUE); $this->SetJson('Loading', $Offset . ' to ' . $Limit); // Build a pager $PagerFactory = new Gdn_PagerFactory(); $this->EventArguments['PagerType'] = 'Pager'; $this->FireEvent('BeforeBuildPager'); $this->Pager = $PagerFactory->GetPager($this->EventArguments['PagerType'], $this); $this->Pager->ClientID = 'Pager'; $this->Pager->Configure($Offset, $Limit, $CountDiscussions, 'discussions/%1$s'); if (!$this->Data('_PagerUrl')) { $this->SetData('_PagerUrl', 'discussions/{Page}'); } $this->SetData('_Page', $Page); $this->SetData('_Limit', $Limit); $this->FireEvent('AfterBuildPager'); // 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 = 'discussions'; } $this->Render(); }
/** * Load discussions for a specific tag. * @param DiscussionsController $Sender */ public function DiscussionsController_Tagged_Create($Sender) { Gdn_Theme::Section('DiscussionList'); $Args = $Sender->RequestArgs; $Get = array_change_key_case($Sender->Request->Get()); if ($UseCategories = C('Plugins.Tagging.UseCategories')) { // The url is in the form /category/tag/p1 $CategoryCode = GetValue(0, $Args); $Tag = GetValue(1, $Args); $Page = GetValue(2, $Args); } else { // The url is in the form /tag/p1 $CategoryCode = ''; $Tag = GetValue(0, $Args); $Page = GetValue(1, $Args); } // Look for explcit values. $CategoryCode = GetValue('category', $Get, $CategoryCode); $Tag = GetValue('tag', $Get, $Tag); $Page = GetValue('page', $Get, $Page); $Category = CategoryModel::Categories($CategoryCode); $Tag = StringEndsWith($Tag, '.rss', TRUE, TRUE); list($Offset, $Limit) = OffsetLimit($Page, C('Vanilla.Discussions.PerPage', 30)); $MultipleTags = strpos($Tag, ',') !== FALSE; $Sender->SetData('Tag', $Tag, TRUE); $TagModel = TagModel::instance(); $RecordCount = FALSE; if (!$MultipleTags) { $Tags = $TagModel->GetWhere(array('Name' => $Tag))->ResultArray(); if (count($Tags) == 0) { throw NotFoundException('Page'); } if (count($Tags) > 1) { foreach ($Tags as $TagRow) { if ($TagRow['CategoryID'] == GetValue('CategoryID', $Category)) { break; } } } else { $TagRow = array_pop($Tags); } $Tags = $TagModel->getRelatedTags($TagRow); $RecordCount = $TagRow['CountDiscussions']; $Sender->SetData('CountDiscussions', $RecordCount); $Sender->SetData('Tags', $Tags); $Sender->SetData('Tag', $TagRow); $ChildTags = $TagModel->getChildTags($TagRow['TagID']); $Sender->SetData('ChildTags', $ChildTags); } $Sender->Title(htmlspecialchars($TagRow['FullName'])); $UrlTag = rawurlencode($Tag); if (urlencode($Tag) == $Tag) { $Sender->CanonicalUrl(Url(ConcatSep('/', "/discussions/tagged/{$UrlTag}", PageNumber($Offset, $Limit, TRUE)), TRUE)); $FeedUrl = Url(ConcatSep('/', "/discussions/tagged/{$UrlTag}/feed.rss", PageNumber($Offset, $Limit, TRUE, FALSE)), '//'); } else { $Sender->CanonicalUrl(Url(ConcatSep('/', 'discussions/tagged', PageNumber($Offset, $Limit, TRUE)) . '?Tag=' . $UrlTag, TRUE)); $FeedUrl = Url(ConcatSep('/', 'discussions/tagged', PageNumber($Offset, $Limit, TRUE, FALSE), 'feed.rss') . '?Tag=' . $UrlTag, '//'); } if ($Sender->Head) { $Sender->AddJsFile('discussions.js'); $Sender->Head->AddRss($FeedUrl, $Sender->Head->Title()); } if (!is_numeric($Offset) || $Offset < 0) { $Offset = 0; } // Add Modules $Sender->AddModule('NewDiscussionModule'); $Sender->AddModule('DiscussionFilterModule'); $Sender->AddModule('BookmarkedModule'); $Sender->SetData('Category', FALSE, TRUE); $Sender->AnnounceData = FALSE; $Sender->SetData('Announcements', array(), TRUE); $DiscussionModel = new DiscussionModel(); $TagModel->SetTagSql($DiscussionModel->SQL, $Tag, $Limit, $Offset, $Sender->Request->Get('op', 'or')); $Sender->DiscussionData = $DiscussionModel->Get($Offset, $Limit, array('Announce' => 'all')); $Sender->SetData('Discussions', $Sender->DiscussionData, TRUE); $Sender->SetJson('Loading', $Offset . ' to ' . $Limit); // Build a pager. $PagerFactory = new Gdn_PagerFactory(); $Sender->Pager = $PagerFactory->GetPager('Pager', $Sender); $Sender->Pager->ClientID = 'Pager'; $Sender->Pager->Configure($Offset, $Limit, $RecordCount, ''); $Sender->View = C('Vanilla.Discussions.Layout'); /* // If these don't equal, then there is a category that should be inserted. if ($UseCategories && $Category && $TagRow['FullName'] != GetValue('Name', $Category)) { $Sender->Data['Breadcrumbs'][] = array('Name' => $Category['Name'], 'Url' => TagUrl($TagRow)); } $Sender->Data['Breadcrumbs'][] = array('Name' => $TagRow['FullName'], 'Url' => ''); */ // Render the controller. $this->View = C('Vanilla.Discussions.Layout') == 'table' ? 'table' : 'index'; $Sender->Render($this->View, 'discussions', 'vanilla'); }
/** * Delete an activity item. * * @since 2.0.0 * @access public * * @param int $ActivityID Unique ID of item to delete. * @param string $TransientKey Verify intent. */ public function Delete($ActivityID = '', $TransientKey = '') { $Session = Gdn::Session(); if (!$Session->ValidateTransientKey($TransientKey)) { throw PermissionException(); } if (!is_numeric($ActivityID)) { throw Gdn_UserException('Invalid activity ID'); } $HasPermission = $Session->CheckPermission('Garden.Activity.Delete'); if (!$HasPermission) { $Activity = $this->ActivityModel->GetID($ActivityID); if (!$Activity) { throw NotFoundException('Activity'); } $HasPermission = $Activity['InsertUserID'] == $Session->UserID; } if (!$HasPermission) { throw PermissionException(); } $this->ActivityModel->Delete($ActivityID); if ($this->_DeliveryType === DELIVERY_TYPE_ALL) { Redirect(GetIncomingValue('Target', $this->SelfUrl)); } // Still here? Getting a 404. $this->ControllerName = 'Home'; $this->View = 'FileNotFound'; $this->Render(); }
/** * Create and display a thumbnail of an uploaded file. * * @param UtilityController $Sender * @param array $Args */ public function utilityController_thumbnail_create($Sender, $Args = array()) { $MediaID = array_shift($Args); if (!is_numeric($MediaID)) { array_unshift($Args, $MediaID); } $SubPath = implode('/', $Args); // Fix mauling of protocol:// URLs. $SubPath = preg_replace('/:\\/{1}/', '://', $SubPath); $Name = $SubPath; $Parsed = Gdn_Upload::parse($Name); // Get actual path to the file. $upload = new Gdn_UploadImage(); $Path = $upload->copyLocal($SubPath); if (!file_exists($Path)) { throw NotFoundException('File'); } // Figure out the dimensions of the upload. $ImageSize = getimagesize($Path); $SHeight = $ImageSize[1]; $SWidth = $ImageSize[0]; if (!in_array($ImageSize[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) { if (is_numeric($MediaID)) { // Fix the thumbnail information so this isn't requested again and again. $Model = new MediaModel(); $Media = array('MediaID' => $MediaID, 'ImageWidth' => 0, 'ImageHeight' => 0, 'ThumbPath' => null); $Model->save($Media); } $Url = Asset('/plugins/FileUpload/images/file.png'); Redirect($Url, 301); } $Options = array(); $ThumbHeight = MediaModel::thumbnailHeight(); $ThumbWidth = MediaModel::thumbnailWidth(); if (!$ThumbHeight || $SHeight < $ThumbHeight) { $Height = $SHeight; $Width = $SWidth; } else { $Height = $ThumbHeight; $Width = round($Height * $SWidth / $SHeight); } if ($ThumbWidth && $Width > $ThumbWidth) { $Width = $ThumbWidth; if (!$ThumbHeight) { $Height = round($Width * $SHeight / $SWidth); } else { $Options['Crop'] = true; } } $TargetPath = "thumbnails/{$Parsed['Name']}"; $ThumbParsed = Gdn_UploadImage::saveImageAs($Path, $TargetPath, $Height, $Width, $Options); // Cleanup if we're using a scratch copy if ($ThumbParsed['Type'] != '' || $Path != MediaModel::pathUploads() . '/' . $SubPath) { @unlink($Path); } if (is_numeric($MediaID)) { // Save the thumbnail information. $Model = new MediaModel(); $Media = array('MediaID' => $MediaID, 'ThumbWidth' => $ThumbParsed['Width'], 'ThumbHeight' => $ThumbParsed['Height'], 'ThumbPath' => $ThumbParsed['SaveName']); $Model->save($Media); } $Url = $ThumbParsed['Url']; redirect($Url, 301); }
/** * Retrieve the user to be manipulated. If no params are passed, this will * retrieve the current user from the session. */ public function GetUserInfo($UserReference = '', $Username = '', $UserID = '') { if ($this->_UserInfoRetrieved) return; if (!C('Garden.Profile.Public') && !Gdn::Session()->IsValid()) Redirect('dashboard/home/permission'); // If a UserID was provided as a querystring parameter, use it over anything else: if ($UserID) { $UserReference = $UserID; $Username = '******'; // Fill this with a value so the $UserReference is assumed to be an integer/userid. } $this->Roles = array(); if ($UserReference == '') { $this->User = $this->UserModel->Get(Gdn::Session()->UserID); } else if (is_numeric($UserReference) && $Username != '') { $this->User = $this->UserModel->Get($UserReference); } else { $this->User = $this->UserModel->GetByUsername($UserReference); } if ($this->User === FALSE) { throw NotFoundException(); } else if ($this->User->Deleted == 1) { Redirect('dashboard/home/deleted'); } else { $this->RoleData = $this->UserModel->GetRoles($this->User->UserID); if ($this->RoleData !== FALSE && $this->RoleData->NumRows(DATASET_TYPE_ARRAY) > 0) $this->Roles = ConsolidateArrayValuesByKey($this->RoleData->Result(), 'Name'); $this->SetData('Profile', $this->User); $this->SetData('UserRoles', $this->Roles); // If the photo contains an http://, it is just an icon (probably from facebook or some external service), don't show it here because the Photo property is used to define logic around allowing thumbnail edits, etc. if ($this->User->Photo != '' && in_array(strtolower(substr($this->User->Photo, 0, 7)), array('http://', 'https:/'))) $this->User->Photo = ''; } // Make sure the userphoto module gets added to the page $UserPhotoModule = new UserPhotoModule($this); $UserPhotoModule->User = $this->User; $this->AddModule($UserPhotoModule); $this->AddSideMenu(); $this->_UserInfoRetrieved = TRUE; return TRUE; }
public function Dispatch($Sender, $RequestArgs = array()) { $Sender->Form = new Gdn_Form(); $ControllerMethod = 'Controller_Index'; if (is_array($RequestArgs) && sizeof($Sender->RequestArgs)) { list($MethodName) = $Sender->RequestArgs; $TestControllerMethod = 'Controller_' . $MethodName; if (method_exists($this, $TestControllerMethod)) { $ControllerMethod = $TestControllerMethod; } } if (method_exists($this, $ControllerMethod)) { $Sender->Plugin = $this; return call_user_func(array($this, $ControllerMethod), $Sender); } else { $PluginName = get_class($this); throw NotFoundException("@{$PluginName}->{$ControllerMethod}()"); } }
/** * Retrieve the user to be manipulated. If no params are passed, this will * retrieve the current user from the session. */ public function GetUserInfo($UserReference = '', $Username = '', $UserID = '') { if (!C('Garden.Profile.Public') && !Gdn::Session()->IsValid()) { Redirect('dashboard/home/permission'); } // If a UserID was provided as a querystring parameter, use it over anything else: if ($UserID) { $UserReference = $UserID; $Username = '******'; // Fill this with a value so the $UserReference is assumed to be an integer/userid. } $this->Roles = array(); if ($UserReference == '') { $this->User = $this->UserModel->Get(Gdn::Session()->UserID); } else { if (is_numeric($UserReference) && $Username != '') { $this->User = $this->UserModel->Get($UserReference); } else { $this->User = $this->UserModel->GetByUsername($UserReference); } } if ($this->User === FALSE) { throw NotFoundException(); } else { if ($this->User->Deleted == 1) { Redirect('dashboard/home/deleted'); } else { $this->RoleData = $this->UserModel->GetRoles($this->User->UserID); if ($this->RoleData !== FALSE && $this->RoleData->NumRows(DATASET_TYPE_ARRAY) > 0) { $this->Roles = ConsolidateArrayValuesByKey($this->RoleData->Result(), 'Name'); } $this->SetData('Profile', $this->User); $this->SetData('UserRoles', $this->Roles); } } // Make sure the userphoto module gets added to the page $UserPhotoModule = new UserPhotoModule($this); $UserPhotoModule->User = $this->User; $this->AddModule($UserPhotoModule); $this->AddSideMenu(); return TRUE; }
/** * Handle discussion option menu Resolve action. * * @throws Exception Throws an exception when the discussion is not found, or the request is not a POST * @return void */ public function discussionController_resolve_create($sender, $args) { $sender->permission('Plugins.Resolved.Manage'); $discussionID = $sender->Request->get('discussionid'); $resolve = $sender->Request->get('resolve'); // Make sure we are posting back. if (!$sender->Request->isPostBack()) { throw PermissionException('Javascript'); } $discussion = $sender->DiscussionModel->getID($discussionID); if (!$discussion) { throw NotFoundException('Discussion'); } // Resolve the discussion. $this->resolve($discussion, $resolve); $sender->sendOptions($discussion); if (!$resolve) { require_once $sender->fetchViewLocation('helper_functions', 'Discussions'); $sender->jsonTarget(".Section-DiscussionList #Discussion_{$discussionID} .Meta-Discussion", '<span class="Tag Tag-Unresolved" title="Unresolved">' . T('Unresolved') . '</span>', 'Prepend'); $sender->jsonTarget(".Section-DiscussionList #Discussion_{$discussionID}", 'Unresolved', 'AddClass'); } else { $sender->jsonTarget(".Section-DiscussionList #Discussion_{$discussionID} .Tag-Unresolved", null, 'Remove'); $sender->jsonTarget(".Section-DiscussionList #Discussion_{$discussionID}", 'Unresolved', 'RemoveClass'); } $sender->jsonTarget("#Discussion_{$discussionID}", null, 'Highlight'); $sender->jsonTarget(".Discussion #Item_0", null, 'Highlight'); $sender->render('Blank', 'Utility', 'Dashboard'); }