public function checkAkismet($RecordType, $Data) { $UserID = $this->UserID(); if (!$UserID) { return false; } $Akismet = self::Akismet(); if (!$Akismet) { return false; } $Akismet->setCommentAuthor($Data['Username']); $Akismet->setCommentAuthorEmail($Data['Email']); $Body = concatSep("\n\n", GetValue('Name', $Data), GetValue('Body', $Data), GetValue('Story', $Data)); $Akismet->setCommentContent($Body); $Akismet->setUserIP($Data['IPAddress']); $Result = $Akismet->isCommentSpam(); return $Result; }
/** * Takes a user object, and writes out an anchor of the user's icon to the user's profile. * * @param object|array $User A user object or array. * @param array $Options */ function userPhoto($User, $Options = array()) { if (is_string($Options)) { $Options = array('LinkClass' => $Options); } if ($Px = val('Px', $Options)) { $User = userBuilder($User, $Px); } else { $User = (object) $User; } $LinkClass = concatSep(' ', val('LinkClass', $Options, ''), 'PhotoWrap'); $ImgClass = val('ImageClass', $Options, 'ProfilePhoto'); $Size = val('Size', $Options); if ($Size) { $LinkClass .= " PhotoWrap{$Size}"; $ImgClass .= " {$ImgClass}{$Size}"; } else { $ImgClass .= " {$ImgClass}Medium"; // backwards compat } $FullUser = Gdn::userModel()->getID(val('UserID', $User), DATASET_TYPE_ARRAY); $UserCssClass = val('_CssClass', $FullUser); if ($UserCssClass) { $LinkClass .= ' ' . $UserCssClass; } $LinkClass = $LinkClass == '' ? '' : ' class="' . $LinkClass . '"'; $Photo = val('Photo', $User, val('PhotoUrl', $User)); $Name = val('Name', $User); $Title = htmlspecialchars(val('Title', $Options, $Name)); $Href = url(userUrl($User)); if ($FullUser && $FullUser['Banned']) { $Photo = c('Garden.BannedPhoto', 'https://c3409409.ssl.cf0.rackcdn.com/images/banned_large.png'); $Title .= ' (' . t('Banned') . ')'; } if ($Photo) { if (!isUrl($Photo)) { $PhotoUrl = Gdn_Upload::url(changeBasename($Photo, 'n%s')); } else { $PhotoUrl = $Photo; } } else { $PhotoUrl = UserModel::getDefaultAvatarUrl($User, 'thumbnail'); } return '<a title="' . $Title . '" href="' . $Href . '"' . $LinkClass . '>' . img($PhotoUrl, array('alt' => $Name, 'class' => $ImgClass)) . '</a>'; }
/** * * * @throws Gdn_UserException */ public function setup() { $Error = ''; if (!function_exists('curl_init')) { $Error = concatSep("\n", $Error, 'This plugin requires curl.'); } if ($Error) { throw new Gdn_UserException($Error, 400); } $this->structure(); }
/** * * * @param $Path * @param bool $Text * @param null $Format * @param array $Options * @return mixed|null|string */ public static function link($Path, $Text = false, $Format = null, $Options = array()) { $Session = Gdn::session(); $Class = val('class', $Options, ''); $WithDomain = val('WithDomain', $Options); $Target = val('Target', $Options, ''); if ($Target == 'current') { $Target = trim(url('', true), '/ '); } if (is_null($Format)) { $Format = '<a href="%url" class="%class">%text</a>'; } switch ($Path) { case 'activity': touchValue('Permissions', $Options, 'Garden.Activity.View'); break; case 'category': $Breadcrumbs = Gdn::controller()->data('Breadcrumbs'); if (is_array($Breadcrumbs) && count($Breadcrumbs) > 0) { $Last = array_pop($Breadcrumbs); $Path = val('Url', $Last); $DefaultText = val('Name', $Last, T('Back')); } else { $Path = '/'; $DefaultText = c('Garden.Title', T('Back')); } if (!$Text) { $Text = $DefaultText; } break; case 'dashboard': $Path = 'dashboard/settings'; touchValue('Permissions', $Options, array('Garden.Settings.Manage', 'Garden.Settings.View')); if (!$Text) { $Text = t('Dashboard'); } break; case 'home': $Path = '/'; if (!$Text) { $Text = t('Home'); } break; case 'inbox': $Path = 'messages/inbox'; touchValue('Permissions', $Options, 'Garden.SignIn.Allow'); if (!$Text) { $Text = t('Inbox'); } if ($Session->isValid() && $Session->User->CountUnreadConversations) { $Class = trim($Class . ' HasCount'); $Text .= ' <span class="Alert">' . $Session->User->CountUnreadConversations . '</span>'; } if (!$Session->isValid() || !Gdn::applicationManager()->checkApplication('Conversations')) { $Text = false; } break; case 'forumroot': $Route = Gdn::router()->getDestination('DefaultForumRoot'); if (is_null($Route)) { $Path = '/'; } else { $Path = combinePaths(array('/', $Route)); } break; case 'profile': touchValue('Permissions', $Options, 'Garden.SignIn.Allow'); if (!$Text && $Session->isValid()) { $Text = $Session->User->Name; } if ($Session->isValid() && $Session->User->CountNotifications) { $Class = trim($Class . ' HasCount'); $Text .= ' <span class="Alert">' . $Session->User->CountNotifications . '</span>'; } break; case 'user': $Path = 'profile'; touchValue('Permissions', $Options, 'Garden.SignIn.Allow'); if (!$Text && $Session->isValid()) { $Text = $Session->User->Name; } break; case 'photo': $Path = 'profile'; TouchValue('Permissions', $Options, 'Garden.SignIn.Allow'); if (!$Text && $Session->isValid()) { $IsFullPath = strtolower(substr($Session->User->Photo, 0, 7)) == 'http://' || strtolower(substr($Session->User->Photo, 0, 8)) == 'https://'; $PhotoUrl = $IsFullPath ? $Session->User->Photo : Gdn_Upload::url(changeBasename($Session->User->Photo, 'n%s')); $Text = img($PhotoUrl, array('alt' => $Session->User->Name)); } break; case 'drafts': TouchValue('Permissions', $Options, 'Garden.SignIn.Allow'); if (!$Text) { $Text = t('My Drafts'); } if ($Session->isValid() && $Session->User->CountDrafts) { $Class = trim($Class . ' HasCount'); $Text .= ' <span class="Alert">' . $Session->User->CountDrafts . '</span>'; } break; case 'discussions/bookmarked': TouchValue('Permissions', $Options, 'Garden.SignIn.Allow'); if (!$Text) { $Text = t('My Bookmarks'); } if ($Session->isValid() && $Session->User->CountBookmarks) { $Class = trim($Class . ' HasCount'); $Text .= ' <span class="Count">' . $Session->User->CountBookmarks . '</span>'; } break; case 'discussions/mine': TouchValue('Permissions', $Options, 'Garden.SignIn.Allow'); if (!$Text) { $Text = t('My Discussions'); } if ($Session->isValid() && $Session->User->CountDiscussions) { $Class = trim($Class . ' HasCount'); $Text .= ' <span class="Count">' . $Session->User->CountDiscussions . '</span>'; } break; case 'register': if (!$Text) { $Text = t('Register'); } $Path = registerUrl($Target); break; case 'signin': case 'signinout': // The destination is the signin/signout toggle link. if ($Session->isValid()) { if (!$Text) { $Text = T('Sign Out'); } $Path = signOutUrl($Target); $Class = concatSep(' ', $Class, 'SignOut'); } else { if (!$Text) { $Text = t('Sign In'); } $Path = signInUrl($Target); if (signInPopup() && strpos(Gdn::Request()->Url(), 'entry') === false) { $Class = concatSep(' ', $Class, 'SignInPopup'); } } break; } if ($Text == false && strpos($Format, '%text') !== false) { return ''; } if (val('Permissions', $Options) && !$Session->checkPermission($Options['Permissions'], false)) { return ''; } $Url = Gdn::request()->url($Path, $WithDomain); if ($TK = val('TK', $Options)) { if (in_array($TK, array(1, 'true'))) { $TK = 'TransientKey'; } $Url .= (strpos($Url, '?') === false ? '?' : '&') . $TK . '=' . urlencode(Gdn::session()->transientKey()); } if (strcasecmp(trim($Path, '/'), Gdn::request()->path()) == 0) { $Class = concatSep(' ', $Class, 'Selected'); } // Build the final result. $Result = $Format; $Result = str_replace('%url', $Url, $Result); $Result = str_replace('%text', $Text, $Result); $Result = str_replace('%class', $Class, $Result); return $Result; }
echo $userBlock; ?> </td> <td style="max-width: 200px;"> <?php $Roles = val('Roles', $User, array()); $RolesString = ''; if ($User->Banned && !in_array('Banned', $Roles)) { $RolesString = t('Banned'); } if ($User->Admin > 1) { $RolesString = concatSep(', ', $RolesString, t('System')); } foreach ($Roles as $RoleID => $RoleName) { $Query = http_build_query(array('Keywords' => $RoleName)); $RolesString = concatSep(', ', $RolesString, '<a href="' . url('/user/browse?' . $Query) . '">' . htmlspecialchars($RoleName) . '</a>'); } echo $RolesString; ?> </td> <td class="Alt"><?php echo Gdn_Format::date($User->DateFirstVisit, 'html'); ?> </td> <td><?php echo Gdn_Format::date($User->DateLastActive, 'html'); ?> </td> <?php if ($ViewPersonalInfo) { ?>
/** * 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; }
/** * Returns the XHTML for a list of checkboxes. * * @param string $FieldName Name of the field being posted with this input. * * @param mixed $DataSet Data to fill the checkbox list. Either an associative * array or a database dataset. ex: RoleID, Name from GDN_Role. * * @param mixed $ValueDataSet Values to be pre-checked in $DataSet. Either an associative array * or a database dataset. ex: RoleID from GDN_UserRole for a single user. * * @param array $Attributes An associative array of attributes for the select. Here is a list of * "special" attributes and their default values: * Attribute Options Default * ------------------------------------------------------------------------ * ValueField The name of the field in 'value' * $DataSet that contains the * option values. * TextField The name of the field in 'text' * $DataSet that contains the * option text. * * @return string */ public function checkBoxList($FieldName, $DataSet, $ValueDataSet = null, $Attributes = false) { // Never display individual inline errors for these CheckBoxes $Attributes['InlineErrors'] = false; $Return = ''; // If the form hasn't been posted back, use the provided $ValueDataSet if ($this->isPostBack() === false) { if ($ValueDataSet === null) { $CheckedValues = $this->getValue($FieldName); } else { $CheckedValues = $ValueDataSet; if (is_object($ValueDataSet)) { $CheckedValues = array_column($ValueDataSet->resultArray(), $FieldName); } } } else { $CheckedValues = $this->getFormValue($FieldName, array()); } $i = 1; if (is_object($DataSet)) { $ValueField = ArrayValueI('ValueField', $Attributes, 'value'); $TextField = ArrayValueI('TextField', $Attributes, 'text'); foreach ($DataSet->result() as $Data) { $Instance = $Attributes; $Instance = removeKeyFromArray($Instance, array('TextField', 'ValueField')); $Instance['value'] = $Data->{$ValueField}; $Instance['id'] = $FieldName . $i; if (is_array($CheckedValues) && in_array($Data->{$ValueField}, $CheckedValues)) { $Instance['checked'] = 'checked'; } $Return .= '<li>' . $this->checkBox($FieldName . '[]', $Data->{$TextField}, $Instance) . "</li>\n"; ++$i; } } elseif (is_array($DataSet)) { foreach ($DataSet as $Text => $ID) { // Set attributes for this instance $Instance = $Attributes; $Instance = removeKeyFromArray($Instance, array('TextField', 'ValueField')); $Instance['id'] = $FieldName . $i; if (is_array($ID)) { $ValueField = arrayValueI('ValueField', $Attributes, 'value'); $TextField = arrayValueI('TextField', $Attributes, 'text'); $Text = val($TextField, $ID, ''); $ID = val($ValueField, $ID, ''); } else { if (is_numeric($Text)) { $Text = $ID; } } $Instance['value'] = $ID; if (is_array($CheckedValues) && in_array($ID, $CheckedValues)) { $Instance['checked'] = 'checked'; } $Return .= '<li>' . $this->checkBox($FieldName . '[]', $Text, $Instance) . "</li>\n"; ++$i; } } return '<ul class="' . concatSep(' ', 'CheckBoxList', val('listclass', $Attributes)) . '">' . $Return . '</ul>'; }
/** * * * @param $sender Sending controller instance. * @param array $args Event arguments. */ public function base_beforeCommentDisplay_handler($sender, $args) { $QnA = valr('Comment.QnA', $args); if ($QnA && isset($args['CssClass'])) { $args['CssClass'] = concatSep(' ', $args['CssClass'], "QnA-Item-{$QnA}"); } }
/** * Perform formatting against a string for the quote tag. * * @param Nbbc $bbcode Instance of Nbbc doing the parsing. * @param int $action Value of one of NBBC's defined constants. Typically, this will be BBCODE_CHECK. * @param string $name Name of the tag. * @param string $default Value of the _default parameter, from the $params array. * @param array $params A standard set parameters related to the tag. * @param string $content Value between the open and close tags, if any. * @return bool|string Formatted value. */ function doQuote($bbcode, $action, $name, $default, $params, $content) { if ($action == Nbbc::BBCODE_CHECK) { return true; } if (is_string($default)) { $defaultParts = explode(';', $default); // support vbulletin style quoting. $Url = array_pop($defaultParts); if (count($defaultParts) == 0) { $params['name'] = $Url; } else { $params['name'] = implode(';', $defaultParts); $params['url'] = $Url; } } $title = ''; if (isset($params['name'])) { $username = trim($params['name']); $username = html_entity_decode($username, ENT_QUOTES, 'UTF-8'); $User = Gdn::userModel()->getByUsername($username); if ($User) { $userAnchor = userAnchor($User); } else { $userAnchor = anchor(htmlspecialchars($username, null, 'UTF-8'), '/profile/' . rawurlencode($username)); } $title = concatSep(' ', $title, $userAnchor, t('Quote wrote', 'wrote')); } if (isset($params['date'])) { $title = concatSep(' ', $title, t('Quote on', 'on'), htmlspecialchars(trim($params['date']))); } if ($title) { $title = $title . ':'; } if (isset($params['url'])) { $url = trim($params['url']); if (preg_match('/(c|d)-(\\d+)/', strtolower($url), $matches)) { if ($matches[1] === 'd') { $url = "/discussion/{$matches[2]}"; } else { $url = "/discussion/comment/{$matches[2]}#Comment_{$matches[2]}"; } } elseif (is_numeric($url)) { $url = "/discussion/comment/{$url}#Comment_{$url}"; } elseif (!$bbcode->isValidURL($url)) { $url = ''; } if ($url) { $title = concatSep(' ', $title, anchor('<span class="ArrowLink">»</span>', $url, ['class' => 'QuoteLink'])); } } if ($title) { $title = "<div class=\"QuoteAuthor\">{$title}</div>"; } return "\n<blockquote class=\"Quote UserQuote\">\n{$title}\n<div class=\"QuoteText\">{$content}</div>\n</blockquote>\n"; }
/** * * * @param EntryController $Sender * @param array $Args */ public function base_connectData_handler($Sender, $Args) { if (val(0, $Args) != 'disqus') { return; } if (isset($_GET['error'])) { throw new Gdn_UserException(val('error_description', $_GET, t('There was an error connecting to Disqus'))); } $Provider = $this->provider(); if (!$Provider) { throw new Gdn_UserException('The Disqus plugin has not been configured correctly.'); } $AppID = $Provider['AuthenticationKey']; $Secret = $Provider['AssociationSecret']; $Code = val('code', $_GET); $Query = ''; if ($Sender->Request->get('display')) { $Query = 'display=' . urlencode($Sender->Request->get('display')); } $RedirectUri = concatSep('&', $this->redirectUri(), $Query); $Form = $Sender->Form; $AccessToken = $Form->getFormValue('AccessToken'); //Gdn::Session()->Stash('Disqus.AccessToken', NULL, NULL); // Get the access token. if ($Code && !$AccessToken) { // Exchange the token for an access token. $Qs = array('grant_type' => 'authorization_code', 'client_id' => $AppID, 'client_secret' => $Secret, 'redirect_uri' => $RedirectUri, 'code' => $Code); $Url = 'https://disqus.com/api/oauth/2.0/access_token/'; //.http_build_query($Qs); // Get the redirect URI. $C = curl_init(); curl_setopt($C, CURLOPT_POST, true); curl_setopt($C, CURLOPT_POSTFIELDS, $Qs); curl_setopt($C, CURLOPT_RETURNTRANSFER, true); curl_setopt($C, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($C, CURLOPT_URL, $Url); $Contents = curl_exec($C); $Info = curl_getinfo($C); if (strpos(val('content_type', $Info, ''), '/json') !== false) { $Tokens = json_decode($Contents, true); } else { parse_str($Contents, $Tokens); } if (val('error', $Tokens)) { throw new Gdn_UserException('Disqus returned the following error: ' . valr('error.message', $Tokens, 'Unknown error.'), 400); } $AccessToken = val('access_token', $Tokens); $Expires = val('expires_in', $Tokens, null); $Form->addHidden('AccessToken', $AccessToken); } if ($AccessToken) { // Grab the user's profile. $Qs = array('access_token' => $AccessToken, 'api_key' => $AppID, 'api_secret' => $Secret); $Url = 'https://disqus.com/api/3.0/users/details.json?' . http_build_query($Qs); $C = curl_init(); curl_setopt($C, CURLOPT_RETURNTRANSFER, true); curl_setopt($C, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($C, CURLOPT_URL, $Url); $Contents = curl_exec($C); $Info = curl_getinfo($C); if (strpos(val('content_type', $Info, ''), '/json') !== false) { $Profile = json_decode($Contents, true); $Profile = $Profile['response']; } else { throw new Gdn_UserException('There was an error trying to get your profile information from Disqus.'); } } else { throw new Gdn_UserException('There was an error trying to get an access token from Disqus.'); } $Form->setFormValue('UniqueID', val('id', $Profile)); $Form->setFormValue('Provider', 'disqus'); $Form->setFormValue('ProviderName', 'Disqus'); $Form->setFormValue('FullName', val('name', $Profile)); $Form->setFormValue('Name', val('username', $Profile)); $Form->setFormValue('Photo', valr('avatar.permalink', $Profile)); $Sender->setData('Verified', true); }
/** * Gets/sets the modules title. * * @param string $Title * @param bool $NoSubtitle * @return mixed|string */ public function title($Title = '', $NoSubtitle = false) { if ($Title != '') { // Apply $Title to $this->_Title and to $this->_Sender. $this->_Title = $Title; $this->_Sender->title($Title); } elseif ($this->_Title == '') { // Get Title from $this->_Sender if not supplied. $this->_Title = valr('Data.Title', $this->_Sender, ''); } if ($NoSubtitle) { return $this->_Title; } else { if ($this->_Subtitle == '') { // Get Subtitle from controller. $this->_Subtitle = valr('Data._Subtitle', $this->_Sender, c('Garden.Title')); } // Default Return title from controller's Data.Title + banner title; return concatSep($this->_TitleDivider, $this->_Title, $this->_Subtitle); } }