Lithium: Can we see queries executed as shown in CakePHP - debugging

Do you know of any method to show the queries being executed in Lithium as it does in CakePHP.
It may become easier for me to find what is executed.
At the bottom of the page it shows the queries executed.
![The screen shot] http://imgur.com/ffNfQ
After I received the answer, I added the code to my controller:
Volumes::applyFilter('find', function($self, $params, $chain) {
echo '<pre>===== self ======<br>';
var_dump($self);
echo '===== params ======<br>';
var_dump($params);
echo '===== chain ======<br>';
var_dump($chain);
echo '</pre>';
$next = $chain->next($self, $params, $chain);
return $next;
});
It gives me an output as to all var_dump of self and params, but I require the SQL query which gets executed.
Please check the screen shot http://imgur.com/ffNfQ

as #Nils suggested, you can leverage Lithium filters and write a simple queries logger.
I made one here. It logs the read queries to a file on a production environment.
You should be able to customize, and add filters on create, update and delete operations to fit your needs.
If you are looking to an out-of-the-box solution like Cake's debug toolbar, check the li3_perf project: https://github.com/tmaiaroto/li3_perf

You can do this by adding filters to the types of queries you wish to log. You can define them globaly in the bootstrap files our you can define them "localy" in the controllers. The example bellow does not print the query nice, however that is pretty easy to do when you have the data.
The code bellow shows how to get the information, it does not output it in a pretty way.
Connections::get('default')->applyFilter('read', function($self, $params, $chain) {
echo "===========</br>\n";
if (is_object($params['query'])){
var_dump($params['query']->conditions());
}
else{
echo 'Query: '; var_dump($params['query']); echo "</br>\n";
}
$time = microtime(true);
$next = $chain->next($self, $params, $chain);
$time = microtime(true) - $time;
echo "Results: " . count((array)$next) . "</br>\n";
echo "Time: " . $time . "</br>\n";
return $next;
});
Please note that echo it the data directly from the filter will render your page useless as this will be printed before headers. However if you save the data in the filter to an array instead of outputting it you can use it later in your views. And you can for instance make a template to add this information to the page.
Edit: updated code
Edit2: added a way to always get the exact SQL that is executed. To get the
Connections::get('default')->applyFilter('_execute', function($self, $params, $chain) {
echo "SQL: " . $params['sql'] . "</br>\n";
$time = microtime(true);
$next = $chain->next($self, $params, $chain);
$time = microtime(true) - $time;
$count = 0;
while ($next->next())
$count++;
$next->rewind();
echo "Count: " . $count . "</br>\n";
echo "Time: " . $time . "</br>\n";
echo "=====================</br>\n";
return $next;
});

Based on all the suggestions by Nils and Mehdi I created a fresh plugin which will only show the query results and not the vardump or print_r() for the queries executed in Lithium with MongoDB.
It really now has become easier for me to find what it being executed.
You can take a look at the project at Github:
https://github.com/nilamdoc/li3_show

Related

How to create a torrent without tracker on Transmission?

I'm trying to create a torrent without a tracker. I just want to send some GoPro footage to a friend of mine but I can't get it working.
I've created a torrent with nothing in the tracker field and set the torrent to public, private is unchecked. I sent myself the file to test downloading it on another computer.
I can't get it to work. I've opened my port, when I run the test, it says the port's open on both my laptop and desktop. I've got a static IP on the desktop which is where the torrent was created and is being shared, and I emailed it to myself. I'm running Transmission on both, but one is Windows and one is Mac.
Any ideas why I can't get it to work? DHT is enabled on both.
Transmission is not the best option for that i advice you to use mktorrent faster and more reliable all my time using it it never failed
but if you want to use transmission as a seeder or a uploader client you can use this php script and just edit it to save the torrent files in transmission watch folder or any folder that you want
<?php
define('ROOT_DIR', '/home');
define('SCAN_DIR', ROOT_DIR.'/scan');
define('COMPLETE_DIR', ROOT_DIR.'/complete');
define('TORRENT_DIR', ROOT_DIR.'/torrent');
define('ANNOUNCE_URL', 'YOUR-TRACKER-ANNOUNCE-AND-PASSKEY-HERE');
define('PIECE_SIZE', '21');
function move($source, $dest) {
$cmd = 'mv "'.$source.'" "'.$dest.'"';
exec($cmd, $output, $return_val);
if ($return_val == 0) return 1;
return 0;
}
function make_torrent($file_full, $new_dir, $file) {
$file = pathinfo($file_full, PATHINFO_BASENAME);
$move_file = $new_dir.'/'.$file;
$rez = move($file_full, $move_file);
if (!$rez) die('Cannot move file!');
$info = pathinfo($file);
$output = TORRENT_DIR.'/'.$info['basename'].'.torrent';
if (file_exists($output)) unlink($output);
$cmd = "mktorrent '$move_file' -o '$output'-l".PIECE_SIZE." -a ".ANNOUNCE_URL;
echo $cmd."<br /> <br /> \n \n";
exec($cmd);
if (file_exists($output)) return $output;
else die('Cannot make torrent!');
}
function scan_folder() {
$dir = SCAN_DIR;
$dir_done = COMPLETE_DIR;
if (!is_dir($dir_done))
{
$ok = mkdir($dir_done);
if (!$ok) die('Cannot create destination folder!');
}
$dh = opendir($dir);
while ( $file = readdir($dh) )
{
if ($file == '.' || $file == '..') continue;
$file_full = $dir.'/'.$file;
if ($file_full == COMPLETE_DIR) continue;
make_torrent($file_full, $dir_done, $file);
}
}
scan_folder();
?>
you can ignore the tracker lines or just delete them the script is more or less self explanatory if you need any help please ask away
iCODEiT 0UT

