Tag Archives: plugin

How to Get the Device’s Phone Number Using PhoneGap Android

I was a bit surprised when three people asked me how to do this in one day. I figured if there was enough interest in it then maybe it deserved a post of it’s own. Basically you want to know the primary phone number of the device your app is running on. In order to do that in PhoneGap you will need to write a plugin to access the TelephonyManager service on Android.

As always the code for this plugin is is GitHub at myTelephoneNumberPlugin repo. If you’d rather have a more detailed walk through please read on.
First up let’s code our JavaScript interface which we will use to get the telephone number. We’ll setup a new interface at”cordova/plugin/telephonenumber” to avoid name collisions. Then the rest is fairly boiler plate code where we declare and error object that we won’t even use and finally provide a get method. When you call the get method you should provide a success callback. The success callback will be invoked with a string that will contain the devices phone number. If something goes wrong the failure callback will be invoked.

Full source at Simon Mac Donald

Understanding the stack index for Zend Framework Controller plugins

Simon R Jones writes a very helpful article about the stack index (the order you fire plugins) and how to customize it;

Zend Framework Controller plugins are a powerful way to inject logic into your controller system at various points, such as before and after an action dispatch. Plugins are run in the order they are added, though it is possible to change the order by defining a custom stack index. ZF internal plugins such as Zend_Controller_Plugin_ErrorHandler, which displays a nice Error 404 page, has a stack index of 999 to ensure it runs at the end of any plugin cycle. However, it’s not so obvious from the ZF manual how to set a custom stack index.

For example, you may have a common admin system layout that does various things to your admin page layout before the page is displayed…

more at simon r jones.

Zend Framework: Module Specific Layout Plugin

Graham Anderson posted an useful workaround for the module specific layout problem;
The default layout plugin will accept a stack of paths in LIFO order.
This allows a very simple hack to always ensure that any module can have it’s own default layout which will automatically override the default module layout.

class App_Controller_Plugin_Layout extends Zend_Controller_Plugin_Layout {

    public function __construct ($layout = null)
    {
        parent::__construct ($layout);
    }

    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        // Insert current module layout dir to to overide any default layouts
        if ( $request->getModuleName() != 'default' ) {

            $layoutPath = APPLICATION_PATH . '/modules/' .
                          $request->getModuleName() . '/views/layouts';

            $paths = array();
            $paths[] = $this->getLayout()->getViewScriptPath();
            $paths[] = $layoutPath;

            $this->getLayout()->setViewScriptPath($paths);
        }
    }
}

Asssuming you set the following application config value:

    resources.layout.layout                  = "default"

Now any module with a default.phtml layout will override the default module layout.

e.g APPLICATION_PATH/modules/foobar/views/layouts/default.phtml

Cheers the noo,
Graham

Zend Framework MVC Request Lifecycle

Kevin Schroeder writes an excellent article about the MVC lifecycle thats a must read for anyone even thinking about writing ZF plugins; Matthew wrote up an article on modules in Zend_Application and that got me thinking a little bit. When I have done training for Zend Framework, one of the things that mystifies students to some extent is the whole plugin architecture and where things can go. There has been several articles written about it, but they tend to use code to describe it. I was only able to find a small handfull of articles that used some kind of chart to describe what goes on. Not that that’s a problem, but I had found that when I drew out the request lifecycle that it helped the students understand it better.

The chart on the right is a color-coded chart that shows when something is executed and where it is executed from. This chart is intentionally missing a whole bunch of things for the purpose of simplicity. If you want a more full explanation of the request lifecycle…

Read full story Friday Framework Highlight: Zend Framework MVC Request Lifecycle

App_Controller_Helper_Params for JSON and XML POSTs

Matthew Weier O’Phinney shares a bit of very useful code to inject request params into a Zend Framework request object from a JSON or XML POST request.

