php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #47869 DocumentComplete does not return a useful COM object
Submitted: 2009-04-01 21:38 UTC Modified: 2009-04-02 16:57 UTC
Votes:4
Avg. Score:3.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: csaba at alum dot mit dot edu Assigned:
Status: Open Package: COM related
PHP Version: 5.3.0RC1 OS: Win XP Pro
Private report: No CVE-ID: None
 [2009-04-01 21:38 UTC] csaba at alum dot mit dot edu
Description:
------------
The DocumentComplete event handler of the InternetExplorer.Application object is supposed to receive two parameters, a $url and a $frame.  The $frame seems to not be useable, except at the top level.  This is in contrast with the same functionality in VBScript, where the frame is accessible.  This report is only for CLI PHP on Windows (my system in Win XP Pro / IE 6)

Reproduce code:
---------------
Two files are needed in the same directory.  The first one is a short .htm file, with the same base name as the .php file.

DocComp.htm:
<html>
<head><title>Document Complete testing</title></head>
<body>Before
<iframe src="http://google.com" style="border:solid 2px red">
</iframe>After
</body></html>


DocComp.php:
<?php  //DocumentComplete example with IFrame
$ie = new COM("InternetExplorer.Application");
$ie->visible = true;

// Determine HTM file name
$loc = __FILE__;
$loc = substr($loc,0,strrpos(__FILE__, ".")) . ".htm";

// hook up an event sink
$sink = new IESink();
com_event_sink ($ie, $sink, "DWebBrowserEvents2");

// Carry out the navigation
print "Navigating to: $loc\n";
$ie->Navigate2($loc);
while (true) {
  try { if ($ie->visible); com_message_pump(1000); }
  catch (com_exception $e) { break; } }
print "\nDone with PHP script";

class IESink {
  public function DocumentComplete(&$frame, $url) {
    static $ctr = 0;
    print "\n\nDocComp: " . (++$ctr) . ") " .
          typename($frame) . " => $url";
    try {
      print "\nReady state: " . $frame->document->readyState;
      print "\nTitle: " . $frame->document->title;
    } catch (com_exception $e) {}  }  }

function typename($objCOM) {
  // mimics VB's typename function
  if (($type=gettype($objCOM))!="object") return $type;
  if (($class=get_class($objCOM)) && $class!="com"
                              && $class!="variant")
    return "Class:$class";
  try {
    $oScript = new COM("MSScriptControl.ScriptControl");
    $oScript->language = "VBScript";
    $oScript->addObject("objCom",$objCOM);
    $type = $oScript->eval("typename(objCom)");
    return "COM:$type"; }
  catch (com_exception $e) { return "object"; } }
?>

Expected result:
----------------
Whenever DocumentComplete fires, I expect to see a grouping of three lines printed to the console: The first one has the typename and the url, the 2nd line would show the ReadyState (of complete), and the 3rd line would show the document's title.

Actual result:
--------------
In the example, when the frame is the top level window, then all three lines show.  However, when the $frame corresponds to the IFrame (containing google) then only one line shows.

If you run the example with a more complex site (such as replacing google.com with ebay.com in DocComp.htm) then you will again have one successful group of three lines, but at least 3 singleton lines corresponding to nested frames (ie. eBay is nested in DocComp.htm, and there are frames within eBay).

The corresponding code works fine with VBScript.  I suspect that somewhere along the line, there's an incorrect permission/security being set in the PHP version.

The reason that it would be good to fix this is that this offers the only viable entry point to nested frames.  For example, if one needed to fix up the CSS on an arriving web page, this is where it should be done.

It made no difference in my testing as to whether the first argument was to DocumentComplete was declared as &$frame or $frame.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-04-02 16:57 UTC] csaba at alum dot mit dot edu
Here is the corresponding VBScript code.  It should be named DocComp.vbs and called with:
CScript /nologo doccomp.vbs

Calling it with CScript will have the print statements go to the cmd window rather than pop up as message boxes.

The thing to note is that all the readyState and Title properties of the documents are shown, and not only the top level.  To give it a different location (web page), change loc in the .vbs file (example: loc="ebay.com"), or change the src of the iframe in DocComp.htm

Csaba Gabor from Vienna

DocComp.vbs:
'DocumentComplete example with IFrame
Set ie = WScript.CreateObject("InternetExplorer.Application", "ie")
ie.visible = true
ctr = 0

'Get the name of the .htm file
loc = WScript.ScriptFullName
For pos=Len(loc) to 1 Step -1
  If mid(loc,pos,1)="." Then Exit For
Next
loc = mid(loc, 1, pos-1) & ".htm"
WScript.Echo "Navigating to: " & loc & vbcrlf


ie.Navigate2(loc)
On Error Resume Next
Do While ie.visible          'Run until IE is closed
    If Err Then Exit Do
    WScript.Sleep 10
Loop
WScript.Echo "Done with VBS script"

Sub ieDocumentComplete (pDisp, url)
  ctr = ctr + 1
  WScript.Echo ctr & ") " & typename(pDisp) & " => " & url
  'Proof of access to the DOM
  WScript.Echo "Ready State: " & pDisp.document.readyState
  WScript.Echo "Title: " & pDisp.document.title & vbCrLf
End Sub
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 14:01:29 2024 UTC