Deploying Laravel Applications to Windows Azure – URL Rewriting

This is just a quick one for reference purposes. You can use Laravel 4 on Windows Azure Websites, but you’ll need to rewrite the urls similarly to you would with apache. Create a file named web.config and drop it into the root of your website (or Github repository if you are deploying from there). This assumes your laravel public directory is src/public .

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <clear />
        <rule name="TransferToPublic" stopProcessing="true">
          <match url="^(app|assets|css|fonts|images|js|packages|favicon.ico)(.*)$" />
          <action type="Rewrite" url="src/public/{R:0}" />
        </rule>
        <rule name="Rewrite requested file/folder to index.php" stopProcessing="true">
          <match url="^(.*)$" ignoreCase="false" />
          <action type="Rewrite" url="src/public/index.php/{R:0}" appendQueryString="true" />
        </rule>
      </rules>
    </rewrite> 
  </system.webServer>
</configuration>
22
Aug 2013
POSTED BY
POSTED IN Azure Laravel
DISCUSSION 3 Comments
TAGS

Using php-resque with Laravel

Jessie O’Brien wrote a great blog post explaining how he’d got php-resque setup with Laravel. I won’t rehash the background on php-resque or Laravel but instead I wanted to post because I did the exact same thing last week, but I went about it in a different way.

To begin, I ported the core of the php-resque run script (Resque.php) into an artisan task. This allows to run artisan which gives you the full laravel environment, but still run the php-resque workers. So to run the queue, it’s as simple as running

php artisan resque <queue> <logLevel> <interval> <pidFile> 
/**
 * A Laravel Task which runs the PHP-Resque worker
 * This should be run using Artisan (php artisan resque) which will 
 * then kick off a php-resque worker and listen for incoming messages 
 * coming into the redis queues.
 */
class Resque_Task
{
    /**
     * @param $arguments
     */
    public function run($arguments)
    {
        Bundle::start('php-resque');

        $queue    = array_get($arguments, 0, 'default');
        $logLevel = array_get($arguments, 1, 0);
        $interval = array_get($arguments, 2, 5);
        $pidFile  = array_get($arguments, 3);

        $redis_config = Config::get("database.redis.default");
        $backend      = $redis_config['host'] . ':' . $redis_config['port'];

        // Connect to Redis
        Resque::setBackend($backend);

        $queues           = explode(',', $queue);
        $worker           = new Resque_Worker($queues);
        $worker->logLevel = $logLevel;

        if ($pidFile) {
            file_put_contents($pidFile, getmypid()) or 
              die('Could not write PID information to ' . $pidFile);
        }

        fwrite(STDOUT, '*** Starting worker ' . $worker . "\n");

        $worker->work($interval);
    }
}

The next piece I wanted, was to be able to write each of the tasks which I execute on the queue as simple artisan tasks. That way I could test them in isolation and run them independantly of the queue just using artisan.

All I needed to do was create a simple php-resque Job which could run any artisan Task.

/**
 * A PHP-Resque Job which starts a Laravel Task.
 * This enables us to use PHP-Resque as robust processing queue
 * but still use Laravel Commands, bundles etc to do the work
 *
 */
class Laravel_Job
{
    public function setUp()
    {
    }

    public function perform()
    {
        $task      = array_get($this->args, 'task');
        $arguments = array_get($this->args, 'arguments');

        Command::run(array($task, $arguments));
    }

    public function tearDown()
    {
    }
}

So, that’s it. If I wanted to run a long-running artisan task, I can simply issue the following command (perhaps from one of my controllers in response to a user action).