Magento foreach() orders getAllItems()

I am not sure why this loop is not working.
$orders = Mage::getSingleton('sales/order')->getCollection()
->addAttributeToSelect('*')
->addFieldToFilter('created_at', array('from'=>$from, 'to'=>$to))
->addAttributeToSort('increment_id', 'ASC')
;
foreach ($orders as $item) {
$order_id = $item->increment_id;
if (is_numeric($order_id)) $order = Mage::getModel('sales/order')->loadByIncrementId($order_id);
if (is_object($order)) {
echo "> O: ". $order_id ."<BR>";
$items = $order->getAllItems();
echo ">> O: ". $order_id ."<BR>";
} else
die("DIE ". var_dump($order));
}
die("<BR> DONE");
The output:
...
...
>> O: 100021819
> O: 100021820
>> O: 100021820
> O: 100021821
The loop never finishes nor does it stop at the same order_id.?
It always fails at $order->getAllItems()
These orders are either pending, processing or complete.
Is there something I should be checking for with $order->getAllItems(), since that's were it's failing.
Thanks.
Jon, I assume the problem you're talking about is your script ending un expectedly. i.e., you see the output with a single >
> O: 100021821
but not the output with the double >>.
Because Magento is so customizable, it's impossible to accurately diagnose your problem with the information given. Something is happening in your system, (a PHP error, an uncaught exception, etc.), that results in your script stopping. Turn on developer mode and set the PHP ini display_errors to 1 (ini_set('display_errors', 1);) and check your error log. One you (or we) have the PHP error, it'll be a lot easier to help you.
My guess is you're running into a memory problem. The way PHP has implemented objects can lead to small memory leaks — objects don't clean up after themselves correctly. This means each time you go through the loop you're slowly consuming the total amount of memory that's allowed for a PHP request. For a system with a significant number of orders, I'd be surprised if the above code could get through everything before running out of memory.
If your problem is a memory problem, there's information on manually cleaning up after PHP's objects in this PDF. You should also consider splitting your actions into multiple requests. i.e. The first request handles orders 1 - 100, the next 101 - 200, etc.
What do you mean it fails?
By the look of the output it doesn't fail there as it outputs text either side of the call to getAllItems()
change:
$items = $order->getAllItems();
to:
foreach($order->getAllItems() as $orderItem) {
echo $orderItem->getId() . "<br />";
}
and see what happens.
The script could be ending on a different order ID each time if you have a low memory limit set on the server and it quits when it runs out of resources.

Codeigniter's XML-RPC shows no response data

I'm attempting to connect to an XML RPC server with no luck, I am getting an empty response with no debugging information whatsoever. I've switched on set_debug(), but still nothing.
Can anyone tell me why I am getting no response from the server, no error information and no debug information?
$this->load->library('xmlrpc');
$this->xmlrpc->set_debug(TRUE);
$this->xmlrpc->server('https://myurl.com/xmlrpc', 80);
$this->xmlrpc->method('login');
$request = array('param1', 'param2');
$this->xmlrpc->request($request);
echo 'Error: '. $this->xmlrpc->display_error() . '<br/>';
echo 'Response: '. print_r($this->xmlrpc->display_response(), true) . '<br/>';
Even if you type https:// in server method you are still connecting with server via http, look at 2nd parameter - the port you have set is 80.
Just in case.
I forgot to use:
$this->xmlrpc->send_request()
its best used in a conditional statement like:
if ( ! $this->xmlrpc->send_request())
{
echo $this->xmlrpc->display_error();
}
else
{
echo '<pre>';
print_r($this->xmlrpc->display_response());
echo '</pre>';
}

