I was trying to use com_event_sink, I came across a problem
Here is a example from php.net
<?php
class IEEventSinker {
var $terminated = false;
function ProgressChange($progress, $progressmax) {
echo "Download progress: $progress / $progressmax\n";
}
function DocumentComplete(&$dom, $url) {
echo "Document $url complete\n";
}
function OnQuit() {
echo "Quit!\n";
$this->terminated = true;
}
}
$ie = new COM("InternetExplorer.Application");
// note that you don't need the & for PHP 5!
$sink = new IEEventSinker();
com_event_sink($ie, $sink, "DWebBrowserEvents2");
$ie->Visible = true;
$ie->Navigate("http://www.example.org");
while(!$sink->terminated) {
com_message_pump(4000);
}
$ie = null;
?>
In the line
com_event_sink($ie, $sink, "DWebBrowserEvents2");
I know the interface used to perform event sink is "DWebBrowserEvents2".
My question is,
Is there anyway that I can view the interface of a COM object?
Since I only got an OCX file with no documentation, I have no idea how to find the interface. Thanks
Related
Until yesterday I was burning my brain trying to switch from a procedural thinking to a OOP thinking; this morning I gave up. I said to my self I wasn't probably ready yet to understand it.
I started then coding in the usual way, writing a function to check if there's the cookie "logged" or not
function chkCookieLogin() {
if(isset($_COOKIE["logged"])) {
$logged = 'true';
$cookieValue = $_COOKIE["logged"];
return $logged;
return $cookieValue;
}
else {
$logged = 'false';
return $logged;
}
}
$result = chkCookieLogin();
if($result == 'true'){
echo $cookieValue;
}
else {
echo 'NO COOKIE';
}
since I run across a problem: I wanted to return two variables ($logged and $cookieValue) instead of just one. I google it and I found this answer where Jasper explains a method using an OOP point of view (or this is what I can see).
That answer opened me a new vision on the OOP so I tried to rewrite what I was trying to achieve this way:
class chkCookie {
public $logged;
public $cookieValue;
public function __construct($logged, $cookieValue) {
$this->logged = $logged;
$this->cookieValue = $cookieValue;
}
function chkCookieLogin() {
$out = new chkCookie();
if(isset($_COOKIE["logged"])) {
$out->logged = 'true';
$out->cookieValue = $_COOKIE["logged"];
return $out;
}
else {
$out->logged = 'false';
return $out;
}
}
}
$vars = chkCookieLogin();
$logged = $vars->logged;
$cookieValue = $vars->cookieValue;
echo $logged; echo $cookieValue;
Obviously it didn't work at the first attempt...and neither at the second and the third. But for the first time I feel I'm at one step to "really touch" the OOP (or this is what I think!).
My questions are:
is this attempt correctly written from the OOP point of view?
If yes, what are the problems? ('cause I guess there's more than one)
Thank you so much!
Credit to #NiettheDarkAbsol for the idea of returning an Array data-type.
Using dependency injection, you can set-up an object like this:
class Factory {
private $Data = [];
public function set($index, $data) {
$this->Data[$index] = $data;
}
public function get($index) {
return $this->Data[$index];
}
}
Then to use the DI module, you can set methods like so (using anonymous functions):
$f = new Factory();
$f->set('Cookies', $_SESSION);
$f->set('Check-Cookie', function() use ($f) {
return $f->get('Cookies')['logged'] ? [true, $f->get('Cookies')['logged']] : [false, null];
});
Using error checks, we can then call the method when and as we need it:
$cookieArr = is_callable($f->get('Check-Cookie')) ? call_user_func($f->get('Check-Cookie')) : [];
echo $cookieArr[0] ? $cookieArr[1] : 'Logged is not set';
I'd also consider adding constants to your DI class, allowing more dynamic approaches rather than doing error checks each time. IE, on set() include a constant like Factory::FUNC_ARRAY so your get() method can return the closure already executed.
You can look into using ternary operators if you're confused.
See it working over at 3v4l.org.
If it means anything, here is an OOP styled approach.
I have a page whit ads, and i set the page currency in "RON" and i convert to show also in "Euro" but in the loop is very slow.. I tried to include the script form other php but stil the same... I tried many currency changer but all have the same problem.. slow the page down.. and if i put the code directly in to the loop then tells me an error: that the class could not be repeated.
here is the php currency what i used:
<?php
class cursBnrXML
{
var $currency = array();
function cursBnrXML($url)
{
$this->xmlDocument = file_get_contents($url);
$this->parseXMLDocument();
}
function parseXMLDocument()
{
$xml = new SimpleXMLElement($this->xmlDocument);
$this->date=$xml->Header->PublishingDate;
foreach($xml->Body->Cube->Rate as $line)
{
$this->currency[]=array("name"=>$line["currency"], "value"=>$line, "multiplier"=>$line["multiplier"]);
}
}
function getCurs($currency)
{
foreach($this->currency as $line)
{
if($line["name"]==$currency)
{
return $line["value"];
}
}
return "Incorrect currency!";
}
}
//#an example of using the cursBnrXML class
$curs=new cursBnrXML("http://www.bnr.ro/nbrfxrates.xml");
?>
You can modify the cursBnrXML class to cache parsed currency so that you do not have to loop over entire collection again each look up.
<?php
class cursBnrXML
{
private $_currency = array();
# keep the constructor the same
# modify this method
function parseXMLDocument()
{
$xml = new SimpleXMLElement($this->xmlDocument);
$this->date=$xml->Header->PublishingDate;
foreach($xml->Body->Cube->Rate as $line)
{
$this->currency[$line["currency"]]=array(
"value"=>$line,
"multiplier"=>$line["multiplier"]
);
}
}
# modify this method too
function getCurs($currency)
{
if (isset($this->_currency[$currency]))
{
return $this->_currency[$currency]['value'];
}
return "Incorrect currency!";
}
}
//#an example of using the cursBnrXML class
$curs=new cursBnrXML("http://www.bnr.ro/nbrfxrates.xml");
?>
I was going through a tutorial, on PHPUNIT i got the tutorial quit well...and do some logins
on my own..
But i went into the web to load a page and submit a value on a real-time page
it works fine... but the issue i have is that after entering the user key ..it submit but it wont wait for the next page
I see similar questions here but none is working-out for me
Pls Can anyone help me.
This is my code
<?php
class TestLogin extends PHPUnit_Extensions_Selenium2TestCase {
public function setUp()
{
$this->setHost('localhost');
$this->setPort(4444);
$this->setBrowser('firefox');
$this->setBrowserUrl('http://localhost/tutor');
}
public function setSpeed($timeInMilliSec)
{
$this->setSpeed('120');
}
/*Function to locate website*/
public function testHasLoginForm()
{
$this->url('http://www.jamb.org.ng/DirectEntry/');/*This is the site*/
$username = $this->byId('ctl00_ContentPlaceHolder1_RegNumber');/*Search for a name*/
##ctl00_ContentPlaceHolder1_txtRegNumber
$action = $this->byId('ctl00_ContentPlaceHolder1_Reprint')->attribute('action');
$this->byId('ctl00_ContentPlaceHolder1_RegNumber')->value('49130518ED');/*value of the textbox*/
$jump = $this->byId('ctl00_ContentPlaceHolder1_Reprint');
$jump->submit();
}
}
?>
You could use
$this->timeouts()->implicitWait(10000);//10 seconds
to set timeout of searching elements on page.
https://github.com/sebastianbergmann/phpunit-selenium/blob/master/PHPUnit/Extensions/Selenium2TestCase/Session/Timeouts.php
Resolved.i just changed
$jump->submit();
to
$this->byName('ctl00$ContentPlaceHolder1$Reprint')->click();
If you want to wait for diffrent elements or even capabilities i suggest use this pattern
This is example wait for element. I recommend using byCssSelector here to get more flexibility.
You can easily use this pattern for example to wait for element to be clickable:
protected function waitForClickable($element, $wait=30) {
for ($i=0; $i <= $wait; $i++) {
try{
$element->click();
return true;
}
catch (Exception $e) {
sleep(1);
}
}
return false;
}
You can even use it in any context passing anonymous function as parameter:
protected function waitForAny($function, $args, $wait=30) {
for ($i=0; $i <= $wait; $i++) {
try{
call_user_func_array($function, $args);
return true;
}
catch (Exception $e) {
sleep(1);
}
}
return false;
}
Usage:
$f = function($e){
$e->click();
};
$this->waitForAny($f, array($element));
I'm trying to make a user friendly way of testing via lime in symfony 1. I want to load a specific sql dump for each test I write (if required). The problem I face is that I don't know how to make dump loading independent of database type. Currently I'm using the shell exec() command. Here is the code :
public function loadSql()
{
$this->diag("Loading dump...");
if ($this->_sql_is_set)
{
if (file_exists($this->_getSqlPath()))
{
$this->_emptyDataBase();
$options = $this->_connection_manager->connection()->getOptions();
$dsn_parts = $this->_connection_manager->parsePdoDsn($options['dsn']);
exec("mysql -u{$options['username']} -p{$options['password']} {$dsn_parts['dbname']} < {$this->_getSqlPath()}");
return $this;
}
else
{
$this->error("Nothing to load : sql file was not found in ".$this->_getDataDir());
exit;
}
}
else
{
$this->error("Nothing to load : sql dump was not set");
exit;
}
}
$this->_connection_manager is an instance of Doctrine_Manager. Any help will with that?
Try with something like that:
public function loadSqlFiles(sfEvent $event)
{
$task = $event->getSubject();
$taskName = $task->getName();
if ($taskName == 'insert-sql') {
$conn = Doctrine_Manager::connection();
$filesPath = sfConfig::get('sf_data_dir') . '/sql/full-data';
// get all files
$files = sfFinder::type('file')->sort_by_name()->name('*.sql')->in($filesPath);
foreach ($files as $file) {
$task->logSection('custom-sql', sprintf('Inserting custom sql file (%s)', $file));
$res = $conn->getDbh()->exec(file_get_contents($file));
}
}
}
The script works fine and is setting the data, but the website code is unable to use it and is instead setting its own memcached values. My website code is written in codeIgniter framework. I don't know why this is happening.
My script code :-
function getFromMemcached($string) {
$memcached_library = new Memcached();
$memcached_library->addServer('localhost', 11211);
$result = $memcached_library->get(md5($string));
return $result;
}
function setInMemcached($string,$result,$TTL = 1800) {
$memcached_library = new Memcached();
$memcached_library->addServer('localhost', 11211);
$memcached_library->set(md5($string),$result, $TTL);
}
/*---------- Function stores complete product page as one function call cache -----------------*/
function getCachedCompleteProduct($productId,$brand)
{
$result = array();
$result = getFromMemcached($productId." product page");
if(true==empty($result))
{
//------- REST CODE storing data in $result------
setInMemcached($productId." product page",$result,1800);
}
return $result;
}
Website Code :-
private function getFromMemcached($string) {
$result = $this->memcached_library->get(md5($string));
return $result;
}
private function setInMemcached($string,$result,$TTL = 1800) {
$this->memcached_library->add(md5($string),$result, $TTL);
}
/*---------- Function stores complete product page as one function call cache -----------------*/
public function getCachedCompleteProduct($productId,$brand)
{
$result = array();
$result = $this->getFromMemcached($productId." product page");
if(true==empty($result))
{
// ----------- Rest Code storing data in $result
$this->setInMemcached($productId." product page",$result,1800);
}
return $result;
}
This is saving data in memcached. I checked by printing inside the if condition and checking the final result
Based on the CodeIgniter docs, you can make use of:
class YourController extends CI_Controller() {
function __construct() {
$this->load->driver('cache');
}
private function getFromMemcached($key) {
$result = $this->cache->memcached->get(md5($key));
return $result;
}
private function setInMemcached($key, $value, $TTL = 1800) {
$this->cache->memcached->save(md5($key), $value, $TTL);
}
public function getCachedCompleteProduct($productId,$brand) {
$result = array();
$result = $this->getFromMemcached($productId." product page");
if( empty($result) ) {
// ----------- Rest Code storing data in $result
$this->setInMemcached($productId." product page",$result,1800);
}
return $result;
}
}
Personally try to avoid 3rd party libraries if it already exists in the core framework. And I have tested this, it's working superbly, so that should fix this for you :)
Just remember to follow the instructions at http://ellislab.com/codeigniter/user-guide/libraries/caching.html#memcached to set the config as needed for the memcache server