예제 #1
1
 /**
  * Write a button drop down control.
  *
  * @param array $Links An array of arrays with the following keys:
  *  - Text: The text of the link.
  *  - Url: The url of the link.
  * @param string|array $CssClass The css class of the link. This can be a two-item array where the second element will be added to the buttons.
  * @param string $Label The text of the button.
  * @since 2.1
  */
 function buttonDropDown($Links, $CssClass = 'Button', $Label = false)
 {
     if (!is_array($Links) || count($Links) < 1) {
         return;
     }
     $ButtonClass = '';
     if (is_array($CssClass)) {
         list($CssClass, $ButtonClass) = $CssClass;
     }
     if (count($Links) < 2) {
         $Link = array_pop($Links);
         if (strpos(GetValue('CssClass', $Link, ''), 'Popup') !== false) {
             $CssClass .= ' Popup';
         }
         echo Anchor($Link['Text'], $Link['Url'], GetValue('ButtonCssClass', $Link, $CssClass));
     } else {
         // NavButton or Button?
         $ButtonClass = ConcatSep(' ', $ButtonClass, strpos($CssClass, 'NavButton') !== false ? 'NavButton' : 'Button');
         if (strpos($CssClass, 'Primary') !== false) {
             $ButtonClass .= ' Primary';
         }
         // Strip "Button" or "NavButton" off the group class.
         echo '<div class="ButtonGroup' . str_replace(array('NavButton', 'Button'), array('', ''), $CssClass) . '">';
         //            echo Anchor($Text, $Url, $ButtonClass);
         echo '<ul class="Dropdown MenuItems">';
         foreach ($Links as $Link) {
             echo wrap(Anchor($Link['Text'], $Link['Url'], val('CssClass', $Link, '')), 'li');
         }
         echo '</ul>';
         echo anchor($Label . ' ' . sprite('SpDropdownHandle'), '#', $ButtonClass . ' Handle');
         echo '</div>';
     }
 }
예제 #2
0
 public function Edit($Reference = 0, $ParentID = '')
 {
     $Session = Gdn::Session();
     $Model = new SectionModel();
     $this->Form->SetModel($Model);
     if ($ParentID) {
         $this->Form->AddHidden('ParentID', $ParentID);
     }
     $Section = False;
     if ($Reference) {
         $Section = $Model->GetID($Reference);
         if (!IsContentOwner($Section, 'Candy.Sections.Edit')) {
             $Section = False;
         }
         if ($Section) {
             $this->Form->AddHidden('SectionID', $Section->SectionID);
             $this->Form->SetData($Section);
         }
     }
     if (!$Section) {
         $this->Permission('Candy.Sections.Add');
     }
     if ($this->Form->AuthenticatedPostBack()) {
         $this->Form->Save($Section);
         if ($this->Form->ErrorCount() == 0) {
             $this->InformMessage(T('Saved'), array('Sprite' => 'Check', 'CssClass' => 'Dismissable AutoDismiss'));
         }
     }
     $this->Title(ConcatSep(' - ', T('Section'), GetValue('Name', $Section)));
     $this->Render();
 }
예제 #3
0
/**
 * Takes a route and prepends the web root (expects "/controller/action/params" as $Path).
 *
 * @param array The parameters passed into the function.
 * The parameters that can be passed to this function are as follows.
 * - <b>path</b>: The relative path for the url. There are some special paths that can be used to return "intelligent" links:
 *    - <b>signinout</b>: This will return a signin/signout url that will toggle depending on whether or not the user is already signed in. When this path is given the text is automaticall set.
 * - <b>withdomain</b>: Whether or not to add the domain to the url.
 * - <b>text</b>: Html text to be put inside an anchor. If this value is set then an html <a></a> is returned rather than just a url.
 * - <b>id, class, etc.></b>: When an anchor is generated then any other attributes are passed through and will be written in the resulting tag.
 * @param Smarty The smarty object rendering the template.
 * @return The url.
 */