“Below is a plugin I use to translate JSON or XML raw post request data to request user parameters.
Note that it expects a “Content-Type” header of either “application/json” or “application/xml”. If those are detected, it then does the translation and injection.
Once it has, you can then simply access the parameters from your request object like any others.
I actually use this with dojox.data.JsonRestStore already, so you should be set. :)”

<?php
class App_Controller_Helper_Params
    extends Zend_Controller_Action_Helper_Abstract
{
    /**
     * @var array Parameters detected in raw content body
     */
    protected $_bodyParams = array();

    /**
     * Do detection of content type, and retrieve parameters from raw body if
     * present
     *
     * @return void
     */
    public function init()
    {
        $request     = $this->getRequest();
        $contentType = $request->getHeader('Content-Type');
        $rawBody     = $request->getRawBody();
        if (!$rawBody) {
            return;
        }
        switch (true) {
            case (strstr($contentType, 'application/json')):
                $this->setBodyParams(Zend_Json::decode($rawBody));
                break;
            case (strstr($contentType, 'application/xml')):
                $config = new Zend_Config_Xml($rawBody);
                $this->setBodyParams($config->toArray());
                break;
            default:
                if ($request->isPut()) {
                    parse_str($rawBody, $params);
                    $this->setBodyParams($params);
                }
                break;
        }
    }

    /**
     * Set body params
     *
     * @param  array $params
     * @return Scrummer_Controller_Action
     */
    public function setBodyParams(array $params)
    {
        $this->_bodyParams = $params;
        return $this;
    }

    /**
     * Retrieve body parameters
     *
     * @return array
     */
    public function getBodyParams()
    {
        return $this->_bodyParams;
    }

    /**
     * Get body parameter
     *
     * @param  string $name
     * @return mixed
     */
    public function getBodyParam($name)
    {
        if ($this->hasBodyParam($name)) {
            return $this->_bodyParams[$name];
        }
        return null;
    }

    /**
     * Is the given body parameter set?
     *
     * @param  string $name
     * @return bool
     */
    public function hasBodyParam($name)
    {
        if (isset($this->_bodyParams[$name])) {
            return true;
        }
        return false;
    }

    /**
     * Do we have any body parameters?
     *
     * @return bool
     */
    public function hasBodyParams()
    {
        if (!empty($this->_bodyParams)) {
            return true;
        }
        return false;
    }

    /**
     * Get submit parameters
     *
     * @return array
     */
    public function getSubmitParams()
    {
        if ($this->hasBodyParams()) {
            return $this->getBodyParams();
        }
        return $this->getRequest()->getPost();
    }

    public function direct()
    {
        return $this->getSubmitParams();
    }
}

Keeping your HTML valid with Zend Framework, Tidy and Firebug

Ryan Mauger wrote a good article on tidying things behind the scenes, during development, definitely worth a look;

With Zend Framework there is an easy way to ensure that you always create valid HTML in your applications. This involves the use of a simple Front Controller Plugin, and the php Tidy component.

Valid HTML is important for a great many reasons, the most important of which is ensuring consistency across all of your visitors browsers. The first step to making sure that your site appears correctly on all the browsers is to ensure that your HTML is valid. Even if the goons at Microsoft continue to ignore the standards and do their own thing, if you at least ensure your html passes validation, then fixing things for Internet Explo(r|it)er of all its versions is a far easier task, and usually possible with a few simple extra styling rules in your CSS.

via Ryan’s Blog.

Bootstrapping Zend_Translate with a LangSelector Plugin

This entry is part 4 of 4 in the series Working with Zend_Translate and Poedit

As an update to the method of having everything related to Zend_Translate and Zend_Locale in the Bootstrap, here is an alternative using an Controller Plugin that does the grunt work of validating, selecting and updating the Zend_Locale, Zend_Registry & Zend_Session using Zend_Session_Namespace. And we are using poedit .po & .mo files as the source as usual.

Please comment as usual if you have a neater way of doing it 🙂

