sweekit Simple development toolkit : Ajax functions, Js renderes, Mobile (iOS / Android) notifier, Google Map

Sweekit - aka Sweelix toolkit

  1. Samples - because it's always easier to understand what can be done
  2. Sweeml
  3. Behaviors
  4. Filters
  5. Javascript functions

The toolkit is under new BSD License except for 3rdParty elements which are under their own licenses.

The project can be found on github : https://github.com/pgaultier/sweekit

Simple demo can be checked here : https://www.sweelix.net/sweekit/demo/

3rd party tools used in the toolkit are

This toolkit was written to ease javascript access during our developments. In order to not create conflict, Sweekit classes are prefixed with Sw

A short explain is available in the doc directory.

Available features :

  • javascript - see doc/sweekit.mkd and doc.javascript.mkd
  • components - App components, ...
  • map - GoogleMap Webservice components
  • helpers - Sweeml (extends CHtml) - see doc/sweekit.mkd
  • behaviors - SwAjaxBehavior, SwClientScriptBehavior, SwRenderBehavior - see doc/behaviors.mkd
  • filters - SwProtocolFilter - see doc/filters.mkd
  • validators - SwFileValidator (for plupload)
  • actions - SwDeleteAction, SwUploadAction (for plupload)
  • commands - SwUploadCommand (to purge plupload temporary directory)
  • web - SwUploadedFile (Retrieve files uploaded with plupload)

Samples - because it's always easier to understand what can be done

Sample app is available to see some features in action. Checkout the samples directory : https://github.com/pgaultier/sweekit/tree/devel/samples

Google Map Webservices

In order to use the google webservices, you have to add a specific component to the main config :

/* imports */
	'imports' => array(
		'ext.sweekit.map.*',
		// other imports
	),
/* configuration array for components */
	'sweekitmap' => array(
		'class' => 'ext.sweekit.map.SwMap',
		'language' => 'fr',
	),

Now you can use the object to fetch data from google map :

  1. Find a place using Coordinates
$coords = new SwMapCoordinates(48.8481132, 2.2744262);

echo $coords->address->formatted."<br/>\n"; // formatted address

// or

echo $coords->address->number."<br/>\n";
echo $coords->address->route."<br/>\n";
echo $coords->address->zipCode."<br/>\n";
echo $coords->address->locality."<br/>\n";

  1. Try to geocode a partial address
// create an empty address
$partialAddress = new SwMapAddress();

$partialAddress->locality = 'Paris';
$partialAddress->route = 'rue Saint'; // this one is partial
$partialAddress->number = 29;
$partialAddress->zipCode = 75002;

// get an array of addresses normalized by google which correspond
// to the partial one we entered
$foundAddresses = $partialAddress->getNormalizedAddresses();

foreach($foundAddresses as $address) {
	echo $address->formatted."<br/>\n";
}

This last sample will display 6 potential addresses


29 Rue Saint-Jacques, 75005 Paris, France
29 Avenue de l'Opéra, 75001 Paris, France
29 Rue Saint-Dominique, 75007 Paris, France
29 Boulevard Saint-Germain, 75005 Paris, France
29 Rue de Caumartin, 75009 Paris, France
29 Rue du Faubourg Saint-Honoré, 75008 Paris, France

Mobile notifier

The mobile notifier allow the developper to send notification to iOS and/or Android system.

Of course, you'll need account information from Google or Apple to be able to send notifications.

Adding the notifier component to the application

/* configuration array */
    mobileNotification' => array(
        'class' => 'ext.sweekit.actions.SwMobileNotifier',
        'mode' => 'production', // can be development to use the sandbox
        'apnsCertificateFile' => 'my_apple_certificate_for_push.pem',
        'apnsCertificatePassphrase' => 'my_apple_certificate_passphrase', // comment out if there is no passphrase
        'apnsEmbeddedCaFile'=>true, // embed entrust ca file if needed (ssl errors, ...)
        'c2dmUsername' => 'my_gmail_push_account@gmail.com',
        'c2dmPassword' => 'my_gmail_push_account_password',
        'c2dmApplicationIdentifier' => 'my_gmail_push_app_identifier',
    ),

