Subversion Repositories fastphp

Rev

Rev 8 | Rev 13 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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