Bootstrap.php

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap {

    protected function _initTranslate()
    {
        // Get current registry
        $registry = Zend_Registry::getInstance();
        /**
         * Set application wide source Locale
         * This is usually your source string language;
         * i.e. $this->translate('Hi I am an English String');
         */
        $locale = new Zend_Locale('en_US');    

        /**
         * Set up and load the translations (all of them!)
         * resources.translate.options.disableNotices = true
         * resources.translate.options.logUntranslated = true
         */
        $translate = new Zend_Translate('gettext',
            APPLICATION_PATH . DIRECTORY_SEPARATOR .'languages', 'auto',
            array(
            'disableNotices' => true,    // This is a very good idea!
            'logUntranslated' => false,  // Change this if you debug
            )
        );
        /**
         * Both of these registry keys are magical and makes
         * ZF 1.7+ do automagical things.
         */
        $registry->set('Zend_Locale', $locale);
        $registry->set('Zend_Translate', $translate);
        return $registry;
    }
}

This little plugin will check every request for a lang paramenter and act on it.
It does not matter if you set the lang parameter using a custom route :lang/:controller/:action
or via a get/post ?lang= etc. one or all of them will work.

library/App/Controller/Plugin/LangSelector.php

<?php
/**
 * @author      Danny Froberg <[email protected]>
 * @name        App_Controller_Plugin_LangSelector
 * @filesource  library/App/Controller/Plugin/LangSelector.php
 * @tutorial    Instantiate in application.ini with;
 *              resources.frontController.plugins.LangSelector =
 *              "App_Controller_Plugin_LangSelector"
 * @desc        Takes the lang parameneter when set either via a
 *              route or get/post and switches Locale, This depends
 *              on the main initTranslate function in Bootstrap.php
 *              to set the initial Zend_Translate object.
 *              Inspiration from ZendCasts LangSelector.
 */
class App_Controller_Plugin_LangSelector extends Zend_Controller_Plugin_Abstract
{
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        $registry = Zend_Registry::getInstance();
        // Get our translate object from registry.
        $translate = $registry->get('Zend_Translate');
        $currLocale = $translate->getLocale();
        // Create Session block and save the locale
        $session = new Zend_Session_Namespace('session');

        $lang = $request->getParam('lang','');
        // Register all your "approved" locales below.
        switch($lang) {
            case "sv":
                $langLocale = 'sv_SE'; break;  
            case "fr":
                $langLocale = 'fr_FR'; break;
            case "en":
                $langLocale = 'en_US'; break;
            default:
                /**
                 * Get a previously set locale from session or set
                 * the current application wide locale (set in
                 * Bootstrap)if not.
                 */
                $langLocale = isset($session->lang) ? $session->lang : $currLocale;
        }

        $newLocale = new Zend_Locale();
        $newLocale->setLocale($langLocale);
        $registry->set('Zend_Locale', $newLocale);

        $translate->setLocale($langLocale);
        $session->lang = $langLocale;

        // Save the modified translate back to registry
        $registry->set('Zend_Translate', $translate);
    }
}

Big thanks to Zend Cast for the inspiration!

Converting your Zend Framework MVC application into an XML webservice using one single plugin

Thijs Feryn writes an excellent article on how to convert your entire MVC app or one or more controllers into a XML service. I actually have this one in a production environment and it works like a charm.

That’s right folks, in this blog post I’ll show you how you can convert your entire MVC application into a REST-style XML webservice. And I’m not talking about refactoring tons of code … NO, we’ll plug this option in without changing a single thing to your action controllers.

This post will contain a detailed description of the concepts used. The source could of the plugin is also shown and finally how it will look like when using it.

The concept

Thanks to those lovely hooks in Zend Framework you can simply intervene in nearly every aspect of the MVC workflow. The image below shows you the workflow.

Zend Controller Basics

