public function Format($String) { $String = str_replace(array('"', ''', ':', 'Â'), array('"', "'", ':', ''), $String); $String = str_replace('<#EMO_DIR#>', 'default', $String); $String = str_replace('<{POST_SNAPBACK}>', '<span class="SnapBack">»</span>', $String); // There is an issue with using uppercase code blocks, so they're forced to lowercase here $String = str_replace(array('[CODE]', '[/CODE]'), array('[code]', '[/code]'), $String); /** * IPB inserts line break markup tags at line breaks. They need to be removed in code blocks. * The original newline/line break should be left intact, so whitespace will be preserved in the pre tag. */ $String = preg_replace_callback('/\\[code\\].*?\\[\\/code\\]/is', function ($CodeBlocks) { return str_replace(array('<br />'), array(''), $CodeBlocks[0]); }, $String); /** * IPB formats some quotes as HTML. They're converted here for the sake of uniformity in presentation. * Attribute order seems to be standard. Spacing between the opening of the tag and the first attribute is variable. */ $String = preg_replace_callback('#<blockquote\\s+class="ipsBlockquote" data-author="([^"]+)" data-cid="(\\d+)" data-time="(\\d+)">(.*?)</blockquote>#is', function ($BlockQuotes) { $Author = $BlockQuotes[1]; $Cid = $BlockQuotes[2]; $Time = $BlockQuotes[3]; $QuoteContent = $BlockQuotes[4]; // $Time will over as a timestamp. Convert it to a date string. $Date = date('F j Y, g:i A', $Time); return "[quote name=\"{$Author}\" url=\"{$Cid}\" date=\"{$Date}\"]{$QuoteContent}[/quote]"; }, $String); // If there is a really long string, it could cause a stack overflow in the bbcode parser. // Not much we can do except try and chop the data down a touch. // 1. Remove html comments. $String = preg_replace('/<!--(.*)-->/Uis', '', $String); // 2. Split the string up into chunks. $Strings = (array) $String; $Result = ''; foreach ($Strings as $String) { $Result .= $this->NBBC()->Parse($String); } // Linkify URLs in content $Result = Gdn_Format::links($Result); // Parsing mentions $Result = Gdn_Format::mentions($Result); // Handling emoji $Result = Emoji::instance()->translateToHtml($Result); // Make sure to clean filter the html in the end. $Config = array('anti_link_spam' => array('`.`', ''), 'comment' => 1, 'cdata' => 3, 'css_expression' => 1, 'deny_attribute' => 'on*', 'elements' => '*-applet-form-input-textarea-iframe-script-style', 'keep_bad' => 0, 'schemes' => 'classid:clsid; href: aim, feed, file, ftp, gopher, http, https, irc, mailto, news, nntp, sftp, ssh, telnet; style: nil; *:file, http, https', 'valid_xml' => 2); $Spec = 'object=-classid-type, -codebase; embed=type(oneof=application/x-shockwave-flash)'; $Result = htmLawed($Result, $Config, $Spec); return $Result; }
/** * Output markup for extended profile fields. * * @param array $profileFields Formatted profile fields. * @param array $allFields Extended profile field data. * @param array $magicLabels "Magic" labels configured on the Profile Extender plug-in class. */ function extendedProfileFields($profileFields, $allFields, $magicLabels = []) { foreach ($profileFields as $name => $value) { // Skip empty and hidden fields. if (!$value || !val('OnProfile', $allFields[$name])) { continue; } // Non-magic fields must be plain text, but we'll auto-link if (!in_array($name, $magicLabels)) { $value = Gdn_Format::links(Gdn_Format::text($value)); } $class = 'Profile' . Gdn_Format::alphaNumeric($name); $label = Gdn_Format::text($allFields[$name]['Label']); $filteredVal = Gdn_Format::htmlFilter($value); echo " <dt class=\"ProfileExtend {$class}\">{$label}</dt> "; echo " <dd class=\"ProfileExtend {$class}\">{$filteredVal}</dd> "; } }
/** * Display custom fields on Profile. */ public function userInfoModule_onBasicInfo_handler($Sender) { if ($Sender->User->Banned) { return; } try { // Get the custom fields $ProfileFields = Gdn::userModel()->getMeta($Sender->User->UserID, 'Profile.%', 'Profile.'); // Import from CustomProfileFields if available if (!count($ProfileFields) && is_object($Sender->User) && c('Plugins.CustomProfileFields.SuggestedFields', false)) { $ProfileFields = Gdn::userModel()->getAttribute($Sender->User->UserID, 'CustomProfileFields', false); if ($ProfileFields) { // Migrate to UserMeta & delete original Gdn::userModel()->setMeta($Sender->User->UserID, $ProfileFields, 'Profile.'); Gdn::userModel()->saveAttribute($Sender->User->UserID, 'CustomProfileFields', false); } } // Send them off for magic formatting $ProfileFields = $this->parseSpecialFields($ProfileFields); // Get all field data, error check $AllFields = $this->getProfileFields(); if (!is_array($AllFields) || !is_array($ProfileFields)) { return; } // DateOfBirth is special case that core won't handle // Hack it in here instead if (c('ProfileExtender.Fields.DateOfBirth.OnProfile')) { // Do not use Gdn_Format::Date because it shifts to local timezone $BirthdayStamp = Gdn_Format::toTimestamp($Sender->User->DateOfBirth); if ($BirthdayStamp) { $ProfileFields['DateOfBirth'] = date(t('Birthday Format', 'F j, Y'), $BirthdayStamp); $AllFields['DateOfBirth'] = array('Label' => t('Birthday'), 'OnProfile' => true); } } // Display all non-hidden fields $ProfileFields = array_reverse($ProfileFields); foreach ($ProfileFields as $Name => $Value) { // Skip empty and hidden fields. if (!$Value || !val('OnProfile', $AllFields[$Name])) { continue; } // Non-magic fields must be plain text, but we'll auto-link if (!in_array($Name, $this->MagicLabels)) { $Value = Gdn_Format::links(Gdn_Format::text($Value)); } echo ' <dt class="ProfileExtend Profile' . Gdn_Format::alphaNumeric($Name) . '">' . Gdn_Format::text($AllFields[$Name]['Label']) . '</dt> '; echo ' <dd class="ProfileExtend Profile' . Gdn_Format::alphaNumeric($Name) . '">' . Gdn_Format::htmlFilter($Value) . '</dd> '; } } catch (Exception $ex) { // No errors } }
/** * * * @param $Mixed * @return mixed|string */ public static function wysiwyg($Mixed) { static $CustomFormatter; if (!isset($CustomFormatter)) { $CustomFormatter = c('Garden.Format.WysiwygFunction', false); } if (!is_string($Mixed)) { return self::to($Mixed, 'Wysiwyg'); } elseif (is_callable($CustomFormatter)) { return $CustomFormatter($Mixed); } else { // The text contains html and must be purified. $Formatter = Gdn::factory('HtmlFormatter'); if (is_null($Formatter)) { // If there is no HtmlFormatter then make sure that script injections won't work. return self::display($Mixed); } // HTML filter first $Mixed = $Formatter->format($Mixed); // Links $Mixed = Gdn_Format::links($Mixed); // Mentions & Hashes $Mixed = Gdn_Format::mentions($Mixed); $Mixed = Emoji::instance()->translateToHtml($Mixed); return $Mixed; } }
/** * Performs replacing operations on a HTML string. Usually for formatting posts. * Runs an HTML string through the links, mentions, emoji and spoilers formatters. * * @param $html An unparsed HTML string. * @return string The formatted HTML string. */ protected static function processHTML($html) { $html = Gdn_Format::links($html); $html = Gdn_Format::mentions($html); $html = Emoji::instance()->translateToHtml($html); $html = Gdn_Format::legacySpoilers($html); return $html; }