Subversion Repositories fastphp

Rev

Rev 42 | Rev 49 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

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