Intellij Kubuntu Alt+Backquote VCS Operations Popup

An annoyance with Kubuntu and Intellij where they share the same key mappings disallowing you from opening the VCS Operations Popup. You could change Intellij’s key maps but if you’re working on different platforms at home and work, teaching yourself different key mappings for the same shortcut isn’t ideal.

On Kubuntu (14.04), to change the Alt+Backquote keymap go to System Settings > Window Management > Task Switcher and find the ‘Current application’ area. You choose, either create new mappings or do what I did and set to none. Wallah! Intellij Alt+Backquote now works.

Mysqli Prepared Statements – Debugging/Echoing SQL Queries

Delving into prepared statements for Mysqli, I discovered the first shortcoming of using the ‘improved’ method… debugging your SQL statements. Whilst you can call up the error message that might occur, it’s not possible to echo the sql query with PHP to see what the query is with the bound parameters.

Solution: Turn on mysql query logging (not slow logs).

Here’s how: Locate your my.cnf file (I used the command ‘locate my.cnf’) and open it with your favourite editor. Scroll down to the area in your my.cnf file under the heading [mysqld], section *Logging and replication* (see snippet below).  Uncomment the line that says general_log_file. For added clarity, I changed the location of my log file to /var/log/mysql/query-debug.log rather than the combined /var/log/mysql/mysql.log that was set as my default. You’ll need to create  (touch) the query-debug.log file and change it’s ownership and permissions to match the mysql.log (you’ll need root access to do this).

1
2
3
4
5
6
7
8
#
# * Logging and Replication
#
# Both location gets rotated by the cronjob.
# Be aware that this log type is a performance killer.
# As of 5.1 you can enable the log at runtime!
general_log_file        = /var/log/mysql/query-debug.log
general_log             = 0

Restart mysql to apply this change in your my.cnf.
As I don’t want the logging to be on all the time, I left the general_log as 0 (zero). We can turn this off and on via your PHP script.

Now in your PHP script where you want to debug the SQL query, add the line

1
$mysqli->query("SET GLOBAL general_log = 'ON'");

where $mysqli is your mysql connection object.

Now you can less or tail that log file to see your queries.

I’m using Ubuntu 12.04, PHP v5.3.10 and MySQL v5.5.24 so I’m not sure if this applies directly to other MySQL versions or Linux distributions but it should give you a good idea.

Australian Government ABN Lookup – Webservice – PHP Example

The PHP example code supplied by http://abr.business.gov.au/Webservices.aspx relied on the nuSoap class. I rewrote it to fit our companies needs, based on what I’ve learned from developing the PPSR Soap class I posted earlier. I hope someone finds this useful.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<?php
include(dirname(__FILE__)."/config.inc.php"); // $abn_guid is set here.
 
/**
 * @author Justin Swan - 16 August 2012
 * extends php soap client to utilize the Australian Government ABN Lookup web service 
 * requires php 5 or greater with lib-xml enabled/compiled in Apache, see the PHP manual for further requirements info
 * 
 * @link    http://www.php.net/manual/en/book.soap.php
 * @link    http://abr.business.gov.au/Webservices.aspx
 * 
 * @param string $guid - get a guid id by registering @ http://abr.business.gov.au/Webservices.aspx
 * 
 */
 
class abnlookup extends SoapClient{
 
    private $guid = ""; 
 
    public function __construct($guid)
    {
        $this->guid = $guid;
        $params = array(
            'soap_version' => SOAP_1_1,
            'exceptions' => true,
            'trace' => 1,
            'cache_wsdl' => WSDL_CACHE_NONE
        ); 
 
        parent::__construct('http://abr.business.gov.au/abrxmlsearch/ABRXMLSearch.asmx?WSDL', $params);
    }
 
    public function searchByAbn($abn, $historical = 'N'){
        $params = new stdClass();
        $params->searchString                = $abn;
        $params->includeHistoricalDetails    = $historical;
        $params->authenticationGuid            = $this->guid;
        return $this->ABRSearchByABN($params);
    }
 
    public function searchByName($company_name){
        $params = new stdClass();
        $params->externalNameSearch = $company_name;
        $params->authenticationGuid            = $this->guid;
        return $this->ABRSearchByName($params);
    }
 }
 
$abn_search_string = "11111111111"; // you can assign your post/get var or abn string here
$name_search_string = "some company name"; // replace with the company name you are trying to search
 
try{
    $abnlookup = new abnlookup($abn_guid);
    try{
        $result = $abnlookup->searchByAbn($abn_search_string); 
        // $result = $abnlookup->searchByName($name_search_string); 
 
        // display all results
        echo "<pre>";
        print_r($result);
        echo "</pre>";
 
        // also display by variables using object notation.
        echo "<pre>";
        $result->ABRPayloadSearchResults->response;
        echo "</pre>";
 
    } catch    (Exception $e){
        throw $e;
    }
 
} catch(Exception $e){
    echo $e->getMessage();
}

Now on GitHub: https://github.com/Kwozzie/australian-government-abn-lookup

PPSR Australia – PHP Example

Having trouble finding a good PHP example to use to start registering your vehicles at http://www.ppsr.gov.au/? Then here you go. A few hours of frustration and looking up other peoples code led me to this basic solution to get started.

Big thanks to https://dwuysan.wordpress.com/ for helping me with getting the TargetEnvironment to work.