You are now able to push messages to mobile devices

Sample for Android
// send message to device
$res = Yii::app()->getComponent('mobileNotification')->sendC2dmMessage(
    'the_android_device_id', // look like base64 encoded data
    array('badge' => 12, 'message' => 'My message to send') // the payload to send to the device
);

Sample for iOS
// send message to device
$res = Yii::app()->getComponent('mobileNotification')->sendApnsMessage(
    'the_ios_device_id', // 64 characters hex id
    array('aps' => array(
        'badge' => CPropertyValue::ensureInteger(12), // make sure data is an integer
        'alert' => 'My message to send',
    ))
);

Apple added a function to check if device should still receive notification.

This method should be called using a cron system in order to purge old pushId from your database to avoid sending useless notifications

$res = Yii::app()->getComponent('mobileNotification')->readApnsFeedback();
/**
 * $res is an array of array : 
 * $res = array(
 *      array($timeStamp, $pushId1),
 *      array($timeStamp, $pushId2),
 *      // ...
 * );
 */

Callback system

As an example, you have created an online shop and in several places, the cart is updated. If in the header there is a widget which shows the number of products, this widget should be updated when the cart is updated.

Using the callback system you can :

Register an event in the widget using Sweeml

<?php Sweeml::registerEvent('updateCart', "function(data){jQuery('#cart.nb').html(data+' products');}"); ?>
    <div id="cart">0 product</div>

Whereever the cart is updated you can raise an event.

<script type="text/javascript">
        function refreshCart() {
            // perform ajax call to refresh info
            jQuery.ajax({
                url : 'http://targeturl',
                success : function(nbOfProducts) {
                    // nbOfProducts is an integer with the number of products in cart
                    <?php echo Sweeml::raiseEvent('updateCart', nbOfProducts); ?>
                }
            });
        }
    </script>
    <a href="#" onclick="refreshCart()">refresh cart</a>
Multi file upload

The basic model

<?php 
    class MyFile extends CFormModel {
        public $thefile;
        public function rules() {
            // NOTE: you should only define rules for those attributes that
            // will receive user inputs.
            return array(
                array('thefile', 'SwFileValidator', 'maxFiles' => 2, 'allowEmpty' => true),
            );
        }
    }

The controller

<?php 
    class UploadController extends CController {
        /**
         * Attach generic actions to handle async uploads
         *
         * @return array
         */
        public function actions() {
            return array(
                'asyncUpload' => 'ext.sweekit.actions.SwUploadAction',
                'asyncDelete' => 'ext.sweekit.actions.SwDeleteAction',
            );
        }
     
        /**
         * initial action
         *
         * @return void
         */
        public function actionIndex() {
            $file = new MyFile();
            if(isset($_POST['MyFile']) == true) {
                // get uploaded files
                $realFiles = SwUploadedFile::getInstances($file, 'thefile');
                foreach($realFiles as $realFile) {
                    // save uploaded files
                    $realFile->saveAs('files/'.$realFile->getName());
                }
            }
            $this->render('index', array('file' => $file));
        }
    }

The view

<?php echo Sweeml::activeAsyncFileUpload($file, 'thefile',array(
        'config' => array(
            'runtimes' => 'html5, flash',
            'auto' => true,
            'ui' => true,
            'maxFileSize' => '512mb',
            'multiSelection' => true,
        ),
        'events'=>array(
            'beforeUpload' => 'js:function(up, file){ 
                $(\'#submitButton\').attr(\'disabled\', \'disabled\'); 
            }',
            'uploadComplete' => 'js:function(up, files){
                $(\'#submitButton\').removeAttr(\'disabled\'); 
            }',
        )
    )); ?>
    
    <?php echo Sweeml::htmlButton('submit', array('type' => 'submit', 'id' => 'submitButton')); ?>

