/**
  * Override the default index method of the settings controller in the
  * dashboard application to render new statistics.
  */
 public function StatsDashboard($Sender)
 {
     $StatsUrl = $this->AnalyticsServer;
     if (!StringBeginsWith($StatsUrl, 'http:') && !StringBeginsWith($StatsUrl, 'https:')) {
         $StatsUrl = Gdn::Request()->Scheme() . "://{$StatsUrl}";
     }
     // Tell the page where to find the Vanilla Analytics provider
     $Sender->AddDefinition('VanillaStatsUrl', $StatsUrl);
     $Sender->SetData('VanillaStatsUrl', $StatsUrl);
     // Load javascript & css, check permissions, and load side menu for this page.
     $Sender->AddJsFile('settings.js');
     $Sender->Title(T('Dashboard'));
     $Sender->RequiredAdminPermissions[] = 'Garden.Settings.Manage';
     $Sender->RequiredAdminPermissions[] = 'Garden.Users.Add';
     $Sender->RequiredAdminPermissions[] = 'Garden.Users.Edit';
     $Sender->RequiredAdminPermissions[] = 'Garden.Users.Delete';
     $Sender->RequiredAdminPermissions[] = 'Garden.Users.Approve';
     $Sender->FireEvent('DefineAdminPermissions');
     $Sender->Permission($Sender->RequiredAdminPermissions, '', FALSE);
     $Sender->AddSideMenu('dashboard/settings');
     if (!Gdn_Statistics::CheckIsEnabled() && Gdn_Statistics::CheckIsLocalhost()) {
         $Sender->Render('dashboardlocalhost', '', 'plugins/VanillaStats');
     } else {
         $Sender->AddJsFile('plugins/VanillaStats/js/vanillastats.js');
         $Sender->AddJsFile('plugins/VanillaStats/js/picker.js');
         $Sender->AddCSSFile('plugins/VanillaStats/design/picker.css');
         $this->ConfigureRange($Sender);
         $VanillaID = Gdn::InstallationID();
         $Sender->SetData('VanillaID', $VanillaID);
         $Sender->SetData('VanillaVersion', APPLICATION_VERSION);
         $Sender->SetData('SecurityToken', $this->SecurityToken());
         // Render the custom dashboard view
         $Sender->Render('dashboard', '', 'plugins/VanillaStats');
     }
 }
 public function Page($Reference)
 {
     $PageModel = new PageModel();
     $Page = $PageModel->GetFullID($Reference);
     if (!$Page) {
         throw NotFoundException();
     }
     $this->Page = $Page;
     if ($this->Head) {
         SetMetaTags($Page, $this);
         if ($Page->CustomCss) {
             $CustomCss = "\n" . $Page->CustomCss;
             if (!StringBeginsWith(trim($CustomCss), '<style', True)) {
                 $CustomCss = Wrap($CustomCss, 'style', array('type' => 'text/css'));
             }
             $this->Head->AddString($CustomCss);
         }
         if ($Page->CustomJs) {
             $CustomJs = $Page->CustomJs;
             if (!StringBeginsWith(trim($CustomJs), '<script', True)) {
                 $CustomJs = Wrap($CustomJs, 'script', array('type' => 'text/javascript'));
             }
             $this->Head->AddString($CustomJs);
         }
     }
     if ($Page->SectionID) {
         $this->Section = BuildNode($Page, 'Section');
         $this->SectionID = $Page->SectionID;
         CandyHooks::AddModules($this, $this->Section);
     }
     $this->FireEvent('ContentPage');
     if ($Page->View) {
         $this->View = $this->FetchViewLocation($this->View, False, False, False);
     }
     if (!$this->View) {
         $this->View = $this->FetchViewLocation('view', 'page', '', False);
         if (!$this->View) {
             $this->View = 'default';
         }
     }
     $this->Title($Page->Title);
     $this->SetData('Content', $Page, True);
     $this->EventArguments['Format'] =& $Page->Format;
     $this->EventArguments['Body'] =& $Page->Body;
     $this->FireEvent('BeforeBodyFormat');
     $this->ContentBodyHtml = Gdn_Format::To($Page->Body, $Page->Format);
     $Doc = PqDocument($this->ContentBodyHtml);
     $Header = $Doc->Find('h1');
     $CountH1 = count($Header);
     if ($CountH1 == 0) {
         $this->SetData('Headline', Gdn_Format::Text($Page->Title));
     } elseif ($CountH1 == 1) {
         $this->SetData('Headline', $Header->Text());
         $Header->Remove();
         $this->ContentBodyHtml = $Doc->Html();
     }
     //
     $this->AddModule('PageInfoModule');
     $this->Render();
 }
 /**
  * Manage the current ranks and add new ones
  */
 public function Settings()
 {
     $this->Permission('Yaga.Ranks.Manage');
     $this->AddSideMenu('rank/settings');
     $this->Title(T('Yaga.Ranks.Manage'));
     // Get list of ranks from the model and pass to the view
     $this->SetData('Ranks', $this->RankModel->Get());
     if ($this->Form->IsPostBack() == TRUE) {
         // Handle the photo upload
         $Upload = new Gdn_Upload();
         $TmpImage = $Upload->ValidateUpload('PhotoUpload', FALSE);
         if ($TmpImage) {
             // Generate the target image name
             $TargetImage = $Upload->GenerateTargetName(PATH_UPLOADS);
             $ImageBaseName = pathinfo($TargetImage, PATHINFO_BASENAME);
             // Save the uploaded image
             $Parts = $Upload->SaveAs($TmpImage, 'yaga' . DS . $ImageBaseName);
             $RelativeUrl = StringBeginsWith($Parts['Url'], Gdn_Url::WebRoot(TRUE), TRUE, TRUE);
             SaveToConfig('Yaga.Ranks.Photo', $RelativeUrl);
             if (C('Yaga.Ranks.Photo') == $Parts['SaveName']) {
                 $this->InformMessage(T('Yaga.Rank.PhotoUploaded'));
             }
         }
     }
     include_once $this->FetchViewLocation('helper_functions', 'rank');
     $this->Render();
 }
Example #4
0
 /**
  *
  * @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) {
         // 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 (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 ' . str_replace(array('NavButton', 'Button'), array('', ''), $CssClass) . '">';
         echo Anchor($Text, $Url, $ButtonClass);
         echo Anchor(Sprite('SpDropdownHandle'), '#', $ButtonClass . ' Handle');
         echo '<ul class="Dropdown MenuItems">';
         foreach ($Links as $Link) {
             echo Wrap(Anchor($Link['Text'], $Link['Url'], GetValue('CssClass', $Link, '')), 'li');
         }
         echo '</ul>';
         echo '</div>';
     }
 }
Example #5
0
 /**
  * Save mask information.
  * 
  * @param array $PostValues 
  * @param mixed $Validation.
  */
 public static function SaveMaskInfo($PostValues, $Validation = False)
 {
     $MaskValues = array();
     foreach ($PostValues as $Key => $Value) {
         if (StringBeginsWith($Key, 'Mask_')) {
             $MaskValues[$Value] = GetValue('Description_' . $Value, $PostValues);
         }
     }
     $NewMaskValues = array_combine($PostValues['Mask'], $PostValues['Description']);
     $MaskValues = $MaskValues + $NewMaskValues;
     $Data = array();
     foreach ($MaskValues as $Int => $Description) {
         $Int = sprintf('%u', $Int);
         if ($Int > 0 && !($Int & $Int - 1)) {
             $Data[$Int] = $Description;
         }
     }
     K('Candy.Mask.Info', $Data);
     return True;
 }
Example #6
0
 public function CalculateRow(&$Row)
 {
     $ActivityType = self::GetActivityType($Row['ActivityTypeID']);
     $Row['ActivityType'] = GetValue('Name', $ActivityType);
     if (is_string($Row['Data'])) {
         $Row['Data'] = @unserialize($Row['Data']);
     }
     $Row['PhotoUrl'] = Url($Row['Route'], TRUE);
     if (!$Row['Photo']) {
         if (isset($Row['ActivityPhoto'])) {
             $Row['Photo'] = $Row['ActivityPhoto'];
             $Row['PhotoUrl'] = UserUrl($Row, 'Activity');
         } else {
             $User = Gdn::UserModel()->GetID($Row['ActivityUserID'], DATASET_TYPE_ARRAY);
             if ($User) {
                 $Photo = $User['Photo'];
                 $Row['PhotoUrl'] = UserUrl($User);
                 if (!$Photo || StringBeginsWith($Photo, 'http')) {
                     $Row['Photo'] = $Photo;
                 } else {
                     $Row['Photo'] = Gdn_Upload::Url(ChangeBasename($Photo, 'n%s'));
                 }
             }
         }
     }
     $Data = $Row['Data'];
     if (isset($Data['ActivityUserIDs'])) {
         $Row['ActivityUserID'] = array_merge(array($Row['ActivityUserID']), $Data['ActivityUserIDs']);
     }
     if (isset($Data['RegardingUserIDs'])) {
         $Row['RegardingUserID'] = array_merge(array($Row['RegardingUserID']), $Data['RegardingUserIDs']);
     }
     $Row['Url'] = ExternalUrl($Row['Route']);
     if ($Row['HeadlineFormat']) {
         $Row['Headline'] = FormatString($Row['HeadlineFormat'], $Row);
     } else {
         $Row['Headline'] = Gdn_Format::ActivityHeadline($Row);
     }
 }