If you’re having trouble with ‘Server Error’ responses when doing searches and registrations, check that you have sufficient funds in your PPSR account. You can use the dummy credit cards numbers as provided by PPSR (in an email you would have recieved when you were granted access to the Discovery environment) and make a payment via the PPSR discovery website (WebUI).

From PPSR: “Server error is generated whenever you try to perform a billable transaction, if the account is configured as PAYG or has insufficient funds.”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
<?php
include("../config.inc.php"); // contains $username and $password
 
class WsseAuthHeader extends SoapHeader {
 
    private $wss_ns = "";
 
    public function __construct($user, $pass, $ns = null) {
        if ($ns) {
            $this->wss_ns = $ns;
        }
 
        $auth = new stdClass();
        $auth->Username = new SoapVar($user, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns);
        $auth->Password = new SoapVar($pass, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns);
 
        $username_token = new stdClass();
        $username_token->UsernameToken = new SoapVar($auth, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns);
 
        $security_sv = new SoapVar(
                        new SoapVar($username_token, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns),
                        SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'Security', $this->wss_ns);
 
        parent::__construct($this->wss_ns, 'Security', $security_sv, true);
    }
}
 
class ppsrSoapClient extends SoapClient{
 
    private        $wsdl;
    private        $wss_ns;
    private        $ppsr_ns;
    private        $params;
    private        $environment;
    private        $username;
    private        $password;
 
    public function __construct($environment,$username,$password)
    {
        $this->wsdl            = "schemas.ppsr.gov.au.2011.04.services.wsdl";
        $this->wss_ns        = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
        $this->ppsr_ns        = "http://schemas.ppsr.gov.au/2011/04/services";
        $this->environment    = $environment;
        $this->username        = $username;
        $this->password        = $password;
        $this->params = array(
            'soap_version' => SOAP_1_1,
            'exceptions' => true,
            'trace' => 1,
            'cache_wsdl' => WSDL_CACHE_NONE,
            'targetenvironment' => $this->environment
        ); 
        parent::__construct($this->wsdl, $this->params);
 
        // save us manually calling this each time.
        $this->setSoapHeaders();
    } 
 
    private function setSoapHeaders(){
        $headers = array();
        $headers[1] = new WsseAuthHeader($this->username, $this->password, $this->wss_ns);
        $headers[2] = new SoapHeader($this->ppsr_ns,'TargetEnvironment',$this->environment,true);    
        $this->__setSoapHeaders($headers);
    }
 
    public function getUsername(){
        return $this->username;
    }
}
 
//Put the service parameters here
try{
    $client = new ppsrSoapClient('Discovery',$username,$password);
    try {
        $result = $client->Ping(array("PingRequest"=>array("CustomersRequestMessageId"=>date("Ymdhisu").__LINE__)));
 
        /*
        $vars = array(
            "CustomersRequestMessageId"=>date("Ymdhisu").__LINE__,
            "Username"=>$client->getUsername(),
            "NewPassword"=>"Newpassword1!" // no spaces, 7-15 characters, 1 x uppercase, 1 x number, 1 x special char, different from last 8 passwords
        );
        $result = $client->ChangeB2GPassword(array("ChangeB2GPasswordRequest"=>$vars));        
        */
 
        echo "<pre>";
        print_r($result);
        echo "</pre>";
 
    } catch (Exception $e) {
        echo "<h1>Exception</h1>";
        echo $e->getMessage();
 
        echo "<h1>Debugging Info</h1>";
        echo "<p>REQUEST HEADERS:\n<pre>" .$client->__getLastRequestHeaders() . "</pre>\n</p>";
        echo "<p>REQUEST:\n<pre>" .$client->__getLastRequest(). "</pre>\n</p>";
 
        echo "<p>RESPONSE HEADERS:\n<pre>" .$client->__getLastResponseHeaders() . "</pre>\n</p>"; 
        echo "<p>RESPONSE:\n<pre>" . $client->__getLastResponse() . "</pre>\n</p>";    
    }
} catch (Exception $e) {
    echo $e->getMessage();
}

Please note, I no longer have access to the PPSR development environment, and this example is now quite old code. There have likely been changes to the PPSR system that this code doesn’t cater for.

Please do not ask me to complete/fix your code, I keep my time outside of work hours reserved for self and family.

YouTube iframe video stays above overlays

I had a YouTube video staying on top of a jQuery lightbox overlay and knew from past experience that it requires setting the wmode = opaque. You can use transparent but opaque is apparently faster (see http://stackoverflow.com/questions/886864/differences-between-using-wmode-transparent-opaque-or-window-for-an-embed).

The problem was, YouTube videos are now being embedded via an iframe and I wasn’t sure how to go about getting the embed code to use the wmode setting.
I found an answer on YouTube itself from 360creations. All good. Just add &wmode=transparent to the end of the YouTube URL, that’s easy, except our administrators add the YouTube embed code (pulled from YouTube without the wmode code added) via an admin section and I needed a way to automate adding this using PHP.

Quick solution:

1
2
3
4
$youtube_embed_code = '<iframe src="http://www.youtube.com/embed/hTCAeGIBaxw" frameborder="0" width="560" height="345"></iframe>';
$patterns[] = '/youtube.com\/embed\/([a-zA-Z0-9._-]+)/';
$replacements[] = 'youtube.com/embed/$1?wmode=transparent"';
echo preg_replace($patterns, $replacements, $youtube_embed_code));