Multiplay Labs

tech hits and tips from Multiplay

Archive for the ‘PHP’ Category

Integrating Legacy PHP applications with WordPress

with 2 comments

Recently we wanted to integrate some existing legacy code into a new wordpress site we were developing. Obviously, we didn’t want to have to reimplement all the code for the wordpress theme separately in a standalone way just to make the two codebases visually consistent, so we looked into how to integrate the two, allowing us to make use of the wordpress theme within the new code.

This turned out to be surprisingly simple, albeit with a few caveats.

First of all, we made sure the legacy codebase had access to the wordpress installation. Next, in our main include in the legacy code (a setup/config script known to always be included), we added the following code:

require( "{$_SERVER['DOCUMENT_ROOT']}/wordpress/wp-load.php" );

This causes all pages in the legacy app to load the wordpress framework. Contrary to instructions on the WordPress Codex (which direct you to require wp-blog-header.php) this serves the page correctly, rather than as a wordpress 404 page. Obviously, you should adjust the require path to match your own environment.

Once this was done, in the legacy applications header and footer includes, we could use wordpress functions such as get_header() and get_footer() to include the parts of the theme we needed.

However, there are some caveats to this approach when integrating with legacy codebases. We found that the database connection of wordpress was overriding the database connection established by our legacy application. Since they had different permissions, the legacy application failed to perform any of it’s queries. A quick hack of resetting the connection back to the app after rendering the header, then restoring the wordpress connection prior to rendering the future fixes this. Obviously the correct solution is to update the legacy app to use a specific database connection object rather than the default of the last connection established, but this isn’t always feasible for some projects due to the time/resources involved.

Written by Andrew Montgomery-Hurrell

July 11th, 2013 at 8:19 am

Posted in PHP,Wordpress

Tagged with ,

SSL errors using PayPal Sandbox in the PHP-SDK

without comments

Recently we’ve been working on some payment related code and found that communication with PayPal’s Sandbox was constantly failing due to SSL related errors, such as these:

curl_exec error 35 error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
curl_exec error 60 SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

As a result, we couldn’t test any code properly which led to a lot of frustration. As it turns out, we weren’t alone in this.

After trying to figure things out, testing our certificates and verifying everything was setup correctly we eventually realised that the PayPal PHP SDK actually has a mistake in it, and specifies the incorrect endpoints for their sandbox when using the API Signature communications method.

On page 25 of their API reference document (PDF) actually specifies the the API Signature and the API Certificate methods on the sandbox should be the same:

But this is not the case, an assertion I make supported by a different set of documentation on the PayPal site.

Fixing the Issue

The entries in the SDK you download are actually wrong so we edited our PayPal SDK files (PayPal/wsdl/paypal-endpoints.php) to point as the correct endpoints specified in the latter document and everything worked fine.

Written by Andrew Montgomery-Hurrell

October 29th, 2012 at 10:43 am

Posted in PHP

Tagged with , , ,

Updated contextual help in WordPress

without comments

If you’re like me and you try to be a good citizen when it comes to writing wordpress plugins, then you’ll write some contextual help/documentation for them that shows up in the appropriate places of the wordpress admin interface.

Since the wordpress 3.3.1 update however, the previous method I used of doing this resulted in the help permanently appearing on the pages in question. When you have a lot of plugins and a lot of help text, that can result in the actual admin interface being several full page scrolls away, which can be pretty annoying.

As such, I recently worked out how to quickly adapt the old simple style of adding contextual help to make use of the newer system.

Before:

// add some contextual help in for add/edit post admin pages
add_action('load-post-new.php', 'myplugin_help');
add_action('load-post.php', 'myplugin_help');
 
function myplugin_help() {
   add_filter('contextual_help','load_myplugin_help');
}
 
function load_myplugin_help($help) {
    echo $help;
    echo "My custom plugin help";
}

After:

// add some contextual help in for add/edit post admin pages
add_action('load-post-new.php', 'myplugin_help');
add_action('load-post.php', 'myplugin_help');
 
function myplugin_help() {
   add_filter('contextual_help','load_myplugin_help');
}
 
function load_myplugin_help($help) {
    get_current_screen()->add_help_tab( array(
        'id'        => 'myplugin-help',
        'title'     => __('My Plugin Help'),
        'content'   => "Help for my plugin"
    ) );
}

The benefit of this new way is that the new system nicely sorts all the help into little menus, so rather than having all of your help on one massive page, the help dropdown at the top of the admin interface provides a menu for each plugin, allowing the help section to take up less space and generally be more usable.