Sweeml

Sweeml override the original CHtml helpers and add several functionnalities

Callback system - aka event management

The callback system allow the developper to register (js) events in the page -- some kind of listeners. In other places, the developer can raise an event. This can be seen as some loose coupling. An other advantage of the callback system is that even if the callback was raised in an iframe, the callback get caught in the main window. In other word, the raised event is re-routed to the main window. This is usefull when iframe (for lightboxes, ...) are used.

Generic callback method

This method produce a javascript string

(string) raiseEvent($eventName, $parameters=array(), $context=null);

This method produce a javascript string which can be used directly as an url

(string) raiseEventUrl($eventName, $parameters=array(), $context=null);

Parameters

  • $eventName (string) name of the event to raise
  • $parameters (array) parameters to pass to the event manager
  • $context (string) context if needed, else will be in global context

This method register directly the event using the clientScript

(string) registerEvent($eventName, $action, $context=null);

This method produce a javascript string

(string) registerEventScript($eventName, $action, $context=null);

Parameters

  • $eventName (string) name of the event to register
  • $action (string) action to execute when event is raised, this is pure javascript code
  • $context (string) context if needed, else will be in registered in global context
Ajax helpers
Ajax request using callback system

Produce an ajax call to $url and perform the update/replace of the target element if content-type is text/html. If the content-type is application/javascript the returned js code is executed.

This system raise also two jQuery events on the target :

  • beforeAjax : raised just before ajax is submited.
  • afterAjax : raised after ajax request (and replace/update) if the call was successfull

This is usefull to prepare data or rebind events when the dom has been replaced.

This method produce a javascript string

(string) raiseAjaxRefresh($target, $url, $data=null, $mode=null);

This method produce a javascript string which can be used directly as an url

(string) raiseAjaxRefreshUrl($target, $url, $data=null, $mode=null);

Parameters

  • $target (string) target element
  • $url (mixed) url in Yii supported format
  • $data (mixed) data to pass
  • $mode (enum) replacement mode can be replace or update
Ajax forms using callback system

This script intercept form posting, perform the post in ajax and update/replace or execute the javavscript depending on the content-type

This method produce a javascript script which should be executed to enable form ajaxify

(string) ajaxSubmitHandlerScript($target);

This method produce a javascript which is automatically registered and ajaxify the form(s)

ajaxSubmitHandler($target);

Parameters

  • $target (string) the target element - form(s) to ajaxify

An easier way to ajaxify the forms using this system is to use the all in one tag generator.

replace the classic

(string) beginForm($action='',$method='post',$htmlOptions=array());

with

(string) beginAjaxForm($action='',$method='post',$htmlOptions=array());

And the form will be automagically ajaxified

Parameters

  • $action (mixed) action
  • $method (string) method
  • $htmlOptions (array) html options
Javascript helper
Redirect system

Usefull when we need to redirect the main window from an iframe. We don't need to know in advance if we are in an iframe or not.

This method produce a javascript string

(string) raiseRedirect($url, $timer=null);

This method produce a javascript string which can be used directly as an url

(string) raiseRedirectUrl($url, $timer=null);

Parameters

  • $url (mixed) url in Yii format
  • $timer (integer) delay in second before executing redirect
Shadowbox system - aka easy lightbox system
Opening shadowbox

This method register all js and css needed to open a shadowbox and open it

This method produce a javascript string

(string) raiseOpenShadowbox($url='#', $shadowBoxOptions=array());

This method produce a javascript string which can be used directly as an url

(string) raiseOpenShadowboxUrl($url='#', $shadowBoxOptions=array());

Parameters

  • $url (mixed) url to open in the shadowbox, information will be normalized
  • $shadowBoxOptions (array) options to pass to shadowbox as described in documentation
Closing shadowbox

This method close current shadowbox

This method produce a javascript string

