Login | ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/fastphp/trunk/FastPHPUtils.pas
Revision: 61
Committed: Tue Feb 25 20:39:22 2020 UTC (4 weeks, 6 days ago) by daniel-marschall
Content type: text/x-pascal
File size: 6502 byte(s)
Log Message:
FastPHP Browser: Meta tags can now be used to change the window title, width and height

File Contents

# Content
1 unit FastPHPUtils;
2
3 interface
4
5 uses
6 Windows, SysUtils, StrUtils, Dialogs, IniFiles, Classes, Forms, ShellAPI, Functions;
7
8 const
9 FASTPHP_GOTO_URI_PREFIX = 'fastphp://editor/gotoline/';
10
11 function GetPHPExe: string;
12 function RunPHPScript(APHPFileName: string; lint: boolean=false; inConsole: boolean=False; ContentCallBack: TContentCallBack=nil): string;
13 function ParseCHM(const chmFile: TFileName): boolean;
14 function IsValidPHPExe(const exeFile: TFileName): boolean;
15
16 implementation
17
18 uses
19 FastPHPConfig;
20
21 function GetPHPExe: string;
22 var
23 od: TOpenDialog;
24 begin
25 result := TFastPHPConfig.PhpInterpreter;
26 if not FileExists(result) then
27 begin
28 od := TOpenDialog.Create(nil);
29 try
30 od.DefaultExt := '.exe';
31 od.FileName := 'php.exe';
32 od.Filter := 'Executable file (*.exe)|*.exe';
33 od.Options := [ofReadOnly, ofHideReadOnly, ofPathMustExist, ofFileMustExist, ofEnableSizing];
34 od.Title := 'Please choose your PHP interpreter (php.exe)';
35
36 if not od.Execute then exit;
37 if not FileExists(od.FileName) then exit;
38 result := od.FileName;
39 finally
40 od.Free;
41 end;
42
43 if not IsValidPHPExe(result) then
44 begin
45 MessageDlg('This is not a valid PHP executable.', mtError, [mbOk], 0);
46 exit;
47 end;
48
49 TFastPHPConfig.PhpInterpreter := result;
50 end;
51 end;
52
53 function RunPHPScript(APHPFileName: string; lint: boolean=false; inConsole: boolean=False; ContentCallBack: TContentCallBack=nil): string;
54 var
55 phpExe, args, batFile, workdir: string;
56 slBat: TStringList;
57 begin
58 phpExe := GetPHPExe;
59 if phpExe = '' then Abort;
60
61 if lint then
62 args := '-l "'+APHPFileName+'"'
63 else
64 args := '-f "'+APHPFileName+'"';
65
66 //workdir := ExtractFileDir(ParamStr(0));
67 workdir := ExtractFileDir(APHPFileName);
68
69 if inConsole then
70 begin
71 (*
72 ShellExecute(0, 'open', PChar(phpExe), PChar(args), PChar(workdir), SW_NORMAL);
73 *)
74 batFile := IncludeTrailingPathDelimiter(GetTempDir) + 'RunFastPHP.bat';
75 slBat := TStringList.Create;
76 try
77 slBat.Add('@echo off');
78 slBat.Add('cd /d "'+workdir+'"');
79 slBat.Add('"'+phpExe+'" ' + args);
80 slBat.Add('pause.');
81 slBat.SaveToFile(batFile);
82 ShellExecute(0, 'open', PChar(batFile), '', '', SW_NORMAL);
83 finally
84 slBat.Free;
85 end;
86
87 result := '';
88 end
89 else
90 begin
91 result := GetDosOutput('"'+phpExe+'" ' + args, workdir, ContentCallBack);
92 end;
93 end;
94
95 function ParseCHM(const chmFile: TFileName): boolean;
96 var
97 test, candidate, candidate2: string;
98 p, p2, q: integer;
99 i: integer;
100 good: Boolean;
101 ini: TMemIniFile;
102 domain: string;
103 sl: TStringList;
104 symbolCount: Integer;
105 sl2: TStrings;
106 outFile: string;
107 begin
108 // TODO: problem: mysqli::commit has /res/mysqli.commit.html -> keyword is NOT commit alone
109
110 outFile := ChangeFileExt(chmFile, '.ini');
111 DeleteFile(outFile);
112 test := LoadFileToStr(chmFile);
113 if Pos('/php_manual_', test) = -1 then
114 begin
115 result := false;
116 exit;
117 end;
118 p := 0;
119 ini := TMemIniFile.Create(outFile);
120 try
121 ini.WriteString('_Info_', 'Source', chmFile);
122 ini.WriteString('_Info_', 'Generated', DateTimeToStr(Now));
123 ini.WriteString('_Info_', 'GeneratorVer', '1.0');
124 ini.WriteString('_Info_', 'Signature', '$ViaThinkSoft$');
125 {$REGION 'Excludes'}
126 // TODO: more excludes
127 ini.WriteBool('_HelpExclude_', 'about', true);
128 ini.WriteBool('_HelpExclude_', 'apache', true);
129 {$ENDREGION}
130 while true do
131 begin
132 if Assigned(Application) then Application.ProcessMessages;
133
134 p := PosEx('/res/', Test, p+1);
135 if p = 0 then break;
136 p2 := PosEx('.html', Test, p);
137 if p = 0 then break;
138 candidate := copy(Test, p+5, p2-p-5);
139 if candidate = '' then continue;
140 if Length(candidate) > 50 then continue;
141 good := true;
142 for i := p+5 to p2-1 do
143 begin
144 if ord(test[i]) < 32 then
145 begin
146 good := false;
147 break;
148 end;
149 {$IFDEF UNICODE}
150 if not CharInSet(test[i], ['a'..'z', 'A'..'Z', '.', '-', '_', '0'..'9']) then
151 {$ELSE}
152 if not (test[i] in ['a'..'z', 'A'..'Z', '.', '-', '_', '0'..'9']) then
153 {$ENDIF}
154 begin
155 ini.WriteInteger('_Errors_', 'Contains unexpected character! ' + candidate, ini.ReadInteger('_Errors_', 'Contains unexpected character! ' + candidate, 0)+1);
156 good := false;
157 break;
158 end;
159 end;
160 if good then
161 begin
162 candidate2 := LowerCase(StringReplace(candidate, '-', '_', [rfReplaceAll]));
163 q := LastPos('.', candidate2);
164 domain := copy(candidate2, 1, q-1);
165 if domain = '' then continue;
166 candidate2 := copy(candidate2, q+1, Length(candidate2)-q);
167 ini.WriteInteger('_Category_', domain, ini.ReadInteger('_Category_', domain, 0)+1);
168 ini.WriteString(domain, candidate2, '/res/'+candidate+'.html');
169 if not ini.ReadBool('_HelpExclude_', domain, false)
170 and (candidate2 <> 'configuration')
171 and (candidate2 <> 'constants')
172 and (candidate2 <> 'installation')
173 and (candidate2 <> 'requirements')
174 and (candidate2 <> 'resources')
175 and (candidate2 <> 'setup') then
176 begin
177 if ini.ReadString('_HelpWords_', candidate2, '') <> '' then
178 begin
179 ini.WriteInteger('_Conflicts_', candidate2, ini.ReadInteger('_Conflicts_', candidate2, 0)+1);
180 end;
181
182 ini.WriteString('_HelpWords_', candidate2, '/res/'+candidate+'.html');
183 end;
184 end;
185 end;
186
187 sl := TStringList.Create;
188 sl2 := TStringList.Create;
189 try
190 ini.ReadSections(sl);
191 ini.WriteInteger('_Info_', 'TotalDomains', sl.Count);
192 symbolCount := 0;
193 for domain in sl do
194 begin
195 ini.ReadSection(domain, sl2);
196 Inc(symbolCount, sl2.Count)
197 end;
198 ini.WriteInteger('_Info_', 'TotalSymbols', symbolCount);
199 finally
200 sl.Free;
201 sl2.Free;
202 end;
203
204 ini.UpdateFile;
205 result := true;
206 finally
207 ini.Free;
208 end;
209 end;
210
211 function IsValidPHPExe(const exeFile: TFileName): boolean;
212 var
213 cont: string;
214 begin
215 cont := LoadFileToStr(exeFile);
216 result := (Pos('php://stdout', cont) >= 0) or
217 (Pos('PHP_SELF', cont) >= 0);
218 end;
219
220 end.