Zend Controller workflow The hooks I’m talking about are actually just methods that are called by the plugin broker system. They already exist as empty methods in the Zend_Controller_Plugin_Abstract which we inherit from. So we override them in order to hook into the MVC flow.

Alle information on Zend Framework plugins can be found in the reference pages. A lot of you Zend Framework experts will now say: “why don’t you just use the context switching action helper?”. I could have done that, but this requires modifying your application. This post is about plugging it in, remember?

How am I doing it then? Well … I hook into the workflow at “post dispatch” time, this means that de dispatcher has already processed al controllers and is about to send all about back to the browser by using a Zend Controller Response object.

Before the front controller sends the output back to the browser, we empty the output’s body and add our own content. This content is retrieved from the view object which would normally parse and render the view object. The view has a set of properties which are set by the controllers. I use the reflection API to get a hold of all these items. Finally I serialize them and output it all.

The plugin

&lt;?php
/**
 * My_Plugin_Xml component
 * Turns an Zend Framework MVC website into an XML webservice
 */
/**
 * My_Plugin_Xml class
 *
 * @author Thijs Feryn &lt;[email protected]&gt;
 */
class My_Plugin_Xml extends Zend_Controller_Plugin_Abstract
{
    /**
     * Stores the front controller
     *
     * @var Zend_Controller_Front
     */
    private $_front;
    /**
     * Stores the XML output in DOMDocument format
     *
     * @var DOMDocument
     */
    private $_xml;
    /**
     * Class constructor
     */
    public function __construct()
    {
        $this-&gt;_front = Zend_Controller_Front::getInstance();
        $layout = Zend_Layout::getMvcInstance();
        $layout-&gt;disableLayout();
    }
    /**
     * Build DOMDocument to convert output to XML
     *
     * @param mixed $return
     * @param Exception $exception
     * @return string
     */
    private function _getXML($return = null,Exception $exception = null)
    {  
        $this-&gt;_xml = new DOMDocument('1.0', 'UTF-8');
        $this-&gt;_xml-&gt;formatOutput = true;
 
        $responseNode = $this-&gt;_xml-&gt;createElement('response');
 
        $exceptionNode = $this-&gt;_xml-&gt;createElement('exception');
        if(null !== $exception && $exception == instanceof( Exception ){
            $exceptionNode-&gt;appendChild(
                $this-&gt;_xml-&gt;createElement('message',
                    $exception-&gt;getMessage()
                )
            );
            $exceptionNode-&gt;appendChild(
                $this-&gt;_xml-&gt;createElement('code',
                    $exception-&gt;getCode()
                )
            ); 
            $exceptionNode-&gt;appendChild(
                $this-&gt;_xml-&gt;createElement('type',
                    get_class($exception)
                )
            ); 
        }
 
        $responseNode-&gt;appendChild($exceptionNode);
        if(null !== $return){
            $responseNode-&gt;appendChild(
                $this-&gt;_serialize('return',$return)
            );
        } else {
            $responseNode-&gt;appendChild(
                $this-&gt;_xml-&gt;createElement('return')
            );
        }
 
        $this-&gt;_xml-&gt;appendChild($responseNode);
        return $this-&gt;_xml-&gt;saveXML();
    }
    /**
     * Modify the HTTP response object
     * Remove the HTML body, replace with XML and change the content-type
     *
     * @param mixed $return
     * @param Exception $exception
     */
    private function _setResponse($return = false,Exception $exception = null)
    {
        $this-&gt;getResponse()-&gt;setHeader('Content-Type','text/xml; charset=UTF-8');
        $this-&gt;getResponse()-&gt;clearBody();
        $this-&gt;getResponse()-&gt;setBody(
            $this-&gt;_getXML($return,$exception)
        );         
    }
    /**
     * Serialize a mixed value to XML in DOMElement format
     * This method can be used recursively in case of objects and arrays
     *  
     * @param string $name
     * @param mixed $value
     * @return DOMElement
     */
    private function _serialize($name,$value)
    {
        if(is_array($value)){
            $element = $this-&gt;_xml-&gt;createElement($name);
            foreach ($value as $k=&gt;$v){
                if(is_numeric($k)){
                    $k = 'item';
                }
                $element-&gt;appendChild($this-&gt;_serialize($k,$v));
            }
        } elseif(is_object($value)){
            $element = $this-&gt;_xml-&gt;createElement($name);
            $reflection = new ReflectionObject($value);
            $properties = $reflection-&gt;getProperties();
            foreach ($properties as $property){
                if($property-&gt;isPublic()){
                    $element-&gt;appendChild(
                        $this-&gt;_serialize(
                            $property-&gt;getName(),
                            $property-&gt;getValue($value)
                        )
                    );
                }
            }
        }else{
            $element = $this-&gt;_xml-&gt;createElement(
                $name,
                (string)$value
            );
        }
        return $element;
    }
    /**
     * preDispatch hook that retrieves if an Exception was thrown in the application
     * If an exception is thrown, the exception is passed to the exception part of the XML output and script execution is terminated
     *
     * @param Zend_Controller_Request_Abstract $request
     */
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        if($this-&gt;getResponse()-&gt;isException()){
            $exArray = $this-&gt;getResponse()-&gt;getException();
            $this-&gt;_setResponse(null,$exArray[0]);  
            $this-&gt;getResponse()-&gt;sendResponse();
            exit();
        }
    }
    /**
     * postDispatch hook that serializes the view object to XML by modifying the HTTP response
     * If no exception was thrown script execution continues and the postDispatch method will be called
     *
     * @param Zend_Controller_Request_Abstract $request
     */
    public function postDispatch(Zend_Controller_Request_Abstract $request)
    {
        $view = Zend_Controller_Action_HelperBroker::getExistingHelper('ViewRenderer')-&gt;view;
        $this-&gt;_setResponse($view); 
    }
}

