Logaholic.de

Avatar

web development

Communicate in Real-Time with online visitors

I really like the LiveChat solution from Livechatinc, it is very easy to integrate into existing projects and the javascript api allows you to enrich the chat session data with whatever you want to identify users, requests or processes. Also included is a ticketing solution as well as tracking and measuring.

LiveChat is an online chat solution that helps you connect with your customers on your website. When using LiveChat, you can see in real time the way visitors behave and approach them on each step of the buying process. This allows you to easily provide instant help and, in result, increase your conversion rates.

LiveChat comes with a ticketing system built into the application. The ticketing system allows you to receive customer queries when you are offline. By creating tickets from your chats, you can stay in touch with customers when you need some time to deal with their cases. You can also receive your support emails as tickets and handle them in one place.

LiveChat comes in three packages tailored to the needs of small, medium and big companies.

With LiveChat, you won’t miss any opportunities to contact your clients. Sign up now for a free 30-day trial. Sign up now

This is what you see from the LiveChat interface as support agent:

Live Chat chat page

How to add transparent SoapHeader authentication as decorator to any existing service class

This should not be limited to it, but I’d like to show how I implemented this inside the Zend Framework and its Zend_Soap_* components.

SoapHeader authentication is a widely used method to secure access to soap Webservices where the credentials are in the request header.

Activating this type of authentication is for me down to a change from this:

$soap = new Zend_Soap_Server($uri.'&wsdl', $serverOptions);
$soap->setClass('My_Service_'.$serviceName);

to this:

$soap = new Zend_Soap_Server($uri.'&wsdl', $serverOptions);
$soap->setClass('My_Soap_Decorator_Secure', 'My_Service_'.$serviceName);

This is the basic decorator code:

/**
 * This class decorates Soap service classes, provides and enforces authentication via soap header 'authenticate'
 *
 * @author Karsten Deubert <karsten@deubert.net>
 */
class My_Soap_Decorator_Secure
{
    /**
     * @var bool
     */
    protected $_authenticationHeaderPresent = false;

    /**
     * @var mixed
     */
    protected $_authenticatedUser = null;

    /**
     * @var mixed
     */
    protected $_serviceClass = null;

    public function __construct($class)
    {
        if (!class_exists($class))
        {
            throw new Exception('invalid class: '.$class);
        }
        $this->_serviceClass = new $class();
    }

    /**
     * @param mixed $data
     * @return void
     */
    public function authenticate($data)
    {
        $this->_authenticationHeaderPresent = true;

        // authentication code which checks if credentials are valid

        $this->_authenticatedUser = $yourAuthenticatedUser;
    }

    public function __call($name, $arguments)
    {
        if (!$this->isAuthenticationHeaderPresent() || is_null($this->_authenticatedUser))
        {
            throw new Exception('authentication failed');
        }
        if (!is_callable(array($this->_serviceClass, $name)))
        {
            throw new Exception('invalid service class method');
        }

        return call_user_func_array(array($this->_serviceClass, $name), $arguments);
    }
}

The usual soap request with authentication header should now look like this:

$authData = new stdClass();
$authData->user = 'foo';
$authData->secret = 'bar';

$authHeader = new SoapHeader($namespace, 'authenticate', $authData);

$soapClient = new SoapClient('http://foo.bar/asdf?wsdl',
    array(
        'cache_wsdl' => 0,
        'soap_version' => SOAP_1_1
    )
);
$soapClient->__setSoapHeaders(array($authHeader));
$soapClient->fooMethod();

With this header the soap server will first execute the authenticate method from the decorator, then (if successful) pass the method call via magic __call to the inner service class and its fooMethod() in this example.

Voila, transparent SoapHeader authentication separated from your service classes ;)

What I haven’t researched fully yet is if there is a way to specify the authenticate header in the WSDL – every comment appreciated.

How to fail ant builds with xbuild