(string) raiseCloseShadowbox();

This method produce a javascript string which can be used directly as an url

(string) raiseCloseShadowboxUrl();

File upload using plupload

The methods

  • (string) activeAsyncFileUpload($model, $attribute, $htmlOptions=array()) ;
  • (string) asyncFileUpload($name, $htmlOptions=array(), $value=null);

This methods should work like the original ones. The difference is that they register js, css and everything to allow multi fileuploads with drag'n'drop and fancy features. See method doc clock for all options

<?php echo Sweeml::activeAsyncFileUpload($myModel, 'uploadField', $options); ?>

Behaviors

SwClientScriptBehavior

SwClientScriptBehavior add sweelix js package management. This behavior is used in Sweeml to register Sweelix Javascript (and Styles) packages like the original registerCoreScript() method

Available packages are

  • sweelix // base js module management
  • debug // debug module,
  • callback // callback module
  • ajax // ajax module (should be used with SwRenderBehavior)
  • shadowbox // shadowbox module
  • plupload (and derivatives) // multi upload module

Attach the behavior to the clientScript component

'clientScript' => array(
        'behaviors' => array(
            'sweelixClientScript' => array(
                'class' => 'ext.sweekit.behaviors.SwClientScriptBehavior',
            ),
        ),
    ),

Use it in your controller or view

// ... controller code
    class MyController extends CController {
        // ...
        public function actionTest() {
            // Register sweelix debug script
            Yii::app()->clientScript->registerSweelixScript('debug');
            // ...
        }
        // ...
    }
SwAjaxBehavior

SwAjaxBehavior add the following methods to CHttpRequest :

(bool) $res = Yii::app()->getRequest()->getIsJsRequest($isAjax=true)

Check if we should return javascript content

(bool) $res = Yii::app()->getRequest()->getIsJsonRequest($isAjax=true)

Check if we should return json content

Example :

Attach the behavior to the request component

'request' => array(
        'behaviors' => array(
            'sweelixAjax' => array(
                'class' => 'ext.sweekit.behaviors.SwAjaxBehavior',
            ),
        ),
    ),
    ///... 

Use it in your controller

// ... controller code
    if(Yii::app()->getRequest()->getIsJsRequest() === true) {
        // render javascript which will be executed by the borwser
        // see below SwRenderBehavior
        $this->renderJs('alert("Request was performed as expected");');
    } elseif(Yii::app()->getRequest()->getIsAjaxRequest() === true) {
        // render partial html
        $this->renderPartial('_htmlPartialView');
    } else {
        // render full html
        $this->render('htmlFullView');
    }
SwRenderBehavior

SwRenderBehavior should be used with SwAjaxBehavior. SwRenderBehavior add the following methods to CController :

$this->redirectJs($url, $timer=null, $terminate=true)

Redirect to $url using javascript. Usefull when the ajax call should initiate a redirect.

$this->renderJs($script, $terminate=true)

Render javascript using correct headers

$this->renderJson($data, $httpCode=200, $terminate=true)

Render data as Json string with correct headers

Example :

Attach the behavior to the controller

class MyController extends CController {
        // ...
        public function behaviors() {
            return array(
                'sweelixRendering' => array(
                    'class' => 'ext.sweekit.behaviors.SwRenderBehavior',
                ),
            );
        }
        // ...
    }

Use it in your code

class MyController extends CController {
        // ...
        public function actionTest() {
            if(Yii::app()->request->isAjaxRequest == true) {
                // this will raise an event using sweelix callback in order to open a shadowbox
                $this->renderJs('alert("direct js rendering")');
            }
        }
        // ...
    }

Filters

SwProtocolFilter

SwProtocolFilter allow automatic switching from HTTP to HTTPS

To force everything in https except the action parse

class MyController extends CController {
        // ...
        public function filters() {
            return array(
                array(
                    'ext.sweekit.filters.SwProtocolFilter - parse',
                    'mode' => 'https',
                ),
            );
        }
    }

