Friday, October 4, 2013

Remote debugging your php project with Netbeans and Xdebug via ssh

Recently I needed to remotely debug my app. Naturally attempt failed. And I began to look for what is wrong.
To make the story short, you need to pay attention to following things:
1. Ensure that xdebug is properly configured on your remote server. You can google 'netbeans xdebug' for this issue.
2. In your netbeans open project properties. Go to 'Run options' then at right bottom corner click 'Advanced'. Now you can see debugging config.
3. Now fill 'Path mapping' config. Key rule here is in server path: path must be real path to the project web dir (where you index.php locsted) Path need to be without symlinks. It is important.
4. End finally at the right side fill path to project on your dev machine.
5. Optionally you can tick Run browser when debugging. End you done with config.

If debugging session is in state 'waiting for connection' you have something blocking between  you and your remote server. In this case you have to make sure that 9000 port is open on both sides. Also if you behind NAT, you need to set up port forwarding as well.

But, if you have ssh access to your application server. Than life will be much better, and is simple as run this command:

ssh -R 9000:localhost:9000 user@server

It will forward remote 9000 port to your computer 9000 port via ssh tunnel. In this case you need to set xdebug config param xdebug.remote_host=localhost cause it actually will be forwarded to you via ssh port forward feature. Thats it.

If you don't see green line after you start debugging session then simply ask me in the comments. I'll try to help.

Monday, September 16, 2013

Custom Asset Package for Symfony2 app or how to generate bundle assets dir in Symfony2 Twig app

If you try to google how to get bundle assets dir in your Symfony2 Twig template you find almost nothing about this.

for example to output some image you need to write following in your twig template:

<img alt="" src="/bundles/sitebundle/images/image.jpg" />

But if you prefer Symfony way, you probably write something like:

<img alt="" src="{{asset('/bundles/sitebundle/images/image.jpg')}}" />

But what if you can generate bundle assets path by bundle name, which is so familiar to you like 'YourGreatBundle' for example.

I decided to write some code for this.

Symfony's asset() twig function actually accepts 2nd argument, which is $packageName. $packageName is just named asset Package instance. By default it is PathPackage. Url for assets generated with getUrl() method of Package instance. All we need is create 
custom asset Package class, let's call it BundlePathPackage:


<?php
namespace Vendor\SiteBundle\Asset\Package;

use 
Symfony\Component\Templating\Asset\PathPackage;
use 
Vendor\SiteBundle\Asset\Package\BundlePathPackageInterface;

/**
 * Allows prepending bundle assets directory to base path
 */

class BundlePathPackage extends PathPackage implements BundlePathPackageInterface {

    
/**
     * @var string
     */
    
private $bundleDir;

    
/**
     * {@inheritdoc}
     */
    
public function __construct($basePath null$version null$format null) {
        
parent::__construct($basePath$version$format);
    }

    
/**
     * If relative url detected, also prepend bundle dir to path
     * {@inheritdoc}
     */
    
public function getUrl($path) {
        if (isset(
$this->bundleDir))
            
$path $this->bundleDir '/' ltrim($path'/');
        return 
parent::getUrl($path);
    }

    
/**
     * {@inheritdoc}
     */
    
public function setBundlePath($bundleName) {
        
$this->bundleDir 'bundles/' strtolower(str_replace('Bundle'''$bundleName));
    }

}





You can find that it extends some interface. Here it is:


<?php
namespace Vendor\SiteBundle\Asset\Package;

interface 
BundlePathPackageInterface {

    
/**
     * registers bundle dir by bundlename
     * @param string $bundleName Identical to what
     * Symfony\Component\HttpKernel\Bundle\BundleInterface->getName() gives
     */
    
public function setBundlePath($bundleName);
}
 


Almost done. Last step would be to tell Kernel that something new happens in our app. Something is Kernel event listener:

<?php
namespace Vendor\SiteBundle\Event\Listener\HttpKernel;

use 
Symfony\Component\HttpKernel\Event\KernelEvent;
use 
Vendor\SiteBundle\Asset\Package\BundlePathPackage;

class 
AssetPackageInjector {

    
/**
     * Inject custom Asset package to Kernel assets helper
     * @param \Symfony\Component\HttpKernel\Event\KernelEvent $event
     */
    
public function onKernelRequest(KernelEvent $event) {
        
$container $event->getDispatcher()->getContainer();

        
/** @var Symfony\Component\Templating\Helper\CoreAssetsHelper */
        
$assetsHelper $container->get('templating.helper.assets');

        
$bundles $container->get('kernel')->getBundles();
        foreach (
$bundles as $bundle) {
            
$bundlePathPackage = new BundlePathPackage();
            
$bundlePathPackage->setBundlePath($bundle->getName());
            
$assetsHelper->addPackage($bundle->getName()$bundlePathPackage);
        }
    }

}
 


Finally we register listener in services.yml configuration file:

services:
  vendor.site.event.listener.assetpackage:
    class: Vendor\SiteBundle\Event\Listener\HttpKernel\AssetPackageInjector
    tags:
      - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }

That's it. Now in Twig we can write following:

<img alt="" src="{{asset('images/image.jpg', 'SiteBundle')}}" />

Or with leading slash (in this case base url will be appended if not standard):

<img alt="" src="{{asset('/images/image.jpg', 'SiteBundle')}}" />

Sunday, September 15, 2013

Jenkins CI server installer for php projects

Recently, working on unit testing of Symfony2 project I thought that it'll be great to integrate Continuous Integration server. I'm using Netbeans IDE for my daily work, and found Netbeans page suggests using Jenkins CI  for php projects. So, after reading Jenkins template for php projects I decide to build installation script for it. So here it is on gihtub trig/jenkins-php-installer And is for those devs, which like to type several words in their terminal while script interactively asks some words about what it going to do, and pick some coffee. At the end of process Jenkins CI server is ready to start building tasks.

Installation script is on it's early stage, currently only in shell script. Who knows maybe it will be useful for someone searching for how to automate Jenkins CI server for php.