Sweekit - aka Sweelix toolkit ¶
- Samples - because it's always easier to understand what can be done
- Sweeml
- Behaviors
- Filters
- 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
- http://www.shadowbox-js.com - Shadowbox, dual license http://www.shadowbox-js.com/LICENSE
- http://www.plupload.com/ - PLupload, dual license http://www.plupload.com/license.php
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 :
- 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";
- 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
- 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
),
)
),
),
),
- 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
- 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
),
)
),
),
),
- 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
- 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
)
),
),
),
//...
- 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>
- 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
- 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
),
)
),
),
),
//...
- 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()); ?>
CUrlManager and SwUploadAction
Hey developers, absolutly fantastic extension, thx.
btw: Does anyone have experience in dealing with the SwUploadAction in connection with using the urlManager configured in the config file in yii?
In case of using CUrlManager I will get the wrong ID in the upload action and the process brokes.
I tried it with the sample project in download library.
Maybe someone can help me, thx.
fixed documentation page on github
Some examples were incorrect, be careful:
// this will NOT work without any error (even in debug mode): Sweeml::registerEvent('testEvent', "function(data){alert('Hello!')}"); // this works fine: Sweeml::registerEvent('testEvent', "js:function(data){alert('Hello!')}");
Please approve my pull request and update this extension page.
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.