PageRenderTime 47ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/Client/PHPPage.cs

#
C# | 652 lines | 533 code | 89 blank | 30 comment | 79 complexity | 81406afabe1238427739f770468fd355 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. //-----------------------------------------------------------------------
  2. // <copyright>
  3. // Copyright (C) Ruslan Yakushev for the PHP Manager for IIS project.
  4. //
  5. // This file is subject to the terms and conditions of the Microsoft Public License (MS-PL).
  6. // See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL for more details.
  7. // </copyright>
  8. //-----------------------------------------------------------------------
  9. using System;
  10. using System.ComponentModel;
  11. using System.Drawing;
  12. using System.Globalization;
  13. using System.IO;
  14. using System.Windows.Forms;
  15. using Microsoft.Web.Management.Client;
  16. using Microsoft.Web.Management.Client.Win32;
  17. using Web.Management.PHP.Config;
  18. namespace Web.Management.PHP
  19. {
  20. [ModulePageIdentifier(Globals.PHPPageIdentifier)]
  21. internal sealed class PHPPage : ModulePage
  22. {
  23. private const int IndexRegisterPhpTask = 0;
  24. private const int IndexChangeVersionTask = 1;
  25. private const int IndexCheckPhpInfoTask = 2;
  26. private const int IndexErrorReportingTask = 0;
  27. private const int IndexLimitsTask = 1;
  28. private const int IndexAllSettingsTask = 2;
  29. private const int IndexAllExtensionsTask = 0;
  30. private const int IndexAddExtensionTask = 1;
  31. // Summary labels
  32. private Label _enabledExtLabel;
  33. private Label _installedExtLabel;
  34. private Label _handlerMappingNameLabel;
  35. private LinkLabel _handlerMappingValueLabel;
  36. private Label _errorLogNameLabel;
  37. private LinkLabel _errorLogValueLabel;
  38. private LinkLabel _configPathValueLabel;
  39. private Label _configPathNameLabel;
  40. private Label _executableValueLabel;
  41. private Label _executableNameLabel;
  42. private Label _versionValueLabel;
  43. private Label _versionNameLabel;
  44. private PHPPageItemControl _phpExtensionItem;
  45. private PHPPageItemControl _phpSettingsItem;
  46. private PHPPageItemControl _phpSetupItem;
  47. private new PHPModule Module
  48. {
  49. get
  50. {
  51. return (PHPModule)base.Module;
  52. }
  53. }
  54. protected override bool ShowTaskList
  55. {
  56. get
  57. {
  58. return false;
  59. }
  60. }
  61. private void AddExtension()
  62. {
  63. using (var dlg = new Extensions.AddExtensionDialog(Module, Connection.IsLocalConnection))
  64. {
  65. if (ShowDialog(dlg) == DialogResult.OK)
  66. {
  67. Navigate(typeof(Extensions.AllExtensionsPage), dlg.AddedExtensionName);
  68. }
  69. }
  70. }
  71. private static string GetHandlerMappingLabelText(bool handlerIsLocal)
  72. {
  73. if (handlerIsLocal)
  74. {
  75. return Resources.PHPPageLocalHandler;
  76. }
  77. return Resources.PHPPageInheritedHandler;
  78. }
  79. private void GetSettings()
  80. {
  81. StartAsyncTask(Resources.AllSettingsPageGettingSettings, OnGetSettings, OnGetSettingsCompleted);
  82. }
  83. private string GetSiteUrlAndName(out string siteName, out string relativePath)
  84. {
  85. using (var dlg = new Setup.SelectSiteAndUrlDialog(Module, Connection))
  86. {
  87. if (ShowDialog(dlg) == DialogResult.OK)
  88. {
  89. siteName = dlg.SiteName;
  90. relativePath = dlg.RelativePath;
  91. return dlg.SelectedUrl;
  92. }
  93. }
  94. siteName = string.Empty;
  95. relativePath = String.Empty;
  96. return null;
  97. }
  98. private void InitializeUI()
  99. {
  100. SuspendLayout();
  101. var uiService = (IManagementUIService)GetService(typeof(IManagementUIService));
  102. var titleFont = (Font)uiService.Styles["PageHeaderTitleFont"];
  103. Padding = new Padding(0, 12, 0, 0);
  104. //
  105. // All page item labels
  106. //
  107. _versionNameLabel = new Label {Text = Resources.PHPPageVersion};
  108. _versionValueLabel = new Label();
  109. _executableNameLabel = new Label {Text = Resources.PHPPageExecutable};
  110. _executableValueLabel = new Label();
  111. _handlerMappingNameLabel = new Label {Text = Resources.PHPPageHandlerMapping};
  112. _handlerMappingValueLabel = new LinkLabel();
  113. _handlerMappingValueLabel.LinkClicked += OnHandlerMappingValueLabelLinkClicked;
  114. _configPathNameLabel = new Label {Text = Resources.PHPPageConfigurationFile};
  115. _configPathValueLabel = new LinkLabel();
  116. _configPathValueLabel.LinkClicked += OnPathLinkLabelLinkClicked;
  117. _errorLogNameLabel = new Label {Text = Resources.PHPPageErrorLog};
  118. _errorLogValueLabel = new LinkLabel();
  119. _errorLogValueLabel.LinkClicked += OnPathLinkLabelLinkClicked;
  120. _enabledExtLabel = new Label();
  121. _installedExtLabel = new Label();
  122. //
  123. // PHPSetup
  124. //
  125. _phpSetupItem = new PHPPageItemControl
  126. {
  127. RightToLeftLayout = RightToLeftLayout,
  128. RightToLeft = RightToLeft
  129. };
  130. _phpSetupItem.TitleClick += OnPHPSetupItemTitleClick;
  131. _phpSetupItem.Title = Resources.PHPSetupItemTitle;
  132. _phpSetupItem.TitleFont = titleFont;
  133. _phpSetupItem.Image = Resources.PHPSetup32;
  134. _phpSetupItem.AddInfoRow(_versionNameLabel, _versionValueLabel);
  135. _phpSetupItem.AddInfoRow(_executableNameLabel, _executableValueLabel);
  136. _phpSetupItem.AddInfoRow(_handlerMappingNameLabel, _handlerMappingValueLabel);
  137. _phpSetupItem.AddTask(OnPHPSetupItemClick,
  138. Resources.PHPSetupItemRegisterPHPTask,
  139. Resources.PHPSetupItemChangeVersionTask,
  140. Resources.PHPSetupItemCheckPHPInfoTask);
  141. Controls.Add(_phpSetupItem);
  142. //
  143. // PHP Settings
  144. //
  145. _phpSettingsItem = new PHPPageItemControl
  146. {
  147. RightToLeftLayout = RightToLeftLayout,
  148. RightToLeft = RightToLeft
  149. };
  150. _phpSettingsItem.TitleClick += OnPHPSettingsItemTitleClick;
  151. _phpSettingsItem.Title = Resources.PHPSettingsItemTitle;
  152. _phpSettingsItem.TitleFont = titleFont;
  153. _phpSettingsItem.Image = Resources.PHPSettings32;
  154. _phpSettingsItem.AddInfoRow(_configPathNameLabel, _configPathValueLabel);
  155. _phpSettingsItem.AddInfoRow(_errorLogNameLabel, _errorLogValueLabel);
  156. if (Connection.IsUserServerAdministrator)
  157. {
  158. _phpSettingsItem.AddTask(OnPHPSettingsItemClick,
  159. Resources.PHPSettingsItemErrorReportingTask,
  160. Resources.PHPSettingsItemLimitsTask,
  161. Resources.PHPSettingsItemAllSettingsTask);
  162. }
  163. else
  164. {
  165. _phpSettingsItem.AddTask(OnPHPSettingsItemClick,
  166. Resources.PHPSettingsItemReadOnlyErrorReportingTask,
  167. Resources.PHPSettingsItemReadOnlyLimitsTask,
  168. Resources.PHPSettingsItemReadOnlyAllSettingsTask);
  169. }
  170. Controls.Add(_phpSettingsItem);
  171. //
  172. // PHP Extensions
  173. //
  174. _phpExtensionItem = new PHPPageItemControl
  175. {
  176. RightToLeftLayout = RightToLeftLayout,
  177. RightToLeft = RightToLeft
  178. };
  179. _phpExtensionItem.TitleClick += OnPHPExtensionItemTitleClick;
  180. _phpExtensionItem.Title = Resources.PHPExtensionsItemTitle;
  181. _phpExtensionItem.TitleFont = titleFont;
  182. _phpExtensionItem.Image = Resources.PHPExtensions32;
  183. _phpExtensionItem.AddSpanRow(_enabledExtLabel);
  184. _phpExtensionItem.AddSpanRow(_installedExtLabel);
  185. if (Connection.IsUserServerAdministrator)
  186. {
  187. _phpExtensionItem.AddTask(OnPHPExtensionItemClick,
  188. Resources.PHPExtensionItemEnableTask, Resources.PHPExtensionItemAddTask);
  189. }
  190. else
  191. {
  192. _phpExtensionItem.AddTask(OnPHPExtensionItemClick,
  193. Resources.PHPExtensionItemReadOnlyEnableTask);
  194. }
  195. Controls.Add(_phpExtensionItem);
  196. // Update the information summaries for each PHPPageItemControl
  197. Refresh();
  198. ResumeLayout(true);
  199. }
  200. private void NavigateToPHPInfo()
  201. {
  202. string siteName;
  203. string relativePath;
  204. var siteUrl = GetSiteUrlAndName(out siteName, out relativePath);
  205. if (!String.IsNullOrEmpty(siteUrl))
  206. {
  207. Navigate(typeof(Setup.PHPInfoPage), new[] { siteUrl, siteName, relativePath });
  208. }
  209. }
  210. protected override void OnActivated(bool initialActivation)
  211. {
  212. base.OnActivated(initialActivation);
  213. if (initialActivation)
  214. {
  215. InitializeUI();
  216. }
  217. }
  218. private static void OnFastCgiLearnMoreLinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
  219. {
  220. string learnMoreUrl = String.Format(Globals.EnableFastCgiLearnMore, CultureInfo.CurrentUICulture.TwoLetterISOLanguageName);
  221. Helper.Browse(learnMoreUrl);
  222. }
  223. private void OnGetSettings(object sender, DoWorkEventArgs e)
  224. {
  225. e.Result = Module.Proxy.GetPHPConfigInfo();
  226. }
  227. private void OnGetSettingsCompleted(object sender, RunWorkerCompletedEventArgs e)
  228. {
  229. try
  230. {
  231. var configInfo = (PHPConfigInfo)e.Result;
  232. UpdatePageItemsState(configInfo);
  233. }
  234. catch (Exception ex)
  235. {
  236. DisplayErrorMessage(ex, Resources.ResourceManager);
  237. UpdatePageItemsState(null);
  238. }
  239. }
  240. private void OnHandlerMappingValueLabelLinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
  241. {
  242. Type handlerMappingsPage = GetPageType("Handlers");
  243. if (handlerMappingsPage != null)
  244. {
  245. Navigate(handlerMappingsPage);
  246. }
  247. }
  248. protected override void OnLayout(LayoutEventArgs e)
  249. {
  250. if (!Visible || Height == 0)
  251. {
  252. return;
  253. }
  254. var controls = Controls;
  255. var clientSize = ClientSize;
  256. var width = clientSize.Width - Padding.Horizontal - 12;
  257. var proposedSize = new Size(width, Int32.MaxValue);
  258. var top = Padding.Top + AutoScrollPosition.Y;
  259. for (var i = 0; i < controls.Count; i++)
  260. {
  261. var ctl = controls[i];
  262. var size = ctl.GetPreferredSize(proposedSize);
  263. ctl.SetBounds(Padding.Left,
  264. top,
  265. size.Width,
  266. size.Height);
  267. top += ctl.Height;
  268. }
  269. if (top >= ClientSize.Height)
  270. {
  271. AdjustFormScrollbars(true);
  272. AutoScrollMinSize = new Size(ClientSize.Width, top);
  273. }
  274. else
  275. {
  276. AutoScrollMinSize = Size.Empty;
  277. AdjustFormScrollbars(false);
  278. }
  279. }
  280. private void OnPathLinkLabelLinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
  281. {
  282. OpenPhysicalFile((string)e.Link.LinkData);
  283. }
  284. private void OnPHPExtensionItemClick(int index)
  285. {
  286. if (index == IndexAllExtensionsTask)
  287. {
  288. Navigate(typeof(Extensions.AllExtensionsPage));
  289. }
  290. if (index == IndexAddExtensionTask)
  291. {
  292. AddExtension();
  293. }
  294. }
  295. private void OnPHPExtensionItemTitleClick(object sender, LinkLabelLinkClickedEventArgs e)
  296. {
  297. Navigate(typeof(Extensions.AllExtensionsPage));
  298. }
  299. private void OnPHPSettingsItemClick(int index)
  300. {
  301. if (index == IndexErrorReportingTask)
  302. {
  303. Navigate(typeof(Settings.ErrorReportingPage));
  304. }
  305. if (index == IndexLimitsTask)
  306. {
  307. Navigate(typeof(Settings.RuntimeLimitsPage));
  308. }
  309. if (index == IndexAllSettingsTask)
  310. {
  311. Navigate(typeof(Settings.AllSettingsPage));
  312. }
  313. }
  314. private void OnPHPSettingsItemTitleClick(object sender, LinkLabelLinkClickedEventArgs e)
  315. {
  316. Navigate(typeof(Settings.AllSettingsPage));
  317. }
  318. private void OnPHPSetupItemClick(int index)
  319. {
  320. if (index == IndexRegisterPhpTask)
  321. {
  322. RegisterPHPWithIIS();
  323. }
  324. else if (index == IndexChangeVersionTask)
  325. {
  326. SelectPHPVersion();
  327. }
  328. else if (index == IndexCheckPhpInfoTask)
  329. {
  330. NavigateToPHPInfo();
  331. }
  332. }
  333. private void OnPHPSetupItemTitleClick(object sender, LinkLabelLinkClickedEventArgs e)
  334. {
  335. NavigateToPHPInfo();
  336. }
  337. private void OnViewRecommendationsLinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
  338. {
  339. using (var dlg = new Setup.RecommendedConfigDialog(Module))
  340. {
  341. if (ShowDialog(dlg) == DialogResult.OK)
  342. {
  343. Refresh();
  344. }
  345. }
  346. }
  347. internal void OpenPhysicalFile(string physicalPath)
  348. {
  349. try
  350. {
  351. if (!String.IsNullOrEmpty(physicalPath) &&
  352. File.Exists(physicalPath))
  353. {
  354. System.Diagnostics.Process.Start(physicalPath);
  355. }
  356. else
  357. {
  358. ShowMessage(String.Format(CultureInfo.CurrentCulture, Resources.ErrorFileDoesNotExist, physicalPath), MessageBoxButtons.OK, MessageBoxIcon.Information);
  359. }
  360. }
  361. catch (Exception ex)
  362. {
  363. DisplayErrorMessage(ex, Resources.ResourceManager);
  364. }
  365. }
  366. private static LinkLabel PrepareNoFastCgiWarning()
  367. {
  368. var result = new LinkLabel();
  369. var sb = new System.Text.StringBuilder();
  370. sb.Append(Resources.WarningPHPConfigNoFastCgi);
  371. var fastCgiLearnMoreLinkStart = Resources.WarningPHPConfigNoFastCgi.Length;
  372. sb.Append(Resources.WarningFastCgiLearnMore);
  373. result.Text = sb.ToString();
  374. var fastCgiLearnMoreLink = new LinkLabel.Link(fastCgiLearnMoreLinkStart, Resources.WarningFastCgiLearnMore.Length, 0);
  375. result.Links.Add(fastCgiLearnMoreLink);
  376. result.LinkClicked += OnFastCgiLearnMoreLinkClicked;
  377. return result;
  378. }
  379. private static void PrepareOpenFileLink(LinkLabel linkLabel, string path, bool showLink)
  380. {
  381. linkLabel.Text = path;
  382. if (showLink && !String.IsNullOrEmpty(path))
  383. {
  384. if (linkLabel.Links.Count == 0)
  385. {
  386. var link = new LinkLabel.Link(0, path.Length, path);
  387. linkLabel.Links.Add(link);
  388. }
  389. else
  390. {
  391. var link = linkLabel.Links[0];
  392. link.Length = path.Length;
  393. link.LinkData = path;
  394. }
  395. }
  396. else
  397. {
  398. if (linkLabel.Links.Count > 0)
  399. {
  400. linkLabel.Links.Clear();
  401. }
  402. }
  403. }
  404. private LinkLabel PreparePHPConfigWarning()
  405. {
  406. var result = new LinkLabel();
  407. var sb = new System.Text.StringBuilder();
  408. sb.Append(Resources.WarningPHPConfigNotOptimal);
  409. var viewRecommendationsLinkStart = Resources.WarningPHPConfigNotOptimal.Length;
  410. sb.Append(Resources.WarningViewRecommendations);
  411. result.Text = sb.ToString();
  412. var fixItLink = new LinkLabel.Link(viewRecommendationsLinkStart, Resources.WarningViewRecommendations.Length, 0);
  413. result.Links.Add(fixItLink);
  414. result.LinkClicked += OnViewRecommendationsLinkClicked;
  415. return result;
  416. }
  417. private static Label PreparePHPRegistrationWarning(PHPRegistrationType registrationType)
  418. {
  419. Label result;
  420. if (registrationType == PHPRegistrationType.Cgi)
  421. {
  422. result = new Label {Text = Resources.WarningPHPConfigCgi};
  423. }
  424. else if (registrationType == PHPRegistrationType.Isapi)
  425. {
  426. result = new Label {Text = Resources.WarningPHPConfigIsapi};
  427. }
  428. else if (registrationType == PHPRegistrationType.None)
  429. {
  430. result = new Label {Text = Resources.WarningPHPConfigNotRegistered};
  431. }
  432. else if (registrationType == PHPRegistrationType.NoneNoFastCgi)
  433. {
  434. result = PrepareNoFastCgiWarning();
  435. }
  436. else
  437. {
  438. // Just in case
  439. result = new Label {Text = String.Empty};
  440. }
  441. return result;
  442. }
  443. protected override void Refresh()
  444. {
  445. GetSettings();
  446. }
  447. private void RegisterPHPWithIIS()
  448. {
  449. using (var dlg = new Setup.RegisterPHPDialog(Module, Connection.IsLocalConnection))
  450. {
  451. if (ShowDialog(dlg) == DialogResult.OK)
  452. {
  453. Refresh();
  454. }
  455. }
  456. }
  457. private void SelectPHPVersion()
  458. {
  459. using (var dlg = new Setup.ChangeVersionDialog(Module))
  460. {
  461. if (ShowDialog(dlg) == DialogResult.OK)
  462. {
  463. Refresh();
  464. }
  465. }
  466. }
  467. protected override bool ShowHelp()
  468. {
  469. return ShowOnlineHelp();
  470. }
  471. protected override bool ShowOnlineHelp()
  472. {
  473. return Helper.Browse(Globals.PHPPageOnlineHelp);
  474. }
  475. private void UpdatePageItemsState(PHPConfigInfo configInfo)
  476. {
  477. UpdatePHPSetupItem(configInfo);
  478. UpdatePHPSettingsItem(configInfo);
  479. UpdatePHPExtensionsItem(configInfo);
  480. PerformLayout();
  481. }
  482. private void UpdatePHPExtensionsItem(PHPConfigInfo configInfo)
  483. {
  484. var isPhpSetup = (configInfo != null && configInfo.RegistrationType == PHPRegistrationType.FastCgi);
  485. _phpExtensionItem.SetTitleState(isPhpSetup);
  486. if (isPhpSetup)
  487. {
  488. _enabledExtLabel.Text = String.Format(CultureInfo.CurrentCulture, Resources.PHPPageEnabledExtensions, configInfo.EnabledExtCount);
  489. _installedExtLabel.Text = String.Format(CultureInfo.CurrentCulture, Resources.PHPPageInstalledExtensions, configInfo.InstalledExtCount);
  490. }
  491. else
  492. {
  493. _enabledExtLabel.Text = Resources.PHPPageExtensionsNotAvailable;
  494. _installedExtLabel.Text = Resources.PHPPageExtensionsNotAvailable;
  495. }
  496. _phpExtensionItem.SetTaskState(IndexAllExtensionsTask, isPhpSetup);
  497. if (Connection.IsUserServerAdministrator)
  498. {
  499. _phpExtensionItem.SetTaskState(IndexAddExtensionTask, isPhpSetup);
  500. }
  501. }
  502. private void UpdatePHPSettingsItem(PHPConfigInfo configInfo)
  503. {
  504. var isPhpSetup = (configInfo != null && configInfo.RegistrationType == PHPRegistrationType.FastCgi);
  505. _phpSettingsItem.SetTitleState(isPhpSetup);
  506. if (isPhpSetup)
  507. {
  508. PrepareOpenFileLink(_configPathValueLabel, configInfo.PHPIniFilePath, Connection.IsLocalConnection);
  509. PrepareOpenFileLink(_errorLogValueLabel, configInfo.ErrorLog, Connection.IsLocalConnection);
  510. }
  511. else
  512. {
  513. PrepareOpenFileLink(_configPathValueLabel, Resources.PHPPagePHPNotAvailable, false);
  514. PrepareOpenFileLink(_errorLogValueLabel, Resources.PHPPagePHPNotAvailable, false);
  515. }
  516. _phpSettingsItem.SetTaskState(IndexErrorReportingTask, isPhpSetup);
  517. _phpSettingsItem.SetTaskState(IndexLimitsTask, isPhpSetup);
  518. _phpSettingsItem.SetTaskState(IndexAllSettingsTask, isPhpSetup);
  519. }
  520. private void UpdatePHPSetupItem(PHPConfigInfo configInfo)
  521. {
  522. bool isPhpSetup = (configInfo != null && configInfo.RegistrationType == PHPRegistrationType.FastCgi);
  523. _phpSetupItem.SetTitleState(isPhpSetup);
  524. _phpSetupItem.ClearWarning();
  525. if (isPhpSetup)
  526. {
  527. // Show warning about non optimal configuration if
  528. // PHP configuration is not optimal and
  529. // user is a server administrator.
  530. if (!configInfo.IsConfigOptimal && Connection.IsUserServerAdministrator)
  531. {
  532. _phpSetupItem.SetWarning(PreparePHPConfigWarning());
  533. }
  534. }
  535. else if (configInfo != null)
  536. {
  537. // Show warning about PHP not being setup or setup incorrectly
  538. _phpSetupItem.SetWarning(PreparePHPRegistrationWarning(configInfo.RegistrationType));
  539. }
  540. else
  541. {
  542. // Show warning about failed IIS configuration
  543. var errorLabel = new Label {Text = Resources.ErrorFailedToGetConfiguration};
  544. _phpSetupItem.SetWarning(errorLabel);
  545. }
  546. _versionValueLabel.Text = isPhpSetup ? configInfo.Version : Resources.PHPPagePHPNotAvailable;
  547. _executableValueLabel.Text = isPhpSetup ? configInfo.Executable : Resources.PHPPagePHPNotAvailable;
  548. _handlerMappingValueLabel.Text = isPhpSetup ? GetHandlerMappingLabelText(configInfo.HandlerIsLocal) : Resources.PHPPagePHPNotAvailable;
  549. // Allow PHP registration only for server administrators
  550. if (configInfo != null && configInfo.RegistrationType != PHPRegistrationType.NoneNoFastCgi)
  551. {
  552. _phpSetupItem.SetTaskState(IndexRegisterPhpTask, Connection.IsUserServerAdministrator);
  553. }
  554. else
  555. {
  556. // If there is an error in IIS configuration then do not allow new registrations
  557. _phpSetupItem.SetTaskState(IndexRegisterPhpTask, false);
  558. }
  559. _phpSetupItem.SetTaskState(IndexChangeVersionTask, isPhpSetup);
  560. _phpSetupItem.SetTaskState(IndexCheckPhpInfoTask, isPhpSetup);
  561. }
  562. }
  563. }