Example #7
0
 public static function Parse($Name)
 {
     $Result = FALSE;
     $Name = str_replace('\\', '/', $Name);
     if (preg_match('`^https?://`', $Name)) {
         $Result = array('Name' => $Name, 'Type' => 'external', 'SaveName' => $Name, 'SaveFormat' => '%s', 'Url' => $Name);
         return $Result;
     } elseif (StringBeginsWith($Name, PATH_UPLOADS)) {
         $Name = ltrim(substr($Name, strlen(PATH_UPLOADS)), '/');
         // This is an upload.
         $Result = array('Name' => $Name, 'Type' => '', 'SaveName' => $Name, 'SaveFormat' => '%s');
     } elseif (preg_match('`^~([^/]*)/(.*)$`', $Name, $Matches)) {
         // The first part of the name tells us the type.
         $Type = $Matches[1];
         $Name = $Matches[2];
         $Result = array('Name' => $Name, 'Type' => $Type, 'SaveName' => "~{$Type}/{$Name}", 'SaveFormat' => "~{$Type}/%s");
     } else {
         $Name = ltrim($Name, '/');
         // This is an upload in the uploads folder.
         $Result = array('Name' => $Name, 'Type' => '', 'SaveName' => $Name, 'SaveFormat' => '%s');
     }
     $UrlPrefix = self::Urls($Result['Type']);
     if ($UrlPrefix === FALSE) {
         $Result['Url'] = FALSE;
     } else {
         $Result['Url'] = $UrlPrefix . '/' . $Result['Name'];
     }
     return $Result;
 }
 /**
  * Main import page.
  *
  * @since 2.0.0
  * @access public
  */
 public function Index()
 {
     $this->Permission('Garden.Import');
     // This permission doesn't exist, so only users with Admin == '1' will succeed.
     $Timer = new Gdn_Timer();
     // Determine the current step.
     $this->Form = new Gdn_Form();
     $Imp = new ImportModel();
     $Imp->LoadState();
     // Search for the list of acceptable imports.
     $ImportPaths = array();
     $ExistingPaths = SafeGlob(PATH_ROOT . '/uploads/export*', array('gz', 'txt'));
     foreach ($ExistingPaths as $Path) {
         $ImportPaths[$Path] = basename($Path);
     }
     // Add the database as a path.
     $ImportPaths = array_merge(array('db:' => T('This Database')), $ImportPaths);
     if ($Imp->CurrentStep < 1) {
         // Check to see if there is a file.
         $ImportPath = C('Garden.Import.ImportPath');
         $Validation = new Gdn_Validation();
         if (strcasecmp(Gdn::Request()->RequestMethod(), 'post') == 0) {
             $Upload = new Gdn_Upload();
             $Validation = new Gdn_Validation();
             if (count($ImportPaths) > 0) {
                 $Validation->ApplyRule('PathSelect', 'Required', T('You must select a file to import.'));
             }
             if (count($ImportPaths) == 0 || $this->Form->GetFormValue('PathSelect') == 'NEW') {
                 $TmpFile = $Upload->ValidateUpload('ImportFile', FALSE);
             } else {
                 $TmpFile = '';
             }
             if ($TmpFile) {
                 $Filename = $_FILES['ImportFile']['name'];
                 $Extension = pathinfo($Filename, PATHINFO_EXTENSION);
                 $TargetFolder = PATH_ROOT . DS . 'uploads' . DS . 'import';
                 if (!file_exists($TargetFolder)) {
                     mkdir($TargetFolder, 0777, TRUE);
                 }
                 $ImportPath = $Upload->GenerateTargetName(PATH_ROOT . DS . 'uploads' . DS . 'import', $Extension);
                 $Upload->SaveAs($TmpFile, $ImportPath);
                 $Imp->ImportPath = $ImportPath;
                 $this->Form->SetFormValue('PathSelect', $ImportPath);
                 $UploadedFiles = GetValue('UploadedFiles', $Imp->Data);
                 $UploadedFiles[$ImportPath] = basename($Filename);
                 $Imp->Data['UploadedFiles'] = $UploadedFiles;
             } elseif ($PathSelect = $this->Form->GetFormValue('PathSelect')) {
                 if ($PathSelect == 'NEW') {
                     $Validation->AddValidationResult('ImportFile', 'ValidateRequired');
                 } else {
                     $Imp->ImportPath = $PathSelect;
                 }
             } elseif (!$Imp->ImportPath && count($ImportPaths) == 0) {
                 // There was no file uploaded this request or before.
                 $Validation->AddValidationResult('ImportFile', $Upload->Exception);
             }
             // Validate the overwrite.
             if (TRUE || strcasecmp($this->Form->GetFormValue('Overwrite'), 'Overwrite') == 0) {
                 if (!StringBeginsWith($this->Form->GetFormValue('PathSelect'), 'Db:', TRUE)) {
                     $Validation->ApplyRule('Email', 'Required');
                     if (!$this->Form->GetFormValue('UseCurrentPassword')) {
                         $Validation->ApplyRule('Password', 'Required');
                     }
                 }
             }
             if ($Validation->Validate($this->Form->FormValues())) {
                 $this->Form->SetFormValue('Overwrite', 'overwrite');
                 $Imp->FromPost($this->Form->FormValues());
                 $this->View = 'Info';
             } else {
                 $this->Form->SetValidationResults($Validation->Results());
             }
         } else {
             $this->Form->SetFormValue('PathSelect', $Imp->ImportPath);
         }
         $Imp->SaveState();
     } else {
         $this->SetData('Steps', $Imp->Steps());
         $this->View = 'Info';
     }
     if (!StringBeginsWith($Imp->ImportPath, 'db:') && !file_exists($Imp->ImportPath)) {
         $Imp->DeleteState();
     }
     try {
         $UploadedFiles = GetValue('UploadedFiles', $Imp->Data, array());
         $ImportPaths = array_merge($ImportPaths, $UploadedFiles);
         $this->SetData('ImportPaths', $ImportPaths);
         $this->SetData('Header', $Imp->GetImportHeader());
         $this->SetData('Stats', GetValue('Stats', $Imp->Data, array()));
         $this->SetData('GenerateSQL', GetValue('GenerateSQL', $Imp->Data));
         $this->SetData('ImportPath', $Imp->ImportPath);
         $this->SetData('OriginalFilename', GetValue('OriginalFilename', $Imp->Data));
         $this->SetData('CurrentStep', $Imp->CurrentStep);
         $this->SetData('LoadSpeedWarning', $Imp->LoadTableType(FALSE) == 'LoadTableWithInsert');
     } catch (Gdn_UserException $Ex) {
         $this->Form->AddError($Ex);
         $Imp->SaveState();
         $this->View = 'Index';
     }
     $this->Render();
 }