function smarty_function_link($Params, &$Smarty)
{
    $Path = GetValue('path', $Params, '', TRUE);
    $WithDomain = GetValue('withdomain', $Params, FALSE, TRUE);
    $RemoveSyndication = GetValue('removeSyndication', $Params, FALSE, TRUE);
    $Text = GetValue('text', $Params, '', TRUE);
    $NoTag = GetValue('notag', $Params, FALSE, TRUE);
    $Class = GetValue('class', $Params, '', TRUE);
    $Session = Gdn::Session();
    $Authenticator = Gdn::Authenticator();
    // Use some logic to expan special urls.
    switch (strtolower($Path)) {
        case "signinout":
            // The destination is the signin/signout toggle link.
            if ($Session->IsValid()) {
                if (!$Text && !$NoTag) {
                    $Text = T('Sign Out');
                }
                $Path = $Authenticator->SignOutUrl();
                $Class = ConcatSep(' ', $Class, 'SignOut');
            } else {
                if (!$Text && !$NoTag) {
                    $Text = T('Sign In');
                }
                $Attribs = array();
                $Path = $Authenticator->SignInUrl('');
                if (Gdn::Config('Garden.SignIn.Popup')) {
                    $Class = ConcatSep(' ', $Class, 'SignInPopup');
                }
            }
            break;
    }
    $Url = Url($Path, $WithDomain, $RemoveSyndication);
    $Url = str_replace('{Session_TransientKey}', $Session->TransientKey(), $Url);
    if (!$Text) {
        $NoTag = TRUE;
    }
    if ($NoTag) {
        $Result = $Url;
    } else {
        $Result = '<a';
        // Add the standard attrbutes to the anchor.
        $ID = GetValue('id', $Params, '', TRUE);
        if ($ID) {
            $Result .= ' id="' . urlencode($ID) . '"';
        }
        $Result .= ' href="' . $Url . '"';
        if ($Class) {
            $Result .= ' class="' . urlencode($Class) . '"';
        }
        // Add anything that's left over.
        foreach ($Params as $Key => $Value) {
            $Result .= ' ' . $Key . '="' . urlencode($Value) . '"';
        }
        // Add the link text.
        $Result .= '>' . $Text . '</a>';
    }
    return $Result;
}
예제 #4
0
 /**
  * Load discussions for a specific tag.
  */
 public function DiscussionsController_Tagged_Create($Sender)
 {
     $Offset = GetValue('1', $Sender->RequestArgs, 'p1');
     list($Offset, $Limit) = OffsetLimit($Offset, Gdn::Config('Vanilla.Discussions.PerPage', 30));
     $Sender->Tag = GetValue('0', $Sender->RequestArgs, '');
     $Sender->Title(T('Tagged with ') . $Sender->Tag);
     $Sender->Head->Title($Sender->Head->Title());
     $Sender->CanonicalUrl(Url(ConcatSep('/', 'discussions/tagged/' . $Sender->Tag, PageNumber($Offset, $Limit, TRUE)), TRUE));
     if ($Sender->Head) {
         $Sender->AddJsFile('discussions.js');
         $Sender->AddJsFile('bookmark.js');
         $Sender->AddJsFile('js/library/jquery.menu.js');
         $Sender->AddJsFile('options.js');
         $Sender->Head->AddRss($Sender->SelfUrl . '/feed.rss', $Sender->Head->Title());
     }
     if (!is_numeric($Offset) || $Offset < 0) {
         $Offset = 0;
     }
     // Add Modules
     $Sender->AddModule('NewDiscussionModule');
     $BookmarkedModule = new BookmarkedModule($Sender);
     $BookmarkedModule->GetData();
     $Sender->AddModule($BookmarkedModule);
     $Sender->SetData('Category', FALSE, TRUE);
     $DiscussionModel = new DiscussionModel();
     $Tag = $DiscussionModel->SQL->Select()->From('Tag')->Where('Name', $Sender->Tag)->Get()->FirstRow();
     $TagID = $Tag ? $Tag->TagID : 0;
     $CountDiscussions = $Tag ? $Tag->CountDiscussions : 0;
     $Sender->SetData('CountDiscussions', $CountDiscussions);
     $Sender->AnnounceData = FALSE;
     $Sender->SetData('Announcements', array(), TRUE);
     $DiscussionModel->FilterToTagID = $TagID;
     $Sender->DiscussionData = $DiscussionModel->Get($Offset, $Limit);
     $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, $CountDiscussions, 'discussions/tagged/' . $Sender->Tag . '/%1$s');
     // Deliver json data if necessary
     if ($Sender->DeliveryType() != DELIVERY_TYPE_ALL) {
         $Sender->SetJson('LessRow', $Sender->Pager->ToString('less'));
         $Sender->SetJson('MoreRow', $Sender->Pager->ToString('more'));
         $Sender->View = 'discussions';
     }
     // Set a definition of the user's current timezone from the db. jQuery
     // will pick this up, compare to the browser, and update the user's
     // timezone if necessary.
     $CurrentUser = Gdn::Session()->User;
     if (is_object($CurrentUser)) {
         $ClientHour = $CurrentUser->HourOffset + date('G', time());
         $Sender->AddDefinition('SetClientHour', $ClientHour);
     }
     // Render the controller
     $Sender->Render(PATH_PLUGINS . '/Tagging/views/taggeddiscussions.php');
 }
 /**
  * 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 = '0')
 {
     // Determine offset from $Page
     list($Page, $Limit) = OffsetLimit($Page, Gdn::Config('Vanilla.Discussions.PerPage', 30));
     $this->CanonicalUrl(Url(ConcatSep('/', 'discussions', PageNumber($Page, $Limit, TRUE)), TRUE));
     // Validate $Page
     if (!is_numeric($Page) || $Page < 0) {
         $Page = 0;
     }
     // Setup head
     $this->Title(T('All Discussions'));
     if ($this->Head) {
         $this->Head->AddRss(Url('/discussions/feed.rss', TRUE), $this->Head->Title());
     }
     // Add modules
     $this->AddModule('NewDiscussionModule');
     $this->AddModule('CategoriesModule');
     $BookmarkedModule = new BookmarkedModule($this);
     $BookmarkedModule->GetData();
     $this->AddModule($BookmarkedModule);
     // Set criteria & get discussions data
     $this->SetData('Category', FALSE, TRUE);
     $DiscussionModel = new DiscussionModel();
     $CountDiscussions = $DiscussionModel->GetCount();
     $this->SetData('CountDiscussions', $CountDiscussions);
     $this->AnnounceData = $Page == 0 ? $DiscussionModel->GetAnnouncements() : FALSE;
     $this->SetData('Announcements', $this->AnnounceData !== FALSE ? $this->AnnounceData : array(), TRUE);
     $this->DiscussionData = $DiscussionModel->Get($Page, $Limit);
     $this->SetData('Discussions', $this->DiscussionData, TRUE);
     $this->SetJson('Loading', $Page . ' 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($Page, $Limit, $CountDiscussions, 'discussions/%1$s');
     $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';
     }
     // Set a definition of the user's current timezone from the db. jQuery
     // will pick this up, compare to the browser, and update the user's
     // timezone if necessary.
     $CurrentUser = Gdn::Session()->User;
     if (is_object($CurrentUser)) {
         $ClientHour = $CurrentUser->HourOffset + date('G', time());
         $this->AddDefinition('SetClientHour', $ClientHour);
     }
     // Render default view (discussions/index.php)
     $this->Render();
 }
예제 #6
0
 public function CheckMollom($RecordType, $Data)
 {
     $UserID = $this->UserID();
     if (!$UserID) {
         return FALSE;
     }
     $Mollom = self::Mollom();
     if (!$Mollom) {
         return FALSE;
     }
     $Result = $Mollom->checkContent(array('checks' => array('spam'), 'postTitle' => GetValue('Name', $Data), 'postBody' => ConcatSep("\n\n", GetValue('Body', $Data), GetValue('Story', $Data)), 'authorName' => $Data['Username'], 'authorEmail' => $Data['Email'], 'authorIp' => $Data['IPAddress']));
     return $Result['spamClassification'] == 'spam' ? true : false;
 }
예제 #7
0
 public function Index($Offset = '0')
 {
     list($Offset, $Limit) = OffsetLimit($Offset, Gdn::Config('Vanilla.Discussions.PerPage', 30));
     $this->CanonicalUrl(Url(ConcatSep('/', 'discussions', PageNumber($Offset, $Limit, TRUE)), TRUE));
     $this->Title(T('All Discussions'));
     if ($this->Head) {
         $this->Head->AddRss($this->SelfUrl . '/feed.rss', $this->Head->Title());
     }
     if (!is_numeric($Offset) || $Offset < 0) {
         $Offset = 0;
     }
     // Add Modules
     $this->AddModule('NewDiscussionModule');
     $this->AddModule('CategoriesModule');
     $BookmarkedModule = new BookmarkedModule($this);
     $BookmarkedModule->GetData();
     $this->AddModule($BookmarkedModule);
     $this->SetData('Category', FALSE, TRUE);
     $DiscussionModel = new DiscussionModel();
     $CountDiscussions = $DiscussionModel->GetCount();
     $this->SetData('CountDiscussions', $CountDiscussions);
     $this->AnnounceData = $Offset == 0 ? $DiscussionModel->GetAnnouncements() : FALSE;
     $this->SetData('Announcements', $this->AnnounceData !== FALSE ? $this->AnnounceData : array(), TRUE);
     $this->DiscussionData = $DiscussionModel->Get($Offset, $Limit);
     $this->SetData('Discussions', $this->DiscussionData, TRUE);
     $this->SetJson('Loading', $Offset . ' to ' . $Limit);
     // Build a pager.
     $PagerFactory = new Gdn_PagerFactory();
     $this->Pager = $PagerFactory->GetPager('Pager', $this);
     $this->Pager->ClientID = 'Pager';
     $this->Pager->Configure($Offset, $Limit, $CountDiscussions, 'discussions/%1$s');
     // Deliver json data if necessary
     if ($this->_DeliveryType != DELIVERY_TYPE_ALL) {
         $this->SetJson('LessRow', $this->Pager->ToString('less'));
         $this->SetJson('MoreRow', $this->Pager->ToString('more'));
         $this->View = 'discussions';
     }
     // Set a definition of the user's current timezone from the db. jQuery
     // will pick this up, compare to the browser, and update the user's
     // timezone if necessary.
     $CurrentUser = Gdn::Session()->User;
     if (is_object($CurrentUser)) {
         $ClientHour = $CurrentUser->HourOffset + date('G', time());
         $this->AddDefinition('SetClientHour', $ClientHour);
     }
     // Render the controller
     $this->Render();
 }
   function CountString($Number, $Url = '', $Options = array()) {
      if (is_string($Options))
         $Options = array('cssclass' => $Options);
      $Options = array_change_key_case($Options);
      $CssClass = GetValue('cssclass', $Options, '');

      if ($Number === NULL && $Url) {
         $CssClass = ConcatSep(' ', $CssClass, 'Popin TinyProgress');
         $Url = htmlspecialchars($Url);
         $Result = "<span class=\"$CssClass\" rel=\"$Url\"></span>";
      } elseif ($Number) {
         $Result = " <span class=\"Count\">$Number</span>";
      } else {
         $Result = '';
      }
      return $Result;
   }
예제 #9
0
 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;
 }
예제 #10
0
 public function Update($Reference = '', $PostBackKey = '')
 {
     $this->Permission('Candy.Chunks.Edit');
     $Content = False;
     $Session = Gdn::Session();
     $this->AddJsFile('jquery.textpandable.js');
     $this->AddJsFile('editform.js');
     $this->Form->SetModel($this->ChunkModel);
     if ($Reference != '') {
         $Content = $this->ChunkModel->GetID($Reference);
         if ($Content) {
             $this->Form->AddHidden('ChunkID', $Content->ChunkID);
             $this->Editing = True;
             $this->Form->SetData($Content);
         }
     }
     $IsFormPostBack = $this->Form->AuthenticatedPostBack();
     $PostAuthenticatedByKey = $Session->ValidateTransientKey($PostBackKey) && $this->Form->IsPostBack();
     if ($IsFormPostBack || $PostAuthenticatedByKey) {
         if ($PostAuthenticatedByKey) {
             // AJAX, set form values.
             $this->Form->SetFormValue('ChunkID', $Content->ChunkID);
             $this->Form->SetFormValue('Body', GetPostValue('Body'));
         }
         $SavedID = $this->Form->Save($Content);
         if ($SavedID) {
             $Message = T('Saved');
             $this->InformMessage($Message, array('Sprite' => 'Check', 'CssClass' => 'Dismissable AutoDismiss'));
             if ($this->DeliveryType() == DELIVERY_TYPE_BOOL) {
                 //$this->SetData('Content', $Content);
                 //$this->SetData('NewBody', Gdn_Format::To($this->Form->GetFormValue('Body'), $Content->Format));
                 $this->SetJson('NewBody', Gdn_Format::To($this->Form->GetFormValue('Body'), $Content->Format));
             }
         }
     } else {
         $this->SetData('Content', $Content);
         $this->Form->SetData($Content);
     }
     $this->Title(ConcatSep(' - ', T('Chunk'), GetValue('Name', $Content)));
     $this->Render();
 }
예제 #11
0
 public function Base_BeforeCommentDisplay_Handler($Sender, $Args)
 {
     $QnA = GetValueR('Comment.QnA', $Args);
     if ($QnA && isset($Args['CssClass'])) {
         $Args['CssClass'] = ConcatSep(' ', $Args['CssClass'], "QnA-Item-{$QnA}");
     }
 }
예제 #12
0
 /**
  * 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;
 }
예제 #13
0
 /**
  * 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;
     }
     // Munge the controller folder onto the controller name if it is present.
     if ($this->ControllerFolder != '') {
         $ControllerName = $this->ControllerFolder . DS . $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';
     } else {
         if ($this->SyndicationMethod == SYNDICATION_RSS) {
             $View .= '_rss';
         }
     }
     $LocationName = ConcatSep('/', strtolower($ApplicationFolder), $ControllerName, $View);
     $ViewPath = ArrayValue($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 = GetValue('SearchPath', $PluginInfo);
             $ApplicationFolder = GetValue('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/{$this->ControllerName}/{$View}";
         }
         // Views come from one of four places:
         $ViewPaths = array();
         foreach ($SubPaths as $SubPath) {
             // 1. An explicitly defined path to a view
             if (strpos($View, DS) !== FALSE) {
                 $ViewPaths[] = $View;
             }
             if ($this->Theme) {
                 // 2. Application-specific theme view. eg. /path/to/application/themes/theme_name/app_name/views/controller_name/
                 $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/
                 $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/
             $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) {
         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;
 }
예제 #14
0
 public function ToString($HighlightRoute = '')
 {
     if ($HighlightRoute == '') {
         $HighlightRoute = $this->_HighlightRoute;
     }
     if ($HighlightRoute == '') {
         $HighlightRoute = Gdn_Url::Request();
     }
     $HighlightUrl = Url($HighlightRoute);
     // Apply a sort to the items if given.
     if (is_array($this->Sort)) {
         $Sort = array_flip($this->Sort);
         foreach ($this->Items as $Group => &$Item) {
             if (isset($Sort[$Group])) {
                 $Item['Sort'] = $Sort[$Group];
             } else {
                 $Item['_Sort'] += count($Sort);
             }
             foreach ($Item['Links'] as $Url => &$Link) {
                 if (isset($Sort[$Url])) {
                     $Link['Sort'] = $Sort[$Url];
                 } elseif (isset($Sort[$Link['Text']])) {
                     $Link['Sort'] = $Sort[$Link['Text']];
                 } else {
                     $Link['_Sort'] += count($Sort);
                 }
             }
         }
     }
     // Sort the groups.
     $this->_Compare($this->Items);
     uasort($this->Items, array($this, '_Compare'));
     // Sort the items within the groups.
     foreach ($this->Items as &$Item) {
         $this->_Compare($Item['Links']);
         uasort($Item['Links'], array($this, '_Compare'));
         // Highlight the group.
         if (GetValue('Url', $Item) && Url($Item['Url']) == $HighlightUrl) {
             $Item['Attributes']['class'] = ConcatSep(' ', GetValue('class', $Item['Attributes']), 'Active');
         }
         // Hightlight the correct item in the group.
         foreach ($Item['Links'] as &$Link) {
             if (GetValue('Url', $Link) && Url($Link['Url']) == $HighlightUrl) {
                 $Link['Attributes']['class'] = ConcatSep(' ', GetValue('class', $Link['Attributes']), 'Active');
                 $Item['Attributes']['class'] = ConcatSep(' ', GetValue('class', $Item['Attributes']), 'Active');
             }
         }
     }
     return parent::ToString();
 }
 /**
  * Display discussions the user has bookmarked.
  *
  * @since 2.0.0
  * @access public
  *
  * @param int $Offset Number of discussions to skip.
  */
 public function Bookmarked($Page = '0')
 {
     $this->Permission('Garden.SignIn.Allow');
     Gdn_Theme::Section('DiscussionList');
     // 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;
     }
     // Determine offset from $Page
     list($Page, $Limit) = OffsetLimit($Page, C('Vanilla.Discussions.PerPage', 30));
     $this->CanonicalUrl(Url(ConcatSep('/', 'discussions', 'bookmarked', PageNumber($Page, $Limit, TRUE, FALSE)), TRUE));
     // Validate $Page
     if (!is_numeric($Page) || $Page < 0) {
         $Page = 0;
     }
     $DiscussionModel = new DiscussionModel();
     $Wheres = array('w.Bookmarked' => '1', 'w.UserID' => Gdn::Session()->UserID);
     $this->DiscussionData = $DiscussionModel->Get($Page, $Limit, $Wheres);
     $this->SetData('Discussions', $this->DiscussionData);
     $CountDiscussions = $DiscussionModel->GetCount($Wheres);
     $this->SetData('CountDiscussions', $CountDiscussions);
     $this->Category = FALSE;
     $this->SetJson('Loading', $Page . ' to ' . $Limit);
     // Build a pager
     $PagerFactory = new Gdn_PagerFactory();
     $this->EventArguments['PagerType'] = 'Pager';
     $this->FireEvent('BeforeBuildBookmarkedPager');
     $this->Pager = $PagerFactory->GetPager($this->EventArguments['PagerType'], $this);
     $this->Pager->ClientID = 'Pager';
     $this->Pager->Configure($Page, $Limit, $CountDiscussions, 'discussions/bookmarked/%1$s');
     if (!$this->Data('_PagerUrl')) {
         $this->SetData('_PagerUrl', 'discussions/bookmarked/{Page}');
     }
     $this->SetData('_Page', $Page);
     $this->SetData('_Limit', $Limit);
     $this->FireEvent('AfterBuildBookmarkedPager');
     // 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';
     }
     // Add modules
     $this->AddModule('DiscussionFilterModule');
     $this->AddModule('NewDiscussionModule');
     $this->AddModule('CategoriesModule');
     // Render default view (discussions/bookmarked.php)
     $this->SetData('Title', T('My Bookmarks'));
     $this->SetData('Breadcrumbs', array(array('Name' => T('My Bookmarks'), 'Url' => '/discussions/bookmarked')));
     $this->Render();
 }
