Welcome to Abdul Malik Ikhsan's Blog

Symfony 2.6 : The good momentum to implement “official” Symfony best practices

Posted in Symfony2 Framework, Tutorial PHP by samsonasik on November 30, 2014

Symfony 2.6 released yesterday. There are ton of features/bug fixes added. There is another thing that awesome! We can implements the “AppBundle way” of the official best practices. Although the AppBundle that mentioned in the official documentation brought by Symfony 2.6, is not in Symfony-standard yet ( at least until now), we can generate it by new updated SensioGeneratorBundle that already shipped by new symfony-standard.


So, after you generate :

php app/console generate:bundle --namespace=AppBundle \
--dir=src --format=annotation --no-interaction

Now, you can have bundle without “vendor” namespace.

Then, if you do what mentioned in the best practices, that template location in app/Resources instead (for templates that the bundle only used in your application). The project structure will like the following :
template-loc
There are complete list of “official” recommended ways to build application using Symfony application including configuration, controllers, templates, forms, internationalization, security, web assets, and tests.

One more thing, now, we can use Symfony Installer to create a new Symfony application that you can download from https://github.com/symfony/symfony-installer . The console interface of installer is pretty good :
symfony-installer1
symfony-installer2

References :
1. http://symfony.com/doc/current/best_practices/index.html
2. https://twitter.com/weaverryan/status/538610340020649984
3. https://github.com/symfony/symfony-installer

Zend Framework 2 : Using AbstractConsoleController and ConsoleModel

Posted in Tutorial PHP, Zend Framework 2 by samsonasik on November 29, 2014

zf2-zendframework2 When using console in ZF2 application, we can extends AbstractConsoleController instead of AbstractActionController. There is overridden dispatch() function in AbstractConsoleController which handle access that doesn’t come from console which is tricked like this :

// ...
    /**
     * {@inheritdoc}
     */
    public function dispatch(RequestInterface $request, ResponseInterface $response = null)
    {
        if (! $request instanceof ConsoleRequest) {
            throw new InvalidArgumentException(sprintf(
                '%s can only dispatch requests in a console environment',
                get_called_class()
            ));
        }
        return parent::dispatch($request, $response);
    }
// ...

So, by extending it, we can reduce its checking. So, our controller will look like the following :

namespace TutorialConsoleModule\Controller;

use Zend\Mvc\Controller\AbstractConsoleController;

class TutorialConsoleController extends AbstractConsoleController
{
    public function showDataAction()
    {
        // ...
    }
}

Now, we need to show something in console, instead of using Response object, we can use ConsoleModel so we can return ConsoleModel that setted with the data like this :

namespace TutorialConsoleModule\Controller;

use Zend\Mvc\Controller\AbstractConsoleController;
use Zend\Text\Table;
use Zend\View\Model\ConsoleModel;

class TutorialConsoleController extends AbstractConsoleController
{
    public function showDataAction()
    {
        $table = new Table\Table([
            'columnWidths' => [20, 20] 
        ]);
        $table->setDecorator('ascii');
        $table->appendRow(['FirstName', 'LastName']);
        $table->appendRow(['Abdul Malik', 'Ikhsan']);
        $table->appendRow(['Sharty', 'Mushlihah']);
    
        $consoleModel = new ConsoleModel();
        $consoleModel->setResult($table);
        
        return $consoleModel;
    }
}

Now, you can just register your controller into module.config.php :

return [
    
    'controllers' => [
        'invokables' => [
            'TutorialConsoleModule\Controller\TutorialConsole'
                => 'TutorialConsoleModule\Controller\TutorialConsoleController',
        ],
    ],
    
    'console' => [
        'router' => [
            'routes' => [
                'show-data' => [
                    'options' => [
                        'route'    => 'show data',
                        'defaults' => [
                            'controller' => 'TutorialConsoleModule\Controller\TutorialConsole',
                            'action'     => 'show-data'
                        ]
                    ]
                ]
            ]
        ]
    ],
];

And you can call in console :

php public/index.php show data

and you will get :
console1

Done 😉

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: ,