Example #9
0
 /**
  * Get the path of a view.
  *
  * @param string $View The name of the view.
  * @param string $Controller The name of the controller invoking the view or blank.
  * @param string $Folder The application folder or plugins/plugin folder.
  * @return string|false The path to the view or false if it wasn't found.
  * @deprecated
  */
 function viewLocation($View, $Controller, $Folder)
 {
     deprecated('viewLocation()');
     $Paths = array();
     if (strpos($View, '/') !== false) {
         // This is a path to the view from the root.
         $Paths[] = $View;
     } else {
         $View = strtolower($View);
         $Controller = strtolower(StringEndsWith($Controller, 'Controller', true, true));
         if ($Controller) {
             $Controller = '/' . $Controller;
         }
         $Extensions = array('tpl', 'php');
         // 1. First we check the theme.
         if (Gdn::Controller() && ($Theme = Gdn::Controller()->Theme)) {
             foreach ($Extensions as $Ext) {
                 $Paths[] = PATH_THEMES . "/{$Theme}/views{$Controller}/{$View}.{$Ext}";
             }
         }
         // 2. Then we check the application/plugin.
         if (StringBeginsWith($Folder, 'plugins/')) {
             // This is a plugin view.
             foreach ($Extensions as $Ext) {
                 $Paths[] = PATH_ROOT . "/{$Folder}/views{$Controller}/{$View}.{$Ext}";
             }
         } else {
             // This is an application view.
             $Folder = strtolower($Folder);
             foreach ($Extensions as $Ext) {
                 $Paths[] = PATH_APPLICATIONS . "/{$Folder}/views{$Controller}/{$View}.{$Ext}";
             }
             if ($Folder != 'dashboard' && StringEndsWith($View, '.master')) {
                 // This is a master view that can always fall back to the dashboard.
                 foreach ($Extensions as $Ext) {
                     $Paths[] = PATH_APPLICATIONS . "/dashboard/views{$Controller}/{$View}.{$Ext}";
                 }
             }
         }
     }
     // Now let's search the paths for the view.
     foreach ($Paths as $Path) {
         if (file_exists($Path)) {
             return $Path;
         }
     }
     Trace(array('view' => $View, 'controller' => $Controller, 'folder' => $Folder), 'View');
     Trace($Paths, 'ViewLocation()');
     return false;
 }
 /**
  * Set user preference for sorting discussions.
  */
 public function Sort($Target = '')
 {
     if (!Gdn::Session()->IsValid()) {
         throw PermissionException();
     }
     if (!$this->Request->IsAuthenticatedPostBack()) {
         throw ForbiddenException('GET');
     }
     // Get param
     $SortField = Gdn::Request()->Post('DiscussionSort');
     $SortField = 'd.' . StringBeginsWith($SortField, 'd.', TRUE, TRUE);
     // Use whitelist here too to keep database clean
     if (!in_array($SortField, DiscussionModel::AllowedSortFields())) {
         throw new Gdn_UserException("Unknown sort {$SortField}.");
     }
     // Set user pref
     Gdn::UserModel()->SavePreference(Gdn::Session()->UserID, 'Discussions.SortField', $SortField);
     if ($Target) {
         Redirect($Target);
     }
     // Send sorted discussions.
     $this->DeliveryMethod(DELIVERY_METHOD_JSON);
     $this->Render();
 }
 /**
  * Run a query, replacing database prefixes.
  * @param string $Sql The sql to execute.
  *  - :_z will be replaced by the import prefix.
  *  - :_ will be replaced by the database prefix.
  * @param array $Parameters PDO parameters to pass to the query.
  * @return Gdn_DataSet
  */
 public function Query($Sql, $Parameters = NULL)
 {
     $Db = Gdn::Database();
     // Replace db prefixes.
     $Sql = str_replace(array(':_z', ':_'), array($Db->DatabasePrefix . self::TABLE_PREFIX, $Db->DatabasePrefix), $Sql);
     // Figure out the type of the type of the query.
     if (StringBeginsWith($Sql, 'select')) {
         $Type = 'select';
     } elseif (StringBeginsWith($Sql, 'truncate')) {
         $Type = 'truncate';
     } elseif (StringBeginsWith($Sql, 'insert')) {
         $Type = 'insert';
     } elseif (StringBeginsWith($Sql, 'update')) {
         $Type = 'update';
     } elseif (StringBeginsWith($Sql, 'delete')) {
         $Type = 'delete';
     } else {
         $Type = 'select';
     }
     // Execute the query.
     if (is_array($Parameters)) {
         $this->SQL->NamedParameters($Parameters);
     }
     $Result = $this->SQL->Query($Sql, $Type);
     //$this->Timer->Split('Sql: '. str_replace("\n", "\n     ", $Sql));
     return $Result;
 }
 /**
  * Banner management screen.
  *
  * @since 2.0.0
  * @access public
  */
 public function Banner()
 {
     $this->Permission('Garden.Settings.Manage');
     $this->AddSideMenu('dashboard/settings/banner');
     $this->Title(T('Banner'));
     $Validation = new Gdn_Validation();
     $ConfigurationModel = new Gdn_ConfigurationModel($Validation);
     $ConfigurationModel->SetField(array('Garden.HomepageTitle' => C('Garden.Title'), 'Garden.Title', 'Garden.Description'));
     // Set the model on the form.
     $this->Form->SetModel($ConfigurationModel);
     // Get the current logo.
     $Logo = C('Garden.Logo');
     if ($Logo) {
         $Logo = ltrim($Logo, '/');
         // Fix the logo path.
         if (StringBeginsWith($Logo, 'uploads/')) {
             $Logo = substr($Logo, strlen('uploads/'));
         }
         $this->SetData('Logo', $Logo);
     }
     // Get the current favicon.
     $Favicon = C('Garden.FavIcon');
     $this->SetData('Favicon', $Favicon);
     $ShareImage = C('Garden.ShareImage');
     $this->SetData('ShareImage', $ShareImage);
     // If seeing the form for the first time...
     if (!$this->Form->AuthenticatedPostBack()) {
         // Apply the config settings to the form.
         $this->Form->SetData($ConfigurationModel->Data);
     } else {
         // Define some validation rules for the fields being saved
         $ConfigurationModel->Validation->ApplyRule('Garden.Title', 'Required');
         $SaveData = array();
         if ($this->Form->Save() !== FALSE) {
             $Upload = new Gdn_Upload();
             try {
                 // Validate the upload
                 $TmpImage = $Upload->ValidateUpload('Logo', FALSE);
                 if ($TmpImage) {
                     // Generate the target image name
                     $TargetImage = $Upload->GenerateTargetName(PATH_UPLOADS);
                     $ImageBaseName = pathinfo($TargetImage, PATHINFO_BASENAME);
                     // Delete any previously uploaded images.
                     if ($Logo) {
                         $Upload->Delete($Logo);
                     }
                     // Save the uploaded image
                     $Parts = $Upload->SaveAs($TmpImage, $ImageBaseName);
                     $ImageBaseName = $Parts['SaveName'];
                     $SaveData['Garden.Logo'] = $ImageBaseName;
                     $this->SetData('Logo', $ImageBaseName);
                 }
                 $ImgUpload = new Gdn_UploadImage();
                 $TmpFavicon = $ImgUpload->ValidateUpload('Favicon', FALSE);
                 if ($TmpFavicon) {
                     $ICOName = 'favicon_' . substr(md5(microtime()), 16) . '.ico';
                     if ($Favicon) {
                         $Upload->Delete($Favicon);
                     }
                     // Resize the to a png.
                     $Parts = $ImgUpload->SaveImageAs($TmpFavicon, $ICOName, 16, 16, array('OutputType' => 'ico', 'Crop' => TRUE));
                     $SaveData['Garden.FavIcon'] = $Parts['SaveName'];
                     $this->SetData('Favicon', $Parts['SaveName']);
                 }
                 $TmpShareImage = $Upload->ValidateUpload('ShareImage', FALSE);
                 if ($TmpShareImage) {
                     $TargetImage = $Upload->GenerateTargetName(PATH_UPLOADS, FALSE);
                     $ImageBaseName = pathinfo($TargetImage, PATHINFO_BASENAME);
                     if ($ShareImage) {
                         $Upload->Delete($ShareImage);
                     }
                     $Parts = $Upload->SaveAs($TmpShareImage, $ImageBaseName);
                     $SaveData['Garden.ShareImage'] = $Parts['SaveName'];
                     $this->SetData('ShareImage', $Parts['SaveName']);
                 }
             } catch (Exception $ex) {
                 $this->Form->AddError($ex);
             }
             // If there were no errors, save the path to the logo in the config
             if ($this->Form->ErrorCount() == 0) {
                 SaveToConfig($SaveData);
             }
             $this->InformMessage(T("Your settings have been saved."));
         }
     }
     $this->Render();
 }
 public function _SetBreadcrumbs($Name = NULL, $Url = NULL)
 {
     // Add the root link.
     if (GetValue('UserID', $this->User) == Gdn::Session()->UserID) {
         $Root = array('Name' => T('Profile'), 'Url' => '/profile');
         $Breadcrumb = array('Name' => $Name, 'Url' => $Url);
     } else {
         $NameUnique = C('Garden.Registration.NameUnique');
         $Root = array('Name' => GetValue('Name', $this->User), 'Url' => UserUrl($this->User));
         $Breadcrumb = array('Name' => $Name, 'Url' => $Url . '/' . ($NameUnique ? '' : GetValue('UserID', $this->User) . '/') . rawurlencode(GetValue('Name', $this->User)));
     }
     $this->Data['Breadcrumbs'][] = $Root;
     if ($Name && !StringBeginsWith($Root['Url'], $Url)) {
         $this->Data['Breadcrumbs'][] = array('Name' => $Name, 'Url' => $Url);
     }
 }
 /**
  * Connect the user with an external source.
  *
  * This controller method is meant to be used with plugins that set its data array to work.
  * Events: ConnectData
  * 
  * @since 2.0.0
  * @access public
  *
  * @param string $Method Used to register multiple providers on ConnectData event.
  */
 public function Connect($Method)
 {
     $this->AddJsFile('entry.js');
     $this->View = 'connect';
     $IsPostBack = $this->Form->IsPostBack() && $this->Form->GetFormValue('Connect', NULL) !== NULL;
     if (!$IsPostBack) {
         // Here are the initial data array values. that can be set by a plugin.
         $Data = array('Provider' => '', 'ProviderName' => '', 'UniqueID' => '', 'FullName' => '', 'Name' => '', 'Email' => '', 'Photo' => '', 'Target' => $this->Target());
         $this->Form->SetData($Data);
         $this->Form->AddHidden('Target', $this->Request->Get('Target', '/'));
     }
     // The different providers can check to see if they are being used and modify the data array accordingly.
     $this->EventArguments = array($Method);
     // Fire ConnectData event & error handling.
     $CurrentData = $this->Form->FormValues();
     try {
         $this->FireEvent('ConnectData');
     } catch (Gdn_UserException $Ex) {
         $this->Form->AddError($Ex);
         return $this->Render('ConnectError');
     } catch (Exception $Ex) {
         if (Debug()) {
             $this->Form->AddError($Ex);
         } else {
             $this->Form->AddError('There was an error fetching the connection data.');
         }
         return $this->Render('ConnectError');
     }
     if (!UserModel::NoEmail()) {
         if (!$this->Form->GetFormValue('Email') || $this->Form->GetFormValue('EmailVisible')) {
             $this->Form->SetFormValue('EmailVisible', TRUE);
             $this->Form->AddHidden('EmailVisible', TRUE);
             if ($IsPostBack) {
                 $this->Form->SetFormValue('Email', GetValue('Email', $CurrentData));
             }
         }
     }
     $FormData = $this->Form->FormValues();
     // debug
     // Make sure the minimum required data has been provided to the connect.
     if (!$this->Form->GetFormValue('Provider')) {
         $this->Form->AddError('ValidateRequired', T('Provider'));
     }
     if (!$this->Form->GetFormValue('UniqueID')) {
         $this->Form->AddError('ValidateRequired', T('UniqueID'));
     }
     if (!$this->Data('Verified')) {
         // Whatever event handler catches this must Set the data 'Verified' to true to prevent a random site from connecting without credentials.
         // This must be done EVERY postback and is VERY important.
         $this->Form->AddError('The connection data has not been verified.');
     }
     if ($this->Form->ErrorCount() > 0) {
         return $this->Render();
     }
     $UserModel = Gdn::UserModel();
     // Check to see if there is an existing user associated with the information above.
     $Auth = $UserModel->GetAuthentication($this->Form->GetFormValue('UniqueID'), $this->Form->GetFormValue('Provider'));
     $UserID = GetValue('UserID', $Auth);
     // Check to synchronise roles upon connecting.
     if (($this->Data('Trusted') || C('Garden.SSO.SynchRoles')) && $this->Form->GetFormValue('Roles', NULL) !== NULL) {
         $SaveRoles = TRUE;
         // Translate the role names to IDs.
         $Roles = $this->Form->GetFormValue('Roles', NULL);
         $Roles = RoleModel::GetByName($Roles);
         $RoleIDs = array_keys($Roles);
         if (empty($RoleIDs)) {
             // The user must have at least one role. This protects that.
             $RoleIDs = $this->UserModel->NewUserRoleIDs();
         }
         $this->Form->SetFormValue('RoleID', $RoleIDs);
     } else {
         $SaveRoles = FALSE;
     }
     if ($UserID) {
         // The user is already connected.
         $this->Form->SetFormValue('UserID', $UserID);
         if (C('Garden.Registration.ConnectSynchronize', TRUE)) {
             $User = Gdn::UserModel()->GetID($UserID, DATASET_TYPE_ARRAY);
             $Data = $this->Form->FormValues();
             // Don't overwrite the user photo if the user uploaded a new one.
             $Photo = GetValue('Photo', $User);
             if (!GetValue('Photo', $Data) || $Photo && !StringBeginsWith($Photo, 'http')) {
                 unset($Data['Photo']);
             }
             // Synchronize the user's data.
             $UserModel->Save($Data, array('NoConfirmEmail' => TRUE, 'FixUnique' => TRUE, 'SaveRoles' => $SaveRoles));
         }
         // Always save the attributes because they may contain authorization information.
         if ($Attributes = $this->Form->GetFormValue('Attributes')) {
             $UserModel->SaveAttribute($UserID, $Attributes);
         }
         // Sign the user in.
         Gdn::Session()->Start($UserID, TRUE, TRUE);
         Gdn::UserModel()->FireEvent('AfterSignIn');
         //         $this->_SetRedirect(TRUE);
         $this->_SetRedirect($this->Request->Get('display') == 'popup');
     } elseif ($this->Form->GetFormValue('Name') || $this->Form->GetFormValue('Email')) {
         $NameUnique = C('Garden.Registration.NameUnique', TRUE);
         $EmailUnique = C('Garden.Registration.EmailUnique', TRUE);
         $AutoConnect = C('Garden.Registration.AutoConnect');
         // Get the existing users that match the name or email of the connection.
         $Search = FALSE;
         if ($this->Form->GetFormValue('Name') && $NameUnique) {
             $UserModel->SQL->OrWhere('Name', $this->Form->GetFormValue('Name'));
             $Search = TRUE;
         }
         if ($this->Form->GetFormValue('Email') && ($EmailUnique || $AutoConnect)) {
             $UserModel->SQL->OrWhere('Email', $this->Form->GetFormValue('Email'));
             $Search = TRUE;
         }
         if ($Search) {
             $ExistingUsers = $UserModel->GetWhere()->ResultArray();
         } else {
             $ExistingUsers = array();
         }
         // Check to automatically link the user.
         if ($AutoConnect && count($ExistingUsers) > 0) {
             foreach ($ExistingUsers as $Row) {
                 if ($this->Form->GetFormValue('Email') == $Row['Email']) {
                     $UserID = $Row['UserID'];
                     $this->Form->SetFormValue('UserID', $UserID);
                     $Data = $this->Form->FormValues();
                     if (C('Garden.Registration.ConnectSynchronize', TRUE)) {
                         // Don't overwrite a photo if the user has already uploaded one.
                         $Photo = GetValue('Photo', $Row);
                         if (!GetValue('Photo', $Data) || $Photo && !StringBeginsWith($Photo, 'http')) {
                             unset($Data['Photo']);
                         }
                         $UserModel->Save($Data, array('NoConfirmEmail' => TRUE, 'FixUnique' => TRUE, 'SaveRoles' => $SaveRoles));
                     }
                     if ($Attributes = $this->Form->GetFormValue('Attributes')) {
                         $UserModel->SaveAttribute($UserID, $Attributes);
                     }
                     // Save the userauthentication link.
                     $UserModel->SaveAuthentication(array('UserID' => $UserID, 'Provider' => $this->Form->GetFormValue('Provider'), 'UniqueID' => $this->Form->GetFormValue('UniqueID')));
                     // Sign the user in.
                     Gdn::Session()->Start($UserID, TRUE, TRUE);
                     Gdn::UserModel()->FireEvent('AfterSignIn');
                     //         $this->_SetRedirect(TRUE);
                     $this->_SetRedirect($this->Request->Get('display') == 'popup');
                     $this->Render();
                     return;
                 }
             }
         }
         $CurrentUserID = Gdn::Session()->UserID;
         // Massage the existing users.
         foreach ($ExistingUsers as $Index => $UserRow) {
             if ($EmailUnique && $UserRow['Email'] == $this->Form->GetFormValue('Email')) {
                 $EmailFound = $UserRow;
                 break;
             }
             if ($UserRow['Name'] == $this->Form->GetFormValue('Name')) {
                 $NameFound = $UserRow;
             }
             if ($CurrentUserID > 0 && $UserRow['UserID'] == $CurrentUserID) {
                 unset($ExistingUsers[$Index]);
                 $CurrentUserFound = TRUE;
             }
         }
         if (isset($EmailFound)) {
             // The email address was found and can be the only user option.
             $ExistingUsers = array($UserRow);
             $this->SetData('NoConnectName', TRUE);
         } elseif (isset($CurrentUserFound)) {
             $ExistingUsers = array_merge(array('UserID' => 'current', 'Name' => sprintf(T('%s (Current)'), Gdn::Session()->User->Name)), $ExistingUsers);
         }
         if (!isset($NameFound) && !$IsPostBack) {
             $this->Form->SetFormValue('ConnectName', $this->Form->GetFormValue('Name'));
         }
         $this->SetData('ExistingUsers', $ExistingUsers);
         if (UserModel::NoEmail()) {
             $EmailValid = TRUE;
         } else {
             $EmailValid = ValidateRequired($this->Form->GetFormValue('Email'));
         }
         if ($this->Form->GetFormValue('Name') && $EmailValid && (!is_array($ExistingUsers) || count($ExistingUsers) == 0)) {
             // There is no existing user with the suggested name so we can just create the user.
             $User = $this->Form->FormValues();
             $User['Password'] = RandomString(50);
             // some password is required
             $User['HashMethod'] = 'Random';
             $User['Source'] = $this->Form->GetFormValue('Provider');
             $User['SourceID'] = $this->Form->GetFormValue('UniqueID');
             $User['Attributes'] = $this->Form->GetFormValue('Attributes', NULL);
             $User['Email'] = $this->Form->GetFormValue('ConnectEmail', $this->Form->GetFormValue('Email', NULL));
             //            $UserID = $UserModel->InsertForBasic($User, FALSE, array('ValidateEmail' => FALSE, 'NoConfirmEmail' => TRUE, 'SaveRoles' => $SaveRoles));
             $UserID = $UserModel->Register($User, array('CheckCaptcha' => FALSE, 'ValidateEmail' => FALSE, 'NoConfirmEmail' => TRUE, 'SaveRoles' => $SaveRoles));
             $User['UserID'] = $UserID;
             $this->Form->SetValidationResults($UserModel->ValidationResults());
             if ($UserID) {
                 $UserModel->SaveAuthentication(array('UserID' => $UserID, 'Provider' => $this->Form->GetFormValue('Provider'), 'UniqueID' => $this->Form->GetFormValue('UniqueID')));
                 $this->Form->SetFormValue('UserID', $UserID);
                 Gdn::Session()->Start($UserID, TRUE, TRUE);
                 Gdn::UserModel()->FireEvent('AfterSignIn');
                 // Send the welcome email.
                 if (C('Garden.Registration.SendConnectEmail', FALSE)) {
                     try {
                         $UserModel->SendWelcomeEmail($UserID, '', 'Connect', array('ProviderName' => $this->Form->GetFormValue('ProviderName', $this->Form->GetFormValue('Provider', 'Unknown'))));
                     } catch (Exception $Ex) {
                         // Do nothing if emailing doesn't work.
                     }
                 }
                 $this->_SetRedirect(TRUE);
             }
         }
     }
     // Save the user's choice.
     if ($IsPostBack) {
         // The user has made their decision.
         $PasswordHash = new Gdn_PasswordHash();
         $UserSelect = $this->Form->GetFormValue('UserSelect');
         if (!$UserSelect || $UserSelect == 'other') {
             // The user entered a username.
             $ConnectNameEntered = TRUE;
             if ($this->Form->ValidateRule('ConnectName', 'ValidateRequired')) {
                 $ConnectName = $this->Form->GetFormValue('ConnectName');
                 $User = FALSE;
                 if (C('Garden.Registration.NameUnique')) {
                     // Check to see if there is already a user with the given name.
                     $User = $UserModel->GetWhere(array('Name' => $ConnectName))->FirstRow(DATASET_TYPE_ARRAY);
                 }
                 if (!$User) {
                     $this->Form->ValidateRule('ConnectName', 'ValidateUsername');
                 }
             }
         } else {
             // The user selected an existing user.
             $ConnectNameEntered = FALSE;
             if ($UserSelect == 'current') {
                 if (Gdn::Session()->UserID == 0) {
                     // This shouldn't happen, but a use could sign out in another browser and click submit on this form.
                     $this->Form->AddError('@You were uexpectidly signed out.');
                 } else {
                     $UserSelect = Gdn::Session()->UserID;
                 }
             }
             $User = $UserModel->GetID($UserSelect, DATASET_TYPE_ARRAY);
         }
         if (isset($User) && $User) {
             // Make sure the user authenticates.
             if (!$User['UserID'] == Gdn::Session()->UserID) {
                 if ($this->Form->ValidateRule('ConnectPassword', 'ValidateRequired', sprintf(T('ValidateRequired'), T('Password')))) {
                     try {
                         if (!$PasswordHash->CheckPassword($this->Form->GetFormValue('ConnectPassword'), $User['Password'], $User['HashMethod'], $this->Form->GetFormValue('ConnectName'))) {
                             if ($ConnectNameEntered) {
                                 $this->Form->AddError('The username you entered has already been taken.');
                             } else {
                                 $this->Form->AddError('The password you entered is incorrect.');
                             }
                         }
                     } catch (Gdn_UserException $Ex) {
                         $this->Form->AddError($Ex);
                     }
                 }
             }
         } elseif ($this->Form->ErrorCount() == 0) {
             // The user doesn't exist so we need to add another user.
             $User = $this->Form->FormValues();
             $User['Name'] = $User['ConnectName'];
             $User['Password'] = RandomString(50);
             // some password is required
             $User['HashMethod'] = 'Random';
             $UserID = $UserModel->Register($User, array('CheckCaptcha' => FALSE, 'NoConfirmEmail' => TRUE, 'SaveRoles' => $SaveRoles));
             $User['UserID'] = $UserID;
             $this->Form->SetValidationResults($UserModel->ValidationResults());
             if ($UserID) {
                 //               // Add the user to the default roles.
                 //               $UserModel->SaveRoles($UserID, C('Garden.Registration.DefaultRoles'));
                 // Send the welcome email.
                 $UserModel->SendWelcomeEmail($UserID, '', 'Connect', array('ProviderName' => $this->Form->GetFormValue('ProviderName', $this->Form->GetFormValue('Provider', 'Unknown'))));
             }
         }
         if ($this->Form->ErrorCount() == 0) {
             // Save the authentication.
             if (isset($User) && GetValue('UserID', $User)) {
                 $UserModel->SaveAuthentication(array('UserID' => $User['UserID'], 'Provider' => $this->Form->GetFormValue('Provider'), 'UniqueID' => $this->Form->GetFormValue('UniqueID')));
                 $this->Form->SetFormValue('UserID', $User['UserID']);
             }
             // Sign the appropriate user in.
             Gdn::Session()->Start($this->Form->GetFormValue('UserID', TRUE, TRUE));
             Gdn::UserModel()->FireEvent('AfterSignIn');
             $this->_SetRedirect(TRUE);
         }
     }
     $this->Render();
 }
 /**
  * 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'], val('CssClass', $Link, '')), 'li');
         }
         echo '</ul>';
         echo anchor(sprite('SpDropdownHandle', 'Sprite', t('Expand for more options.')), '#', $ButtonClass . ' Handle');
         echo '</div>';
     }
 }
 /**
  * Undocumented method.
  *
  * @todo Method RenderMaster() needs a description.
  */
 public function RenderMaster()
 {
     // Build the master view if necessary
     if (in_array($this->_DeliveryType, array(DELIVERY_TYPE_ALL))) {
         $this->MasterView = $this->MasterView();
         // Only get css & ui components if this is NOT a syndication request
         if ($this->SyndicationMethod == SYNDICATION_NONE && is_object($this->Head)) {
             //            if (ArrayHasValue($this->_CssFiles, 'style.css')) {
             //               $this->AddCssFile('custom.css');
             //
             //               // Add the theme option's css file.
             //               if ($this->Theme && $this->ThemeOptions) {
             //                  $Filenames = GetValueR('Styles.Value', $this->ThemeOptions);
             //                  if (is_string($Filenames) && $Filenames != '%s')
             //                     $this->_CssFiles[] = array('FileName' => ChangeBasename('custom.css', $Filenames), 'AppFolder' => FALSE, 'Options' => FALSE);
             //               }
             //            } elseif (ArrayHasValue($this->_CssFiles, 'admin.css')) {
             //               $this->AddCssFile('customadmin.css');
             //            }
             $this->EventArguments['CssFiles'] =& $this->_CssFiles;
             $this->FireEvent('BeforeAddCss');
             $ETag = AssetModel::ETag();
             $CombineAssets = C('Garden.CombineAssets');
             $ThemeType = IsMobile() ? 'mobile' : 'desktop';
             // And now search for/add all css files.
             foreach ($this->_CssFiles as $CssInfo) {
                 $CssFile = $CssInfo['FileName'];
                 // style.css and admin.css deserve some custom processing.
                 if (in_array($CssFile, array('style.css', 'admin.css'))) {
                     if (!$CombineAssets) {
                         // Grab all of the css files from the asset model.
                         $AssetModel = new AssetModel();
                         $CssFiles = $AssetModel->GetCssFiles($ThemeType, ucfirst(substr($CssFile, 0, -4)), $ETag);
                         foreach ($CssFiles as $Info) {
                             $this->Head->AddCss($Info[1], 'all', TRUE, $CssInfo);
                         }
                     } else {
                         $Basename = substr($CssFile, 0, -4);
                         $this->Head->AddCss(Url("/utility/css/{$ThemeType}/{$Basename}-{$ETag}.css", '//'), 'all', FALSE, $CssInfo['Options']);
                     }
                     continue;
                 }
                 if (StringBeginsWith($CssFile, 'http')) {
                     $this->Head->AddCss($CssFile, 'all', GetValue('AddVersion', $CssInfo, TRUE), $CssInfo['Options']);
                     continue;
                 } elseif (strpos($CssFile, '/') !== FALSE) {
                     // A direct path to the file was given.
                     $CssPaths = array(CombinePaths(array(PATH_ROOT, str_replace('/', DS, $CssFile))));
                 } else {
                     //                  $CssGlob = preg_replace('/(.*)(\.css)/', '\1*\2', $CssFile);
                     $AppFolder = $CssInfo['AppFolder'];
                     if ($AppFolder == '') {
                         $AppFolder = $this->ApplicationFolder;
                     }
                     // CSS comes from one of four places:
                     $CssPaths = array();
                     if ($this->Theme) {
                         // Use the default filename.
                         $CssPaths[] = PATH_THEMES . DS . $this->Theme . DS . 'design' . DS . $CssFile;
                     }
                     // 3. Application or plugin.
                     if (StringBeginsWith($AppFolder, 'plugins/')) {
                         // The css is coming from a plugin.
                         $AppFolder = substr($AppFolder, strlen('plugins/'));
                         $CssPaths[] = PATH_PLUGINS . "/{$AppFolder}/design/{$CssFile}";
                         $CssPaths[] = PATH_PLUGINS . "/{$AppFolder}/{$CssFile}";
                     } elseif (in_array($AppFolder, array('static', 'resources'))) {
                         // This is a static css file.
                         $CssPaths[] = PATH_ROOT . "/resources/css/{$CssFile}";
                     } else {
                         // Application default. eg. root/applications/app_name/design/
                         $CssPaths[] = PATH_APPLICATIONS . DS . $AppFolder . DS . 'design' . DS . $CssFile;
                     }
                     // 4. Garden default. eg. root/applications/dashboard/design/
                     $CssPaths[] = PATH_APPLICATIONS . DS . 'dashboard' . DS . 'design' . DS . $CssFile;
                 }
                 // Find the first file that matches the path.
                 $CssPath = FALSE;
                 foreach ($CssPaths as $Glob) {
                     $Paths = SafeGlob($Glob);
                     if (is_array($Paths) && count($Paths) > 0) {
                         $CssPath = $Paths[0];
                         break;
                     }
                 }
                 // Check to see if there is a CSS cacher.
                 $CssCacher = Gdn::Factory('CssCacher');
                 if (!is_null($CssCacher)) {
                     $CssPath = $CssCacher->Get($CssPath, $AppFolder);
                 }
                 if ($CssPath !== FALSE) {
                     $CssPath = substr($CssPath, strlen(PATH_ROOT));
                     $CssPath = str_replace(DS, '/', $CssPath);
                     $this->Head->AddCss($CssPath, 'all', TRUE, $CssInfo['Options']);
                 }
             }
             // Add a custom js file.
             if (ArrayHasValue($this->_CssFiles, 'style.css')) {
                 $this->AddJsFile('custom.js');
             }
             // only to non-admin pages.
             // And now search for/add all JS files.
             $Cdns = array();
             if (Gdn::Request()->Scheme() != 'https' && !C('Garden.Cdns.Disable', FALSE)) {
                 $Cdns = array('jquery.js' => 'http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js');
             }
             $this->EventArguments['Cdns'] =& $Cdns;
             $this->FireEvent('AfterJsCdns');
             foreach ($this->_JsFiles as $Index => $JsInfo) {
                 $JsFile = $JsInfo['FileName'];
                 if (isset($Cdns[$JsFile])) {
                     $JsFile = $Cdns[$JsFile];
                 }
                 if (strpos($JsFile, '//') !== FALSE) {
                     // This is a link to an external file.
                     $this->Head->AddScript($JsFile, 'text/javascript', GetValue('Options', $JsInfo, array()));
                     continue;
                 } elseif (strpos($JsFile, '/') !== FALSE) {
                     // A direct path to the file was given.
                     $JsPaths = array(CombinePaths(array(PATH_ROOT, str_replace('/', DS, $JsFile)), DS));
                 } else {
                     $AppFolder = $JsInfo['AppFolder'];
                     if ($AppFolder == '') {
                         $AppFolder = $this->ApplicationFolder;
                     }
                     // JS can come from a theme, an any of the application folder, or it can come from the global js folder:
                     $JsPaths = array();
                     if ($this->Theme) {
                         // 1. Application-specific js. eg. root/themes/theme_name/app_name/design/
                         $JsPaths[] = PATH_THEMES . DS . $this->Theme . DS . $AppFolder . DS . 'js' . DS . $JsFile;
                         // 2. Garden-wide theme view. eg. root/themes/theme_name/design/
                         $JsPaths[] = PATH_THEMES . DS . $this->Theme . DS . 'js' . DS . $JsFile;
                     }
                     // 3. The application or plugin folder.
                     if (StringBeginsWith(trim($AppFolder, '/'), 'plugins/')) {
                         $JsPaths[] = PATH_PLUGINS . strstr($AppFolder, '/') . "/js/{$JsFile}";
                         $JsPaths[] = PATH_PLUGINS . strstr($AppFolder, '/') . "/{$JsFile}";
                     } else {
                         $JsPaths[] = PATH_APPLICATIONS . "/{$AppFolder}/js/{$JsFile}";
                     }
                     // 4. Global JS folder. eg. root/js/
                     $JsPaths[] = PATH_ROOT . DS . 'js' . DS . $JsFile;
                     // 5. Global JS library folder. eg. root/js/library/
                     $JsPaths[] = PATH_ROOT . DS . 'js' . DS . 'library' . DS . $JsFile;
                 }
                 // Find the first file that matches the path.
                 $JsPath = FALSE;
                 foreach ($JsPaths as $Glob) {
                     $Paths = SafeGlob($Glob);
                     if (is_array($Paths) && count($Paths) > 0) {
                         $JsPath = $Paths[0];
                         break;
                     }
                 }
                 if ($JsPath !== FALSE) {
                     $JsSrc = str_replace(array(PATH_ROOT, DS), array('', '/'), $JsPath);
                     $Options = (array) $JsInfo['Options'];
                     $Options['path'] = $JsPath;
                     $Version = GetValue('Version', $JsInfo);
                     if ($Version) {
                         TouchValue('version', $Options, $Version);
                     }
                     $this->Head->AddScript($JsSrc, 'text/javascript', $Options);
                 }
             }
         }
         // Add the favicon.
         $Favicon = C('Garden.FavIcon');
         if ($Favicon) {
             $this->Head->SetFavIcon(Gdn_Upload::Url($Favicon));
         }
         // Make sure the head module gets passed into the assets collection.
         $this->AddModule('Head');
     }
     // Master views come from one of four places:
     $MasterViewPaths = array();
     $MasterViewPath2 = ViewLocation($this->MasterView() . '.master', '', $this->ApplicationFolder);
     if (strpos($this->MasterView, '/') !== FALSE) {
         $MasterViewPaths[] = CombinePaths(array(PATH_ROOT, str_replace('/', DS, $this->MasterView) . '.master*'));
     } else {
         if ($this->Theme) {
             // 1. Application-specific theme view. eg. root/themes/theme_name/app_name/views/
             $MasterViewPaths[] = CombinePaths(array(PATH_THEMES, $this->Theme, $this->ApplicationFolder, 'views', $this->MasterView . '.master*'));
             // 2. Garden-wide theme view. eg. /path/to/application/themes/theme_name/views/
             $MasterViewPaths[] = CombinePaths(array(PATH_THEMES, $this->Theme, 'views', $this->MasterView . '.master*'));
         }
         // 3. Application default. eg. root/app_name/views/
         $MasterViewPaths[] = CombinePaths(array(PATH_APPLICATIONS, $this->ApplicationFolder, 'views', $this->MasterView . '.master*'));
         // 4. Garden default. eg. root/dashboard/views/
         $MasterViewPaths[] = CombinePaths(array(PATH_APPLICATIONS, 'dashboard', 'views', $this->MasterView . '.master*'));
     }
     // Find the first file that matches the path.
     $MasterViewPath = FALSE;
     foreach ($MasterViewPaths as $Glob) {
         $Paths = SafeGlob($Glob);
         if (is_array($Paths) && count($Paths) > 0) {
             $MasterViewPath = $Paths[0];
             break;
         }
     }
     if ($MasterViewPath != $MasterViewPath2) {
         Trace("Master views differ. Controller: {$MasterViewPath}, ViewLocation(): {$MasterViewPath2}", TRACE_WARNING);
     }
     $this->EventArguments['MasterViewPath'] =& $MasterViewPath;
     $this->FireEvent('BeforeFetchMaster');
     if ($MasterViewPath === FALSE) {
         trigger_error(ErrorMessage("Could not find master view: {$this->MasterView}.master*", $this->ClassName, '_FetchController'), E_USER_ERROR);
     }
     /// A unique identifier that can be used in the body tag of the master view if needed.
     $ControllerName = $this->ClassName;
     // Strip "Controller" from the body identifier.
     if (substr($ControllerName, -10) == 'Controller') {
         $ControllerName = substr($ControllerName, 0, -10);
     }
     // Strip "Gdn_" from the body identifier.
     if (substr($ControllerName, 0, 4) == 'Gdn_') {
         $ControllerName = substr($ControllerName, 4);
     }
     $this->SetData('CssClass', $this->Application . ' ' . $ControllerName . ' ' . $this->RequestMethod . ' ' . $this->CssClass, TRUE);
     // Check to see if there is a handler for this particular extension.
     $ViewHandler = Gdn::Factory('ViewHandler' . strtolower(strrchr($MasterViewPath, '.')));
     if (is_null($ViewHandler)) {
         $BodyIdentifier = strtolower($this->ApplicationFolder . '_' . $ControllerName . '_' . Gdn_Format::AlphaNumeric(strtolower($this->RequestMethod)));
         include $MasterViewPath;
     } else {
         $ViewHandler->Render($MasterViewPath, $this);
     }
 }
   /**
    * Banner management screen.
    */
   public function Banner() {
      $this->Permission('Garden.Settings.Manage');
      $this->AddSideMenu('dashboard/settings/banner');
      $this->Title(T('Banner'));
      
      $Validation = new Gdn_Validation();
      $ConfigurationModel = new Gdn_ConfigurationModel($Validation);
      $ConfigurationModel->SetField(array('Garden.Title'));
      
      // Set the model on the form.
      $this->Form->SetModel($ConfigurationModel);

      // Get the current logo.
      $Logo = C('Garden.Logo');
      if ($Logo) {
         $Logo = ltrim($Logo, '/');
         // Fix the logo path.
         if (StringBeginsWith($Logo, 'uploads/'))
            $Logo = substr($Logo, strlen('uploads/'));
         $this->SetData('Logo', $Logo);
      }
      
      // If seeing the form for the first time...
      if ($this->Form->AuthenticatedPostBack() === FALSE) {
         // Apply the config settings to the form.
         $this->Form->SetData($ConfigurationModel->Data);
      } else {
         // Define some validation rules for the fields being saved
         $ConfigurationModel->Validation->ApplyRule('Garden.Title', 'Required');
         
         if ($this->Form->Save() !== FALSE) {
            $Upload = new Gdn_Upload();
            try {
               // Validate the upload
               $TmpImage = $Upload->ValidateUpload('Logo', FALSE);
               if ($TmpImage) {
                  // Generate the target image name
                  $TargetImage = $Upload->GenerateTargetName(PATH_ROOT . DS . 'uploads');
                  $ImageBaseName = pathinfo($TargetImage, PATHINFO_BASENAME);
                  
                  // Delete any previously uploaded images.
                  if ($Logo)
                     $Upload->Delete($Logo);
                  
                  // Save the uploaded image
                  $Parts = $Upload->SaveAs(
                     $TmpImage,
                     $ImageBaseName
                  );
                  $ImageBaseName = $Parts['SaveName'];
               }
            } catch (Exception $ex) {
               $this->Form->AddError($ex->getMessage());
            }
            // If there were no errors, save the path to the logo in the config
            if ($this->Form->ErrorCount() == 0 && $Upload->GetUploadedFileName() != '') {
               SaveToConfig('Garden.Logo', $ImageBaseName);
               $this->SetData('Logo', $ImageBaseName);
            }
            
            $this->InformMessage(T("Your settings have been saved."));
         }
      }
      
      $this->Render();      
   }
    /**
     * Alternate version of Index that uses the embed master view.
     *
     * @param int $DiscussionID Unique identifier, if discussion has been created.
     * @param string $DiscussionStub Deprecated.
     * @param int $Offset
     * @param int $Limit
     */
    public function Embed($DiscussionID = '', $DiscussionStub = '', $Offset = '', $Limit = '')
    {
        $this->Title(T('Comments'));
        // Add theme data
        $this->Theme = C('Garden.CommentsTheme', $this->Theme);
        Gdn_Theme::Section('Comments');
        // Force view options
        $this->MasterView = 'empty';
        $this->CanEditComments = FALSE;
        // Don't show the comment checkboxes on the embed comments page
        // Add some css to help with the transparent bg on embedded comments
        if ($this->Head) {
            $this->Head->AddString('<style type="text/css">
body { background: transparent !important; }
</style>');
        }
        // Javascript files & options
        $this->AddJsFile('jquery.gardenmorepager.js');
        $this->AddJsFile('jquery.autogrow.js');
        $this->RemoveJsFile('autosave.js');
        $this->AddJsFile('discussion.js');
        $this->AddDefinition('DoInform', '0');
        // Suppress inform messages on embedded page.
        $this->AddDefinition('SelfUrl', Gdn::Request()->PathAndQuery());
        $this->AddDefinition('Embedded', TRUE);
        // Define incoming variables (prefer querystring parameters over method parameters)
        $DiscussionID = is_numeric($DiscussionID) && $DiscussionID > 0 ? $DiscussionID : 0;
        $DiscussionID = GetIncomingValue('vanilla_discussion_id', $DiscussionID);
        $Offset = GetIncomingValue('Offset', $Offset);
        $Limit = GetIncomingValue('Limit', $Limit);
        $vanilla_identifier = GetIncomingValue('vanilla_identifier', '');
        // Only allow vanilla identifiers of 32 chars or less - md5 if larger
        if (strlen($vanilla_identifier) > 32) {
            $vanilla_identifier = md5($vanilla_identifier);
        }
        $vanilla_type = GetIncomingValue('vanilla_type', 'page');
        $vanilla_url = GetIncomingValue('vanilla_url', '');
        $vanilla_category_id = GetIncomingValue('vanilla_category_id', '');
        $ForeignSource = array('vanilla_identifier' => $vanilla_identifier, 'vanilla_type' => $vanilla_type, 'vanilla_url' => $vanilla_url, 'vanilla_category_id' => $vanilla_category_id);
        $this->SetData('ForeignSource', $ForeignSource);
        // Set comment sorting
        $SortComments = C('Garden.Embed.SortComments') == 'desc' ? 'desc' : 'asc';
        $this->SetData('SortComments', $SortComments);
        // Retrieve the discussion record
        $Discussion = FALSE;
        if ($DiscussionID > 0) {
            $Discussion = $this->DiscussionModel->GetID($DiscussionID);
        } else {
            if ($vanilla_identifier != '' && $vanilla_type != '') {
                $Discussion = $this->DiscussionModel->GetForeignID($vanilla_identifier, $vanilla_type);
            }
        }
        // Set discussion data if we have one for this page
        if ($Discussion) {
            $this->Permission('Vanilla.Discussions.View', TRUE, 'Category', $Discussion->PermissionCategoryID);
            $this->SetData('Discussion', $Discussion, TRUE);
            $this->SetData('DiscussionID', $Discussion->DiscussionID, TRUE);
            $this->Title($Discussion->Name);
            // Actual number of comments, excluding the discussion itself
            $ActualResponses = $Discussion->CountComments;
            // Define the query offset & limit
            if (!is_numeric($Limit) || $Limit < 0) {
                $Limit = C('Garden.Embed.CommentsPerPage', 30);
            }
            $OffsetProvided = $Offset != '';
            list($Offset, $Limit) = OffsetLimit($Offset, $Limit);
            $this->Offset = $Offset;
            if (C('Vanilla.Comments.AutoOffset')) {
                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(DiscussionUrl($Discussion, PageNumber($this->Offset, $Limit)));
            // Load the comments.
            $CurrentOrderBy = $this->CommentModel->OrderBy();
            if (StringBeginsWith(GetValueR('0.0', $CurrentOrderBy), 'c.DateInserted')) {
                $this->CommentModel->OrderBy('c.DateInserted ' . $SortComments);
            }
            // allow custom sort
            $this->SetData('Comments', $this->CommentModel->Get($Discussion->DiscussionID, $Limit, $this->Offset), TRUE);
            if (count($this->CommentModel->Where()) > 0) {
                $ActualResponses = FALSE;
            }
            $this->SetData('_Count', $ActualResponses);
            // Build a pager
            $PagerFactory = new Gdn_PagerFactory();
            $this->EventArguments['PagerType'] = 'MorePager';
            $this->FireEvent('BeforeBuildPager');
            $this->Pager = $PagerFactory->GetPager($this->EventArguments['PagerType'], $this);
            $this->Pager->ClientID = 'Pager';
            $this->Pager->MoreCode = 'More Comments';
            $this->Pager->Configure($this->Offset, $Limit, $ActualResponses, 'discussion/embed/' . $Discussion->DiscussionID . '/' . Gdn_Format::Url($Discussion->Name) . '/%1$s');
            $this->Pager->CurrentRecords = $this->Comments->NumRows();
            $this->FireEvent('AfterBuildPager');
        }
        // Define the form for the comment input
        $this->Form = Gdn::Factory('Form', 'Comment');
        $this->Form->Action = Url('/vanilla/post/comment/');
        $this->Form->AddHidden('CommentID', '');
        $this->Form->AddHidden('Embedded', 'true');
        // Tell the post controller that this is an embedded page (in case there are custom views it needs to pick up from a theme).
        $this->Form->AddHidden('DisplayNewCommentOnly', 'true');
        // Only load/display the new comment after posting (don't load all new comments since the page last loaded).
        // Grab the page title
        if ($this->Request->Get('title')) {
            $this->Form->SetValue('Name', $this->Request->Get('title'));
        }
        // Set existing DiscussionID for comment form
        if ($Discussion) {
            $this->Form->AddHidden('DiscussionID', $Discussion->DiscussionID);
        }
        foreach ($ForeignSource as $Key => $Val) {
            // Drop the foreign source information into the form so it can be used if creating a discussion
            $this->Form->AddHidden($Key, $Val);
            // Also drop it into the definitions so it can be picked up for stashing comments
            $this->AddDefinition($Key, $Val);
        }
        // Retrieve & apply the draft if there is one:
        $Draft = FALSE;
        if (Gdn::Session()->UserID && $Discussion) {
            $DraftModel = new DraftModel();
            $Draft = $DraftModel->Get(Gdn::Session()->UserID, 0, 1, $Discussion->DiscussionID)->FirstRow();
            $this->Form->AddHidden('DraftID', $Draft ? $Draft->DraftID : '');
        }
        if ($Draft) {
            $this->Form->SetFormValue('Body', $Draft->Body);
        } else {
            // Look in the session stash for a comment
            $StashComment = Gdn::Session()->Stash('CommentForForeignID_' . $ForeignSource['vanilla_identifier'], '', FALSE);
            if ($StashComment) {
                $this->Form->SetValue('Body', $StashComment);
                $this->Form->SetFormValue('Body', $StashComment);
            }
        }
        // Deliver JSON data if necessary
        if ($this->_DeliveryType != DELIVERY_TYPE_ALL) {
            if ($this->Discussion) {
                $this->SetJson('LessRow', $this->Pager->ToString('less'));
                $this->SetJson('MoreRow', $this->Pager->ToString('more'));
            }
            $this->View = 'comments';
        }
        // Ordering note for JS
        if ($SortComments == 'desc') {
            $this->AddDefinition('PrependNewComments', '1');
        }
        // Report the discussion id so js can use it.
        if ($Discussion) {
            $this->AddDefinition('DiscussionID', $Discussion->DiscussionID);
        }
        $this->FireEvent('BeforeDiscussionRender');
        $this->Render();
    }
 /**
  * Call a method on the given model.
  */
 public function Model()
 {
     $this->Permission('Garden.Settings.Manage');
     $this->DeliveryMethod(DELIVERY_METHOD_JSON);
     $this->DeliveryType(DELIVERY_TYPE_DATA);
     $Args = func_get_args();
     // Check to see if we have a model.
     $ModelName = StringEndsWith(array_shift($Args), 'Model', TRUE, TRUE);
     $ModelName = ucfirst($ModelName) . 'Model';
     if (!class_exists($ModelName)) {
         throw NotFoundException($ModelName);
     }
     // Check for json/xml style extension.
     if (count($Args)) {
         $LastArg = $Args[count($Args) - 1];
         $Extension = strrchr($LastArg, '.');
         if ($Extension) {
             $Args[count($Args) - 1] = substr($LastArg, 0, -strlen($Extension));
             $Extension = strtolower($Extension);
             if ($Extension == '.xml') {
                 $this->DeliveryMethod(DELIVERY_METHOD_XML);
             }
         }
     }
     // Instantiate the model.
     $Model = new $ModelName();
     $MethodName = array_shift($Args);
     // Reflect the arguments.
     $Callback = array($Model, $MethodName);
     if ($this->Request->Get('help')) {
         $this->SetData('Model', get_class($Model));
         if ($MethodName) {
             if (!method_exists($Model, $MethodName)) {
                 throw NotFoundException($ModelName . '->' . $MethodName . '()');
             }
             $this->SetData('Method', $MethodName);
             $Meth = new ReflectionMethod($Callback[0], $Callback[1]);
             $MethArgs = $Meth->getParameters();
             $Args = array();
             foreach ($MethArgs as $Index => $MethArg) {
                 $ParamName = $MethArg->getName();
                 if ($MethArg->isDefaultValueAvailable()) {
                     $Args[$ParamName] = $MethArg->getDefaultValue();
                 } else {
                     $Args[$ParamName] = 'REQUIRED';
                 }
             }
             $this->SetData('Args', $Args);
         } else {
             $Class = new ReflectionClass($Model);
             $Meths = $Class->getMethods();
             $Methods = array();
             foreach ($Meths as $Meth) {
                 $MethodName = $Meth->getName();
                 if (StringBeginsWith($MethodName, '_')) {
                     continue;
                 }
                 $MethArgs = $Meth->getParameters();
                 $Args = array();
                 foreach ($MethArgs as $Index => $MethArg) {
                     $ParamName = $MethArg->getName();
                     if ($MethArg->isDefaultValueAvailable()) {
                         $Args[$ParamName] = $MethArg->getDefaultValue();
                     } else {
                         $Args[$ParamName] = 'REQUIRED';
                     }
                 }
                 $Methods[$MethodName] = array('Method' => $MethodName, 'Args' => $Args);
             }
             $this->SetData('Methods', $Methods);
         }
     } else {
         if (!method_exists($Model, $MethodName)) {
             throw NotFoundException($ModelName . '->' . $MethodName . '()');
         }
         $MethodArgs = ReflectArgs($Callback, $this->Request->Get(), $Args);
         $Result = call_user_func_array($Callback, $MethodArgs);
         if (is_array($Result)) {
             $this->Data = $Result;
         } elseif (is_a($Result, 'Gdn_DataSet')) {
             $Result = $Result->ResultArray();
             $this->Data = $Result;
         } elseif (is_a($Result, 'stdClass')) {
             $this->Data = (array) $Result;
         } else {
             $this->SetData('Result', $Result);
         }
     }
     $this->Render();
 }
Example #20
0
 public static function CssPath($ThemeType, $Filename, $Folder)
 {
     if (!$ThemeType) {
         $ThemeType = IsMobile() ? 'mobile' : 'desktop';
     }
     // 1. Check for a url.
     if (IsUrl($Filename)) {
         return array($Filename, $Filename);
     }
     // 2. Check for a full path.
     if (strpos($Filename, '/') !== FALSE) {
         $Filename = '/' . ltrim($Filename, '/');
         $Path = PATH_ROOT . $Filename;
         if (file_exists($Path)) {
             return array($Path, $Filename);
         } else {
             return FALSE;
         }
     }
     // 3. Check the theme.
     if ($Theme = Gdn::ThemeManager()->ThemeFromType($ThemeType)) {
         $Paths[] = array(PATH_THEMES . "/{$Theme}/design/{$Filename}", "/themes/{$Theme}/design/{$Filename}");
     }
     if ($Folder) {
         // 4. Check static, a plugin or application.
         if (in_array($Folder, array('resources', 'static'))) {
             $path = "/resources/css/{$Filename}";
             $Paths[] = array(PATH_ROOT . $path, $path);
         } elseif (StringBeginsWith($Folder, 'plugins/')) {
             $Folder = substr($Folder, strlen('plugins/'));
             $Paths[] = array(PATH_PLUGINS . "/{$Folder}/design/{$Filename}", "/plugins/{$Folder}/design/{$Filename}");
             $Paths[] = array(PATH_PLUGINS . "/{$Folder}/{$Filename}", "/plugins/{$Folder}/{$Filename}");
         } else {
             $Paths[] = array(PATH_APPLICATIONS . "/{$Folder}/design/{$Filename}", "/applications/{$Folder}/design/{$Filename}");
         }
     }
     // 5. Check the default.
     if ($Folder != 'dashboard') {
         $Paths[] = array(PATH_APPLICATIONS . '/dashboard/design/$Filename', "/applications/dashboard/design/{$Filename}");
     }
     foreach ($Paths as $Info) {
         if (file_exists($Info[0])) {
             return $Info;
         }
     }
     return FALSE;
 }
Example #21
0
 /**
  * Adds a JS file to search for in the application or global js folder(s).
  *
  * @param string $FileName The js file to search for.
  * @param string $AppFolder The application folder that should contain the JS file. Default is to use the application folder that this controller belongs to.
  */
 public function addJsFile($FileName, $AppFolder = '', $Options = null)
 {
     $JsInfo = array('FileName' => $FileName, 'AppFolder' => $AppFolder, 'Options' => $Options);
     if (StringBeginsWith($AppFolder, 'plugins/')) {
         $Name = stringBeginsWith($AppFolder, 'plugins/', true, true);
         $Info = Gdn::pluginManager()->getPluginInfo($Name, Gdn_PluginManager::ACCESS_PLUGINNAME);
         if ($Info) {
             $JsInfo['Version'] = val('Version', $Info);
         }
     } else {
         $JsInfo['Version'] = APPLICATION_VERSION;
     }
     $this->_JsFiles[] = $JsInfo;
 }
Example #22
0
}
$Photo = $User->Photo;
if ($User->Banned) {
    $BannedPhoto = C('Garden.BannedPhoto', 'http://cdn.vanillaforums.com/images/banned_large.png');
    if ($BannedPhoto) {
        $Photo = Gdn_Upload::Url($BannedPhoto);
    }
}
if ($Photo) {
    ?>
   <div class="Photo PhotoWrap PhotoWrapLarge <?php 
    echo GetValue('_CssClass', $User);
    ?>
">
      <?php 
    if (StringBeginsWith($Photo, 'http')) {
        $Img = Img($Photo, array('class' => 'ProfilePhotoLarge'));
    } else {
        $Img = Img(Gdn_Upload::Url(ChangeBasename($Photo, 'p%s')), array('class' => 'ProfilePhotoLarge'));
    }
    if (!$User->Banned && (Gdn::Session()->UserID == $User->UserID || Gdn::Session()->CheckPermission('Garden.Users.Edit'))) {
        echo Anchor(Wrap(T('Change Picture')), '/profile/picture?userid=' . $User->UserID, 'ChangePicture');
    }
    echo $Img;
    ?>
   </div>
<?php 
} else {
    if ($User->UserID == Gdn::Session()->UserID || Gdn::Session()->CheckPermission('Garden.Users.Edit')) {
        ?>
   <div class="Photo"><?php 
Example #23
0
 /**
  * Offers a quick and dirty way of parsing an addon's info array without using eval().
  * @param string $Path The path to the info array.
  * @param string $Variable The name of variable containing the information.
  * @return array|false The info array or false if the file could not be parsed.
  */
 public static function ParseInfoArray($Path, $Variable = FALSE)
 {
     $fp = fopen($Path, 'rb');
     $Lines = array();
     $InArray = FALSE;
     // Get all of the lines in the info array.
     while (($Line = fgets($fp)) !== FALSE) {
         // Remove comments from the line.
         $Line = preg_replace('`\\s//.*$`', '', $Line);
         if (!$Line) {
             continue;
         }
         if (!$InArray && preg_match('`\\$([A-Za-z]+Info)\\s*\\[`', trim($Line), $Matches)) {
             $Variable = $Matches[1];
             if (preg_match('`\\[\\s*[\'"](.+?)[\'"]\\s*\\]`', $Line, $Matches)) {
                 $GlobalKey = $Matches[1];
                 $InArray = TRUE;
             }
         } elseif ($InArray && StringEndsWith(trim($Line), ';')) {
             break;
         } elseif ($InArray) {
             $Lines[] = trim($Line);
         }
     }
     fclose($fp);
     if (count($Lines) == 0) {
         return FALSE;
     }
     // Parse the name/value information in the arrays.
     $Result = array();
     foreach ($Lines as $Line) {
         // Get the name from the line.
         if (!preg_match('`[\'"](.+?)[\'"]\\s*=>`', $Line, $Matches) || !substr($Line, -1) == ',') {
             continue;
         }
         $Key = $Matches[1];
         // Strip the key from the line.
         $Line = trim(trim(substr(strstr($Line, '=>'), 2)), ',');
         if (strlen($Line) == 0) {
             continue;
         }
         $Value = NULL;
         if (is_numeric($Line)) {
             $Value = $Line;
         } elseif (strcasecmp($Line, 'TRUE') == 0 || strcasecmp($Line, 'FALSE') == 0) {
             $Value = $Line;
         } elseif (in_array($Line[0], array('"', "'")) && substr($Line, -1) == $Line[0]) {
             $Quote = $Line[0];
             $Value = trim($Line, $Quote);
             $Value = str_replace('\\' . $Quote, $Quote, $Value);
         } elseif (StringBeginsWith($Line, 'array(') && substr($Line, -1) == ')') {
             // Parse the line's array.
             $Line = substr($Line, 6, strlen($Line) - 7);
             $Items = explode(',', $Line);
             $Array = array();
             foreach ($Items as $Item) {
                 $SubItems = explode('=>', $Item);
                 if (count($SubItems) == 1) {
                     $Array[] = trim(trim($SubItems[0]), '"\'');
                 } elseif (count($SubItems) == 2) {
                     $SubKey = trim(trim($SubItems[0]), '"\'');
                     $SubValue = trim(trim($SubItems[1]), '"\'');
                     $Array[$SubKey] = $SubValue;
                 }
             }
             $Value = $Array;
         }
         if ($Value != NULL) {
             $Result[$Key] = $Value;
         }
     }
     $Result = array($GlobalKey => $Result, 'Variable' => $Variable);
     return $Result;
 }
 /**
  * Returns a platform-specific query to fetch column data from $Table.
  *
  * @param string $Table The name of the table to fetch column data from.
  */
 public function FetchColumnSql($Table) {
    if ($Table[0] != '`' && !StringBeginsWith($Table, $this->Database->DatabasePrefix))
       $Table = $this->Database->DatabasePrefix.$Table;
    
    return "show columns from ".$this->FormatTableName($Table);
 }
Example #25
0
 /**
  * Undocumented method.
  *
  * @todo Method RenderMaster() needs a description.
  */
 public function RenderMaster()
 {
     // Build the master view if necessary
     if (in_array($this->_DeliveryType, array(DELIVERY_TYPE_ALL))) {
         $this->MasterView = $this->MasterView();
         // Only get css & ui components if this is NOT a syndication request
         if ($this->SyndicationMethod == SYNDICATION_NONE && is_object($this->Head)) {
             if (ArrayHasValue($this->_CssFiles, 'style.css')) {
                 $this->AddCssFile('custom.css');
             }
             if (ArrayHasValue($this->_CssFiles, 'admin.css')) {
                 $this->AddCssFile('customadmin.css');
             }
             $this->EventArguments['CssFiles'] =& $this->_CssFiles;
             $this->FireEvent('BeforeAddCss');
             // And now search for/add all css files
             foreach ($this->_CssFiles as $CssInfo) {
                 $CssFile = $CssInfo['FileName'];
                 if (strpos($CssFile, '/') !== FALSE) {
                     // A direct path to the file was given.
                     $CssPaths = array(CombinePaths(array(PATH_ROOT, str_replace('/', DS, $CssFile))));
                 } else {
                     $CssGlob = preg_replace('/(.*)(\\.css)/', '\\1*\\2', $CssFile);
                     $AppFolder = $CssInfo['AppFolder'];
                     if ($AppFolder == '') {
                         $AppFolder = $this->ApplicationFolder;
                     }
                     // CSS comes from one of four places:
                     $CssPaths = array();
                     if ($this->Theme) {
                         // 1. Application-specific css. eg. root/themes/theme_name/app_name/design/
                         // $CssPaths[] = PATH_THEMES . DS . $this->Theme . DS . $AppFolder . DS . 'design' . DS . $CssGlob;
                         // 2. Theme-wide theme view. eg. root/themes/theme_name/design/
                         // a) Check to see if a customized version of the css is there.
                         if ($this->ThemeOptions) {
                             $Filenames = GetValueR('Styles.Value', $this->ThemeOptions);
                             if (is_string($Filenames) && $Filenames != '%s') {
                                 $CssPaths[] = PATH_THEMES . DS . $this->Theme . DS . 'design' . DS . ChangeBasename($CssFile, $Filenames);
                             }
                         }
                         // b) Use the default filename.
                         $CssPaths[] = PATH_THEMES . DS . $this->Theme . DS . 'design' . DS . $CssFile;
                     }
                     // 3. Application or plugin.
                     if (StringBeginsWith($AppFolder, 'plugins/')) {
                         // The css is coming from a plugin.
                         $AppFolder = substr($AppFolder, strlen('plugins/'));
                         $CssPaths[] = PATH_PLUGINS . "/{$AppFolder}/design/{$CssFile}";
                         $CssPaths[] = PATH_PLUGINS . "/{$AppFolder}/{$CssFile}";
                     } else {
                         // Application default. eg. root/applications/app_name/design/
                         $CssPaths[] = PATH_APPLICATIONS . DS . $AppFolder . DS . 'design' . DS . $CssFile;
                     }
                     // 4. Garden default. eg. root/applications/dashboard/design/
                     $CssPaths[] = PATH_APPLICATIONS . DS . 'dashboard' . DS . 'design' . DS . $CssFile;
                 }
                 // Find the first file that matches the path.
                 $CssPath = FALSE;
                 foreach ($CssPaths as $Glob) {
                     $Paths = SafeGlob($Glob);
                     if (is_array($Paths) && count($Paths) > 0) {
                         $CssPath = $Paths[0];
                         break;
                     }
                 }
                 // Check to see if there is a CSS cacher.
                 $CssCacher = Gdn::Factory('CssCacher');
                 if (!is_null($CssCacher)) {
                     $CssPath = $CssCacher->Get($CssPath, $AppFolder);
                 }
                 if ($CssPath !== FALSE) {
                     $CssPath = substr($CssPath, strlen(PATH_ROOT));
                     $CssPath = str_replace(DS, '/', $CssPath);
                     $this->Head->AddCss($CssPath, 'all', TRUE, $CssInfo['Options']);
                 }
             }
             // Add a custom js file.
             if (ArrayHasValue($this->_CssFiles, 'style.css')) {
                 $this->AddJsFile('custom.js');
             }
             // only to non-admin pages.
             // And now search for/add all JS files
             foreach ($this->_JsFiles as $Index => $JsInfo) {
                 $JsFile = $JsInfo['FileName'];
                 if (strpos($JsFile, '//') !== FALSE) {
                     // This is a link to an external file.
                     $this->Head->AddScript($JsFile);
                     continue;
                 }
                 if (strpos($JsFile, '/') !== FALSE) {
                     // A direct path to the file was given.
                     $JsPaths = array(CombinePaths(array(PATH_ROOT, str_replace('/', DS, $JsFile)), DS));
                 } else {
                     $AppFolder = $JsInfo['AppFolder'];
                     if ($AppFolder == '') {
                         $AppFolder = $this->ApplicationFolder;
                     }
                     // JS can come from a theme, an any of the application folder, or it can come from the global js folder:
                     $JsPaths = array();
                     if ($this->Theme) {
                         // 1. Application-specific js. eg. root/themes/theme_name/app_name/design/
                         $JsPaths[] = PATH_THEMES . DS . $this->Theme . DS . $AppFolder . DS . 'js' . DS . $JsFile;
                         // 2. Garden-wide theme view. eg. root/themes/theme_name/design/
                         $JsPaths[] = PATH_THEMES . DS . $this->Theme . DS . 'js' . DS . $JsFile;
                     }
                     // 3. The application or plugin folder.
                     if (StringBeginsWith(trim($AppFolder, '/'), 'plugins/')) {
                         $JsPaths[] = PATH_PLUGINS . strstr($AppFolder, '/') . "/js/{$JsFile}";
                         $JsPaths[] = PATH_PLUGINS . strstr($AppFolder, '/') . "/{$JsFile}";
                     } else {
                         $JsPaths[] = PATH_APPLICATIONS . "/{$AppFolder}/js/{$JsFile}";
                     }
                     // 4. Global JS folder. eg. root/js/
                     $JsPaths[] = PATH_ROOT . DS . 'js' . DS . $JsFile;
                     // 5. Global JS library folder. eg. root/js/library/
                     $JsPaths[] = PATH_ROOT . DS . 'js' . DS . 'library' . DS . $JsFile;
                 }
                 // Find the first file that matches the path.
                 $JsPath = FALSE;
                 foreach ($JsPaths as $Glob) {
                     $Paths = SafeGlob($Glob);
                     if (is_array($Paths) && count($Paths) > 0) {
                         $JsPath = $Paths[0];
                         break;
                     }
                 }
                 if ($JsPath !== FALSE) {
                     $JsSrc = str_replace(array(PATH_ROOT, DS), array('', '/'), $JsPath);
                     $Options = (array) $JsInfo['Options'];
                     $Options['path'] = $JsPath;
                     $Version = GetValue('Version', $JsInfo);
                     if ($Version) {
                         TouchValue('version', $Options, $Version);
                     }
                     $this->Head->AddScript($JsSrc, 'text/javascript', $Options);
                 }
             }
         }
         // Add the favicon
         $this->Head->SetFavIcon(C('Garden.FavIcon', Asset('themes/' . $this->Theme . '/design/favicon.png')));
         // Make sure the head module gets passed into the assets collection.
         $this->AddModule('Head');
     }
     // Master views come from one of four places:
     $MasterViewPaths = array();
     if (strpos($this->MasterView, '/') !== FALSE) {
         $MasterViewPaths[] = CombinePaths(array(PATH_ROOT, str_replace('/', DS, $this->MasterView) . '.master*'));
     } else {
         if ($this->Theme) {
             // 1. Application-specific theme view. eg. root/themes/theme_name/app_name/views/
             $MasterViewPaths[] = CombinePaths(array(PATH_THEMES, $this->Theme, $this->ApplicationFolder, 'views', $this->MasterView . '.master*'));
             // 2. Garden-wide theme view. eg. /path/to/application/themes/theme_name/views/
             $MasterViewPaths[] = CombinePaths(array(PATH_THEMES, $this->Theme, 'views', $this->MasterView . '.master*'));
         }
         // 3. Application default. eg. root/app_name/views/
         $MasterViewPaths[] = CombinePaths(array(PATH_APPLICATIONS, $this->ApplicationFolder, 'views', $this->MasterView . '.master*'));
         // 4. Garden default. eg. root/dashboard/views/
         $MasterViewPaths[] = CombinePaths(array(PATH_APPLICATIONS, 'dashboard', 'views', $this->MasterView . '.master*'));
     }
     // Find the first file that matches the path.
     $MasterViewPath = FALSE;
     foreach ($MasterViewPaths as $Glob) {
         $Paths = SafeGlob($Glob);
         if (is_array($Paths) && count($Paths) > 0) {
             $MasterViewPath = $Paths[0];
             break;
         }
     }
     $this->EventArguments['MasterViewPath'] =& $MasterViewPath;
     $this->FireEvent('BeforeFetchMaster');
     if ($MasterViewPath === FALSE) {
         trigger_error(ErrorMessage("Could not find master view: {$this->MasterView}.master*", $this->ClassName, '_FetchController'), E_USER_ERROR);
     }
     /// A unique identifier that can be used in the body tag of the master view if needed.
     $ControllerName = $this->ClassName;
     // Strip "Controller" from the body identifier.
     if (substr($ControllerName, -10) == 'Controller') {
         $ControllerName = substr($ControllerName, 0, -10);
     }
     // Strip "Gdn_" from the body identifier.
     if (substr($ControllerName, 0, 4) == 'Gdn_') {
         $ControllerName = substr($ControllerName, 4);
     }
     $this->SetData('CssClass', $this->Application . ' ' . $ControllerName . ' ' . $this->RequestMethod . ' ' . $this->CssClass, TRUE);
     // Check to see if there is a handler for this particular extension.
     $ViewHandler = Gdn::Factory('ViewHandler' . strtolower(strrchr($MasterViewPath, '.')));
     if (is_null($ViewHandler)) {
         $BodyIdentifier = strtolower($this->ApplicationFolder . '_' . $ControllerName . '_' . Gdn_Format::AlphaNumeric(strtolower($this->RequestMethod)));
         include $MasterViewPath;
     } else {
         $ViewHandler->Render($MasterViewPath, $this);
     }
 }
Example #26
0
 public function FetchPageInfo($Url, $ThrowError = FALSE)
 {
     $PageInfo = FetchPageInfo($Url, 3, $ThrowError);
     $Title = GetValue('Title', $PageInfo, '');
     if ($Title == '') {
         if ($ThrowError) {
             throw new Gdn_UserException(T("The page didn't contain any information."));
         }
         $Title = FormatString(T('Undefined discussion subject.'), array('Url' => $Url));
     } else {
         if ($Strip = C('Vanilla.Embed.StripPrefix')) {
             $Title = StringBeginsWith($Title, $Strip, TRUE, TRUE);
         }
         if ($Strip = C('Vanilla.Embed.StripSuffix')) {
             $Title = StringEndsWith($Title, $Strip, TRUE, TRUE);
         }
     }
     $Title = trim($Title);
     $Description = GetValue('Description', $PageInfo, '');
     $Images = GetValue('Images', $PageInfo, array());
     $Body = FormatString(T('EmbeddedDiscussionFormat'), array('Title' => $Title, 'Excerpt' => $Description, 'Image' => count($Images) > 0 ? Img(GetValue(0, $Images), array('class' => 'LeftAlign')) : '', 'Url' => $Url));
     if ($Body == '') {
         $Body = $ForeignUrl;
     }
     if ($Body == '') {
         $Body = FormatString(T('EmbeddedNoBodyFormat.'), array('Url' => $Url));
     }
     $Result = array('Name' => $Title, 'Body' => $Body, 'Format' => 'Html');
     return $Result;
 }
 public function ScanPluginFile($PluginFile, $VariableName = NULL)
 {
     // Find the $PluginInfo array
     if (!file_exists($PluginFile)) {
         return;
     }
     $Lines = file($PluginFile);
     $InfoBuffer = FALSE;
     $ClassBuffer = FALSE;
     $ClassName = '';
     $PluginInfoString = '';
     if (!$VariableName) {
         $VariableName = 'PluginInfo';
     }
     $ParseVariableName = '$' . $VariableName;
     ${$VariableName} = array();
     foreach ($Lines as $Line) {
         if ($InfoBuffer && substr(trim($Line), -2) == ');') {
             $PluginInfoString .= $Line;
             $ClassBuffer = TRUE;
             $InfoBuffer = FALSE;
         }
         if (StringBeginsWith(trim($Line), $ParseVariableName)) {
             $InfoBuffer = TRUE;
         }
         if ($InfoBuffer) {
             $PluginInfoString .= $Line;
         }
         if ($ClassBuffer && strtolower(substr(trim($Line), 0, 6)) == 'class ') {
             $Parts = explode(' ', $Line);
             if (count($Parts) > 2) {
                 $ClassName = $Parts[1];
             }
             break;
         }
     }
     unset($Lines);
     if ($PluginInfoString != '') {
         eval($PluginInfoString);
     }
     // Define the folder name and assign the class name for the newly added item
     if (isset(${$VariableName}) && is_array(${$VariableName})) {
         $Item = array_pop($Trash = array_keys(${$VariableName}));
         ${$VariableName}[$Item]['Index'] = $Item;
         ${$VariableName}[$Item]['ClassName'] = $ClassName;
         ${$VariableName}[$Item]['PluginFilePath'] = $PluginFile;
         ${$VariableName}[$Item]['PluginRoot'] = dirname($PluginFile);
         if (!array_key_exists('Name', ${$VariableName}[$Item])) {
             ${$VariableName}[$Item]['Name'] = $Item;
         }
         if (!array_key_exists('Folder', ${$VariableName}[$Item])) {
             ${$VariableName}[$Item]['Folder'] = $Item;
         }
         return ${$VariableName}[$Item];
     } elseif ($VariableName !== NULL) {
         if (isset(${$VariableName})) {
             return ${$VariableName};
         }
     }
     return NULL;
 }
Example #28
0
 /**
  * Execute a single validation rule and return its result.
  *
  * @param mixed $Value The value to validate.
  * @param string $FieldName The name of the field to put into the error result.
  * @param string|array $Rule The rule to validate which can be one of the following.
  *  - string: The name of a function used to validate the value.
  *  - 'regex:<regex>': The regular expression used to validate the value.
  *  - array: An array with the following keys:
  *    - Name: The name of the function used to validate.
  *    - Args: An argument to pass to the function after the value.
  * @param string $CustomError A custom error message.
  * @return bool|string One of the following
  *  - TRUE: The value passed validation.
  *  - string: The error message associated with the error.
  */
 public static function ValidateRule($Value, $FieldName, $Rule, $CustomError = FALSE)
 {
     // Figure out the type of rule.
     if (is_string($Rule)) {
         if (StringBeginsWith($Rule, 'regex:', TRUE)) {
             $RuleName = 'regex';
             $Args = substr($Rule, 6);
         } elseif (StringBeginsWith($Rule, 'function:', TRUE)) {
             $RuleName = substr($Rule, 9);
         } else {
             $RuleName = $Rule;
         }
     } elseif (is_array($Rule)) {
         $RuleName = GetValue('Name', $Rule);
         $Args = GetValue('Args', $Rule);
     }
     if (!isset($Args)) {
         $Args = NULL;
     }
     if (function_exists($RuleName)) {
         $Result = $RuleName($Value, $Args);
         if ($Result === TRUE) {
             return TRUE;
         } elseif ($CustomError) {
             return $CustomError;
         } elseif (is_string($Result)) {
             return $Result;
         } else {
             return sprintf(T($RuleName), T($FieldName));
         }
     } else {
         return sprintf('Validation does not exist: %s.', $RuleName);
     }
 }
Example #29
0
 function ExternalUrl($Path)
 {
     $Format = C('Garden.ExternalUrlFormat');
     if ($Format && !StringBeginsWith($Path, 'http')) {
         $Result = sprintf($Format, ltrim($Path, '/'));
     } else {
         $Result = Url($Path, TRUE);
     }
     return $Result;
 }
Example #30
0
 /**
  * Modifies $this->Table() with the columns specified with $this->Column().
  *
  * @param boolean $Explicit If TRUE, this method will remove any columns from the table that were not
  * defined with $this->Column().
  */
 protected function _Modify($Explicit = FALSE)
 {
     $Px = $this->_DatabasePrefix;
     $AdditionalSql = array();
     // statements executed at the end
     // Returns an array of schema data objects for each field in the specified
     // table. The returned array of objects contains the following properties:
     // Name, PrimaryKey, Type, AllowNull, Default, Length, Enum.
     $ExistingColumns = $this->ExistingColumns();
     $AlterSql = array();
     // 1. Remove any unnecessary columns if this is an explicit modification
     if ($Explicit) {
         // array_diff returns values from the first array that aren't present
         // in the second array. In this example, all columns currently in the
         // table that are NOT in $this->_Columns.
         $RemoveColumns = array_diff(array_keys($ExistingColumns), array_keys($this->_Columns));
         foreach ($RemoveColumns as $Column) {
             $AlterSql[] = "drop column `{$Column}`";
         }
     }
     // Prepare the alter query
     $AlterSqlPrefix = 'alter table `' . $this->_DatabasePrefix . $this->_TableName . "`\n";
     // 2. Alter the table storage engine.
     $ForceDatabaseEngine = C('Database.ForceStorageEngine');
     if ($ForceDatabaseEngine && !$this->_TableStorageEngine) {
         $this->_TableStorageEngine = $ForceDatabaseEngine;
     }
     $Indexes = $this->_IndexSql($this->_Columns);
     $IndexesDb = $this->_IndexSqlDb();
     if ($this->_TableStorageEngine) {
         $CurrentEngine = $this->Database->Query("show table status where name = '" . $this->_DatabasePrefix . $this->_TableName . "'")->Value('Engine');
         if (strcasecmp($CurrentEngine, $this->_TableStorageEngine)) {
             // Check to drop a fulltext index if we don't support it.
             if (!$this->_SupportsFulltext()) {
                 foreach ($IndexesDb as $IndexName => $IndexSql) {
                     if (StringBeginsWith($IndexSql, 'fulltext', TRUE)) {
                         $DropIndexQuery = "{$AlterSqlPrefix} drop index {$IndexName};\n";
                         if (!$this->Query($DropIndexQuery)) {
                             throw new Exception(sprintf(T('Failed to drop the index `%1$s` on table `%2$s`.'), $IndexName, $this->_TableName));
                         }
                     }
                 }
             }
             $EngineQuery = $AlterSqlPrefix . ' engine = ' . $this->_TableStorageEngine;
             if (!$this->Query($EngineQuery)) {
                 throw new Exception(sprintf(T('Failed to alter the storage engine of table `%1$s` to `%2$s`.'), $this->_DatabasePrefix . $this->_TableName, $this->_TableStorageEngine));
             }
         }
     }
     // 3. Add new columns & modify existing ones
     // array_diff returns values from the first array that aren't present in
     // the second array. In this example, all columns in $this->_Columns that
     // are NOT in the table.
     $PrevColumnName = FALSE;
     foreach ($this->_Columns as $ColumnName => $Column) {
         if (!array_key_exists($ColumnName, $ExistingColumns)) {
             // This column name is not in the existing column collection, so add the column
             $AddColumnSql = 'add ' . $this->_DefineColumn(GetValue($ColumnName, $this->_Columns));
             if ($PrevColumnName !== FALSE) {
                 $AddColumnSql .= " after `{$PrevColumnName}`";
             }
             $AlterSql[] = $AddColumnSql;
             //            if (!$this->Query($AlterSqlPrefix.$AddColumnSql))
             //               throw new Exception(sprintf(T('Failed to add the `%1$s` column to the `%1$s` table.'), $Column, $this->_DatabasePrefix.$this->_TableName));
         } else {
             $ExistingColumn = $ExistingColumns[$ColumnName];
             $ExistingColumnDef = $this->_DefineColumn($ExistingColumn);
             $ColumnDef = $this->_DefineColumn($Column);
             $Comment = "/* Existing: {$ExistingColumnDef}, New: {$ColumnDef} */\n";
             if ($ExistingColumnDef != $ColumnDef) {
                 //$Column->Type != $ExistingColumn->Type || $Column->AllowNull != $ExistingColumn->AllowNull || ($Column->Length != $ExistingColumn->Length && !in_array($Column->Type, array('tinyint', 'smallint', 'int', 'bigint', 'float', 'double')))) {
                 // The existing & new column types do not match, so modify the column.
                 $ChangeSql = $Comment . 'change `' . $ColumnName . '` ' . $this->_DefineColumn(GetValue($ColumnName, $this->_Columns));
                 $AlterSql[] = $ChangeSql;
                 //					if (!$this->Query($AlterSqlPrefix.$ChangeSql))
                 //						throw new Exception(sprintf(T('Failed to modify the data type of the `%1$s` column on the `%2$s` table.'),
                 //                     $ColumnName,
                 //                     $this->_DatabasePrefix.$this->_TableName));
                 // Check for a modification from an enum to an int.
                 if (strcasecmp($ExistingColumn->Type, 'enum') == 0 && in_array(strtolower($Column->Type), $this->Types('int'))) {
                     $Sql = "update `{$Px}{$this->_TableName}` set `{$ColumnName}` = case `{$ColumnName}`";
                     foreach ($ExistingColumn->Enum as $Index => $NewValue) {
                         $OldValue = $Index + 1;
                         if (!is_numeric($NewValue)) {
                             continue;
                         }
                         $NewValue = (int) $NewValue;
                         $Sql .= " when {$OldValue} then {$NewValue}";
                     }
                     $Sql .= " else `{$ColumnName}` end";
                     $Description = "Update {$this->_TableName}.{$ColumnName} enum values to {$Column->Type}";
                     $AdditionalSql[$Description] = $Sql;
                 }
             }
         }
         $PrevColumnName = $ColumnName;
     }
     if (count($AlterSql) > 0) {
         if (!$this->Query($AlterSqlPrefix . implode(",\n", $AlterSql))) {
             throw new Exception(sprintf(T('Failed to alter the `%s` table.'), $this->_DatabasePrefix . $this->_TableName));
         }
     }
     // 4. Update Indexes.
     $IndexSql = array();
     // Go through the indexes to add or modify.
     foreach ($Indexes as $Name => $Sql) {
         if (array_key_exists($Name, $IndexesDb)) {
             if ($Indexes[$Name] != $IndexesDb[$Name]) {
                 if ($Name == 'PRIMARY') {
                     $IndexSql[$Name] = $AlterSqlPrefix . "drop primary key;\n";
                 } else {
                     $IndexSql[$Name] = $AlterSqlPrefix . 'drop index ' . $Name . ";\n";
                 }
                 $IndexSql[$Name] .= $AlterSqlPrefix . "add {$Sql};\n";
             }
             unset($IndexesDb[$Name]);
         } else {
             $IndexSql[$Name] = $AlterSqlPrefix . "add {$Sql};\n";
         }
     }
     // Go through the indexes to drop.
     if ($Explicit) {
         foreach ($IndexesDb as $Name => $Sql) {
             if ($Name == 'PRIMARY') {
                 $IndexSql[$Name] = $AlterSqlPrefix . "drop primary key;\n";
             } else {
                 $IndexSql[$Name] = $AlterSqlPrefix . 'drop index ' . $Name . ";\n";
             }
         }
     }
     // Modify all of the indexes.
     foreach ($IndexSql as $Name => $Sql) {
         if (!$this->Query($Sql)) {
             throw new Exception(sprintf(T('Error.ModifyIndex', 'Failed to add or modify the `%1$s` index in the `%2$s` table.'), $Name, $this->_TableName));
         }
     }
     // Run any additional Sql.
     foreach ($AdditionalSql as $Description => $Sql) {
         if (!$this->Query($Sql)) {
             throw new Exception("Error modifying table: {$Description}.");
         }
     }
     $this->Reset();
     return TRUE;
 }