Resque::enqueue('queue', 'Laravel_Job', array('task => 'LongRunningLaravelTask', 'arguments' => 'some param'), true);
05
Dec 2012
POSTED BY
POSTED IN Laravel PHP
DISCUSSION 6 Comments

PHP for .NET developers

For the last 10 years I have been a .NET developer and before that I worked with C++ and MFC, so I’m pretty familiar with windows and IIS development. However, more recently I have been working almost exclusively with PHP. I have used PHP on and off for as long as I have been working with .NET but not in a professional capacity. I’ve always been disappointed with PHP compared to .NET that it didn’t have the same range of tools and features so I always felt uncomfortable and wanted to get back to Visual Studio as quickly as possible. However, things have changed, PHP has grown up and I finally feel like I have everything I need to create great apps in PHP. I’m going to talk about some of the tools and features I use in .NET and their equivalents in PHP. I won’t be discussing language features because it’s covered extensively elsewhere and I don’t know enough about it to speak with any authority. Also, this isn’t intended to be an exhaustive list, more of a starting point for .NET devs starting to work with PHP.

Frameworks

I love ASP.NET and more specifically ASP.NET MVC. Of course MVC isn’t exclusive to ASP so there are a number of MVC frameworks in PHP. Here’s a few to start you off.

Zend Framework – this is a heavyweight framework which includes MVC amongst many other things. It’s very enterprise focused and is quite mature. However, I find it overly complex and the learning curve is steep.

CodeIgniter – this is the one I am most familiar with having worked with the Expressionengine CMS a lot recently (which is based on CodeIgniter). This is a great framework but has been neglected recently which has seen it left behind by new entrants into the market. Its promise to support PHP 4 has also seen it held back from using some of the more modern features of PHP, alhough I believe the next version of CodeIgniter will be PHP 5 only.

FuelPHP – this is a framework which I believe was an attempt to improve on CodeIgniter by dropping PHP4 support and taking advantage of PHP 5 features. It looks like a nice framework but I haven’t really used it so can’t comment further

Laravel – this is just awesome in every way. Its tagline is ‘A Framework for Web Artisans’ – an artisan I most definitely am not – but look past that and you’ll see some truly beautiful, thoughtful and elegant code. This framework has a base requirement of PHP 5.3 which allows Laravel to take advantage of some of the great 5.3 features (such as namespaces, auto loading and closures which are similar to Lambdas). This is the framework I am currently using and I will be referring to it throughout the rest of this article because it’s great.

Routing

Routing in laravel is actually quite similar to ASP.NET so you should feel right at home. It has routing by verb (GET,POST,PUT etc), basic constraints and also has the reverse URL generation (same as URL.Action()). However, its syntax is cleaner and it has one additional feature: you can declare routes as a closure (like a Lambda Expression) and just return your views etc inline within the route definition. No need for a controller. I personally don’t use this feature but I think it’s a great idea for smaller sites or simple actions which don’t require a full controller.

IOC / Dependancy Injection

Inversion of Control (IOC) and Dependancy Injection (DI) are two really useful features of any modern language, especially for automated testing. In .NET I used StructureMap and it could do everything I needed, although with a somewhat verbose dialect and configuration management.

Laravel has a very simple IoC Container but it works great. You effectively register your type with the global container when you start up the app and then retrieve instances of your type thoughout the app simply by calling the static IoC::resolve() method. You can setup your type to be a singleton, and you can intialise it with a specific instance rather than a factory method. That’s it, and to be honest that’s enough for most apps.

ORMs

ORMs in my experience are a blessing and a curse. My ORM of choice in .NET is NHibernate but I’ve also used LinQ2SQL and Entity Framework but I’m not a fan of those.

In PHP there are a few ORM options but Laravel has its own ORM called Eloquent. Of course it’s nowhere near as complex as NHibernate but that can only be a good thing. It supports all the basic CRUD features, relationships, eager loading etc and the syntax is clean and simple. You can even go further and link in Laravel’s validation routines to get automatic model validation which takes you very close to having something similar to Data Annotaions in .NET.

Package Management

So I love nuget. It’s a blessing for .NET and makes it so simple to add functionality to an app from the massive range of open source libraries available.

PHP has an equivalent system called Composer and the default public package repository is called packagist. This is not as large a repository as nuget.org but it has everything you need. And if it doesn’t you can create your own.

Laravel can use composer but it also has it’s own similar proposition called bundles. These are self-registering packages which reside within your Laravel project which can inject functionality into your Laravel app. Because bundles are Laravel specific, they can integrate further than Composer even going so far as to create their own controllers, views and routes. However, it has been recognised that this is a duplication given the ubiquity of Composer and so in the upcoming Laravel 4 release bundles are to be replaced with Composer packages.

IDE

PHP development in my experience is done is either of two ways; either the old school way which is just using a text editor or using a full IDE.

So, first things first, what is the equivalent to Visual Studio for PHP? Well, there are many and in my opinion, none of them are as good as VS. But do you need VS? Probably not. There are a number of IDEs available and I’ve tried most of them, but my favourite is PHPStorm. It’s made by the geniuses at Jetbrains (who you’ll be familiar with if you use ReSharper) and has some great features (refactoring, test running, source code management, error detection) and is very actively developed. It costs money but it’s not expensive.

The other route which is popular is to use a text editor rather than an IDE and then use command line tools for running tests, source control etc. The most popular text editor at the moment seems to be Sublime Text 2 and deservedly so. It’s great. It looks beautiful, it’s fast and has some great editing features. I use it from time to time for editing single files but I prefer having an IDE so I can visualise my whole project.

Source Control

I’ve used Sourcesafe and TFS in my .NET work so everything else is fantastic in comparison. There are many solutions available but really you want to use git, and more specifically GitHub.com. Git is a great source control system, but github takes it to the next level and is just amazing. Everything integrates with it and once you understand how git works you will love it.

Automated Testing

Unit and integration testing are frankly a time consuming pain point for me. However, I love the security, code quality improvements and confidence it gives me to make changes in my code without fear of unintended consequences. In the .NET world there are a multitude of solutions but most people will use either MSTest or NUnit.

In PHP there is really only one player, and that’s PHPUnit. You’ll be pleased to know that PHPUnit is actually pretty good. It has a lot of the features you would expect (many assertation types, expected exceptions, tearup/teardown methods etc) and works pretty well for the most part. It can also integrate with PHP Code Coverage to give you some notion of coverage for our code. Also, PHPStorm integrates with both PHPUnit and PHP Code Coverage so you can run tests and see coverage directly in the IDE.

Cloud Hosting & PaaS

“The Cloud” is an annoying buzzword right now but if you are building a startup, cloud hosting is the obvious starting point. .NET has AppHarbor which is awesome, and Azure which is awesome now that Scott Guthrie is in charge, and gets better month by month.

PHP has a few cloud providers. Here’s my one line review of each

PHPFog – control panel looks great, infrastructure is flakey. Support is fast and helpful.

PagodaBox – supposed to integrate with github, but didn’t work for me.

Orchestra.io

Heroku – this is the original cloud provider and arguably the best. It’s primary focus is ruby but you can run PHP instead, although I haven’t tried it.

Continuous Integration (CI)

CI for me is a must have. AppHarbor has it built-in as part of the deployment process and I’ve also used TeamCity extensively.

For PHP, there are hosted CI providers such as CircleCI (great, but a bit pricey for me), TravisCI (great but open source projects only) and probably others. You could also setup your own TeamCity or Jenkins server (there’s a PHP specific template for it). They all integrate with git/github and can run all your PHP unit tests, coverage etc.

Summary

So there you have it, a starter guide for .NET developers looking at PHP. There are still a bunch of features I miss from ASP.NET MVC such as model binding, LINQ etc but for the most part PHP has something which achieve the same thing.

How are you finding the transition from .NET to PHP? Anything which I’ve missed from the above

 

27
Oct 2012
POSTED BY
POSTED IN .NET PHP
DISCUSSION 5 Comments
TAGS

,

Formatting Channel Entries as JSON in ExpressionEngine

If you are working with javascript a lot in ExpressionEngine, you will probably at some point need to use AJAX. Libraries such as jQuery make this easy, and out of the box it’s possible to create simple ExpressionEngine templates which can return HTML to be consumed by your javascript code. However, it is sometimes more convenient to return JSON data which can then be formatted client-side using javascript.

Producing JSON with ExpressionEngine is not so straightforward. There is a plugin for ExpressionEngine which produce JSON formatted output but this offers no customisation over the output, which is especially important if using complex custom fields (such as Channel Files or Channel Images).

Basic JSON

The solution is to create the formatted JSON yourself using standard ExpressionEngine templates. Below is a simple example of a channel entry formatted as JSON. The basic form of JSON is that each object should consist of a series of name-value pairs, with each pair separated by a comma, with the whole object surrounded by braces.

  {
    "Title": "Test Blog Post",
    "Link": "http://www.mysite.com/blog/view/test-blog-post/",
    "Summary": "This is the summary of my blog post",
    "Category": "Test Posts",
    "Image": "<img width=\"100\" height=\"100\" alt=\"Image Description\" title=\"Image Title\" src=\"http://www.mysite.com/images/test-blog-post-image.png\">"
  }

Notice that any double-quotes in the values have to be escaped with a forward-slash to ensure they can be interpreted correctly in javascript.

If you have multiple objects (i.e. an array), each object should be separated by a comma and the whole array should be enclosed in square brackets.

[
  {
    "Title": "Test Blog Post",
    "Link": "http://www.mysite.com/blog/view/test-blog-post/",
    "Summary": "This is the summary of my blog post",
    "Category": "Test Posts",
    "Image": "<img width=\"100\" height=\"100\" alt=\"Image Description\" title=\"Image Title\" src=\"http://www.mysite.com/images/test-blog-post-image.png\">"
  },
  {
    "Title": "Test Blog Post 2",
    "Link": "http://www.mysite.com/blog/view/test-blog-post2/",
    "Summary": "This is the summary of my blog post 2",
    "Category": "Test Posts",
    "Image": "<img width=\"100\" height=\"100\" alt=\"Image Description\" title=\"Image Title\" src=\"http://www.mysite.com/images/test-blog-post2-image.png\">"
  }
]

Producing JSON with ExpressionEngine

So, that’s the basic form of JSON, how can we produce this in ExpressionEngine using templates? Here is an example which does just that.

[
    {exp:channel:entries channel="blog" limit="100" backspace="6"}
    {
        "Title": "{title}",
        "Link": "{title_permalink="blog/view"}",
        "Summary": "{if summary}{summary}{/if}",
        "Category": "{categories limit="1"}{category_name}{/categories}",
        "Image": "{exp:channel_images:images entry_id="{entry_id}" limit="1"}<img width=\"{image:width}\" height=\"{image:height}\" alt=\"{image:description}\" title=\"{image:title}\" src=\"{image:url}\">{/exp:channel_images:images}"
    },
    {/exp:channel:entries}
]

All we are doing here is injecting into a simple JSON template the channel tags to produce the output required. As you can see, we can format the channel tags however we want, including using conditionals, nest tags etc.

Producing JSON with ExpressionEngine Correctly

There’s just one problem with the template above. We’ve already stated above that any double-quotes in the JSON object values need to be escaped to ensure that we don’t break the formatting of the output. However, we cannot be sure what values will be within the individual channel entries. We therefore need to act defensively and remove/escape any characters which might cause problems. Luckily for us, that nice man Low has provided the excellent Low Replace plugin which allows us to perform find and replace operations on any tag prior to display.

In this case, we want to prefix double-quotes with a backslash, and also also remove any linebreaks as then can also destroy the formatting.

[
    {exp:channel:entries channel="blog" limit="100" backspace="6"}
    {
        "Title": "{exp:low_replace find="QUOTE|NEWLINE" replace="\QUOTE|SPACE" multiple="yes"}{title}{/exp:low_replace}",
        "Link": "{title_permalink="blog/view"}",
        "Summary": "{if summary}{exp:low_replace find="QUOTE|NEWLINE" replace="\QUOTE|SPACE" multiple="yes"}{summary}{/exp:low_replace}{/if}",
        "Category": "{categories limit="1"}{exp:low_replace find="QUOTE|NEWLINE" replace="\QUOTE|SPACE" multiple="yes"}{category_name}{/exp:low_replace}{/categories}",
        "Image": "{exp:channel_images:images entry_id="{entry_id}" limit="1"}<img width=\"{image:width}\" height=\"{image:height}\" alt=\"{image:description}\" title=\"{image:title}\" src=\"{image:url}\">{/exp:channel_images:images}"
    },
    {/exp:channel:entries}
]

And you’re done. >Once you’ve completed your JSON, you might want to check that the JSON produced is valid (because if it isn’t valid your jQuery will typically fail silently). For this, I use the excellent JSLint online validator.

05
Jan 2012
POSTED BY
POSTED IN ExpressionEngine
DISCUSSION 7 Comments
TAGS

Don’t forget your XID!

Having just spent over an hour trying to work out why my Module Control Panel forms weren’t submitting correctly, I thought I’d document the fix here (for my purposes and yours).

The error I was seeing was that when submitting my control panel form, rather than posting to my module function, the form was redirecting back to the ExpressionEngine control panel homepage. The reason for this? I had forgotten to include the XID secure form hidden post variable.

Wrong

<form method="post" action="<?=$base_url?>&amp;method=save">
...blah
<input type="submit" name="Save"/>
</form>

Right

<form method="post" action="<?=$base_url?>&amp;method=save">
<input type="hidden" name="XID" value="<?=XID_SECURE_HASH?>" />
blah
<input type="submit" name="Save"/>
</form>
19
Dec 2011
POSTED BY
POSTED IN ExpressionEngine
DISCUSSION 3 Comments
TAGS

Using jQueryUI features in your ExpressionEngine Control Panel

Sometimes you might find it useful to add some additional UI features to your EE control panel pages – luckily EE comes bundled with jQuery and jQueryUI so you can use any of the jQuery UI widgets without needing to bundle the scripts themselves. In this example, I’m going to add a nice Date Picker control to a form to make it easier for users to enter dates.

To begin with, we need to tell EE to include the necessary jquery UI features. jQueryUI is modular and has dependencies, so even though I only want to use the ‘datepicker’ feature, that in turn relies on the ‘core’ library so I need to include them both in the list of required modules. This code will need to be in your control panel function prior to loading your view

$this->EE->cp->add_js_script(
array('ui' => array(
'core', 'datepicker'
)
));

And then in your view, it’s the usual jQuery code to wire it up. In this case I’m going to declare that any input field with a class of “datepicker” should be converted into a jQueryUI datepicker field.

<script type="text/javascript">
    $(function() {

        $("input.datepicker").datepicker();

    });
</script>

<form method="post">

<input id="expiry_date" class="medium datepicker" type="text" name="expiry_date" value="<?=htmlspecialchars($expiry_date)?>" />

<input class="submit" type="submit" value="<?=lang('submit')?>" />

</form>

You can of course do the same for any other jQuery UI feature which means it’s easy to add great interactive features to your control panel forms

08
Dec 2011
POSTED BY
DISCUSSION 2 Comments
TAGS

Using ExpressionEngine Actions with AJAX

ExpressionEngine Actions are lightweight hooks in EE which allow you to register a class & method to be called on a specific URL regardless of the templates or urls which have been configured on the user’s site.

Actions are a great way for your plugin to handle AJAX requests because your EE module can register an action and then call that action from the client using jQuery or similar. However, there are a couple of caveats which you need to be aware of

In my particular case, the fact that the template engine is not loaded is a major problem because I want to return some HTML back to client – HTML which has been generated from an EE template.

Firstly, I need to make sure that the template library is loaded, and if it isn’t I need to load it manually.

class My_module {

    function __construct() {

        $this->EE =& get_instance();

        // --------------------------------------
        // Make sure the template library is loaded
        // It isn't by default when running as an action
        // --------------------------------------

        // Load EE Templates if it doesn't exist
        if ( ! class_exists('EE_Template'))
        {
	        $this->EE->TMPL =& load_class('Template', 'libraries', 'EE_');
        }
    }
}

The last thing to be aware of is that for action methods, you can’t just return your parsed template as you would in a normal module method. For example, a normal method might look like


function my_method() {

    ...

    $template  = $this->EE->functions->prep_conditionals($template, $conditionals);
    $template  = $this->EE->TMPL->parse_variables_row($template, $view_data);

    return $template;
}

However, for an action, you need to perform an extra parse step and then manually push the output to the browser.


function my_ajax_method() {

    ...

    $template  = $this->EE->functions->prep_conditionals($template, $conditionals);
    $template  = $this->EE->TMPL->parse_variables_row($template, $view_data);

    $this->EE->TMPL->parse($template);

    $this->EE->output->set_output($this->EE->TMPL->final_template);
}

Even better, if you are using JSON to return your data, you can utilise a built-in EE function to format your data. It also has the added benefit of automatically disabling the profiler.


function my_ajax_method() {

    ...

    $template  = $this->EE->functions->prep_conditionals($template, $conditionals);
    $template  = $this->EE->TMPL->parse_variables_row($template, $view_data);

    $this->EE->TMPL->parse($template);

    $data = array('html'    => $this->EE->TMPL->final_template,
                  'success' => true);

    $this->EE->output->send_ajax_response($data);
}
10
Nov 2011
POSTED BY
DISCUSSION 4 Comments
TAGS

When ExpressionEngine calls your class to execute an action, it passes a constructor argument of 0

In /system/expressionengine/libraries/Actions.php, you will find this code around line 185

    // Instantiate the class/method		
    $ACT = new $class(0);

Not sure why this is done, but if your class takes a constructor argument (like mine does) you may find yourself scratching your head at why it won’t load when called from an action.

09
Nov 2011
POSTED BY
POSTED IN ExpressionEngine PHP
DISCUSSION 1 Comment
TAGS

Using Partial Views in the ExpressionEngine Control Panel (for ajax requests or similar)

If you want to use ajax to populate certain parts of your Control Panel user interface in ExpressionEngine, you will find that you have a problem if you want to use the standard MVC framework included, because EE will wrap all your views with the control panel “frame” (html/images/css etc).

For example, the following view is intended to be returned as a partial view to be called using ajax, but it will instead be wrapped by the EE control panel


public function ajax_example()
{
	// --------------------------------------
	// Load view and return it
	// --------------------------------------
	
	$data = array('some_view_data' => 'Value');

	return $this->EE->load->view('ajax_example_view', $data, TRUE);
}

To fix this, all we have to do is grab the output from our view and spit it straight out to the browser without returning it to the calling function (which is where the frame is added).


public function ajax_example()
{
	// --------------------------------------
	// Load view and echo it
	// --------------------------------------

	$data = array('some_view_data' => 'Value');

	echo $this->EE->load->view('ajax_example_view', $data, TRUE);

	exit;
}

This works, but you do lose some functionality, such as seeing the output profiler and/or template debugger. However, we can fix this by using the EE/CI output class instead to display the view.


public function ajax_example()
{
	// --------------------------------------
	// Load view and display it
	// --------------------------------------

	$data = array('some_view_data' => 'Value');

	$response = $this->EE->load->view('ajax_example_view', $data, TRUE);

	$this->EE->output->set_output($response);
	$this->EE->output->_display();

	exit;
}

This works better, but we don’t always want to see the output profiler, especially on ajax requests because the profiler output could break the layout or, if we are returning JSON for example, can destroy the output totally. So, let’s wrap this up into a helper method with some optional parameters


public function ajax_example()
{
	// --------------------------------------
	// Load view and display it
	// --------------------------------------

	$data = array('some_view_data' => 'Value');

	$this->partial_view('ajax_example_view', $data);

}

private function partial_view($view_name, $data, $show_profiler = null) {

	$response = $this->EE->load->view($view_name, $data, TRUE);

	if(isset($show_profiler)) {
		$this->EE->output->enable_profiler($show_profiler);
	}

	$this->EE->output->set_output($response);
	this->EE->output->_display();

	exit;
}
08
Nov 2011
POSTED BY
DISCUSSION 2 Comments
TAGS

How to dynamically create url_titles with jQuery in ExpressionEngine modules

Whilst developing your custom module for EE, you might have a requirement to add a Url Title for one of your data types. ExpressionEngine does this in a few places in the control panel (for new Entries, Channels etc) so why not just reuse the existing functionality?

First, we need to load the ‘ee_url_title’ jQuery plugin which EllisLabs have kindly provided. The snippet below does this for you and needs to be included in your mcp file controller method.


$this->EE->cp->add_js_script('plugin', 'ee_url_title');

Now, we need to switch over to your view and add a little javascript. So given the following html code in your view


<label for="title"><?=lang('title')?></label>
<input type="text" name="title" id="title" value="<?=htmlspecialchars($title)?>" />

<label for="url_title"><?=lang('url_title')?></label></td>
<input type="text" name="url_title" id="url_title" value="<?=htmlspecialchars($url_title)?>" />

You only need to add the following snippet of javascript, this can either be in your view, or even better add it to a separate javascript file.

$(function() {

	// Attach url_title live feedback
	$("#title").bind("keyup blur",function(){
		$("#title").ee_url_title($("#url_title"));
	});

});
08
Nov 2011
POSTED BY
DISCUSSION 1 Comment
TAGS