예제 #16
0
      $Message = nl2br(SliceString(Gdn_Format::Text(Gdn_Format::To($Conversation->LastMessage, $Conversation->Format), FALSE), 100));

   if (StringIsNullOrEmpty(trim($Message)))
      $Message = T('Blank Message');


   $this->EventArguments['Conversation'] = $Conversation;
?>
<li class="<?php echo $CssClass; ?>">
   <?php
   $Names = '';
   $PhotoUser = NULL;
   foreach ($Conversation->Participants as $User) {
      if (GetValue('UserID', $User) == Gdn::Session()->UserID)
         continue;
      $Names = ConcatSep(', ', $Names, GetValue('Name', $User));
      if (!$PhotoUser && GetValue('Photo', $User))
         $PhotoUser = $User;
   }
   ?>
   <?php if ($PhotoUser) { ?>
   <div class="Photo"><?php echo UserPhoto($PhotoUser); ?></div>
   <?php } ?>
   <div class="ItemContent Conversation">
      <?php
      $Url = '/messages/'.$Conversation->ConversationID.'/#Item_'.$JumpToItem;

      if ($Names) {
         echo '<h3 class="Users">', Anchor(htmlspecialchars($Names), $Url), '</h3>';
      }
      if ($SubjectsVisible && $Subject = GetValue('Subject', $Conversation)) {
예제 #17
0
 /**
  * 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');
 }
 public function Title($Title = '') {
    if ($Title != '') {
       // Apply $Title to $this->_Title and return it;
       $this->_Title = $Title;
       $this->_Sender->Title($Title);
       return $Title;
    } else if ($this->_Title != '') {
       // Return $this->_Title if set;
       return $this->_Title;
    } else {
       // Default Return title from controller's Data.Title + banner title;
       return ConcatSep(' - ', GetValueR('Data.Title', $this->_Sender, ''), C('Garden.Title'));
    }
 }
예제 #19
0
 /**
  * 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 = ConsolidateArrayValuesByKey($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 = GetValue($TextField, $ID, '');
                 $ID = GetValue($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', GetValue('listclass', $Attributes)) . '">' . $Return . '</ul>';
 }
예제 #20
0
 /**
  * Default profile page.
  *
  * If current user's profile, get notifications. Otherwise show their activity (if available) or discussions.
  *
  * @since 2.0.0
  * @access public
  * @param mixed $UserReference Unique identifier, possible ID or username.
  * @param string $Username.
  * @param int $UserID Unique ID.
  */
 public function Index($UserReference = '', $Username = '', $UserID = '')
 {
     $this->GetUserInfo($UserReference, $Username, $UserID);
     if ($this->User->Admin == 2 && $this->Head) {
         // Don't index internal accounts. This is in part to prevent vendors from getting endless Google alerts.
         $this->Head->AddTag('meta', array('name' => 'robots', 'content' => 'noindex'));
         $this->Head->AddTag('meta', array('name' => 'googlebot', 'content' => 'noindex'));
     }
     if ($this->User->UserID == Gdn::Session()->UserID) {
         return $this->Notifications();
     } elseif (C('Garden.Profile.ShowActivities', TRUE)) {
         return $this->Activity($UserReference, $Username, $UserID);
     } else {
         return Gdn::Dispatcher()->Dispatch('/profile/discussions/' . ConcatSep('/', rawurlencode($UserReference), rawurlencode($Username), rawurlencode($UserID)));
     }
 }
예제 #21
0
 function DoQuote($bbcode, $action, $name, $default, $params, $content)
 {
     if ($action == 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 (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, array('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";
 }
예제 #22
0
 /**
  * Write a button group control.
  *
  * @param array $Links An array of arrays with the following keys:
  *  - Text: The text of the link.
  *  - Url: The url of the link.
  * @param string|array $CssClass The css class of the link. This can be a two-item array where the second element will be added to the buttons.
  * @param string|false $Default The url of the default link.
  * @since 2.1
  */
 function buttonGroup($Links, $CssClass = 'Button', $Default = false)
 {
     if (!is_array($Links) || count($Links) < 1) {
         return;
     }
     $Text = $Links[0]['Text'];
     $Url = $Links[0]['Url'];
     $ButtonClass = '';
     if (is_array($CssClass)) {
         list($CssClass, $ButtonClass) = $CssClass;
     }
     if ($Default && count($Links) > 1) {
         if (is_array($Default)) {
             $DefaultText = $Default['Text'];
             $Default = $Default['Url'];
         }
         // Find the default button.
         $Default = ltrim($Default, '/');
         foreach ($Links as $Link) {
             if (StringBeginsWith(ltrim($Link['Url'], '/'), $Default)) {
                 $Text = $Link['Text'];
                 $Url = $Link['Url'];
                 break;
             }
         }
         if (isset($DefaultText)) {
             $Text = $DefaultText;
         }
     }
     if (count($Links) < 2) {
         echo Anchor($Text, $Url, $CssClass);
     } else {
         // NavButton or Button?
         $ButtonClass = ConcatSep(' ', $ButtonClass, strpos($CssClass, 'NavButton') !== false ? 'NavButton' : 'Button');
         if (strpos($CssClass, 'Primary') !== false) {
             $ButtonClass .= ' Primary';
         }
         // Strip "Button" or "NavButton" off the group class.
         echo '<div class="ButtonGroup Multi ' . str_replace(array('NavButton', 'Button'), array('', ''), $CssClass) . '">';
         echo Anchor($Text, $Url, $ButtonClass);
         echo '<ul class="Dropdown MenuItems">';
         foreach ($Links as $Link) {
             echo Wrap(Anchor($Link['Text'], $Link['Url'], GetValue('CssClass', $Link, '')), 'li');
         }
         echo '</ul>';
         echo Anchor(Sprite('SpDropdownHandle', 'Sprite', T('Expand for more options.')), '#', $ButtonClass . ' Handle');
         echo '</div>';
     }
 }
 /**
  * Save message from form submission.
  * 
  * @since 2.0.0
  * @access public
  *
  * @param array $FormPostValues Values submitted via form.
  * @return int Unique ID of message created or updated.
  */
 public function Save($FormPostValues, $Conversation = NULL)
 {
     $Session = Gdn::Session();
     // Define the primary key in this model's table.
     $this->DefineSchema();
     // Add & apply any extra validation rules:
     $this->Validation->ApplyRule('Body', 'Required');
     $this->AddInsertFields($FormPostValues);
     // Validate the form posted values
     $MessageID = FALSE;
     if ($this->Validate($FormPostValues)) {
         $Fields = $this->Validation->SchemaValidationFields();
         // All fields on the form that relate to the schema
         TouchValue('Format', $Fields, C('Garden.InputFormatter', 'Html'));
         $MessageID = $this->SQL->Insert($this->Name, $Fields);
         $this->LastMessageID = $MessageID;
         $ConversationID = ArrayValue('ConversationID', $Fields, 0);
         if (!$Conversation) {
             $Conversation = $this->SQL->GetWhere('Conversation', array('ConversationID' => $ConversationID))->FirstRow(DATASET_TYPE_ARRAY);
         }
         // Get the new message count for the conversation.
         $SQLR = $this->SQL->Select('MessageID', 'count', 'CountMessages')->Select('MessageID', 'max', 'LastMessageID')->From('ConversationMessage')->Where('ConversationID', $ConversationID)->Get()->FirstRow(DATASET_TYPE_ARRAY);
         if (sizeof($SQLR)) {
             list($CountMessages, $LastMessageID) = array_values($SQLR);
         } else {
             return;
         }
         // Update the conversation's DateUpdated field.
         $DateUpdated = Gdn_Format::ToDateTime();
         $this->SQL->Update('Conversation c')->Set('CountMessages', $CountMessages)->Set('LastMessageID', $LastMessageID)->Set('UpdateUserID', Gdn::Session()->UserID)->Set('DateUpdated', $DateUpdated)->Where('ConversationID', $ConversationID)->Put();
         // Update the last message of the users that were previously up-to-date on their read messages.
         $this->SQL->Update('UserConversation uc')->Set('uc.LastMessageID', $MessageID)->Set('uc.DateConversationUpdated', $DateUpdated)->Where('uc.ConversationID', $ConversationID)->Where('uc.Deleted', '0')->Where('uc.CountReadMessages', $CountMessages - 1)->Where('uc.UserID <>', $Session->UserID)->Put();
         // Update the date updated of the users that were not up-to-date.
         $this->SQL->Update('UserConversation uc')->Set('uc.DateConversationUpdated', $DateUpdated)->Where('uc.ConversationID', $ConversationID)->Where('uc.Deleted', '0')->Where('uc.CountReadMessages <>', $CountMessages - 1)->Where('uc.UserID <>', $Session->UserID)->Put();
         // Update the sending user.
         $this->SQL->Update('UserConversation uc')->Set('uc.CountReadMessages', $CountMessages)->Set('Deleted', 0)->Set('uc.DateConversationUpdated', $DateUpdated)->Where('ConversationID', $ConversationID)->Where('UserID', $Session->UserID)->Put();
         // Find users involved in this conversation
         $UserData = $this->SQL->Select('UserID')->Select('LastMessageID')->Select('Deleted')->From('UserConversation')->Where('ConversationID', $ConversationID)->Get()->Result(DATASET_TYPE_ARRAY);
         $UpdateCountUserIDs = array();
         $NotifyUserIDs = array();
         // Collapse for call to UpdateUserCache and ActivityModel.
         $InsertUserFound = FALSE;
         foreach ($UserData as $UpdateUser) {
             $LastMessageID = GetValue('LastMessageID', $UpdateUser);
             $UserID = GetValue('UserID', $UpdateUser);
             $Deleted = GetValue('Deleted', $UpdateUser);
             if ($UserID == GetValue('InsertUserID', $Fields)) {
                 $InsertUserFound = TRUE;
                 if ($Deleted) {
                     $this->SQL->Put('UserConversation', array('Deleted' => 0, 'DateConversationUpdated' => $DateUpdated), array('ConversationID' => $ConversationID, 'UserID' => $UserID));
                 }
             }
             // Update unread for users that were up to date
             if ($LastMessageID == $MessageID) {
                 $UpdateCountUserIDs[] = $UserID;
             }
             // Send activities to users that have not deleted the conversation
             if (!$Deleted) {
                 $NotifyUserIDs[] = $UserID;
             }
         }
         if (!$InsertUserFound) {
             $UserConversation = array('UserID' => GetValue('InsertUserID', $Fields), 'ConversationID' => $ConversationID, 'LastMessageID' => $LastMessageID, 'CountReadMessages' => $CountMessages, 'DateConversationUpdated' => $DateUpdated);
             $this->SQL->Insert('UserConversation', $UserConversation);
         }
         if (sizeof($UpdateCountUserIDs)) {
             $ConversationModel = new ConversationModel();
             $ConversationModel->UpdateUserUnreadCount($UpdateCountUserIDs, TRUE);
         }
         $ActivityModel = new ActivityModel();
         foreach ($NotifyUserIDs as $NotifyUserID) {
             if ($Session->UserID == $NotifyUserID) {
                 continue;
             }
             // don't notify self.
             // Notify the users of the new message.
             $ActivityID = $ActivityModel->Add($Session->UserID, 'ConversationMessage', '', $NotifyUserID, '', "/messages/{$ConversationID}#{$MessageID}", FALSE);
             $Story = GetValue('Body', $Fields, '');
             if (C('Conversations.Subjects.Visible')) {
                 $Story = ConcatSep("\n\n", GetValue('Subject', $Conversation, ''), $Story);
             }
             $ActivityModel->SendNotification($ActivityID, $Story);
         }
     }
     return $MessageID;
 }
예제 #24
0
파일: popin.php 프로젝트: rnovino/Garden
   </li>
<?php 
if (count($this->Data('Conversations'))) {
    ?>
   <?php 
    foreach ($this->Data('Conversations') as $Row) {
        $Subject = '';
        if ($Row['Subject']) {
            $Subject = Gdn_Format::Text($Row['Subject']);
        } else {
            $Subject = '';
            foreach ($Row['Participants'] as $User) {
                if (!isset($PhotoUser)) {
                    $PhotoUser = $User;
                }
                $Subject = ConcatSep(', ', $Subject, FormatUsername($User, 'You'));
            }
        }
        if (!isset($PhotoUser)) {
            $PhotoUser = UserBuilder($Row, 'LastMessage');
        }
        ?>
   <li class="Item" rel="<?php 
        echo Url("/messages/{$Row['ConversationID']}#latest");
        ?>
">
      <div class="Author Photo"><?php 
        echo UserPhoto($PhotoUser);
        ?>
</div>
      <div class="ItemContent">
예제 #25
0
      <?php 
    }
    ?>
      <td style="max-width: 200px;">
         <?php 
    $Roles = GetValue('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) {
        ?>
예제 #26
0
 /**
  * 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 = GetValue('Px', $Options)) {
         $User = UserBuilder($User, $Px);
     } else {
         $User = (object) $User;
     }
     $LinkClass = ConcatSep(' ', GetValue('LinkClass', $Options, ''), 'PhotoWrap');
     $ImgClass = GetValue('ImageClass', $Options, 'ProfilePhoto');
     $Size = GetValue('Size', $Options);
     if ($Size) {
         $LinkClass .= " PhotoWrap{$Size}";
         $ImgClass .= " {$ImgClass}{$Size}";
     } else {
         $ImgClass .= " {$ImgClass}Medium";
         // backwards compat
     }
     $FullUser = Gdn::UserModel()->GetID(GetValue('UserID', $User), DATASET_TYPE_ARRAY);
     $UserCssClass = GetValue('_CssClass', $FullUser);
     if ($UserCssClass) {
         $LinkClass .= ' ' . $UserCssClass;
     }
     $LinkClass = $LinkClass == '' ? '' : ' class="' . $LinkClass . '"';
     $Photo = GetValue('Photo', $User);
     $Name = GetValue('Name', $User);
     $Title = htmlspecialchars(GetValue('Title', $Options, $Name));
     if ($FullUser && $FullUser['Banned']) {
         $Photo = C('Garden.BannedPhoto', 'http://cdn.vanillaforums.com/images/banned_large.png');
         $Title .= ' (' . T('Banned') . ')';
     }
     if (!$Photo && function_exists('UserPhotoDefaultUrl')) {
         $Photo = UserPhotoDefaultUrl($User, $ImgClass);
     }
     if ($Photo) {
         if (!isUrl($Photo)) {
             $PhotoUrl = Gdn_Upload::Url(ChangeBasename($Photo, 'n%s'));
         } else {
             $PhotoUrl = $Photo;
         }
         $Href = Url(UserUrl($User));
         return '<a title="' . $Title . '" href="' . $Href . '"' . $LinkClass . '>' . Img($PhotoUrl, array('alt' => $Name, 'class' => $ImgClass)) . '</a>';
     } else {
         return '';
     }
 }
예제 #27
0
 public function Index($DiscussionID = '', $DiscussionStub = '', $Offset = '', $Limit = '')
 {
     $this->AddCssFile('vanilla.css');
     $Session = Gdn::Session();
     $this->AddJsFile('jquery.resizable.js');
     $this->AddJsFile('jquery.ui.packed.js');
     $this->AddJsFile('jquery.autogrow.js');
     //      $this->AddJsFile('jquery.gardenmorepager.js');
     $this->AddJsFile('options.js');
     $this->AddJsFile('bookmark.js');
     $this->AddJsFile('discussion.js');
     $this->AddJsFile('autosave.js');
     // Load the discussion record
     $DiscussionID = is_numeric($DiscussionID) && $DiscussionID > 0 ? $DiscussionID : 0;
     $this->SetData('Discussion', $this->DiscussionModel->GetID($DiscussionID), TRUE);
     if (!is_object($this->Discussion)) {
         return Gdn::Dispatcher()->Dispatch('Default404');
     }
     // Check Permissions
     $this->Permission('Vanilla.Discussions.View', TRUE, 'Category', $this->Discussion->CategoryID);
     $this->SetData('CategoryID', $this->CategoryID = $this->Discussion->CategoryID, TRUE);
     // Setup
     $this->Title($this->Discussion->Name);
     // Actual number of comments, excluding the discussion itself
     $ActualResponses = $this->Discussion->CountComments - 1;
     // Define the query offset & limit
     if (!is_numeric($Limit) || $Limit < 0) {
         $Limit = C('Vanilla.Comments.PerPage', 50);
     }
     $OffsetProvided = $Offset != '';
     list($Offset, $Limit) = OffsetLimit($Offset, $Limit);
     // If $Offset isn't defined, assume that the user has not clicked to
     // view a next or previous page, and this is a "view" to be counted.
     if ($Offset == '') {
         $this->DiscussionModel->AddView($DiscussionID);
     }
     $this->Offset = $Offset;
     if (C('Vanilla.Comments.AutoOffset')) {
         if (!is_numeric($this->Offset) || $this->Offset < 0 || !$OffsetProvided) {
             // Round down to the appropriate offset based on the user's read comments & comments per page
             $CountCommentWatch = $this->Discussion->CountCommentWatch > 0 ? $this->Discussion->CountCommentWatch : 0;
             if ($CountCommentWatch > $ActualResponses) {
                 $CountCommentWatch = $ActualResponses;
             }
             // (((67 comments / 10 perpage) = 6.7) rounded down = 6) * 10 perpage = offset 60;
             $this->Offset = floor($CountCommentWatch / $Limit) * $Limit;
         }
         if ($ActualResponses <= $Limit) {
             $this->Offset = 0;
         }
         if ($this->Offset == $ActualResponses) {
             $this->Offset -= $Limit;
         }
     } else {
         if ($this->Offset == '') {
             $this->Offset = 0;
         }
     }
     if ($this->Offset < 0) {
         $this->Offset = 0;
     }
     // Set the canonical url to have the proper page title.
     $this->CanonicalUrl(Url(ConcatSep('/', 'discussion/' . $this->Discussion->DiscussionID . '/' . Gdn_Format::Url($this->Discussion->Name), PageNumber($this->Offset, $Limit, TRUE)), TRUE));
     // Make sure to set the user's discussion watch records
     $this->CommentModel->SetWatch($this->Discussion, $Limit, $this->Offset, $this->Discussion->CountComments);
     // Load the comments
     $this->SetData('CommentData', $this->CommentModel->Get($DiscussionID, $Limit, $this->Offset), TRUE);
     $this->SetData('Comments', $this->CommentData);
     // Build a pager
     $PagerFactory = new Gdn_PagerFactory();
     $this->Pager = $PagerFactory->GetPager('Pager', $this);
     $this->Pager->ClientID = 'Pager';
     $this->Pager->Configure($this->Offset, $Limit, $ActualResponses, 'discussion/' . $DiscussionID . '/' . Gdn_Format::Url($this->Discussion->Name) . '/%1$s');
     //      $this->Pager->MoreCode = '%1$s more comments';
     //      $this->Pager->LessCode = '%1$s older comments';
     //      $this->Pager->ClientID = 'Pager';
     //      $this->Pager->Configure(
     //         $this->Offset,
     //         $Limit,
     //         $ActualResponses,
     //         'discussion/'.$DiscussionID.'/'.Gdn_Format::Url($this->Discussion->Name).'/%1$s/%2$s/'
     //      );
     // Define the form for the comment input
     $this->Form = Gdn::Factory('Form', 'Comment');
     $this->Form->Action = Url('/vanilla/post/comment/');
     $this->DiscussionID = $this->Discussion->DiscussionID;
     $this->Form->AddHidden('DiscussionID', $this->DiscussionID);
     $this->Form->AddHidden('CommentID', '');
     // Retrieve & apply the draft if there is one:
     $DraftModel = new DraftModel();
     $Draft = $DraftModel->Get($Session->UserID, 0, 1, $this->Discussion->DiscussionID)->FirstRow();
     $this->Form->AddHidden('DraftID', $Draft ? $Draft->DraftID : '');
     if ($Draft) {
         $this->Form->SetFormValue('Body', $Draft->Body);
     }
     // 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 = 'comments';
     }
     // Add Modules
     $this->AddModule('NewDiscussionModule');
     $this->AddModule('CategoriesModule');
     $BookmarkedModule = new BookmarkedModule($this);
     $BookmarkedModule->GetData();
     $this->AddModule($BookmarkedModule);
     $this->FireEvent('BeforeDiscussionRender');
     $this->Render();
 }
예제 #28
0
 /**
  *
  *
  * @param string $Type
  * @return string
  */
 public function toStringPrevNext($Type = 'more')
 {
     $this->CssClass = ConcatSep(' ', $this->CssClass, 'PrevNextPager');
     $CurrentPage = PageNumber($this->Offset, $this->Limit);
     $Pager = '';
     if ($CurrentPage > 1) {
         $PageParam = 'p' . ($CurrentPage - 1);
         $Pager .= anchor(t('Previous'), $this->PageUrl($CurrentPage - 1), 'Previous', array('rel' => 'prev'));
     }
     $HasNext = true;
     if ($this->CurrentRecords !== false && $this->CurrentRecords < $this->Limit) {
         $HasNext = false;
     }
     if ($HasNext) {
         $PageParam = 'p' . ($CurrentPage + 1);
         $Pager = ConcatSep(' ', $Pager, anchor(t('Next'), $this->PageUrl($CurrentPage + 1), 'Next', array('rel' => 'next')));
     }
     $ClientID = $this->ClientID;
     $ClientID = $Type == 'more' ? $ClientID . 'After' : $ClientID . 'Before';
     if (isset($this->HtmlBefore)) {
         $Pager = $this->HtmlBefore . $Pager;
     }
     return $Pager == '' ? '' : sprintf($this->Wrapper, Attribute(array('id' => $ClientID, 'class' => $this->CssClass)), $Pager);
 }
예제 #29
0
 public function DiscussionController_BeforeCommentDisplay_Handler($Sender, $Args)
 {
     if (!isset($Args['Comment'])) {
         return;
     }
     $Comment = $Args['Comment'];
     if (!GetValue('Type', $Comment) == 'Whisper') {
         return;
     }
     $Args['CssClass'] = ConcatSep(' ', $Args['CssClass'], 'Whisper');
 }
예제 #30
0
 public function PathAndQuery($PathAndQuery = NULL)
 {
     // Set the path and query if it is supplied.
     if ($PathAndQuery) {
         // Parse out the path into parts.
         $Parts = parse_url($PathAndQuery);
         $Path = GetValue('path', $Parts, '');
         // Check for a filename.
         $Filename = basename($Path);
         if (strpos($Filename, '.') !== FALSE) {
             $Path = substr($Path, 0, -strlen($Filename));
         } else {
             $Filename = '';
         }
         $Path = trim($Path, '/');
         $Query = GetValue('query', $Parts, '');
         if (strlen($Query) > 0) {
             $GetParts = explode('&', $Query);
             $Get = array();
             foreach ($GetParts as $GetPart) {
                 $GetTuple = explode('=', $GetPart);
                 $Get[urldecode($GetTuple[0])] = urldecode(GetValue(1, $GetTuple, ''));
             }
         } else {
             $Get = array();
         }
         // Set the parts of the query here.
         $this->_ParsedRequest['Path'] = $Path;
         $this->_ParsedRequest['Filename'] = $Filename;
         $this->_RequestArguments[self::INPUT_GET] = $Get;
     }
     // Construct the path and query.
     $Result = $this->Path();
     $Filename = $this->Filename();
     if ($Filename && $Filename != 'default') {
         $Result .= ConcatSep('/', $Result, $Filename);
     }
     $Get = $this->GetRequestArguments(self::INPUT_GET);
     if (count($Get) > 0) {
         $Result .= '?' . http_build_query($Get);
     }
     return $Result;
 }