public function Analytics($Method, $RequestParameters, $Callback = FALSE) { $AnalyticsServer = C('Garden.Analytics.Remote', 'http://analytics.vanillaforums.com'); $FullMethod = explode('/', $Method); if (sizeof($FullMethod) < 2) { array_unshift($FullMethod, "analytics"); } list($ApiController, $ApiMethod) = $FullMethod; $ApiController = strtolower($ApiController); $ApiMethod = StringEndsWith(strtolower($ApiMethod), '.json', TRUE, TRUE) . '.json'; $FinalURL = CombinePaths(array($AnalyticsServer, $ApiController, $ApiMethod)); // Sign request $this->Sign($RequestParameters, TRUE); $FinalURL .= '?' . http_build_query($RequestParameters); try { $Response = ProxyRequest($FinalURL, 10, TRUE); } catch (Exception $e) { $Response = FALSE; } if ($Response !== FALSE) { $JsonResponse = json_decode($Response); if ($JsonResponse !== FALSE) { $JsonResponse = (array) GetValue('Analytics', $JsonResponse, FALSE); } // If we received a reply, parse it if ($JsonResponse !== FALSE) { $this->ParseAnalyticsResponse($JsonResponse, $Response, $Callback); return $JsonResponse; } } return FALSE; }
public function Structure($AppName = 'garden', $Drop = '0', $Explicit = '0') { $this->Permission('Garden.AdminUser.Only'); $File = CombinePaths(array(PATH_APPLICATIONS, $AppName, 'settings', 'structure.php'), DS); if (file_exists($File)) { $Validation = new Gdn_Validation(); $Database = Gdn::Database(); $Construct = $Database->Structure(); $Drop = $Drop == '0' ? FALSE : TRUE; $Explicit = $Explicit == '0' ? FALSE : TRUE; try { include $File; } catch (Exception $ex) { $this->Form->AddError(strip_tags($ex->getMessage())); } if ($this->Form->ErrorCount() == 0) { echo 'Success'; } else { echo $this->Form->Errors(); } } $this->ControllerName = 'home'; $this->View = 'filenotfound'; $this->Render(); }
/** * Update the configuration. * * @return void */ protected function config() { saveToConfig('Garden.Cookie.Salt', RandomString(10)); $ApplicationInfo = []; include CombinePaths([PATH_APPLICATIONS . DS . 'dashboard' . DS . 'settings' . DS . 'about.php']); // Detect Internet connection for CDNs $Disconnected = !(bool) @fsockopen('ajax.googleapis.com', 80); saveToConfig(['Garden.Version' => arrayValue('Version', val('Dashboard', $ApplicationInfo, []), 'Undefined'), 'Garden.Cdns.Disable' => $Disconnected, 'Garden.CanProcessImages' => function_exists('gd_info'), 'EnabledPlugins.HtmLawed' => 'HtmLawed']); }
/** * Special function automatically run upon clicking 'Enable' on your application. * Change the word 'skeleton' anywhere you see it. */ public function Setup() { // You need to manually include structure.php here for it to get run at install. include(PATH_APPLICATIONS . DS . 'skeleton' . DS . 'settings' . DS . 'structure.php'); // This just gets the version number and stores it in the config file. Good practice but optional. $ApplicationInfo = array(); include(CombinePaths(array(PATH_APPLICATIONS . DS . 'skeleton' . DS . 'settings' . DS . 'about.php'))); $Version = ArrayValue('Version', ArrayValue('Skeleton', $ApplicationInfo, array()), 'Undefined'); SaveToConfig('Skeleton.Version', $Version); }
/** * Constructor */ function __construct() { $this->PhpMailer = new PHPMailer(); $this->PhpMailer->CharSet = C('Garden.Charset', 'utf-8'); $this->PhpMailer->SingleTo = C('Garden.Email.SingleTo', FALSE); $this->PhpMailer->PluginDir = CombinePaths(array(PATH_LIBRARY, 'vendors/phpmailer/')); $this->PhpMailer->Hostname = C('Garden.Email.Hostname', ''); $this->PhpMailer->Encoding = 'quoted-printable'; $this->Clear(); parent::__construct(); }
function ServerMapFolder($resourceType, $folderPath, $sCommand) { // Get the resource type directory. $sResourceTypePath = GetResourceTypeDirectory($resourceType, $sCommand); // Ensure that the directory exists. $sErrorMsg = CreateServerFolder($sResourceTypePath); if ($sErrorMsg != '') { SendError(1, "Error creating folder \"{$sResourceTypePath}\" ({$sErrorMsg})"); } // Return the resource type directory combined with the required path. return CombinePaths($sResourceTypePath, $folderPath); }
public function Base_BeforeAddCss_Handler($Sender) { if ($Sender->DeliveryType() != DELIVERY_TYPE_ALL) { return; } $CssFiles =& $Sender->EventArguments['CssFiles']; foreach ($CssFiles as $Index => $CssInfo) { $CssFile = $CssInfo['FileName']; if (substr($CssFile, -7) != '.dt.css') { continue; } $AppFolder = $CssInfo['AppFolder']; if ($AppFolder == '') { $AppFolder = $Sender->ApplicationFolder; } $CssPaths = array(); if (strpos($CssFile, '/') !== False) { $CssPaths[] = CombinePaths(array(PATH_ROOT, $CssFile)); } else { if ($Sender->Theme) { $CssPaths[] = PATH_THEMES . DS . $Sender->Theme . DS . 'design' . DS . $CssFile; } $CssPaths[] = PATH_APPLICATIONS . DS . $AppFolder . DS . 'design' . DS . $CssFile; $CssPaths[] = PATH_APPLICATIONS . DS . 'dashboard' . DS . 'design' . DS . $CssFile; } $CssPath = False; foreach ($CssPaths as $Glob) { $Paths = SafeGlob($Glob); if (count($Paths) > 0) { $CssPath = $Paths[0]; break; } } if ($CssPath == False) { continue; } // not found $Basename = pathinfo(pathinfo($CssPath, 8), 8); // without .dt.css $Hash = self::GetHash($CssPath . filemtime($CssPath)); $CacheFileName = sprintf('__%s-c-%s.css', $Basename, $Hash); $CachedCssFile = dirname($CssPath) . DS . $CacheFileName; if (!file_exists($CachedCssFile)) { self::MakeCssFile($CssPath, $CachedCssFile, True); } // TODO: use AbsoluteSource() from 2.0.18 // ... and replace preprocessored dt.css file by css $CssInfo['FileName'] = substr($CachedCssFile, strlen(PATH_ROOT)); $CssFiles[$Index] = $CssInfo; // AppFolder nevermind (will be ignored) } }
public function Check($Type = '', $Name = '') { if ($Type != '' && $Name != '') { $this->AddItem($Type, $Name); } if (count($this->_Items) > 0) { // TODO: Use garden update check url instead of this: $UpdateUrl = Url('/lussumo/update', TRUE, TRUE); $Host = Gdn_Url::Host(); $Path = CombinePaths(array(Gdn_Url::WebRoot(), 'lussumo', 'update'), '/'); $Port = 80; /* $UpdateUrl = Gdn::Config('Garden.UpdateCheckUrl', ''); $UpdateUrl = parse_url($UpdateUrl); $Host = ArrayValue('host', $UpdateUrl, 'www.lussumo.com'); $Path = ArrayValue('path', $UpdateUrl, '/'); $Port = ArrayValue('port', $UpdateUrl, '80'); */ $Path .= '?Check=' . urlencode(Format::Serialize($this->_Items)); $Locale = Gdn::Config('Garden.Locale', 'Undefined'); $Referer = Gdn_Url::WebRoot(TRUE); if ($Referer === FALSE) { $Referer = 'Undefined'; } $Timeout = 10; $Response = ''; // Connect to the update server. $Pointer = @fsockopen($Host, '80', $ErrorNumber, $Error, $Timeout); if (!$Pointer) { throw new Exception(sprintf(Gdn::Translate('Encountered an error when attempting to connect to the update server (%1$s): [%2$s] %3$s'), $UpdateUrl, $ErrorNumber, $Error)); } else { // send the necessary headers to get the file fputs($Pointer, "GET {$Path} HTTP/1.0\r\n" . "Host: {$Host}\r\n" . "User-Agent: Lussumo Garden/1.0\r\n" . "Accept: */*\r\n" . "Accept-Language: " . $Locale . "\r\n" . "Accept-Charset: utf-8;\r\n" . "Keep-Alive: 300\r\n" . "Connection: keep-alive\r\n" . "Referer: {$Referer}\r\n\r\n"); // Retrieve the response from the remote server while ($Line = fread($Pointer, 4096)) { $Response .= $Line; } fclose($Pointer); // Remove response headers $Response = substr($Response, strpos($Response, "\r\n\r\n") + 4); } $Result = Format::Unserialize($Response); // print_r($Result); if (is_array($Result)) { $this->_Items = $Result; } else { $Result = FALSE; } return $Result; } }
/** * Set up ProxyRequest * * Options: * URL * Host * Method * ConnectTimeout * Timeout * Redirects * Cookies * SaveAs * CloseSession * Redirected * Debug * Simulate * * @param boolean $Loud * @param array $RequestDefaults * @return type */ public function __construct($Loud = FALSE, $RequestDefaults = NULL) { $this->Loud = $Loud; $CookieKey = md5(mt_rand(0, 72312189) . microtime(true)); if (defined('PATH_CACHE')) { $this->CookieJar = CombinePaths(array(PATH_CACHE, "cookiejar.{$CookieKey}")); } else { $this->CookieJar = CombinePaths(array("/tmp", "cookiejar.{$CookieKey}")); } if (!is_array($RequestDefaults)) { $RequestDefaults = array(); } $Defaults = array('URL' => NULL, 'Host' => NULL, 'Method' => 'GET', 'ConnectTimeout' => 5, 'Timeout' => 5, 'TransferMode' => 'normal', 'SaveAs' => NULL, 'Redirects' => TRUE, 'SSLNoVerify' => FALSE, 'PreEncodePost' => TRUE, 'Cookies' => TRUE, 'CookieJar' => FALSE, 'CookieSession' => FALSE, 'CloseSession' => TRUE, 'Redirected' => FALSE, 'Debug' => FALSE, 'Simulate' => FALSE); $this->RequestDefaults = array_merge($Defaults, $RequestDefaults); }
public function Setup() { // Got Setup? $Database = Gdn::Database(); $Config = Gdn::Factory(Gdn::AliasConfig); $Drop = C('Skeleton.Version') === FALSE ? TRUE : FALSE; $Explicit = TRUE; $Validation = new Gdn_Validation(); // This is going to be needed by structure.php to validate permission names include PATH_APPLICATIONS . DS . 'skeleton' . DS . 'settings' . DS . 'structure.php'; $ApplicationInfo = array(); include CombinePaths(array(PATH_APPLICATIONS . DS . 'skeleton' . DS . 'settings' . DS . 'about.php')); $Version = ArrayValue('Version', ArrayValue('Skeleton', $ApplicationInfo, array()), 'Undefined'); SaveToConfig('Skeleton.Version', $Version); }
function ServerMapFolder($resourceType, $folderPath, $sCommand) { global $Config; // Get the resource type directory. $sResourceTypePath = GetResourceTypeDirectory($resourceType, $sCommand); // Ensure that the directory exists. $sErrorMsg = CreateServerFolder($sResourceTypePath); if ($sErrorMsg != '') { SendError(1, "Ошибка создания папки \"{$sResourceTypePath}\" ({$sErrorMsg})"); } if ($Config['ThumbList'] && $resourceType == 'Image') { ServerMapFolder('ImageThumb', $folderPath, $sCommand); } // Return the resource type directory combined with the required path. return CombinePaths($sResourceTypePath, $folderPath); }
public function Analytics($Method, $RequestParameters, $Callback = FALSE, $ParseResponse = TRUE) { $FullMethod = explode('/', $Method); if (sizeof($FullMethod) < 2) { array_unshift($FullMethod, "analytics"); } list($ApiController, $ApiMethod) = $FullMethod; $ApiController = strtolower($ApiController); $ApiMethod = StringEndsWith(strtolower($ApiMethod), '.json', TRUE, TRUE) . '.json'; $FinalURL = 'http://' . CombinePaths(array($this->AnalyticsServer, $ApiController, $ApiMethod)); // Allow hooking of analytics events $this->EventArguments['AnalyticsMethod'] =& $Method; $this->EventArguments['AnalyticsArgs'] =& $RequestParameters; $this->EventArguments['AnalyticsUrl'] =& $FinalURL; $this->FireEvent('SendAnalytics'); // Sign request $this->Sign($RequestParameters, TRUE); $RequestMethod = GetValue('RequestMethod', $RequestParameters, 'GET'); unset($RequestParameters['RequestMethod']); try { $ProxyRequest = new ProxyRequest(FALSE, array('Method' => $RequestMethod, 'Timeout' => 10, 'Cookies' => FALSE)); $Response = $ProxyRequest->Request(array('Url' => $FinalURL), $RequestParameters); } catch (Exception $e) { $Response = FALSE; } if ($Response !== FALSE) { $JsonResponse = json_decode($Response, TRUE); if ($JsonResponse !== FALSE) { if ($ParseResponse) { $AnalyticsJsonResponse = (array) GetValue('Analytics', $JsonResponse, FALSE); // If we received a reply, parse it if ($AnalyticsJsonResponse !== FALSE) { $this->ParseAnalyticsResponse($AnalyticsJsonResponse, $Response, $Callback); return $AnalyticsJsonResponse; } } else { return $JsonResponse; } } return $Response; } return FALSE; }
/** * Setup the application. * * The methods in setup controllers should not call "Render". Rendering will * be handled by the controller that initiated the setup. This method should * return a boolean value indicating success. * * @return bool True on successful setup */ public function Index() { $Database = Gdn::Database(); $Config = Gdn::Factory(Gdn::AliasConfig); $Drop = Gdn::Config('Conversations.Version') === FALSE ? TRUE : FALSE; $Explicit = TRUE; $Validation = new Gdn_Validation(); // This is going to be needed by structure.php to validate permission names try { include PATH_APPLICATIONS . DS . 'conversations' . DS . 'settings' . DS . 'structure.php'; } catch (Exception $ex) { $this->Form->AddError(strip_tags($ex->getMessage())); } if ($this->Form->ErrorCount() == 0) { $ApplicationInfo = array(); include CombinePaths(array(PATH_APPLICATIONS . DS . 'conversations' . DS . 'settings' . DS . 'about.php')); $Version = ArrayValue('Version', ArrayValue('Conversations', $ApplicationInfo, array()), 'Undefined'); SaveToConfig('Conversations.Version', $Version); } return $this->Form->ErrorCount() > 0 ? FALSE : TRUE; }
public function Structure($AppName = 'garden', $CaptureOnly = '1', $Drop = '0', $Explicit = '0') { $this->Permission('Garden.AdminUser.Only'); $File = CombinePaths(array(PATH_APPLICATIONS, $AppName, 'settings', 'structure.php'), DS); if (file_exists($File)) { $Validation = new Gdn_Validation(); $Database = Gdn::Database(); $Drop = $Drop == '0' ? FALSE : TRUE; $Explicit = $Explicit == '0' ? FALSE : TRUE; $CaptureOnly = !($CaptureOnly == '0'); $Structure = Gdn::Structure(); $Structure->CaptureOnly = $CaptureOnly; $this->SetData('CaptureOnly', $Structure->CaptureOnly); $this->SetData('Drop', $Drop); $this->SetData('Explicit', $Explicit); $this->SetData('ApplicationName', $AppName); $this->SetData('Status', ''); try { include $File; } catch (Exception $ex) { $this->Form->AddError(strip_tags($ex->getMessage())); } if (property_exists($Structure, 'CapturedSql')) { $this->SetData('CapturedSql', (array) $Structure->CapturedSql); } else { $this->SetData('CapturedSql', array()); } if ($this->Form->ErrorCount() == 0 && !$CaptureOnly) { $this->SetData('Status', 'The structure was successfully executed.'); } } //$this->ControllerName = 'home'; //$this->View = 'filenotfound'; $this->AddCssFile('admin.css'); $this->Render(); }
/** * Check an addon's file to extract the addon information out of it. * * @param string $Path The path to the file. * @param bool $Fix Whether or not to fix files that have been zipped incorrectly. * @return array An array of addon information. */ public static function analyzeAddon($Path, $ThrowError = true) { if (!file_exists($Path)) { if ($ThrowError) { throw new Exception("{$Path} not found.", 404); } return false; } $Result = array(); $InfoPaths = array('/settings/about.php', '/default.php', '/class.*.plugin.php', '/about.php', '/definitions.php', '/index.php', 'vanilla2export.php'); // Get the list of potential files to analyze. if (is_dir($Path)) { $Entries = self::_GetInfoFiles($Path, $InfoPaths); } else { $Entries = self::_GetInfoZip($Path, $InfoPaths, false, $ThrowError); $DeleteEntries = true; } foreach ($Entries as $Entry) { if ($Entry['Name'] == '/index.php') { // This could be the core vanilla package. $Version = self::ParseCoreVersion($Entry['Path']); if (!$Version) { continue; } // The application was confirmed. $Addon = array('AddonKey' => 'vanilla', 'AddonTypeID' => ADDON_TYPE_CORE, 'Name' => 'Vanilla', 'Description' => 'Vanilla is an open-source, standards-compliant, multi-lingual, fully extensible discussion forum for the web. Anyone who has web-space that meets the requirements can download and use Vanilla for free!', 'Version' => $Version, 'Path' => $Entry['Path']); break; } elseif ($Entry['Name'] == 'vanilla2export.php') { // This could be the vanilla porter. $Version = self::ParseCoreVersion($Entry['Path']); if (!$Version) { continue; } $Addon = array('AddonKey' => 'porter', 'AddonTypeID' => ADDON_TYPE_CORE, 'Name' => 'Vanilla Porter', 'Description' => 'Drop this script in your existing site and navigate to it in your web browser to export your existing forum data to the Vanilla 2 import format.', 'Version' => $Version, 'Path' => $Entry['Path']); break; } else { // This could be an addon. $Info = self::ParseInfoArray($Entry['Path']); if (!is_array($Info) && count($Info)) { continue; } $Key = key($Info); $Variable = $Info['Variable']; $Info = $Info[$Key]; // Validate the addon. $Name = $Entry['Name']; $Valid = true; if (!val('Name', $Info)) { $Info['Name'] = $Key; } if (!val('Description', $Info)) { $Result[] = $Name . ': ' . sprintf(t('ValidateRequired'), t('Description')); $Valid = false; } if (!val('Version', $Info)) { $Result[] = $Name . ': ' . sprintf(t('ValidateRequired'), t('Version')); $Valid = false; } if (isset($Entry['Base']) && strcasecmp($Entry['Base'], $Key) != 0 && $Variable != 'ThemeInfo') { $Result[] = "{$Name}: The addon's key is not the same as its folder name."; $Valid = false; } if (!$Valid) { continue; } // The addon is valid. $Addon = array_merge(array('AddonKey' => $Key, 'AddonTypeID' => ''), $Info); switch ($Variable) { case 'ApplicationInfo': $Addon['AddonTypeID'] = ADDON_TYPE_APPLICATION; break; case 'LocaleInfo': $Addon['AddonTypeID'] = ADDON_TYPE_LOCALE; break; case 'PluginInfo': $Addon['AddonTypeID'] = ADDON_TYPE_PLUGIN; break; case 'ThemeInfo': $Addon['AddonTypeID'] = ADDON_TYPE_THEME; break; } } } if ($DeleteEntries) { $FolderPath = substr($Path, 0, -4); Gdn_FileSystem::RemoveFolder($FolderPath); } // Add the addon requirements. if ($Addon) { $Requirements = arrayTranslate($Addon, array('RequiredApplications' => 'Applications', 'RequiredPlugins' => 'Plugins', 'RequiredThemes' => 'Themes')); foreach ($Requirements as $Type => $Items) { if (!is_array($Items)) { unset($Requirements[$Type]); } } $Addon['Requirements'] = serialize($Requirements); $Addon['Checked'] = true; $Addon['Path'] = $Path; $UploadsPath = PATH_UPLOADS . '/'; if (stringBeginsWith($Addon['Path'], $UploadsPath)) { $Addon['File'] = substr($Addon['Path'], strlen($UploadsPath)); } if (is_file($Path)) { $Addon['MD5'] = md5_file($Path); $Addon['FileSize'] = filesize($Path); } } elseif ($ThrowError) { $Msg = implode("\n", $Result); throw new Gdn_UserException($Msg, 400); } else { return false; } return $Addon; // Figure out what kind of addon this is. $Root = ''; $NewRoot = ''; $Addon = false; foreach ($Entries as $Entry) { $Name = '/' . ltrim($Entry['name'], '/'); $Filename = basename($Name); $Folder = substr($Name, 0, -strlen($Filename)); $NewRoot = ''; // Check to see if the entry is a plugin file. if ($Filename == 'default.php' || StringEndsWith($Filename, '.plugin.php')) { if (count(explode('/', $Folder)) > 3) { // The file is too deep to be a plugin file. continue; } // This could be a plugin file, but we have to examine its info array. $Zip->extractTo($FolderPath, $Entry['name']); $FilePath = CombinePaths(array($FolderPath, $Name)); $Info = self::ParseInfoArray($FilePath, 'PluginInfo'); Gdn_FileSystem::RemoveFolder(dirname($FilePath)); if (!is_array($Info) || !count($Info)) { continue; } // Check to see if the info array conforms to a plugin spec. $Key = key($Info); $Info = $Info[$Key]; $Root = trim($Folder, '/'); $Valid = true; // Make sure the key matches the folder name. if ($Root && strcasecmp($Root, $Key) != 0) { $Result[] = "{$Name}: The plugin's key is not the same as its folder name."; $Valid = false; } else { $NewRoot = $Root; } if (!val('Description', $Info)) { $Result[] = $Name . ': ' . sprintf(t('ValidateRequired'), t('Description')); $Valid = false; } if (!val('Version', $Info)) { $Result[] = $Name . ': ' . sprintf(t('ValidateRequired'), t('Version')); $Valid = false; } if ($Valid) { // The plugin was confirmed. $Addon = array('AddonKey' => $Key, 'AddonTypeID' => ADDON_TYPE_PLUGIN, 'Name' => val('Name', $Info) ? $Info['Name'] : $Key, 'Description' => $Info['Description'], 'Version' => $Info['Version'], 'Path' => $Path); break; } continue; } // Check to see if the entry is an application file. if (StringEndsWith($Name, '/settings/about.php')) { if (count(explode('/', $Folder)) > 4) { $Result[] = "{$Name}: The application's info array was not in the correct location."; // The file is too deep to be a plugin file. continue; } // This could be a plugin file, but we have to examine its info array. $Zip->extractTo($FolderPath, $Entry['name']); $FilePath = CombinePaths(array($FolderPath, $Name)); $Info = self::ParseInfoArray($FilePath, 'ApplicationInfo'); Gdn_FileSystem::RemoveFolder(dirname($FilePath)); if (!is_array($Info) || !count($Info)) { $Result[] = "{$Name}: The application's info array could not be parsed."; continue; } $Key = key($Info); $Info = $Info[$Key]; $Root = trim(substr($Name, 0, -strlen('/settings/about.php')), '/'); $Valid = true; // Make sure the key matches the folder name. if ($Root && strcasecmp($Root, $Key) != 0) { $Result[] = "{$Name}: The application's key is not the same as its folder name."; $Valid = false; } else { $NewRoot = $Root; } if (!val('Description', $Info)) { $Result[] = $Name . ': ' . sprintf(t('ValidateRequired'), t('Description')); $Valid = false; } if (!val('Version', $Info)) { $Result[] = $Name . ': ' . sprintf(t('ValidateRequired'), t('Version')); $Valid = false; } if ($Valid) { // The application was confirmed. $Addon = array('AddonKey' => $Key, 'AddonTypeID' => ADDON_TYPE_APPLICATION, 'Name' => val('Name', $Info) ? $Info['Name'] : $Key, 'Description' => $Info['Description'], 'Version' => $Info['Version'], 'Path' => $Path); break; } continue; } // Check to see if the entry is a theme file. if (StringEndsWith($Name, '/about.php')) { if (count(explode('/', $Folder)) > 3) { // The file is too deep to be a plugin file. continue; } // This could be a theme file, but we have to examine its info array. $Zip->extractTo($FolderPath, $Entry['name']); $FilePath = CombinePaths(array($FolderPath, $Name)); $Info = self::ParseInfoArray($FilePath, 'ThemeInfo'); Gdn_FileSystem::RemoveFolder(dirname($FilePath)); if (!is_array($Info) || !count($Info)) { continue; } $Key = key($Info); $Info = $Info[$Key]; $Valid = true; $Root = trim(substr($Name, 0, -strlen('/about.php')), '/'); // Make sure the theme is at least one folder deep. if (strlen($Root) == 0) { $Result[] = $Name . ': The theme must be in a folder.'; $Valid = false; } if (!val('Description', $Info)) { $Result[] = $Name . ': ' . sprintf(t('ValidateRequired'), t('Description')); $Valid = false; } if (!val('Version', $Info)) { $Result[] = $Name . ': ' . sprintf(t('ValidateRequired'), t('Version')); $Valid = false; } if ($Valid) { // The application was confirmed. $Addon = array('AddonKey' => $Key, 'AddonTypeID' => ADDON_TYPE_THEME, 'Name' => val('Name', $Info) ? $Info['Name'] : $Key, 'Description' => $Info['Description'], 'Version' => $Info['Version'], 'Path' => $Path); break; } } if (StringEndsWith($Name, '/definitions.php')) { if (count(explode('/', $Folder)) > 3) { // The file is too deep to be a plugin file. continue; } // This could be a locale pack, but we have to examine its info array. $Zip->extractTo($FolderPath, $Entry['name']); $FilePath = CombinePaths(array($FolderPath, $Name)); $Info = self::ParseInfoArray($FilePath, 'LocaleInfo'); Gdn_FileSystem::RemoveFolder(dirname($FilePath)); if (!is_array($Info) || !count($Info)) { continue; } $Key = key($Info); $Info = $Info[$Key]; $Valid = true; $Root = trim(substr($Name, 0, -strlen('/definitions.php')), '/'); // Make sure the locale is at least one folder deep. if ($Root != $Key) { $Result[] = $Name . ': The locale pack\'s key must be the same as its folder name.'; $Valid = false; } if (!val('Locale', $Info)) { $Result[] = $Name . ': ' . sprintf(t('ValidateRequired'), t('Locale')); $Valud = false; } elseif (strcasecmp($Info['Locale'], $Key) == 0) { $Result[] = $Name . ': ' . t('The locale\'s key cannot be the same as the name of the locale.'); $Valid = false; } if (!val('Description', $Info)) { $Result[] = $Name . ': ' . sprintf(t('ValidateRequired'), t('Description')); $Valid = false; } if (!val('Version', $Info)) { $Result[] = $Name . ': ' . sprintf(t('ValidateRequired'), t('Version')); $Valid = false; } if ($Valid) { // The locale pack was confirmed. $Addon = array('AddonKey' => $Key, 'AddonTypeID' => ADDON_TYPE_LOCALE, 'Name' => val('Name', $Info) ? $Info['Name'] : $Key, 'Description' => $Info['Description'], 'Version' => $Info['Version'], 'Path' => $Path); break; } } // Check to see if the entry is a core file. if (StringEndsWith($Name, '/index.php')) { if (count(explode('/', $Folder)) != 3) { // The file is too deep to be the core's index.php continue; } // This could be a theme file, but we have to examine its info array. $Zip->extractTo($FolderPath, $Entry['name']); $FilePath = CombinePaths(array($FolderPath, $Name)); // Get the version number from the core. $Version = self::ParseCoreVersion($FilePath); if (!$Version) { continue; } // The application was confirmed. $Addon = array('AddonKey' => 'vanilla', 'AddonTypeID' => ADDON_TYPE_CORE, 'Name' => 'Vanilla', 'Description' => 'Vanilla is an open-source, standards-compliant, multi-lingual, fully extensible discussion forum for the web. Anyone who has web-space that meets the requirements can download and use Vanilla for free!', 'Version' => $Version, 'Path' => $Path); $Info = array(); break; } } if ($Addon) { // Add the requirements. $Requirements = arrayTranslate($Info, array('RequiredApplications' => 'Applications', 'RequiredPlugins' => 'Plugins', 'RequiredThemes' => 'Themes')); foreach ($Requirements as $Type => $Items) { if (!is_array($Items)) { unset($Requirements[$Type]); } } $Addon['Requirements'] = serialize($Requirements); $Addon['Checked'] = true; $UploadsPath = PATH_ROOT . '/uploads/'; if (stringBeginsWith($Addon['Path'], $UploadsPath)) { $Addon['File'] = substr($Addon['Path'], strlen($UploadsPath)); } if ($Fix) { // Delete extraneous files. foreach ($Deletes as $Delete) { $Zip->deleteName($Delete['name']); } } } $Zip->close(); if (file_exists($FolderPath)) { Gdn_FileSystem::RemoveFolder($FolderPath); } if ($Addon) { $Addon['MD5'] = md5_file($Path); $Addon['FileSize'] = filesize($Path); return $Addon; } else { if ($ThrowError) { $Msg = implode("\n", $Result); throw new Exception($Msg, 400); } else { return false; } } }
/** * Captcha-authenticated registration. Used by default. * * Events: RegistrationSuccessful * * @access private * @since 2.0.0 */ private function RegisterCaptcha() { Gdn::UserModel()->AddPasswordStrength($this); include CombinePaths(array(PATH_LIBRARY, 'vendors/recaptcha', 'functions.recaptchalib.php')); if ($this->Form->IsPostBack() === TRUE) { // Add validation rules that are not enforced by the model $this->UserModel->DefineSchema(); $this->UserModel->Validation->ApplyRule('Name', 'Username', $this->UsernameError); $this->UserModel->Validation->ApplyRule('TermsOfService', 'Required', T('You must agree to the terms of service.')); $this->UserModel->Validation->ApplyRule('Password', 'Required'); $this->UserModel->Validation->ApplyRule('Password', 'Strength'); $this->UserModel->Validation->ApplyRule('Password', 'Match'); // $this->UserModel->Validation->ApplyRule('DateOfBirth', 'MinimumAge'); $this->FireEvent('RegisterValidation'); try { $Values = $this->Form->FormValues(); unset($Values['Roles']); $AuthUserID = $this->UserModel->Register($Values); if ($AuthUserID == UserModel::REDIRECT_APPROVE) { $this->Form->SetFormValue('Target', '/entry/registerthanks'); $this->_SetRedirect(); return; } elseif (!$AuthUserID) { $this->Form->SetValidationResults($this->UserModel->ValidationResults()); if ($this->_DeliveryType != DELIVERY_TYPE_ALL) { $this->_DeliveryType = DELIVERY_TYPE_MESSAGE; } } else { // The user has been created successfully, so sign in now. if (!Gdn::Session()->IsValid()) { Gdn::Session()->Start($AuthUserID, TRUE, (bool) $this->Form->GetFormValue('RememberMe')); } try { $this->UserModel->SendWelcomeEmail($AuthUserID, '', 'Register'); } catch (Exception $Ex) { } $this->FireEvent('RegistrationSuccessful'); // ... and redirect them appropriately $Route = $this->RedirectTo(); if ($this->_DeliveryType != DELIVERY_TYPE_ALL) { $this->RedirectUrl = Url($Route); } else { if ($Route !== FALSE) { Redirect($Route); } } } } catch (Exception $Ex) { $this->Form->AddError($Ex); } } $this->Render(); }
/** * Allows the configuration of basic setup information in Garden. This * should not be functional after the application has been set up. * * @since 2.0.0 * @access public * @param string $RedirectUrl Where to send user afterward. */ public function Configure($RedirectUrl = '') { // Create a model to save configuration settings $Validation = new Gdn_Validation(); $ConfigurationModel = new Gdn_ConfigurationModel($Validation); $ConfigurationModel->SetField(array('Garden.Locale', 'Garden.Title', 'Garden.RewriteUrls', 'Garden.WebRoot', 'Garden.Cookie.Salt', 'Garden.Cookie.Domain', 'Database.Name', 'Database.Host', 'Database.User', 'Database.Password', 'Garden.Registration.ConfirmEmail', 'Garden.Email.SupportName')); // Set the models on the forms. $this->Form->SetModel($ConfigurationModel); // Load the locales for the locale dropdown // $Locale = Gdn::Locale(); // $AvailableLocales = $Locale->GetAvailableLocaleSources(); // $this->LocaleData = array_combine($AvailableLocales, $AvailableLocales); // If seeing the form for the first time... if (!$this->Form->IsPostback()) { // Force the webroot using our best guesstimates $ConfigurationModel->Data['Database.Host'] = 'localhost'; $this->Form->SetData($ConfigurationModel->Data); } else { // Define some validation rules for the fields being saved $ConfigurationModel->Validation->ApplyRule('Database.Name', 'Required', 'You must specify the name of the database in which you want to set up Vanilla.'); // Let's make some user-friendly custom errors for database problems $DatabaseHost = $this->Form->GetFormValue('Database.Host', '~~Invalid~~'); $DatabaseName = $this->Form->GetFormValue('Database.Name', '~~Invalid~~'); $DatabaseUser = $this->Form->GetFormValue('Database.User', '~~Invalid~~'); $DatabasePassword = $this->Form->GetFormValue('Database.Password', '~~Invalid~~'); $ConnectionString = GetConnectionString($DatabaseName, $DatabaseHost); try { $Connection = new PDO($ConnectionString, $DatabaseUser, $DatabasePassword); } catch (PDOException $Exception) { switch ($Exception->getCode()) { case 1044: $this->Form->AddError(T('The database user you specified does not have permission to access the database. Have you created the database yet? The database reported: <code>%s</code>'), strip_tags($Exception->getMessage())); break; case 1045: $this->Form->AddError(T('Failed to connect to the database with the username and password you entered. Did you mistype them? The database reported: <code>%s</code>'), strip_tags($Exception->getMessage())); break; case 1049: $this->Form->AddError(T('It appears as though the database you specified does not exist yet. Have you created it yet? Did you mistype the name? The database reported: <code>%s</code>'), strip_tags($Exception->getMessage())); break; case 2005: $this->Form->AddError(T("Are you sure you've entered the correct database host name? Maybe you mistyped it? The database reported: <code>%s</code>"), strip_tags($Exception->getMessage())); break; default: $this->Form->AddError(sprintf(T('ValidateConnection'), strip_tags($Exception->getMessage()))); break; } } $ConfigurationModel->Validation->ApplyRule('Garden.Title', 'Required'); $ConfigurationFormValues = $this->Form->FormValues(); if ($ConfigurationModel->Validate($ConfigurationFormValues) !== TRUE || $this->Form->ErrorCount() > 0) { // Apply the validation results to the form(s) $this->Form->SetValidationResults($ConfigurationModel->ValidationResults()); } else { $Host = array_shift(explode(':', Gdn::Request()->RequestHost())); $Domain = Gdn::Request()->Domain(); // Set up cookies now so that the user can be signed in. $ExistingSalt = C('Garden.Cookie.Salt', FALSE); $ConfigurationFormValues['Garden.Cookie.Salt'] = $ExistingSalt ? $ExistingSalt : RandomString(10); $ConfigurationFormValues['Garden.Cookie.Domain'] = ''; // Don't set this to anything by default. # Tim - 2010-06-23 // Additional default setup values. $ConfigurationFormValues['Garden.Registration.ConfirmEmail'] = TRUE; $ConfigurationFormValues['Garden.Email.SupportName'] = $ConfigurationFormValues['Garden.Title']; $ConfigurationModel->Save($ConfigurationFormValues, TRUE); // If changing locale, redefine locale sources: $NewLocale = 'en-CA'; // $this->Form->GetFormValue('Garden.Locale', FALSE); if ($NewLocale !== FALSE && Gdn::Config('Garden.Locale') != $NewLocale) { $ApplicationManager = new Gdn_ApplicationManager(); $Locale = Gdn::Locale(); $Locale->Set($NewLocale, $ApplicationManager->EnabledApplicationFolders(), Gdn::PluginManager()->EnabledPluginFolders(), TRUE); } // Install db structure & basic data. $Database = Gdn::Database(); $Database->Init(); $Drop = FALSE; // Gdn::Config('Garden.Version') === FALSE ? TRUE : FALSE; $Explicit = FALSE; try { include PATH_APPLICATIONS . DS . 'dashboard' . DS . 'settings' . DS . 'structure.php'; } catch (Exception $ex) { $this->Form->AddError($ex); } if ($this->Form->ErrorCount() > 0) { return FALSE; } // Create the administrative user $UserModel = Gdn::UserModel(); $UserModel->DefineSchema(); $UsernameError = T('UsernameError', 'Username can only contain letters, numbers, underscores, and must be between 3 and 20 characters long.'); $UserModel->Validation->ApplyRule('Name', 'Username', $UsernameError); $UserModel->Validation->ApplyRule('Name', 'Required', T('You must specify an admin username.')); $UserModel->Validation->ApplyRule('Password', 'Required', T('You must specify an admin password.')); $UserModel->Validation->ApplyRule('Password', 'Match'); $UserModel->Validation->ApplyRule('Email', 'Email'); if (!($AdminUserID = $UserModel->SaveAdminUser($ConfigurationFormValues))) { $this->Form->SetValidationResults($UserModel->ValidationResults()); } else { // The user has been created successfully, so sign in now. SaveToConfig('Garden.Installed', TRUE, array('Save' => FALSE)); Gdn::Session()->Start($AdminUserID, TRUE); SaveToConfig('Garden.Installed', FALSE, array('Save' => FALSE)); } if ($this->Form->ErrorCount() > 0) { return FALSE; } // Assign some extra settings to the configuration file if everything succeeded. $ApplicationInfo = array(); include CombinePaths(array(PATH_APPLICATIONS . DS . 'dashboard' . DS . 'settings' . DS . 'about.php')); // Detect rewrite abilities try { $Query = ConcatSep('/', Gdn::Request()->Domain(), Gdn::Request()->WebRoot(), 'dashboard/setup'); $Results = ProxyHead($Query, array(), 3); $CanRewrite = FALSE; if (in_array(ArrayValue('StatusCode', $Results, 404), array(200, 302)) && ArrayValue('X-Garden-Version', $Results, 'None') != 'None') { $CanRewrite = TRUE; } } catch (Exception $e) { // cURL and fsockopen arent supported... guess? $CanRewrite = function_exists('apache_get_modules') && in_array('mod_rewrite', apache_get_modules()) ? TRUE : FALSE; } SaveToConfig(array('Garden.Version' => ArrayValue('Version', GetValue('Dashboard', $ApplicationInfo, array()), 'Undefined'), 'Garden.RewriteUrls' => $CanRewrite, 'Garden.CanProcessImages' => function_exists('gd_info'), 'EnabledPlugins.GettingStarted' => 'GettingStarted', 'EnabledPlugins.HtmLawed' => 'HtmLawed')); } } return $this->Form->ErrorCount() == 0 ? TRUE : FALSE; }
/** * 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); } }
/** * Returns the location of the view for this module in the filesystem. * * @param string $View * @param string $ApplicationFolder * @return array */ public function fetchViewLocation($View = '', $ApplicationFolder = '') { if ($View == '') { $View = strtolower($this->name()); } if (substr($View, -6) == 'module') { $View = substr($View, 0, -6); } if (substr($View, 0, 4) == 'gdn_') { $View = substr($View, 4); } if ($ApplicationFolder == '') { $ApplicationFolder = strpos($this->_ApplicationFolder, '/') ? $this->_ApplicationFolder : strtolower($this->_ApplicationFolder); } $ThemeFolder = $this->_ThemeFolder; $ViewPath = null; // Try to use Gdn_Controller's FetchViewLocation if (Gdn::controller() instanceof Gdn_Controller) { try { $ViewPath = Gdn::controller()->fetchViewLocation($View, 'modules', $ApplicationFolder); } catch (Exception $Ex) { } } if (!$ViewPath) { $ViewPaths = array(); // 1. An explicitly defined path to a view if (strpos($View, '/') !== false) { $ViewPaths[] = $View; } // 2. A theme if ($ThemeFolder != '') { // a. Application-specific theme view. eg. /path/to/application/themes/theme_name/app_name/views/modules/ $ViewPaths[] = CombinePaths(array(PATH_THEMES, $ThemeFolder, $ApplicationFolder, 'views', 'modules', $View . '.php')); // b. Garden-wide theme view. eg. /path/to/application/themes/theme_name/views/modules/ $ViewPaths[] = CombinePaths(array(PATH_THEMES, $ThemeFolder, 'views', 'modules', $View . '.php')); } // 3. Application default. eg. /path/to/application/app_name/views/controller_name/ if ($this->_ApplicationFolder) { $ViewPaths[] = CombinePaths(array(PATH_APPLICATIONS, $ApplicationFolder, 'views', 'modules', $View . '.php')); } else { $ViewPaths[] = dirname($this->path()) . "/../views/modules/{$View}.php"; } // 4. Garden default. eg. /path/to/application/dashboard/views/modules/ $ViewPaths[] = CombinePaths(array(PATH_APPLICATIONS, 'dashboard', 'views', 'modules', $View . '.php')); $ViewPath = Gdn_FileSystem::exists($ViewPaths); } if ($ViewPath === false) { throw new Exception(ErrorMessage('Could not find a `' . $View . '` view for the `' . $this->Name() . '` module in the `' . $ApplicationFolder . '` application.', get_class($this), 'FetchView'), E_USER_ERROR); } return $ViewPath; }
/** * Takes the path to an asset (image, js file, css file, etc) and prepends the webroot. */ function SmartAsset($Destination = '', $WithDomain = FALSE, $AddVersion = FALSE) { $Destination = str_replace('\\', '/', $Destination); if (substr($Destination, 0, 7) == 'http://' || substr($Destination, 0, 8) == 'https://') { $Result = $Destination; } else { $Parts = array(Gdn_Url::WebRoot($WithDomain), $Destination); if (!$WithDomain) { array_unshift($Parts, '/'); } $Result = CombinePaths($Parts, '/'); } if ($AddVersion) { if (strpos($Result, '?') === FALSE) { $Result .= '?'; } else { $Result .= '&'; } // Figure out which version to put after the asset. $Version = APPLICATION_VERSION; if (preg_match('`^/([^/]+)/([^/]+)/`', $Destination, $Matches)) { $Type = $Matches[1]; $Key = $Matches[2]; static $ThemeVersion = NULL; switch ($Type) { case 'plugins': $PluginInfo = Gdn::PluginManager()->GetPluginInfo($Key); $Version = GetValue('Version', $PluginInfo, $Version); break; case 'themes': if ($ThemeVersion === NULL) { $ThemeInfo = Gdn::ThemeManager()->GetThemeInfo(Theme()); if ($ThemeInfo !== FALSE) { $ThemeVersion = GetValue('Version', $ThemeInfo, $Version); } else { $ThemeVersion = $Version; } } $Version = $ThemeVersion; break; } } $Result .= 'v=' . urlencode($Version); } return $Result; }
/** * Automatically executed when application is enabled. * * @since 2.0.0 * @package Vanilla */ public function Setup() { $Database = Gdn::Database(); $Config = Gdn::Factory(Gdn::AliasConfig); $Drop = Gdn::Config('Vanilla.Version') === FALSE ? TRUE : FALSE; $Explicit = TRUE; // Call structure.php to update database $Validation = new Gdn_Validation(); // Needed by structure.php to validate permission names include PATH_APPLICATIONS . DS . 'vanilla' . DS . 'settings' . DS . 'structure.php'; include PATH_APPLICATIONS . DS . 'vanilla' . DS . 'settings' . DS . 'stub.php'; $ApplicationInfo = array(); include CombinePaths(array(PATH_APPLICATIONS . DS . 'vanilla' . DS . 'settings' . DS . 'about.php')); $Version = ArrayValue('Version', ArrayValue('Vanilla', $ApplicationInfo, array()), 'Undefined'); $Save = array('Vanilla.Version' => $Version, 'Routes.DefaultController' => 'discussions'); SaveToConfig($Save); }
public function Structure($AppName = 'all', $CaptureOnly = '1', $Drop = '0', $Explicit = '0') { $this->Permission('Garden.Settings.Manage'); $Files = array(); $AppName = $AppName == '' ? 'all': $AppName; if ($AppName == 'all') { // Load all application structure files. $ApplicationManager = new Gdn_ApplicationManager(); $Apps = $ApplicationManager->EnabledApplications(); $AppNames = ConsolidateArrayValuesByKey($Apps, 'Folder'); foreach ($AppNames as $AppName) { $Files[] = CombinePaths(array(PATH_APPLICATIONS, $AppName, 'settings', 'structure.php'), DS); } $AppName = 'all'; } else { // Load that specific application structure file. $Files[] = CombinePaths(array(PATH_APPLICATIONS, $AppName, 'settings', 'structure.php'), DS); } $Validation = new Gdn_Validation(); $Database = Gdn::Database(); $Drop = $Drop == '0' ? FALSE : TRUE; $Explicit = $Explicit == '0' ? FALSE : TRUE; $CaptureOnly = !($CaptureOnly == '0'); $Structure = Gdn::Structure(); $Structure->CaptureOnly = $CaptureOnly; $SQL = Gdn::SQL(); $SQL->CaptureModifications = $CaptureOnly; $this->SetData('CaptureOnly', $Structure->CaptureOnly); $this->SetData('Drop', $Drop); $this->SetData('Explicit', $Explicit); $this->SetData('ApplicationName', $AppName); $this->SetData('Status', ''); $FoundStructureFile = FALSE; foreach ($Files as $File) { if (file_exists($File)) { $FoundStructureFile = TRUE; try { include($File); } catch (Exception $Ex) { $this->Form->AddError($Ex); } } } // Run the structure of all of the plugins. $Plugins = Gdn::PluginManager()->EnabledPlugins(); foreach ($Plugins as $PluginKey => $Plugin) { $PluginInstance = Gdn::PluginManager()->GetPluginInstance($PluginKey, Gdn_PluginManager::ACCESS_PLUGINNAME); if (method_exists($PluginInstance, 'Structure')) $PluginInstance->Structure(); } if (property_exists($Structure->Database, 'CapturedSql')) $this->SetData('CapturedSql', (array)$Structure->Database->CapturedSql); else $this->SetData('CapturedSql', array()); if ($this->Form->ErrorCount() == 0 && !$CaptureOnly && $FoundStructureFile) $this->SetData('Status', 'The structure was successfully executed.'); $this->AddSideMenu('dashboard/settings/configure'); $this->AddCssFile('admin.css'); $this->SetData('Title', T('Database Structure Upgrades')); $this->Render(); }
public function FindPluginFile($PluginPath) { if (!is_dir($PluginPath)) { return FALSE; } $PluginFiles = scandir($PluginPath); $TestPatterns = array('default.php', '*plugin.php'); foreach ($PluginFiles as $PluginFile) { foreach ($TestPatterns as $Test) { if (fnmatch($Test, $PluginFile)) { return CombinePaths(array($PluginPath, $PluginFile)); } } } return FALSE; }
/** * Undocumented method. * * @todo Method RenderMaster() needs a description. */ public function RenderMaster() { // Build the master view if necessary if ($this->_DeliveryType == DELIVERY_TYPE_ALL) { // Define some default master views unless one was explicitly defined if ($this->MasterView == '') { // If this is a syndication request, use the appropriate master view if ($this->SyndicationMethod == SYNDICATION_ATOM) { $this->MasterView = 'atom'; } else { if ($this->SyndicationMethod == SYNDICATION_RSS) { $this->MasterView = 'rss'; } else { $this->MasterView = 'default'; } } // Otherwise go with the default } // Only get css & ui components if this is NOT a syndication request if ($this->SyndicationMethod == SYNDICATION_NONE && is_object($this->Head)) { // 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(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. Garden-wide theme view. eg. root/themes/theme_name/design/ $CssPaths[] = PATH_THEMES . DS . $this->Theme . DS . 'design' . DS . $CssGlob; } // 3. Application default. eg. root/applications/app_name/design/ $CssPaths[] = PATH_APPLICATIONS . DS . $AppFolder . DS . 'design' . DS . $CssGlob; // 4. Garden default. eg. root/applications/garden/design/ $CssPaths[] = PATH_APPLICATIONS . DS . 'garden' . DS . 'design' . DS . $CssGlob; } // Find the first file that matches the path. $CssPath = FALSE; foreach ($CssPaths as $Glob) { $Paths = glob($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 = str_replace(array(PATH_ROOT, DS), array('', '/'), $CssPath); $this->Head->AddCss($CssPath, 'screen'); } } } // Make sure the head and menu modules get passed into the assets collection. $this->AddModule('Head'); $this->AddModule('Menu'); } // Master views come from one of four places: $MasterViewPaths = array(); 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/garden/views/ $MasterViewPaths[] = CombinePaths(array(PATH_APPLICATIONS, 'garden', 'views', $this->MasterView . '.master*')); // Find the first file that matches the path. $MasterViewPath = FALSE; foreach ($MasterViewPaths as $Glob) { $Paths = glob($Glob); if (is_array($Paths) && count($Paths) > 0) { $MasterViewPath = $Paths[0]; break; } } 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; if (substr($ControllerName, -10) == 'Controller') { $ControllerName = substr($ControllerName, 0, -10); } // Strip "Controller" from the body identifier. $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 . '_' . Format::AlphaNumeric(strtolower($this->RequestMethod))); include $MasterViewPath; } else { $ViewHandler->Render($MasterViewPath, $this); } }
function Url($Destination = '', $WithDomain = FALSE, $RemoveSyndication = FALSE) { // Cache the rewrite urls config setting in this object. static $RewriteUrls = NULL; if (is_null($RewriteUrls)) { $RewriteUrls = ForceBool(Gdn::Config('Garden.RewriteUrls', FALSE)); } $Prefix = substr($Destination, 0, 7); if (in_array($Prefix, array('http://', 'https:/'))) { return $Destination; } else { if ($Destination == '#' || $Destination == '') { if ($WithDomain) { return Gdn_Url::Request(TRUE, TRUE, $RemoveSyndication) . $Destination; } else { return '/' . Gdn_Url::Request(TRUE, FALSE, $RemoveSyndication) . $Destination; } } else { $Paths = array(); if (!$WithDomain) { $Paths[] = '/'; } $Paths[] = Gdn_Url::WebRoot($WithDomain); if (!$RewriteUrls) { $Paths[] = 'index.php'; } $Paths[] = $Destination; return CombinePaths($Paths, '/'); } } }
$Info .= anchor(t('Visit Site'), $PluginUrl); } echo $Info != '' ? $Info : ' '; ?> </td> </tr> <?php if ($Upgrade) { ?> <tr class="<?php echo $RowClass; ?> "> <td colspan="2"> <div class="Alert"><a href="<?php echo CombinePaths(array($UpdateUrl, 'find', urlencode($ScreenName)), '/'); ?> "><?php printf(t('%1$s version %2$s is available.'), $ScreenName, $NewVersion); ?> </a></div> </td> </tr> <?php } } } ?> </tbody> </table>
public function ThemeView($View) { $ThemeViewLoc = CombinePaths(array(PATH_THEMES, Gdn::Controller()->Theme, 'views', $this->GetPluginFolder(FALSE))); if (file_exists($ThemeViewLoc . DS . $View . '.php')) { $View = $ThemeViewLoc . DS . $View . '.php'; } else { $View = $this->GetView($View . '.php'); } return $View; }
/** * Searches through the /cache/controller_mappings.php file for the requested * controller. If it doesn't find it, it searches through the entire * application's folders for the requested controller. If it finds the * controller, it adds the mapping to /cache/controller_mappings.php so it * won't need to search again. If it doesn't find the controller file * anywhere, it throws a fatal error. * * @param boolean $ThrowErrorOnFailure * @todo $ThrowErrorOnFailure needs a description. */ private function _FetchController($ThrowErrorOnFailure = FALSE) { $ControllerWhiteList = $this->EnabledApplicationFolders(); // Don't include it if it's already been included if (!class_exists($this->ControllerName())) { $PathParts = array('controllers'); if ($this->_ControllerFolder != '') { $PathParts[] = $this->_ControllerFolder; } $PathParts[] = strtolower($this->_ControllerName) . '.php'; $ControllerFileName = CombinePaths($PathParts); // Force the mapping to search in the app folder if it was in the request if ($this->_ApplicationFolder != '' && InArrayI($this->_ApplicationFolder, $ControllerWhiteList)) { // Limit the white list to the specified application folder $ControllerWhiteList = array($this->_ApplicationFolder); } $ControllerPath = Gdn_FileSystem::FindByMapping('controller_mappings.php', 'Controller', PATH_APPLICATIONS, $ControllerWhiteList, $ControllerFileName); if ($ControllerPath !== FALSE) { // Strip the "Application Folder" from the controller path (this is // used by the controller for various purposes. ie. knowing which // application to search in for a view file). $this->_ApplicationFolder = explode(DS, str_replace(PATH_APPLICATIONS . DS, '', $ControllerPath)); $this->_ApplicationFolder = $this->_ApplicationFolder[0]; // Load the application's master controller if (!class_exists($this->_ApplicationFolder . 'Controller')) { include CombinePaths(array(PATH_APPLICATIONS, $this->_ApplicationFolder, 'controllers', 'appcontroller.php')); } // Now load the library (no need to check for existence - couldn't // have made it here if it didn't exist). include $ControllerPath; } } if (!class_exists($this->ControllerName())) { if ($ThrowErrorOnFailure === TRUE) { if (ForceBool(Gdn::Config('Garden.Debug'))) { trigger_error(ErrorMessage('Controller not found: ' . $this->ControllerName(), 'Dispatcher', '_FetchController'), E_USER_ERROR); } else { // Return a 404 message list($this->_ApplicationFolder, $this->_ControllerName, $this->_ControllerMethod) = explode('/', $this->Routes['Default404']); $ControllerFileName = CombinePaths(array('controllers', strtolower($this->_ControllerName) . '.php')); $ControllerPath = Gdn_FileSystem::FindByMapping('controller_mappings.php', 'Controller', PATH_APPLICATIONS, $ControllerWhiteList, $ControllerFileName); include CombinePaths(array(PATH_APPLICATIONS, $this->_ApplicationFolder, 'controllers', 'appcontroller.php')); include $ControllerPath; } } return FALSE; } else { return TRUE; } }
private function RegisterCaptcha() { include CombinePaths(array(PATH_LIBRARY, 'vendors/recaptcha', 'functions.recaptchalib.php')); if ($this->Form->IsPostBack() === TRUE) { // Add validation rules that are not enforced by the model $this->UserModel->DefineSchema(); $this->UserModel->Validation->ApplyRule('Name', 'Username', self::UsernameError); $this->UserModel->Validation->ApplyRule('TermsOfService', 'Required', 'You must agree to the terms of service.'); $this->UserModel->Validation->ApplyRule('Password', 'Required'); $this->UserModel->Validation->ApplyRule('Password', 'Match'); // $this->UserModel->Validation->ApplyRule('DateOfBirth', 'MinimumAge'); if (!$this->UserModel->InsertForBasic($this->Form->FormValues())) { $this->Form->SetValidationResults($this->UserModel->ValidationResults()); if ($this->_DeliveryType != DELIVERY_TYPE_ALL) { $this->_DeliveryType = DELIVERY_TYPE_MESSAGE; } } else { // The user has been created successfully, so sign in now $Authenticator = Gdn::Authenticator()->AuthenticateWith('password'); $Authenticator->FetchData($this->Form); $AuthUserID = $Authenticator->Authenticate(); // ... and redirect them appropriately $Route = $this->RedirectTo(); if ($this->_DeliveryType != DELIVERY_TYPE_ALL) { $this->RedirectUrl = Url($Route); } else { if ($Route !== FALSE) { Redirect($Route); } } } } $this->Render(); }
} if ($PluginUrl != '') { $Info .= '<span>|</span>'; $Info .= Anchor('Visit Site', $PluginUrl); } echo $Info != '' ? $Info : ' '; ?> </td> </tr> <?php if ($Upgrade) { ?> <tr class="<?php echo $RowClass; ?> "> <td colspan="2"><div class="Alert"><a href="<?php echo CombinePaths(array($AddonUrl, 'find', urlencode($PluginName)), '/'); ?> "><?php printf(T('%1$s version %2$s is available.'), $ScreenName, $NewVersion); ?> </a></div></td> </tr> <?php } } } ?> </tbody> </table>