While setting up a new mono (C# with xbuild) project with ant as build tool I discovered that xbuild always exits with return code 0.

Exit code 0 should always stand for “process finished, everything went fine” – ant consequently concludes that every xbuild run is a success… which is not always true.

Since I need that information to control wether to perform further steps in the project (auto-deployment to test system) or not, I am now scanning the xbuild output for “Build FAILED.” like this in my ant build.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project name="foobar" default="build" basedir=".">
    <target name="xbuild">
        <exec executable="xbuild" failonerror="true" dir="${basedir}" vmlauncher="false" outputproperty="xbuild.output" />
        <echo message="${xbuild.output}" />
    </target>

    <target name="failbuild-on-error">
        <fail message="Build Failed">
            <condition>
                <contains string="${xbuild.output}" substring="Build FAILED." />
            </condition>
        </fail>
    </target>

    <target name="build" depends="xbuild,failbuild-on-error"/>
</project>

Zend_MVC, Controller Plugins and Annotations

While it is common practice in many enterprise grade environments to use annotations to not only document but also influence code, I am missing some of this goodness in Zend Framework MVC (1.x) applications.

Recently I had the idea to influence Controller Actions with annotations but discarded it with thoughts like “In PHP I will have to use reflection and some black magic to get this working which will have insane performance hits for my applications”.
… until I set everything up to see that it costs just 1-2ms in average per request without any form of caching.

As example this is code I use to set the used layout script via @layout annotation:

Before:

public function fooAction()
{
    $this->_helpers->layout->setLayout('bar');
    //...
}

After:

/**
 * @layout bar
 */
public function fooAction()
{
    //...
}

Abstract Class (reflection = php5.3) to get the action’s docblock

This needs more work to reflect the configurable module/controller directory and prefixDefaultModule Zend_MVC settings – this may not work for you out of the box.

/**
 * @author Karsten Deubert <karsten@deubert.net>
 */
abstract class My_Controller_Plugin_Annotation_Abstract extends Zend_Controller_Plugin_Abstract
{
    /**
     * @return string
     */
    protected function _getDocblockForControllerAction()
    {
        /** @var $request Zend_Controller_Request_Http */
        $request = $this->getRequest();

        $frontController = Zend_Controller_Front::getInstance();

        /** @var $dispatcher Zend_Controller_Dispatcher_Standard */
        $dispatcher = $frontController->getDispatcher();

        $controllerName =
            ucfirst($dispatcher->formatModuleName($request->getModuleName()))
            .'_'
            .$dispatcher->formatControllerName($request->getControllerName());

        $controllerPath =
            $frontController->getModuleDirectory($request->getModuleName())
            .DIRECTORY_SEPARATOR
            .$frontController->getModuleControllerDirectoryName()
            .DIRECTORY_SEPARATOR
            .$dispatcher->formatControllerName($request->getControllerName())
            .'.php';

        require_once $controllerPath;

        $actionName = $dispatcher->formatActionName($request->getActionName());

        $reflectionClass = new ReflectionClass($controllerName);
        if (!$reflectionClass->hasMethod($actionName))
        {
            return '';
        }

        $reflectionMethod = $reflectionClass->getMethod($actionName);

        $docBlock = $reflectionMethod->getDocComment();
        return $docBlock;
    }
}

Controller Plugin code:

/**
 * @author Karsten Deubert <karsten@deubert.net>
 */
class My_Controller_Plugin_Annotation_Layout extends My_Controller_Plugin_Annotation_Abstract
{
    /**
     * @param Zend_Controller_Request_Abstract $request
     * @return void
     */
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        /** @var $request Zend_Controller_Request_Http */
        if (!$request instanceof Zend_Controller_Request_Http)
        {
            return;
        }

        $docBlock = $this->_getDocblockForControllerAction();

        $pattern = '#@layout (\S+)#iu';

        $matches = array();
        $matchesCount = preg_match($pattern, $docBlock, $matches);

        if (!$matchesCount)
        {
            return;
        }

        $layout = Zend_Layout::getMvcInstance();

        if ($matches[1] === 'disabled')
        {
            $layout->disableLayout();
        }
        else
        {
            $layout->setLayout($matches[1]);
        }
    }
}

I have several Annotation Controller Plugins in place for very different purposes and… love them!

PHP 5.3.1 and SoapHeader on windows getting ignored

Today I spent a decent amount of time to realise that PHP 5.3.1 and its SoapServer doesn’t handle provided SoapHeaders as it should. If you provide a SoapHeader named ‘authenticate’ the corresponding method ‘authenticate’ should get executed before any other method – but seems to be ignored with the specified version (on windows using XAMPP).

After upgrading to PHP 5.3.5 (as in the latest XAMPP package) everything works as expected.

You are what you read

279038_1921708527789_1394340376_31755266_5688486_o

Who are you?

,