The plugin registration

To activate the plugin, just call the registerPlugin method from the front controller. In my case this is done in my Initializer class which is allready a plugin.

$this-&gt;_front-&gt;registerPlugin(new My_Plugin_Xml());

The app

This application has one single controller which is the IndexController. There are 2 actions:

* IndexAction: the default action which assigns an object to the view
* ExceptionAction: an action which throws an exception

Pretty simple, pretty basic, but mind the exception: my plugin can catch it by hooking into the flow at preDispatch time. At that time we can already determine if the response contains an exception. Luckily, in this stage the front controller hasn’t yet sent additional error output to the view.

&lt;?php
class IndexController extends Zend_Controller_Action
{
    public function indexAction()
    {
        $obj = new stdClass();
        $obj2 = new stdClass();
        $obj2-&gt;c = 'xyz';
        $obj2-&gt;d = '123';
        $obj-&gt;a = 'abc';
        $obj-&gt;b = $obj2;
        $this-&gt;view-&gt;content= $obj;
    }
    public function exceptionAction()
    {
        throw new Exception('It all goes wrong!');
    }
}

The output

indexAction

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;response&gt;
  &lt;exception/&gt;
  &lt;return&gt;
    &lt;content&gt;
      &lt;a&gt;abc&lt;/a&gt;
      &lt;b&gt;
        &lt;c&gt;xyz&lt;/c&gt;
        &lt;d&gt;123&lt;/d&gt;
      &lt;/b&gt;
    &lt;/content&gt;
  &lt;/return&gt;
&lt;/response&gt;

exceptionAction

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;response&gt;
  &lt;exception&gt;
    &lt;message&gt;It all goes wrong!&lt;/message&gt;
    &lt;code&gt;0&lt;/code&gt;
    &lt;type&gt;Exception&lt;/type&gt;
  &lt;/exception&gt;
  &lt;return/&gt;
&lt;/response&gt;