To force everything in http except the action parse

class MyController extends CController {
        // ...
        public function filters() {
            return array(
                array(
                    'ext.sweekit.filters.SwProtocolFilter + parse',
                    'mode' => 'https',
                ),
            );
        }
    }

Javascript functions

Package dependancies are automatically resolved.

sweelix

Core package, this package define the base namespace jQuery.sweelix and a basic module system.

No usefull function is exported

debug - depends on sweelix

Debugging package for js. This is a simple console wrapper. Once module is inited, following methods are added to the jQuery.sweelix object :

log, debug, info, warn, error, assert, dir, trace, count, group, groupEnd

    // .. js code
    jQuery.sweelix.log('Loging info in the console');
    // .. js code

If the debug is activated, the console will display the string "Loging info in the console". If debug is deactivated, the console will remain empty

In order to be able to use the debug module you have to add SwClientScriptBehavior and configure it

  1. Configure application to enable debugging
// App config code
    'clientScript' => array(
        'behaviors' => array(
            'sweelixClientScript' => array(
                'class' => 'ext.sweekit.behaviors.SwClientScriptBehavior',
                'config' => array(
                    'debug' => array(
                        'debug' => true, // default false - (de)activate debug
                        'method' => 'log', // default 'log' - default console method used when logging
                        'fallback' => false, // default false - if console is not available use alerts
                    ),
                )
            ),
        ),
    ),    
  1. Use debugging functions in the code
// View code
    // register debug module
    <?php Yii::app()->clientScript->registerSweelixScript('debug'); ?>
    // perform some debugging
    <script type="text/javascript">
        jQuery(document).ready(function(){
            jQuery.sweelix.log('Document is ready, starting js');
            // ... js code
        });
    </script>
callback - depends on debug and sweelix

Callback system. This system allow the developer to register and raise events

In order to be able to use the debug module you have to add SwClientScriptBehavior and configure it

  1. Configure application to enable debugging and callback
// App config code
    'clientScript' => array(
        'behaviors' => array(
            'sweelixClientScript' => array(
                'class' => 'ext.sweekit.behaviors.SwClientScriptBehavior',
                'config' => array(
                    'debug' => array(
                        'debug' => true, // default false - (de)activate debug
                        'method' => 'log', // default 'log' - default console method used when logging
                        'fallback' => false, // default false - if console is not available use alerts
                    ),
                    'callback' => array(
                        'globalCblName' => 'swlx', // default 'swlx' - default namespace of registered events
                        'top' => true, // default true - if true, event are always re-routed to top window
                    ),
                )
            ),
        ),
    ),    
  1. Use callback functions in the code
// View code
    // register callback module
    <?php Yii::app()->clientScript->registerSweelixScript('callback'); ?>
    // perform some regisration
    <script type="text/javascript">
        jQuery(document).ready(function(){
            jQuery.sweelix.register('myRegisteredEvent', function(params){ alert('my event was raised with myParam value : '+params.myParam); });
            // ... js code
        });
    </script>
    // ...
    <a href="#" onclick="jQuery.sweelix.raise('myRegisteredEvent', {'myParam':2})">Raise the event</a>
ajax - depends on callback, debug and sweelix

Ajax system allow the developper to perform easy ajax requests

  1. Configure application to enable debugging, callback and ajax