Written by Andrew Montgomery-Hurrell

January 16th, 2012 at 2:56 pm

Posted in Code,PHP,Wordpress

Tagged with

php Segmentation fault (core dumped) in xmlFreeMutex

without comments

Having just rebuilt a clean install of php 5.3.6 it was crashing left right and center even a php -m caused it.

The stack looks like the following under gdb

#0 0x0000000103db8600 in ?? ()
#1 0x0000000100ce1a95 in xmlFreeMutex () from /usr/local/lib/libxml2.so.5
#2 0x0000000100ce14d5 in xmlCleanupGlobals () from /usr/local/lib/libxml2.so.5
#3 0x0000000100c79f4a in xmlCleanupParser () from /usr/local/lib/libxml2.so.5
#4 0x000000000044daa8 in php_libxml_shutdown ()
#5 0x000000000044dad9 in zm_shutdown_libxml ()
#6 0x000000000055289f in module_destructor ()
#7 0x0000000000559be4 in zend_hash_apply_deleter ()
#8 0x0000000000559e58 in zend_hash_graceful_reverse_destroy ()
#9 0x000000000054dfc8 in zend_shutdown ()
#10 0x00000000004fbb9a in php_module_shutdown ()
#11 0x00000000005d55e2 in main ()
#12 0x0000000000417125 in _start ()

The problem is being caused by libxml2 under FreeBSD being compiled as threaded by default where as php isn’t.

The fix is simple select the LINKTHR option from make config and recompile php and its modules to be safe 🙂

Written by Dilbert

June 16th, 2011 at 11:47 am

Posted in FreeBSD,PHP

PHP class_exists fails to return for missing dependent classes

without comments

If you call class_exists( $sClass ) which in turn triggers an autoloader that fails to load a dependent class of $sClass e.g. where $sClass extends a missing class, then class_exists fails silently and never returns.

Note this only fails on missing dependent classes if the original class fails to load then class_exists returns false as expected.

The following code demonstrates the bug:
AutoLoader.php:

<?php
class AutoLoader
{
    // Public Methods
    public static function factory( $sClass )
    {
        error_log( "factory: $sClass" );
        if ( class_exists( $sClass ) )
        {
            error_log( "Class Exists" );
            return new $sClass;
        }
        error_log( "Failed to autoload: $sClass" );
        return null;
    }
    public static function autoload( $sClass )
    {
        // NOTE: its unclear if the return codes of autoload functions are ever used?
        error_log( "autoload: $sClass" );
        if ( class_exists( $sClass, false ) )
        {
            error_log( "Already loaded" );
            return true;
        }
        error_log( "including: $sClass" );
        $iRet = @include_once( "$sClass.php" );
        error_log( "included: $iRet for $sClass, " . class_exists( $sClass, false ) );
 
        return class_exists( $sClass, false );
    }
}
 
// Register our Autoloader
spl_autoload_register( array( 'AutoLoader', 'autoload' ) );
 
$oMyClass = AutoLoader::factory( 'MyClass' );
if ( $oMyClass )
{
    error_log( "Got object:" . get_class( $oMyClass ) );
}
else
{
    error_log( "Failed to load 'MyClass'" );
}
?>

MyClass.php

<?php class MyClass extends MyBaseClass {} ?>

This bug is registered here: http://bugs.php.net/bug.php?id=53036

Written by Dilbert

October 10th, 2010 at 4:22 pm

Posted in Code,PHP

PayPal PHP SOAP Interface Memory Leak Fix

without comments

Due to the fact that the PayPal SOAP interface relies heavily on exceptions within pear its call to backtrace quickly causes a significant memory leak resulting in long running processes exiting with something like:
PHP Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 13 bytes) in /usr/local/share/pear/PEAR.php on line 884

Fortunately the fix is quite simple:-

--- /usr/local/share/pear.old/PEAR.php.orig     Tue Feb  2 18:47:42 2010
+++ /usr/local/share/pear.old/PEAR.php  Tue Feb  2 23:24:45 2010
@@ -860,7 +862,7 @@
         $this->userinfo  = $userinfo;
         if (function_exists("debug_backtrace")) {
             if (@!PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) {
-                $this->backtrace = debug_backtrace();
+                $this->backtrace = debug_backtrace( false ); // Don't populate the object reference as this causes circular reference and hence memory leak
             }
         }
         if ($mode & PEAR_ERROR_CALLBACK) {

Written by Dilbert

October 4th, 2010 at 4:24 pm

Posted in Code,PHP