Welcome to Abdul Malik Ikhsan's Blog

Using Ember.js in Zend Framework 2 Application

Posted in Javascript, Tutorial PHP, Zend Framework 2 by samsonasik on January 7, 2015

Ember.js is one of the javascript frameworks that adopt Single-Page Application principles. When working with Zend Framework 2 application, we can terminate 2 step view process to just render the view (not the layout) when the request that comes is XmlHttpRequest. We can do it in our Module.php like the following code :

use Zend\View\Model\ViewModel;

class Module
{
    public function onBootstrap($e)
    {
        $eventManager = $e->getApplication()->getEventManager();
        $sharedEvents = $eventManager->getSharedManager();
        $sharedEvents->attach('Zend\Mvc\Controller\AbstractActionController',
            'dispatch', function($e)
        {
            $result = $e->getResult();
            if ($result instanceof ViewModel) {
                $result->setTerminal($e->getRequest()->isXmlHttpRequest());
            }
        });

        // ...
    }
    
    // ...
}

At this post, I will try to make a 3 static page : ‘Home’, ‘About’, and ‘Contact’ in Application module. Let’s first create the navigation :

// config/autoload/navigation.global.php
return [
    'navigation' => [
        'default' => [
            [
                'label' => 'Home',
                'route' => 'home'
            ],
            [
                'label'  => 'About',
                'route'  => 'about',
            ],
            [
                'label' => 'Contact',
                'route' => 'contact',
            ],
        ],
    ],
];

We can then register the navigation service :

// module/Application/config/module.config.php
// ...
   'service_manager' => [
      'factories' => [
            'Navigation' => 'Zend\Navigation\Service\DefaultNavigationFactory',
       ],
    ]
// ...

From the navigation registered above, we can create 3 controller like this :
1. IndexController

// module/Application/src/Application/Controller/IndexController.php
namespace Application\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;

class IndexController extends AbstractActionController
{
    public function indexAction()
    {
        return new ViewModel();
    }
}

2. AboutController

// module/Application/src/Application/Controller/AboutController.php
namespace Application\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;

class AboutController extends AbstractActionController
{
    public function indexAction()
    {
        return new ViewModel();
    }
}

3. ContactController

// module/Application/src/Application/Controller/ContactController.php
namespace Application\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;

class ContactController extends AbstractActionController
{
    public function indexAction()
    {
        return new ViewModel();
    }
}

Controllers created, we can register it into module.config.php under ‘router’ and ‘controllers’ :

// module/Application/config/module.config.php
// ...
   'router' => [
        'routes' => [
            'about' => [
                'type'    => 'Literal',
                'options' => [
                    'route'    => '/about',
                    'defaults' => [
                        'controller' => 'Application\Controller\About',
                        'action'        => 'index',
                    ],
                ],
            ],

            'contact' => [
                'type'    => 'Literal',
                'options' => [
                    'route'    => '/contact',
                    'defaults' => [
                        'controller' => 'Application\Controller\Contact',
                        'action'        => 'index',
                    ],
                ],
            ],
         ],
    ],

    'controllers' => [
        'invokables' => [
            'Application\Controller\Index' => 'Application\Controller\IndexController',
            'Application\Controller\Contact' => 'Application\Controller\ContactController',
            'Application\Controller\About' => 'Application\Controller\AboutController',
        ],
    ],
// ...

I assume you have using default ZendSkeletonApplication so the IndexController route already defined. Ok, now we need to fill the view.
1 index view ( same as the skeleton app view/application/index/index.phtml )
2 about view

// module/Application/view/application/about/index.phtml
<h1>About Me</h1>
<p>
    I'm a web developer.
</p>

3 contact view

// module/Application/view/application/contact/index.phtml
<h1>Contact Me</h1>
<p>
    You can contact me via <a href="mailto: foo@bar.baz.com">foo@bar.baz.com</a>
</p>

Yup, Let’s go to javascript side.

First, require Ember.js in bower.json and install it :

// bower.json
{
    "name":"ZF2 App with Ember Demo",
    "dependencies": {
        "ember": "1.*"
    }
}

Configure it to be installed in public/js folder in .bowerrc.

// .bowerrc
{
    "directory": "public/js",
    "json": "bower.json"
}

Run bower install :

bower install

For Ember 1.10, As we will need template compilation, We need to require ember-template-compiler like shown in here. To make it included, we need to require it in layout.phtml in headScript() view helper :

echo $this->headScript()
            ->prependFile($this->basePath() . '/js/bootstrap.min.js')
            ->prependFile($this->basePath() . '/js/jquery.min.js')
            ->prependFile($this->basePath() . '/js/respond.min.js', 'text/javascript', array('conditional' => 'lt IE 9',))
            ->prependFile($this->basePath() . '/js/html5shiv.js',   'text/javascript', array('conditional' => 'lt IE 9',))

            // ember js dependencies
            ->appendFile($this->basePath() . '/js/ember/ember-template-compiler.js')
            ->appendFile($this->basePath() . '/js/ember/ember.min.js');
        ; 

Now, we need to create a new javascript file for its application specific requirement, I name it app.js :

// public/js/app.js
App = Ember.Application.create();

App.Router.map(function() {
    this.resource('home', {
        path: '/'
    });
    this.resource('about');
    this.resource('contact');
});

Layout

We need to replace :

<?php echo $this->content; ?>

with

{{outlet}}

And wrap it in <script type="text/x-handlebars"> :