// App config code
    'clientScript' => array(
        'behaviors' => array(
            'sweelixClientScript' => array(
                'class' => 'ext.sweekit.behaviors.SwClientScriptBehavior',
                'config' => array(
                    'debug' => array(
                        'debug' => true, // default false - (de)activate debug
                        'method' => 'log', // default 'log' - default console method used when logging
                        'fallback' => false, // default false - if console is not available use alerts
                    ),
                    'callback' => array(
                        'globalCblName' => 'swlx', // default 'swlx' - default namespace of registered events
                        'top' => true, // default true - if true, event are always re-routed to top window
                    ),
                    // ajax module has no configuration vars
                )
            ),
        ),
    ),
    //...     
  1. Use ajax functions in the code (view)
    // View code
    // register ajax module
    <?php Yii::app()->clientScript->registerSweelixScript('ajax'); ?>
    // perform some regisration
    <script type="text/javascript">
        var parameters ={
            'targetUrl' : 'http://www.myurl.com?r=site/cool',
            'data' : {}, // data to post
            'mode' : '', // can be replace or empty
            'targetSelector' : '#myDiv'
        };
    </script>
    // ...
    <a href="#" onclick="jQuery.sweelix.raise('ajaxRefreshHandler', parameters)">Raise the event</a>
    // ...
    <div id="#myDiv">
        This div should be updated
    </div>
<?php echo CHtml::link('Raise the event','#', array(
    	'onclick'=> Sweeml::raiseAjaxRefresh('#myDiv', array('site/cool')), 
    )); ?>
    // ...
    <div id="#myDiv">
        This div should be updated
    </div>
  1. Respond to call in controller
// Controller code
    public function actionCool() {
        // ... controller code
        if(Yii::app()->getRequest()->getIsAjaxRequest() === true) {
            // render partial html
            $this->renderPartial('_htmlPartialView');
        } else {
            // render full html
            $this->render('htmlFullView');
        }
    }
shadowbox - depends on callback, debug and sweelix

Shadowbox system allow easy lightbox management

  1. Configure application to enable debugging, and callback
// App config code
    'clientScript' => array(
        'behaviors' => array(
            'sweelixClientScript' => array(
                'class' => 'ext.sweekit.behaviors.SwClientScriptBehavior',
                'config' => array(
                    'debug' => array(
                        'debug' => true, // default false - (de)activate debug
                        'method' => 'log', // default 'log' - default console method used when logging
                        'fallback' => false, // default false - if console is not available use alerts
                    ),
                    'callback' => array(
                        'globalCblName' => 'swlx', // default 'swlx' - default namespace of registered events
                        'top' => true, // default true - if true, event are always re-routed to top window
                    ),
                )
            ),
        ),
    ),
    //...     
  1. Use shadowbox functions in the code (view)
    // View code
    // register ajax module
    <?php Yii::app()->clientScript->registerSweelixScript('shadowbox'); ?>
    // perform some regisration
    <script type="text/javascript">
        var parameters ={
            content: 'http://www.example.com/?r=site/lb',
            player: "iframe",
            title: "Lightbox",
            height: 350,
            width: 350
        };
    </script>
    // ...
    <a href="javascript:void(0);" onclick="jQuery.sweelix.raise('shadowboxOpen', parameters)">Open the shadowbox</a>
    // ...
    <a href="javascript:void(0);" onclick="jQuery.sweelix.raise('shadowboxClose')">Close shadowbox</a>
<?php echo CHtml::link('Open the shadowbox','#', array(
    	'onclick'=> Sweeml::raiseOpenShadowbox(array('site/lb'), array(
    	    'title' => 'Lightbox',
    	    'height' => 350,
    	    'width' => 350,
    	)), 
    )); ?>
    <?php echo CHtml::link('Close shadowbox','#', array(
    	'onclick'=> Sweeml::raiseCloseShadowbox(), 
    )); ?>
// ...
    // or using js in url 
    <?php echo CHtml::link('Open the shadowbox',
            Sweeml::raiseOpenShadowboxUrl(array('site/lb'), array(
    	        'title' => 'Lightbox',
                'height' => 350,
                'width' => 350,
    	    )) 
    ); ?>
    <?php echo CHtml::link('Close shadowbox',Sweeml::raiseCloseShadowboxUrl()); ?>
13 0
21 followers
1 130 downloads
Yii Version: 1.1
License: BSD-2-Clause
Category: Others
Developed by: kiwisoft
Created on: Feb 17, 2012
Last updated: 11 years ago

Downloads

show all