PageRenderTime 46ms CodeModel.GetById 17ms app.highlight 22ms RepoModel.GetById 1ms app.codeStats 1ms

/trunk/Client/PHPPage.cs

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