// module/Application/view/layout/layout.phtml
// ...
<script type="text/x-handlebars">
        <nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
            <div class="container">
                <div class="navbar-header">
                    <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                    <a class="navbar-brand" href="<?php echo $this->url('home') ?>"><img src="<?php echo $this->basePath('img/zf2-logo.png') ?>" alt="Zend Framework 2"/> <?php echo $this->translate('Skeleton Application') ?></a>
                </div>
                
                    <div class="collapse navbar-collapse">
                        <ul class="nav navbar-nav">
                            <?php $navigationContainer = $this->navigation('navigation')->getContainer();
                                  foreach($navigationContainer as $page) {
                            ?>
                                <li>
                                    {{#link-to '<?php echo $page->get('route'); ?>'}}
                                        <?php echo $page->get('label'); ?>
                                    {{/link-to}}
                                </li>  
                            <?php   }   ?>
                        </ul>
                        
                    </div><!--/.nav-collapse -->
            </div>
        </nav>
        
        <div class="container">
            {{outlet}}
        </div>
</script>

We need to require our public/js/app.js in footer :

<?php
$script =  $this->inlineScript();
$script->appendFile($this->basePath() . '/js/app.js');

echo $script;
?>
</body> // means in the footer!

Yup, time to make ajax works, modify public/js/app.js by adding the following codes :

// public/js/app.js
// ...
App.HomeRoute = Ember.Route.extend({
   beforeModel: function() {
     return $.ajax({
        url: '/'
     })
     .then(function(response) {
        Ember.TEMPLATES.home = Ember.Handlebars.compile(response);
    });
   }
});

App.AboutRoute = Ember.Route.extend({
   beforeModel: function() {
     return $.ajax({
        url: '/about'
     })
     .then(function(response) {
        Ember.TEMPLATES.about = Ember.Handlebars.compile(response);
    });
   }
});

App.ContactRoute = Ember.Route.extend({
   beforeModel: function() {
     return $.ajax({
        url: '/contact'
     })
     .then(function(response) {
        Ember.TEMPLATES.contact = Ember.Handlebars.compile(response);
    });
   }
});

// to remove # ( hash ) in url
if (window.history && window.history.pushState) {
    App.Router.reopen({
      location: 'history'
    });
}

Great! If everything ok, then your ZF2 app with Ember.js should work like a magic! The requested page loaded without refreshing the page!. about-png

Bonus

You can make ‘li’ under ‘ul’ for navigation class setted to active when it in the page, with create new ‘li’ component, we can add it in public/js/app.js

// public/js/app.js
// ...
App.LinkLiComponent = Ember.Component.extend({
  tagName: 'li',
  classNameBindings: ['active'],
  active: function() {
    return this.get('childViews').anyBy('active');
  }.property('childViews.@each.active')
});

Ember.Handlebars.helper('link-li', App.LinkLiComponent);

And then, we can modify the looks like :

// module/Application/view/layout/layout.phtml
// ...
<?php $navigationContainer = $this->navigation('navigation')->getContainer();
      foreach($navigationContainer as $page) { ?>

     {{#link-li}}
        {{#link-to '<?php echo $page->get('route'); ?>'}}
           <?php echo $page->get('label'); ?>
        {{/link-to}}
     {{/link-li}}  

<?php   }   ?>

Ok, I hope it useful for you ;). Want to grab the sourcecode ? Clone from my repository https://github.com/samsonasik/zfember 😉

Images :
1. http://www.gravatar.com/avatar/0cf15665a9146ba852bf042b0652780a?s=200
References :
1. http://emberjs.com/
2. http://code.tutsplus.com/tutorials/getting-into-ember-js-part-2–net-31132
3. http://code.tutsplus.com/tutorials/getting-into-emberjs-part-3–net-31394
4. http://stackoverflow.com/questions/17792280/ember-live-uploading-templates
5. http://stackoverflow.com/questions/19871265/ember-js-with-external-handlebars-template
6. http://stackoverflow.com/questions/14328295/how-do-i-bind-to-the-active-class-of-a-link-using-the-new-ember-router
7. http://en.wikipedia.org/wiki/Single-page_application
8. http://emberjs.com/blog/2015/02/07/ember-1-10-0-released.html

Advertisements

Using PHP Phantomjs with Codeception

Posted in Javascript by samsonasik on December 18, 2014

phantomjs logoWhen you do a web acceptance test for web with javascript support, and you want to use phantomjs but doesn’t have root access to install new application, you probably need this, the “jonnyw/php-phantomjs” lib. You can install via composer parallel with “codeception/codeception” by configuring composer.json like the following :
 

{
    "require": {
        "codeception/codeception": "2.*",
        "jonnyw/php-phantomjs": "3.*"
    },
    "scripts": {
        "post-install-cmd": [
            "PhantomInstaller\\Installer::installPhantomJS"
        ],
        "post-update-cmd": [
            "PhantomInstaller\\Installer::installPhantomJS"
        ]
    }
}

and then run :

composer install

Ok, when everything installed, you already have : vendor/bin/phantomjs executable file.

If you add :

   "config": {
        "bin-dir": "bin"
    }

Inside your composer.json, you should have individual bin folder outside the vendor folder so you can run from it like described at http://jonnnnyw.github.io/php-phantomjs/. I personally like it should be inside the vendor instead. You can choose what you prefer.

Next step is start the phantomjs service by run command :

vendor/bin/phantomjs --webdriver=4444

Let’s continue to the sample page, try create a sample html page :

<html>
<body>

   <h1>Hello World!</h1>
 
  <button name="test-btn" id="test-btn">test-btn</button>
  <script type="text/javascript" src="jquery.js"></script>
  <script type="text/javascript">
    $(document).ready(function() {
       $("#test-btn").click(function() {
            $("h1").html("abcdef");
       });
    });
  </script> 

</body>
</html>

At this sample page, we want to :

if user go to /index.html, he will see “Hello World!” and don’t see the “abcdef” inside “h1” and then if user click “#test-btn” then he can see “Hello World!” replaced with “abcdef” and see the “abcdef” inside “h1”.

Now, let’s initialize the codecept by open separate console window and run :

vendor/bin/codecept bootstrap

Then, call command :

vendor/bin/codecept generate:cept acceptance Index

We then will get pre-filled configuration and make tests with folder named “tests”. What we need to do, is configure the ‘tests/acceptance.suite.yml’ file like the following :

# Codeception Test Suite Configuration
# filename tests/acceptance.suite.yml
class_name: AcceptanceTester
modules:
    enabled: [WebDriver]
    config:
        WebDriver:
            url: 'http://localhost/codeceptiontest/' # our url base
            browser: firefox
            capabilities:
                unexpectedAlertBehaviour: 'accept'

Great! then we can create a test in ‘tests/acceptance/IndexCept.php’ :

// filename : tests/acceptance/IndexCept.php
$I = new AcceptanceTester($scenario);
$I->wantTo('see home page');
$I->amOnPage('/index.html');
$I->see('Hello World!');
$I->dontSee("abcdef", '//body/h1');
$I->click('#test-btn');
// $I->wait(1); // you can set delay
$I->See('abcdef','//body/h1');

And finally! Run the test!

vendor/bin/codecept run acceptance

run-test-codeception-php-phantomjs

Done 😉

References :
1. http://jonnnnyw.github.io/php-phantomjs/
2. http://codeception.com/docs/modules/WebDriver

Tagged with:

Re-fill selectize js value

Posted in Javascript, Teknologi by samsonasik on November 28, 2014

It’s been a while since I didn’t write a post about non-framework category. Ok, this time, I will show you how to use selectize js on re-fill functionality. Selectize js is a jQuery plugin that useful for tagging and autocomplete. I used it in several projects. Once it’s installed and selectize() called, your form can be like the following :
selectize-1
In images demo above, I want to re-set the “district” based on the “province” changes by javascript. To make selectize still applied to “district”, you need to do :

  • re-set Html option values
  • re-set selectize value options

Ok, let’s do a demo application for this.
1. Preparation
1.a make bower.json for dependency requirements definition

{
    "name":"Selectize Demo",
    "dependencies": {
        "jquery": "1.11.1",
        "selectize":"0.11.2"
    }
}

1.b make .bowerrc for specification

{
    "directory": "js",
    "json": "bower.json"
}

1.c install dependencies

bower install

2. Initialize selectize
We can initialize selectize js by include it in the header ( js and css ) like this :

    <link href="./js/selectize/dist/css/selectize.default.css" media="screen" rel="stylesheet" type="text/css">

    <script type="text/javascript" src="./js/jquery/dist/jquery.min.js"></script>
    <script type="text/javascript" src="./js/selectize/dist/js/standalone/selectize.min.js"></script>

and then, we create the elements which we want to selectize :

<form method="post">

     <select name="province_id" id="province_id">
            <option value="0">--Select Province--</option>
            <option value="1">Jawa Barat</option>
            <option value="2">Jawa Tengah</option>
      </select>

      <select name="district" id="district">
            <option value="0">--Select District--</option>
      </select>

</form>

Now, time to execute :


        $(document).ready(function() {
            //initialize selectize for both fields
            $("#province_id").selectize();
            $("#district").selectize();
        });  

3. Do the awesome
Ok, now what ? We need to re-fill the “district” data on change of “province”, In this case, I wrote a case when using Ajax request and catched by PHP script. So, create a “change-data.php” file :

<?php

if (isset($_POST['province_id'])) {

    $data = [];
    if ($_POST['province_id'] == 1) {
        $data = [
            0 => [
                'id' => 1,
                'name' => 'Bandung',
            ],
            1 => [
                'id' => 2,
                'name' => 'Cimahi',
            ]
        ];
    }

    if ($_POST['province_id'] == 2) {
        $data = [
            0 => [
                'id' => 3,
                'name' => 'Kudus',
            ],
            1 => [
                'id' => 4,
                'name' => 'Cirebon',
            ]
        ];
    }

    echo json_encode($data);
}

Basically, the selectize can be filled by json object that have “text” and “value” key, like the following :

[
    {text: "Bandung", value: 1 },
    {text: "Cimahi", value: 2 }
]

So, we need to get the data, and convert to json object, we can do with eval :

new_value_options = eval('(' + new_value_options + ')');

Ok, now, let’s do this :

$(document).ready(function() {
            //initialize selectize for both fields
            $("#province_id").selectize();
            $("#district").selectize();

            // onchange
            $("#province_id").change(function() {
                $.post('./change-data', { 'province_id' : $(this).val() } , function(jsondata) {
                    var htmldata = '';
                    var new_value_options   = '[';
                    for (var key in jsondata) {
                        htmldata += '<option value="'+jsondata[key].id+'">'+jsondata[key].name+'</option>';

                        var keyPlus = parseInt(key) + 1;
                        if (keyPlus == jsondata.length) {
                            new_value_options += '{text: "'+jsondata[key].name+'", value: '+jsondata[key].id+'}';
                        } else {
                            new_value_options += '{text: "'+jsondata[key].name+'", value: '+jsondata[key].id+'},';
                        }
                    }
                    new_value_options   += ']';

                    //convert to json object
                    new_value_options = eval('(' + new_value_options + ')');
                    if (new_value_options[0] != undefined) {
                        // re-fill html select option field 
                        $("#district").html(htmldata);
                        // re-fill/set the selectize values
                        var selectize = $("#district")[0].selectize;

                        selectize.clear();
                        selectize.clearOptions();
                        selectize.renderCache['option'] = {};
                        selectize.renderCache['item'] = {};

                        selectize.addOption(new_value_options);

                        selectize.setValue(new_value_options[0].value);
                    }

                }, 'json');
            });
        });

That’s it, hope it helpful. Want to grab the code ? grab it from https://github.com/samsonasik/selectize-demo

Tagged with: ,

Zend Framework : CSRF ( Cross Site Request Forgery ) Protection

Posted in Javascript, Teknologi, Tutorial PHP, Zend Framework by samsonasik on May 6, 2011

XHR (  XMLHttpRequest ) adalah backbone dari aplikasi web 2.0. Adalah fungsi javascript yang powerfull yang menciptakan HttpRequest. Namun, dari kemudahan yang didapat, ternyata XHR menghadirkan konsekuensi tersendiri, yaitu security hole. XHR, seperti yang telah diatur oleh W3C (  World Wide Web Consortium ), hanya digunakan ketika request itu berasal dari website di mana javascript di muat ( same origin ) untuk menghindari penyalahgunaan dari pihak yang tidak bertanggungjawab.
‘Tekanan’ untuk membolehkan adanya akses cross domain mengingkat dengan adanya konsep mash-ups (sebuah konsep di mana membolehkan data dari beberapa site untuk bisa digabungkan dalam satu single view). Requirement ini bertentangan dengan “same origin policy” ( kebijakan penggunaan request dalam site yang sama)  yang diformulasikan untuk XHR. Sebagai response dari kebutuhan ini, maka kebijakan tersebut  diextends ke “level 2” standard, yang membolehkan akses cross domain jika persyaratan lain terpenuhi, untuk melindungi pengguna (W3C Web Applications Working Group, 2008).
Baca Selengkapnya

CORS ( Cross-Origin Resource Sharing ) : connecting multiple site with multiple request method

Posted in Javascript, Teknologi by samsonasik on April 23, 2011

CORS adalah draft teknologi yang dikembangkan oleh W3C sebagai alternatif yang lebih modern ketimbang JSONP. Ketika JSONP hanya men-support  GET request method, CORS juga mensupport POST request method. Teknologi ini dikembangkan karena semakin kompleksnya kebutuhan mashup data di dunia internet. Ide dasar dari CORS ini adalah meng-custom HTTP Header agar client dan server dapat mengetahui satu sama lain apabila request dan response berhasil atau gagal dilakukan.
Kali ini, saya akan mencoba memaparkan tentang contoh implementasi CORS menggunakan jQuery javascript library, dan plugin CORS. Plugin asli dapat didownload di sini , yang akan saya sampaikan di sini sudah saya modifikasi dari aslinya untuk kebutuhan jQuery versi 1.5.
Pertama, kita siapkan dulu jQuery library kita, bisa didownload di sini. Setelah itu, kita buat plugin untuk handle CORS sebagai berikut :

(function($) {
    //activate cors support <-- for jQuery 1.5
    jQuery.support.cors = true;

    $.corsGET = function(url,callback){
        try{
           jQuery.get(url, callback);
        }catch(e){
            // jQuery get() failed, try IE8 CORS, or use the proxy
            if (jQuery.browser.msie && window.XDomainRequest) {
                // Use Microsoft XDR
                var xdr = new XDomainRequest();
                xdr.open("get", url);
                xdr.onload = function() {
                    callback(this.responseText, 'success');
                };
                xdr.send();
            } else{
                try {
                    // Ancient browser, use our proxy
                    var ancientcallback = function() {
                    var textstatus = 'error';
                    var data = 'error';

                    if ((this.readyState == 4)
                        && (this.status == '200')) {
                            textstatus = 'success';
                            data = this.responseText;
                        }
                        callback(data, textstatus);
                    };

                    // proxy_xmlhttp is a separate script you'll have to set up
                    request = new proxy_xmlhttp();
                    request.open('GET', url, true);
                    request.onreadystatechange = ancientcallback;
                    request.send();
                } catch(e) {
                    // Could not fetch using the proxy
                    alert('failed !!! ');
                }
            }
        }
    };

    $.corsPOST = function(url,data,callback){
        try{
            jQuery.post(url, data, callback);
        }catch(e){
             // jQuery post() failed, try IE8 CORS, or use the proxy
            if (jQuery.browser.msie && window.XDomainRequest) {
                // Use XDR
                var xdr = new XDomainRequest();
                xdr.open("post", url);
                xdr.send(params);
                xdr.onload = function() {
                    callback(xdr.responseText, 'success');
                };
            } else{
                try {
                    // Use the proxy to post the data.
                    request = new proxy_xmlhttp();
                    request.open("POST", url, true);
                    request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
                    request.send(params);
                } catch(e2) {
                   // could not post using the proxy
                   alert('failed !!! ');
                }
            }
        }
    };

})(jQuery);

Kita bisa simpan plugin ini dan kita beri nama : jquery.cors.js . Ok, setelah itu kita buat contoh file sebagai requester cross domain kita, contoh sebagai berikut :

<!DOCTYPE html>
<html>
<head>
  <title>
      Test CORS ( Cross-Origin Resource Sharing )
  </title>
  <script type="text/javascript" src="jquery-1.5.2.min.js"></script>
  <script type="text/javascript" src="jquery.cors.js"></script>
  <script type="text/javascript">
     $(document).ready(function(){
         $("#sendDataBtn").click(function(){
            //clear label ...
            $("#resultcors").html();

            if ($("#typeofparameter").val()=='get'){
              $.corsGET('http://service.yourdomain.com?nama='+$("input[name=nama]").val()+'&'+(new Date()).getTime() ,
                function(data){
                  $("#resultcors").html('The response is : '+data);
              });
            }else{
              $.corsPOST('http://service.yourdomain.com?'+(new Date()).getTime() , {  nama: $("input[name=nama]").val() },
                function(data){
                  $("#resultcors").html('The response is : '+data);
              });
            }
         });
     });
  </script>
</head>
<body>
    <input type="text" name="nama" size="50" /> <br />
    type : <select name="typeofparameter" id="typeofparameter">
               <option value="get">GET</option>
               <option value="post">POST</option>
           </select>

    <input type="button" id="sendDataBtn" value="Send Data" />

    <br />
    <label id="resultcors"></label>

</body>
</html>

Kalau sudah, kita buat deh file responder-nya ( kita buat di server lain atau atas nama domain lain).

<?php
// Specify domains from which requests are allowed
header('Access-Control-Allow-Origin: *');
// Specify which request methods are allowed
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
// Additional headers which may be sent along with the CORS request
// The X-Requested-With header allows jQuery requests to go through
header('Access-Control-Allow-Headers: X-Requested-With');
// Set the age to 1 day ( 86400 ) to improve speed/caching.
header('Access-Control-Max-Age: 86400');

// Exit early so the page isn't fully loaded for options requests
if (strtolower($_SERVER['REQUEST_METHOD']) == 'options') {
    exit();
}

// If raw post data, this could be from IE8 XDomainRequest
// Only use this if you want to populate $_POST in all instances
if (isset($HTTP_RAW_POST_DATA)) {
    $data = explode('&', $HTTP_RAW_POST_DATA);
    foreach ($data as $val) {
       if (!empty($val)) {
         list($key, $value) = explode('=', $val);
         $_POST[$key] = urldecode($value);
       }
    }
}

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    echo  '<strong>posted</strong> : '.strtoupper(  $_REQUEST['nama'] );
}

if ($_SERVER['REQUEST_METHOD'] == 'GET') {
    echo '<strong>getted </strong> : '.strtoupper(  $_GET['nama'] );
}

Taraaaa….Sehingga jika ditest, akan tampil sebagai berikut :

Gambar :
http://t2.gstatic.com/images?q=tbn:ANd9GcSbW9iPimNholkyrzJ2tvD-uqRQ8_5KkBC4hVLys9XEVh4KTN81

Referensi :
http://plugins.jquery.com/project/cors
http://en.wikipedia.org/wiki/Cross-Origin_Resource_Sharing
http://en.wikipedia.org/wiki/JSONP
http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/
http://enable-cors.org/
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
https://developer.mozilla.org/en/http_access_control
http://blueonionsoftware.com/blog.aspx?p=03aff202-4198-4606-b9d6-686fd13697ee
http://msdn.microsoft.com/en-us/library/cc288060%28v=vs.85%29.aspx

Zend Framework : Output Escaping – preventing XSS

Posted in Javascript, Teknologi, Tutorial PHP, Zend Framework by samsonasik on April 19, 2011

Cross-site scripting (XSS) merupakan salah satu jenis serangan injeksi kode yang secara umum ditemukan di aplikasi berbasis web melalui client-side script.  Salah satu cara menanganinya adalah dengan cara meng-escape output yang tampil pada halaman web. Pada Symfony Framework, output escaping otomatis dilakukan oleh framework itu sendiri, untuk Zend Framework , preventing XSS adalah tugas programmer :). XSS terjadi di bagian View, maka dari itu, Zend Framework menyediakan component Zend_View ( “view” portion of the ZF model-view-controller pattern) yang bisa digunakan untuk meng-escape output dari misalnya :

<script type="text/javascript">alert('hello');</script>

menjadi :

&lt;script type="text/javascript"&gt;alert('hello');&lt;/script&gt;

Sehingga kode javascript tidak tereksekusi. Nah, ada 2 cara penggunaan metode ini :
1. Encoding before echoing
Di layer View, tinggal kita panggil :

<?php echo $this->escape("<script type=\"text/javascript\">alert('hello');</script>"); ?>

2. Encoding when assigning template variables
Cara yang kedua ini, kita escape dulu di controller, contoh sebagai berikut :

$this->view->title = $this->view->escape("<script type=\"text/javascript\">alert('hello');</script>");

Baru di layer view :

 echo $this->title; 

Referensi :
http://www.scribd.com/doc/18171526/Secure-Programming-with-the-Zend-Framework
http://www.minte9.com/kb/zend-view-helper-programming-zend-framework-i329
http://devzone.zend.com/article/3412
http://en.wikipedia.org/wiki/Client-side_script
http://en.wikipedia.org/wiki/Cross-site_scripting
http://id.wikipedia.org/wiki/XSS
http://stackoverflow.com/questions/507593/what-is-the-best-way-to-escape-user-output-with-the-zend-framework

YQL AND JSON – Cross Domain Request Handling

Posted in Javascript, Teknologi by samsonasik on March 17, 2011
YQL Logo

YQL

YQL ( Yahoo! Query Language ) adalah Bahasa Query yang dibuat oleh Yahoo! ( sebagai bagian dari Yahoo! Developer Network ).  YQL memungkinkan kita untuk mengquery, filter, dan mengkombinasikan data dari sumber-sumber yang berbeda di internet. Statement YQL berupa sintaks yang mirip SQL yang memudahkan developer untuk mempelajarinya.

Untuk mengakses YQL Web Service, aplikasi web kita dapat memanggil HTTP GET, passing YQL statement di URL Parameter seperti contoh berikut :

http://query.yahooapis.com/v1/public/yql?q=SELECT * FROM flickr.photos.search WHERE text="Cat"

Baik, saya akan mencoba memberi sebuah contoh simple penggunaan YQL dengan Ajax request ( menggunakan jQuery javascript library ). Anggaplah kita mempunyai server side application berupa sebuah file php dengan content sebagai berikut  ( dengan domain http://subdomain.yourdomain.com dan file yang diakses adalah file.php ) :

<?php
$data = array('nama' =>
 array('aku','kamu','dia','anda','mereka','saya','SAMSONASIK'));

echo json_encode($data);

Nah, kita akan coba akses dari client secara Ajax, dengan kode sebagai berikut :

<html>
 <head>
 <script type="text/javascript" src="jquery.js"></script>
 <script type="text/javascript">

 $(document).ready(function(){
 $("#crosscaller").click(function(){
 //get current time content ...
 var site = 'http://subdomain.yourdomain.com/file.php?'+(new Date()).getTime();
 //yql ...
 var yql = 'http://query.yahooapis.com/v1/public/yql?q=' + encodeURIComponent('select * from html where url="' + site + '"') + '&format=xml&diagnostics=false&_maxage=1';

 // Request that YSQL string, and run a callback function.
 $.ajax({url: yql,
 dataType: 'json',
 jsonp: 'callback',
 jsonpCallback: 'callhandler'
 });
 });
 });

 function callhandler(data) {
 // If we have something to work with...
 if ( data.results[0] ) {
 // Strip out all script tags, for security reasons.
 // BE VERY CAREFUL. This helps, but we should do more.
 data = data.results[0].replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '');

 $("#result").html('').html(data);

 var jsondataHTML  = $("#result p").html() ;

 var ItemsJson = JSON.parse(jsondataHTML);

 //get items of json object ...
 alert(ItemsJson.nama[1]);

 }
 // Else, Maybe we requested a site that doesn't exist, and nothing returned.
 else {throw new Error('Failed ...');}
 }

 </script>
 </head>
<body>
 <input type="button"  id="crosscaller" value="get your domain content" />

 <!-- get data -->
 <div id="result"></div>

</body>
</html>

Sehingga jika kita run, akan tampil sebagai berikut :

Image :
http://l.yimg.com/a/i/us/pps/yql128.gif
Referensi :
http://developer.yahoo.com/yql/guide/running-chapt.html
http://icant.co.uk/articles/crossdomain-ajax-with-jquery/
https://gist.github.com/raw/726079/a67c59253fa9700e1d29a5af100b9b2a937f0ad0/yql-cross-domain.html

jQuery – membuat plugin sendiri

Posted in Javascript by samsonasik on November 2, 2010

Selain Prototype Javascript library,  jQuery adalah salah satu library javascript yang banyak dipakai para developer ( kalau saya sih, tukang nonton kamen rider aja, hehehehe).  jQuery mempunyai ukuran yang relative kecil dibandingkan dengan library-library javascript lainnya dan mudah untuk dipelajari. Kita bisa dengan mudah meng-extends core library jQuery, dan membuat plugin sendiri untuk kebutuhan kita yg lebih spesifik.
Pada kesempatan kali ini, saya akan mencoba memaparkan cara membuat plugin sendiri di jQuery.
Hal pertama yg harus kita lakukan adalah menambahkan property ke dalam jQuery.fn object (  anggaplah kita akan membuat sebuah plugin untuk animasi menggoyang element ),  simpan dalam file goyang.jQuery.js

 $.fn.goyang = function(){};

Jika kita ingin menambahkan parameter, kita bisa gunakan seperti berikut :

 $.fn.goyang = function(options){};

Berikut contoh coding  jquery plugin untuk menggoyang element :

$.fn.goyang = function(options){
//setting default value jika parameter tidak dilewatkan
var    defaults = {
 left:'500',
 right:'1000'
 },
 settings = $.extend({}, defaults, options);

 var element = this;  //"this" adalah DOM object
 var leftpost = parseInt($(element).css("left")) -  parseInt(settings.left);
 $(element).click(function(){
 //geser kiri...
 $(element).animate({
 left:  leftpost
 },function(){
 //geser kanan...
 $(element).animate({ left: leftpost + parseInt(settings.right) });
 });
 });
};

Nah, kalau sudah, kita tinggal panggil deh :

<script type="text/javascript" src="jquery-1.4.2.js"></script>
<script type="text/javascript" src="goyang.jQuery.js"></script>
<script type="text/javascript">
 $(document).ready(function(){
$('#book').goyang({   /* override default value */     left:'300', right:'700' });
 });
</script>

<div>
 <img  id="book" src="book.png" alt="" width="100" height="200" style="position: relative;left:600px"/>
</div>

simple kan ? hehehe
——————————
This article contained copyrighted material licensed under various creative commons licenses unless otherwise noted:
Image :
http://tpgblog.com/2009/11/30/jquery-plugin-its-cutetime-1-0-5/
Articles :
http://docs.jquery.com/Plugins/Authoring
http://net.tutsplus.com/articles/news/learn-how-to-create-a-jquery-plugin/
http://net.tutsplus.com/articles/news/you-still-cant-create-a-jquery-plugin/
http://jqfundamentals.com/book/book.html
jQuery 1.4 API ( CHM Version )

Zend Framework : ZendX_JQuery, View Helper untuk mengintegrasikan jQuery dan ZF

Posted in Javascript, Tutorial PHP, Zend Framework by samsonasik on August 1, 2010

ZendX merupakan Zend Framework Extensions Library , dibuat untuk meningkatkan kemampuan Zend Library itu sendiri secara lebih spesifik untuk kebutuhan-kebutuhan yang spesifik pula. Seperti halnya Zend_Dojo yang telah ada sebelumnya, ZenX_JQuery_View_Helper digunakan untuk mengintegrasikan jQuery dengan Zend Framework. ZendX_JQuery ini secara default mengimplementasikan Data Mashup,  di mana resource-resouce yang dibutuhkan ( dalam hal ini library jQuery) dipanggil secara outsource. Kita tidak perlu menginclude secara manual library jQuery-nya, karena otomatis akan dipanggil secara mashup, dalam kasus ini dari googleapis.

Berikut contoh kode programnya.
Pertama, kita set Helper untuk View dari Bootstrap.php

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
 function _initView()
 {
 $view = new Zend_View();
 $view->addHelperPath('ZendX/JQuery/View/Helper/', 'ZendX_JQuery_View_Helper');

 $viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
 $viewRenderer->setView($view);
 Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
 }
}

Setelah itu, kita tinggal panggil  di layout :

<html>
<head><title>JQuery and ZF Integration</title>
<?php echo $this->jQuery(); ?>
</head>
<body>
<?php echo $this->layout()->content; ?>
</body>
</html>

Ok, kalau sudah, kita bisa panggil di View :

<?php echo $this->ajaxLink("Show me something",
 $this->baseUrl()."/partialrenderer/loadhello",
 array('update' => '#content'));?>

Kalau di view source, akan tergenerate secara otomatis javascript seperti di bawah ini :

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
//<!--
$(document).ready(function() {
    $('a.ajaxLink1').click(function() { $.get('/zftutwordpress/public/partialrenderer/loadhello', {}, function(data, textStatus) { $('#content').html(data); }, 'html');return false; });
});
//-->
</script>

Lalu bagaimana jika tidak tersedia jaringan internet ? Kita bisa setlocalpath-nya dengan cara mengubah kode programnya menjadi seperti di bawah ini :

<html>
<head><title>JQuery and ZF Integration</title>
<?php echo $this->jQuery()->setLocalPath(path/to/jquery.js); ?>
</head>
<body>
<?php echo $this->layout()->content; ?>
</body>
</html>

This article contained copyrighted material licensed under various creative commons licenses unless otherwise noted:
Photo :
1. http://www.lgeoresearch.com/wp-content/themes/arthemia-premium/scripts/timthumb.php?src=/img/MashupHandshake.jpg&w=150&h=150&zc=1&q=100
Articles :
1. http://framework.zend.com/manual/en/
2. http://code.google.com/p/zendx/

Object Oriented JavaScript

Posted in Javascript by samsonasik on July 30, 2010

Sudah Javascript, Object Oriented lagi ? Heu..heu…, OOP nya aja masih Oge-oge Pusing, xi.xi.xi. :D. Bayangkan, dalam Javascript, Array adalah Object, Function adalah Object, Object adalah Object, so, Object dalam javascript itu apa ? Object dalam javascript adalah koleksi pasangan nama-nilai. Nama-nama berupa string, dan value bisa berupa Strings, numbers, booleans, dan objects (haiyah, tambah puyeng dah 😛 ). Ok, Lanjutttt…

Jika value adalah function, kita bisa bilang bahwa itu adalah method. Ketika sebuah metode objek dipanggil, variabel ini disetel ke objek. method dapat memanggil instance variable dengan keyword this.

contoh :

function setJs(str)
{
   this.MemberStr = str;
}

Maka, Jika kita instansiasi menjadi object :

var objSetStr = new setJs('this is a string');

maka, objSetStr.MemberStr berisi value ‘this is a string’
Penggunaan keyword this menunjukkan bahwa atribut itu bermodifier public , bagaimana dengan atribut bermodifier private ?
Cara pembuatan private modifier adalah dengan var , contoh  :

function HaiFromJs(str){
 //memberattr adalah atribut bermodifier private
//ia tidak bisa dipanggil dari luar function secara langsung.
 var memberattr = str ;
 this.hai = function(){
 alert ( "Hai " +memberattr+"\n apa kabar ? ");
 }
 }

 //buat object
 var haiObj = new HaiFromJs( "Samsonasik" );
 haiObj.hai();

sumber :
http://www.crockford.com/javascript/private.html
http://t1.gstatic.com/images?q=tbn:RhNF4WHmbEsPXM::&t=1&usg=__3rGjJy1YhTIJOBhFLOXM7dzC8iM=
http://en.wikipedia.org/wiki/Javascript
http://en.wikipedia.org/wiki/Class_%28computer_science%29
John Resig : Secrets Of the Javascript Ninja.

jQuery : Ajax Multi Window Modal using jQueryUI

Posted in Javascript by samsonasik on June 7, 2010

jQueryUI adalah bundle untuk low-level abstraction jQuery library untuk kebutuhan interaksi dan efek. jQueryUI mempunyai banyak theme yang bisa kita pilih serta kita modifikasi sesuai kebutuhan.

Pada kesempatan kali ini, saya akan mencoba memaparkan tentang Ajax Multi Window Modal dengan jQueryUI. Untuk yang terbiasa memakai prototype javascript Framework tentulah telah terbiasa dengan multi windownya. Bagaimana dengan jQuery ? Saya pernah discuss dengan salah satu senior saya di kantor saya dulu, kalau untuk jQuery, kita memang harus pintar-pintar memilah mana yang cocok untuk dipakai ( karena ke-OpenSource-annya , banyak developer-developer yang mengembangkan plugin-plugin yang tentu tidak termonitor dengan baik dari sisi kualitasnya – baca : salah satu kelemahan open source,- kalau untuk kelebihan opensource tentu tidak perlu kita bicarakan di sini 🙂 ). jQueryUI adalah salah satu bundle library yang sangat saya rekomendasikan untuk dipakai karena dikembangkan dengan jQuery’s event-driven architecture

Ok, let’s begin.
Pertama, kita download dulu jQueryUI nya. Setelah itu, kita bisa pilah folder-folder dalam development bundle yang telah kita download tadi. Kita hanya butuh library jQuery nya, kemudian folder external, themes, dan ui, setelah itu baiknya kita kelompokkan dalam satu folder khusus. seperti berikut.

Dari gambar di atas, ceritanya index.html adalah file utama yang akan menampilkan halaman-halaman lain dalam bentuk window modal, loaded.html adalah isi window pertama yang akan ditampilkan, dan loaded2.html adalah isi window kedua yang akan ditampilkan.
Nah, setelah kita siapkan file-file di atas, saatnya coding 😀

<script type="text/javascript" src="jquery-1.4.2.js"></script>
<link type="text/css" href="jqueryUI/themes/start/jquery.ui.all.css" rel="stylesheet" />
<script type="text/javascript" src="jqueryUI/external/jquery.bgiframe-2.1.1.js.js"></script>
<script type="text/javascript" src="jqueryUI/ui/jquery.ui.core.js"></script>
<script type="text/javascript" src="jqueryUI/ui/jquery.ui.widget.js"></script>
<script type="text/javascript" src="jqueryUI/ui/jquery.ui.mouse.js"></script>
<script type="text/javascript" src="jqueryUI/ui/jquery.ui.draggable.js"></script>
<script type="text/javascript" src="jqueryUI/ui/jquery.ui.position.js"></script>
<script type="text/javascript" src="jqueryUI/ui/jquery.ui.resizable.js"></script>
<script type="text/javascript" src="jqueryUI/ui/jquery.ui.dialog.js"></script>
<script type="text/javascript">
//variable for options value of window
var dialogOpt1,dialogOpt2 = {};
//variable check if popop opened
var setpopup1,setpopup2 = false;
//for popup1
function setOpts1(tinggi,lebar,judul,url)
{
 //reset...
 setpopup1 = true;

 //set options
 dialogOpt1 = {
 bgiframe: true,
 modal: true,
 autoOpen: false,
 height:tinggi,
 width:lebar,
 draggable: true,
 resizeable: true,
 title:judul
 };

 //assign idwindow
 $("#example").dialog(dialogOpt1);
 $("#example").load(url, [], function(){
 $("#example").dialog("open");
 }
 );
}

//for popup2
function setOpts2(tinggi,lebar,judul,url)
{
 //reset...
 setpopup2 = true;

 //set options
 dialogOpt2 = {
 bgiframe: true,
 modal: true,
 autoOpen: false,
 height:tinggi,
 width:lebar,
 draggable: true,
 resizeable: true,
 title:judul
 };

 //assign idwindow
 $("#example2").dialog(dialogOpt2);
 $("#example2").load(url, [], function(){
 $("#example2").dialog("open");
 }
 );
}

$(document).ready(function(){
 //for auto center windows if page is long
 $(window).bind('scroll', function() {
 dialogOpt1.position  = 'center';
 dialogOpt2.position  = 'center';
 if (setpopup1==true && $(".ui-dialog").css("display")!="none" )  $("#example").dialog(dialogOpt1);
 if (setpopup2==true && $(".ui-dialog").css("display")!="none" )  $("#example2").dialog(dialogOpt2);
 });
});
</script>

<input type="button" value="show" onclick="setOpts1(400,900,'First Content','loaded.html');"/>
<div id="example"></div>
<div id="example2"></div>

Kalau sudah, kita siapkan file dengan content yang akan dipanggil.
a. loaded.html ( file pertama yg diload / popup window modal pertama )

<input type="button" id="showdialog2" value="show" onclick="setOpts2(200,400,'Second Content','loaded2.html');"/>
First Modal

b. loaded2.html ( file kedua yg diload / popup window modal kedua)

Second Modal.

Ok, kalau sudah, tinggal kita test, sehingga tampil seperti berikut :

jQuery – Using JSON for data transfers

Posted in Javascript, tips and tricks, Tutorial PHP by samsonasik on April 14, 2010

JSON (dilafalkan “Jason”),  adalah singkatan dari JavaScript Object Notation (bahasa Indonesia: notasi objek JavaScript), adalah suatu format ringkas pertukaran data komputer. Formatnya berbasis teks dan terbaca-manusia serta digunakan untuk merepresentasikan struktur data sederhana dan larik asosiatif (disebut objek).

Penggunaan JSON pada pertukaran transfer data, terutama ketika kita menggunakan AJAX, sangatlah bermanfaat, tapi tentu saja alangkah lebih baiknya, jika selain memanfaatkan JSON secara murni, kita juga tahu tools-tools yang bisa digunakan agar pemanfaatan JSON bisa lebih cepat. Salah satu Tools yang bisa digunakan adalah Javascript Library yang tentu sudah tidak asing lagi bagi kita semua, yaitu jQuery.

Ok, saya akan memberikan satu contoh sederhana pemanfaatan JSON menggunakan jQuery javascript library dan PHP.
Pertama, kita siapkan file2 yang dibutuhkan, seperti gambar berikut:

Keterangan :
1. frmjson.html     : file view kita.
2. getjson.php       : serverside script untuk menangkap data yang ditransfer.
3. jquery-1.4.2.js : Javascript library-nya.
————
Now, let’s coding :
1. frmjson.html

<!-- frmjson.html -->
<script type="text/javascript" src="jquery-1.4.2.js"></script>
<script type="text/javascript">
 $(document).ready(function(){
 //closure button berid = "setter" diklik...
 $("#setter").click(function(){
 $.post("getjson.php",{
 nama : $("#nama").val(),
 alamat : $("#alamat").val()
 }, function(data){
 //jika response telah berhasil... (set label...)
 $("#lblgetattr").html(data.nama+" beralamat di "+data.alamat);
 },"json");
 });
 });
</script>
Nama : <input type="text" id="nama"> <br>
Alamat : <input type="text" id="alamat"> <br>
<input type="button" value="SetAtribute" id="setter">
<br>
Atribut yang sudah terset adalah : <label id="lblgetattr"></label>

2. getjson.php :

<?php
 $data['nama'] =  strtoupper($_POST['nama']);
 $data['alamat'] = $_POST['alamat'];

 echo json_encode($data);

3. jQuery-1.4.2.js (Bisa didownload di situs http://jquery.com )

Sebelum button dengan id =”setter” diklik, maka akan tampil halaman seperti ini :

Dari gambar di atas, kita belum melihat respon apa2 karena button dengan id =”setter” belum kita klik, jika kita isi nama dan alamat, kemudian kita klik button dengan id=”setter” tersebut, maka akan tampil seperti berikut :

Gambar di atas menunjukkkan dari sisi background, javascript mengirimkan request ke getjson.php , kemudian response tersebut dikirim ke browser, dan ditampilkan di view browser.

Asik kan yach ? welcome to RIA world 🙂
———————–

Referensi :
http://id.wikipedia.org/wiki/JSON
http://json.org/
http://jquery.com

Tagged with: ,