PHP parse error in rss parse function

I have a client who needs a website urgently, but I have no access to information such as the control panel.
PHP Version is 4.4 Which is a pain as I'm used to 5.
The first problem is I keep getting:
Parse error: parse error, unexpected T_OBJECT_OPERATOR, expecting ')' in D:\hshome\*******\********\includes\functions.php on line 37
This is the function in question:
function read_rss($display=0,$url='') {
$doc = new DOMDocument();
$doc->load($url);
$itemArr = array();
foreach ($doc->getElementsByTagName('item') as $node) {
if ($display == 0) {
break;
}
$itemRSS = array(
'title'=>$node->getElementsByTagName('title')->item(0)->nodeValue,
'description'=>$node->getElementsByTagName('description')->item(0)->nodeValue,
'link'=>$node->getElementsByTagName('link')->item(0)->nodeValue);
array_push($itemArr, $itemRSS);
$display--;
}
return $itemArr;
}
And the line in question:
'title'=>$node->getElementsByTagName('title')->item(0)->nodeValue,
PHP4 does not support object dereferencing. So $obj->something()->something will not work. You need to do $tmp = $obj->something(); $tmp->something...
You can't do that in PHP 4.
Have to do something like
$nodes = $node->getElementsByTagName('title');
$item = $nodes->item(0);
$value = $item->nodeValue,
Try it and it will work.
You can't chain object calls in PHP 4. You're going to have to make each call separately to a variable and store it all.
$titleobj = $node->getElementsByTagName('title');
$itemobj = $titleobj->item(0);
$value = $itemobj->nodeValue;
...
'title'=>$value,
you'll have to do it on all those chained calls
As for .htaccess ... you need to talk to someone who controls the actual server. It sounds like .htaccess isn't allowed to change the setting you're trying to change.
You need to break down that line into individual variables. PHP 4 does not like -> following parentheses. Do this instead:
$title = $node->getElementsByTagName('title');
$title = $title->item(0);
$description = $node->getElementsByTagName('description');
$description = $description->item(0);
$link = $node->getElementsByTagName('link');
$link = $link->item(0);
$itemRSS = array(
'title'=>$title->nodeValue,
'description'=>$description->nodeValue,
'link'=>$link->nodeValue);
The two variable declarations for each may be redundant and condensed, I'm not sure how PHP4 will respond. You can try to condense them if you want.
DOMDocument is php 5 function.You cant use it.
you may need to use DOM XML (PHP 4) Functions

How can I automate an existing instance of Internet Explorer using Perl?

I am struggling to get control of an IE preview control which is 'Internet Explorer_Server' class on an external windows application with perl.
Internet Explorer_Server is the class name of the window, I've found it with Spy++. and here’s my assertion code of it
$className = Win32::GUI::GetClassName($window);
if ($className eq "Internet Explorer_Server") {
...
}
I can get a handle of that 'Internet Explorer_Server' with Win32::GUI::GetWindow, but have no idea what to do next.
Updated: You are going down the wrong path. What you need is Win32::OLE.
#!/usr/bin/perl
use strict;
use warnings;
use Win32::OLE;
$Win32::OLE::Warn = 3;
my $shell = get_shell();
my $windows = $shell->Windows;
my $count = $windows->{Count};
for my $item ( 1 .. $count ) {
my $window = $windows->Item( $item );
my $doc = $window->{Document};
next unless $doc;
print $doc->{body}->innerHTML;
}
sub get_shell {
my $shell;
eval {
$shell = Win32::OLE->GetActiveObject('Shell.Application');
};
die "$#\n" if $#;
return $shell if defined $shell;
$shell = Win32::OLE->new('Shell.Application')
or die "Cannot get Shell.Application: ",
Win32::OLE->LastError, "\n";
}
__END__
So, this code finds a window with a Document property and prints the HTML. You will have to decide on what criteria you want to use to find the window you are interested in.
ShellWindows documentation.
You may want to have a look at Win32::IE::Mechanize. I am not sure whether you can control an existing IE window with this module, but accessing a single URL should be possible in about five lines of code.
Have you looked at Samie http://samie.sourceforge.net/ as this is a perl module to control IE

Resources