Sunday, February 24, 2013

Using Teamcity + ANT to deploy Yii website

Over the last couple of weeks, I've deferred a bit from my normal .NET stuff and I'm working on some PHP projects within the company. I set up a website that offers an API to our partners and I've decided to go with Yii, because it seems quite popular at the moment.

Getting into Yii is very easy - there are great 'hello world' tutorials out there and after that it's really simple to get a hang of. Anyway - I set up deployment using our Teamcity server using an ANT script. 

Here's the steps of the ANT script:

  1. Overwrite the main.config file by my custom main.live.config file - containing db connection to the production DB etc. 
  2. Update the main.php configuration file and replacing some version and build numbers, so that I can display rev. ####, build ### at the bottom.
  3. Zip the checkout folder
  4. Upload the zipped file over ssh
  5. Remote unzip the file

Deployment takes 30 seconds here . Check it out:



  
  


  
    
    
    
  


  
    
    
    
    
      
    
    
    
  


  
    
    
      
    
    
  


    
    
    
    
  

  
    
    
    
  

  
    
    
    
    


I see that the code formatter is messing up the XML code - so just copy pasting won't work I'm affraid. Echo is an empty XML node of couse - like <echo .... /> .
Anyway - for us this is a great way of deploying our Yii site quickly, with updated version numbers and custom production configuration.

Tuesday, February 12, 2013

Resharper

I've introduced ReSharper at the office, and honestly, I cannot picture developing without it anymore. It boosts productivity, improves quality and consistency of your code. I'm assuming you're all familiar with it, if not - it's a Visual Studio plugin.

Anyway - I had planned to blog about it somewhere in the future, but this guy beat me to it: Dzone article: How Resharper rocks my day.


Sublime Text - great PHP editor

This week I'm doing some PHP work since we're setting up an API and we want to run it on a linux server. Since it's been a while for me since I worked with PHP, I needed to set up my environment. I started out using Visual Studio with the PHP plugin. It's fine - but most of the nice stuff ( debugging + IntelliSense ) is in the PRO version. Moved on to NetBeans. Great stuff: IntelliSense - debugging, PHP Unit integration + many many more things. That's going to be the one I'll using. But - when looking for some PHPUnit stuff, I came across this video:

   

First of all - this guy ( Jeffrey Way I believe ) is BLAZING fast and never seems to make any mistakes. Secondly - I was intrigued by the editor he's using. It's Sublime Text. Get it here. It's not free, but doesn't cost a lot either. I downloaded it and it's SO quick. There's is the 'find everything' button CTRL-P. Use '@' as a first character to look for members. You'll probably want some plugins - get them from here and follow the instructions. I got zen-coding and PhpDoc plugins to play around a little, and recorded it.

   

Since I'm not a PHP expert - I like to get a lot of IDE support, therefore I will still be using netbeans. However - this editor is gorgeous, really intuitive and amazingly fast.

Saturday, February 9, 2013

HTML productivity booster: zen-coding

Over the last week I've written an API for my business and needed to created some documentation for it. Using Twitter bootrap, some of it looks like this:

Which looks like this in HTML:
subscription_startdate
Startdate of the subscription
subscription_enddate
Enddate of the subscription ( nullable )
subscription_typeid
Type ID of the subscription
subscription_type
Subscription type. Typically 'Business' or 'Compleet'
profile_id
The Business Compleet User ID
profile_initials
Profile initials
...
Which is formatted by Twitter Bootstrap. What I did was copy-paste a bunch of
and filled those out. What I should have done was get a zen-coding plugin for my environment ( NetBeans at the time, but it's also available for Visual Studio and Sublime text ) and use that. Zen-coding allows you to quickly generate HTML in your favorite IDE. With the plugin installed in Sublime, I type:
dl.dl-horizontal>(dt+dd)*5
Hit TAB and it results in:
BOOM! Done.

So you start out by defining you element type ('dl' in my case). The '.horizonal' sets the class very intuitively ( for id - use '#' ... obviously ). The '>' denotes the child elements. The I want a 'dt' with a 'dd' sibling - hence the '+', and that 5 times.


Monday, February 4, 2013

Using Ninject to inject session variables into controller properties

According to our JAVA developer, JAVA spring can inject session variables into controller properties. So - I was triggered to see if I could hack something together that resembles this behavior in C#, using Ninject. So here's a quick thing that I put together:
    internal class StandardKernelWithSessionResolution : StandardKernel
    {
        public override IEnumerable Resolve(Ninject.Activation.IRequest request)
        {
            if (request.Target != null && HttpContext.Current != null && HttpContext.Current.Session != null && HttpContext.Current.Session[request.Target.Name] != null)
            {
                Log.Debug("Property {0} is being injected from session", request.Target.Name);
                return new List() { HttpContext.Current.Session[request.Target.Name] };
            }
            return base.Resolve(request);
        }
    }
In your MVC application, you will need to use StandardKernelWithSessionResolution() as opposed to the StandardKernel() call. Also, you will need to instantiate the session variable once, but after that you're good:
    public class HomeController : Controller
    {
        [Inject]
        public Person SessionInjectedPerson { get; set; }

        public ActionResult Index()
        {
            this.SessionInjectedPerson = new Person();
            return View(this.SessionInjectedPerson);
        }

        public ActionResult UpdatePerson()
        {
            this.SessionInjectedPerson.Name = this.SessionInjectedPerson.Name + " > ";
            return this.View("Index",this.SessionInjectedPerson);
        }
It's not very well tested and you it works on the fact that the session entry name is the same as the property, however - it might save you some time.

Sunday, February 3, 2013

Zero implementation PHP API Wrapper in C#

The MoneyMedic API wrapper NuGet package that I wrote in December doesn't actually implement the methods of the API. All the methods actually look something like this:

    internal class MoneyMedicAPI : IMoneyMedicApi
    {
        ...
        public get_invoices_response get_invoices(string api_key, 
                                                  MoneyMedicEnum.SortInvoicesBy sortby, 
                                                  MoneyMedicEnum.SortDir sortdir)
        {
            throw new NotImplementedException();
        }
    }

When figuring out how to implement the wrapper I obseved:

  • All API calls result in a URL call with a query string that holds the method parameters and values. Like https://www.moneymedic.eu/api/[METHOD_NAME/?[PARAMETER_NAME]=[PARAMETER_VALUE]&....etc....
  • The JSON or XML response will need to be parsed into an instance of some response class


Therefore I decided to use the following setup:

  • A method call on the IMoneyMedicAPI interface is being intercepted
  • The intercepted method name matches the actual method name, the parameter names match the actual parameter names ( although StyleCop doesn't like this too much ).
  • The interceptor creates the MoneyMedic URL from intercepted method name + creates the query string from the parameter names and their corresponding values.
  • Using JSON.NET, the result is parsed to a result object, that corresponds to the information in the documentation and returns this to the caller.


And thus the actual implementation is never used or called - hence the NotImplementedExceptions that will never be thrown

Here's the interceptor:
// -------------------------------------------------------------------------------
// 
//   2012 Jochen van Wylick
// 
// -------------------------------------------------------------------------------

namespace MoneyMedicAPI
{
    using Ninject.Extensions.Interception;

    /// 
    /// The money medic API interceptor.
    /// Intercepts calls to the MoneyMedicAPI.
    /// 
    public class MoneyMedicApiInterceptor : IInterceptor
    {
        #region IMethodInterceptor Members

        /// 
        /// The MoneyMedic interceptor.
        /// 
        /// 
        /// The invocation.
        /// 
        public void Intercept(IInvocation invocation)
        {
            // Get the parameter collection
            var parameters = invocation.Request.Method.GetParameters();

            // Get the argument collection
            var arguments = invocation.Request.Arguments;

            // Invoke the API call and return the value
            invocation.ReturnValue = MoneyMedicApiHelper.InvokeApiCall(
                invocation.Request.Method.Name, parameters, arguments, invocation.Request.Method.ReturnType);
        }

        #endregion
    }
}

This made the wrapper very easy to implement. Furthermore I could use it for other wrappers if I wanted but still provide IntelliSense to the caller.