Getting started with AbstractRestfulController

Zend Framework 2 introduced a new controller abstract class: AbstractRestfulController (more docs here). This is used to create restful services (which will communicate with javascript in the browser, for example).

Controllers implementing AbstractRestfulController, can expose normal actions in addition to the REST methods. Following the Zend convention, these the name of these methods must end in “Action”.

Example Rest Controller, with only the getList() method populated.

class TestRestController extends AbstractRestfulController
{
    public function indexAction()
    {
        return new ViewModel();
    }
 
    /**
     * Return list of resources
     *
     * @return mixed
     */
    public function getList()
    {
        return new JsonModel(array(
            array('name' => 'test'),
            array('name' => 'second')
        ));
    }
 
    /**
     * Return single resource
     *
     * @param  mixed $id
     * @return mixed
     */
    public function get($id)
    {
        //TODO: Implement Method
    }
 
    /**
     * Create a new resource
     *
     * @param  mixed $data
     * @return mixed
     */
    public function create($data)
    {
        //TODO: Implement Method
    }
 
    /**
     * Update an existing resource
     *
     * @param  mixed $id
     * @param  mixed $data
     * @return mixed
     */
    public function update($id, $data)
    {
        //TODO: Implement Method
    }
 
    /**
     * Delete an existing resource
     *
     * @param  mixed $id
     * @return mixed
     */
    public function delete($id)
    {
        //TODO: Implement Method
    }
}

I found the dispatch logic for AbstractRestfulController a little confusing.
If there is an available “action” value on the request object, the controller attempts to find the corresponding action method. If there is no action value, then it dispatches to the REST methods. This essentially means that we will have to setup custom routes to dispatch to AbstractRestfulControllers as the “action” value will typically have a default value of “index” if we are following the traditional route configuration.

If you are getting 404 Not Found errors, when you are expecting the REST methods to be executing, this is probably the problem.

Example route configuration (In module.config.php):

return array(
    'controllers' => array(
        'invokables' => array(
            'Application\Controller\TestRest' => 'Application\Controller\TestRestController',
        ),
    ),
 
    'router' => array(
        'routes' => array(
            'rest' => array(
                'type'    => 'Literal',
                'options' => array(
                    'route'    => '/rest',
                    'defaults' => array(
                        '__NAMESPACE__' => 'Application\Controller',
                    ),
                ),
                'may_terminate' => true,
                'child_routes' => array(
                    'default' => array(
                        'type'    => 'Segment',
                        'options' => array(
                            'route'    => '/:controller[/:id][/]',
                            'constraints' => array(
                                'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
                            ),
                            'defaults' => array(
                            ),
                        ),
                    ),
                ),
            ),
        ),
    ),

To get the controller to just render the JSON in the JsonModel returned by the getList method, we have to add a view manager strategy to the config:

return array(
    'view_manager' => array(
        'template_path_stack' => array(
            __DIR__ . '/../view',
        ),
        'strategies' => array(
            'ViewJsonStrategy',
        ),
    ),
);

, ,

No Comments

Composer and Git on Windows

I’ve been having some problems downloading packages using Composer. It seems GitHub is having some hickups and it’s returning errors such as:

[Composer\Downloader\TransportException]                                     
  The "http://nodeload.github.com/symfony/Yaml/zipball/v2.1.3" file could not be downloaded (HTTP/1.1 404 Not Found)    

As a workaround you can use the

--prefer-source

flag to tell Composer to download the source code rather than using a bundled package. However, this means that you must have Git on your path, otherwise composer won’t be able to find it.

When I installed git, I chose the option to use the git shell, and as a result it didn’t put it on my path. I could put the cmd folder in the git installation location on the path, but instead of polluting my path, I decided to modify the composer.bat file to set the path to git.

@ECHO OFF
 
rem Include GIT on the path
SET PATH=%PATH%;C:\Program Files (x86)\Git\cmd
 
SET composerScript=composer.phar
php "%~dp0%composerScript%" %*

On Windows 7, if you used the composer installer, composer.bat should be in C:\ProgramData\Composer\bin. Make sure you change the path to git to reflect your environment.

2 Comments

Hijacker Camper Jack ORing Rebuild Parts List

Over the weekend we were rebuilding the Hijacker Camper Jacks on our camper. Since Hijacker has gotten out of the camper jack business, the rebuild kits are tough to find. We were in NAPA (Canada) and managed to size replacement o-rings that seem to do the trick. The product codes for the replacement o-rings are:

NAPA Part Number Hijacker Part # Description
DYN-54112 HJ-111 STATIC O-RINGS 1/2″ ID
DYN-54012 HJ-112 CHECK VALVE / PAC END O-RING 7/16″ ID
DYN-54008 HJ-114 RELEASE VALVE O-RING 3/16″ ID
DYN-54011 HJ-121 PLUNGER O-RING 5/16″ ID

Refer to the illustrations and tables in the following PDF for more information:
Hijacker Camper Jack Manual

, , ,

3 Comments

Advanced Permalinks Plugin RSS Feed Fix

I use the Advanced Permalinks plugin on my site because I changed my permalink structure and didn’t want incoming links to return 404 errors. However, at some point the plugin has broken the RSS feed functionality of WordPress. When I visit the feed url on my site, a blank page is returned with no errors.

It appears that this is due to the Advanced Permalinks plugin ending the php script if the redirect parameter is present, even if the plugin didn’t preform any redirect.

Here is a patch file to fix the problem (For Advanced Permalinks 0.1.21)

--- advanced-permalinks-0.1.21/advanced-permalinks.php	2012-05-05 09:06:10.000000000 -0600
+++ advanced-permalinks/advanced-permalinks.php	2012-08-31 14:13:06.006393800 -0600
@@ -451,13 +451,18 @@
 		// Have we triggered a redirect?
 		if (isset ($vars->query_vars['redirect']))
 		{
-			if (isset ($vars->query_vars['author_name']))
+            $didRedirect = false;
+			if (isset ($vars->query_vars['author_name'])){
 				wp_redirect (get_author_posts_url (0, $vars->query_vars['author_name']));
-			else if (isset ($vars->query_vars['category_name']))
+                $didRedirect = true;
+            }
+			else if (isset ($vars->query_vars['category_name'])){
 				wp_redirect (get_category_link (get_category_by_path ($vars->query_vars['category_name'])));
+                $didRedirect = true;
+            }
 
-			// Stop anything else
-			die ();
+            if($didRedirect)
+                die();
 		}
 
 		// Workaround for WP 2.3

Save the text to a file and run patch against your Advanced Permalinks directory.

Or, if you want to manually modify the plugin, open up the advanced-permalinks.php file in the editor, and change the contents of the parse_request function to be:

/**
 * Hook into the 'parse_request' action and check if our rewrite rules require a redirection
 *
 * @param array $vars Variables
 * @return array Variables
 **/
 
function parse_request ($vars)
{
	// Have we triggered a redirect?
	if (isset ($vars->query_vars['redirect']))
	{
		$didRedirect = false;
		if (isset ($vars->query_vars['author_name'])){
			wp_redirect (get_author_posts_url (0, $vars->query_vars['author_name']));
			$didRedirect = true;
		}
		else if (isset ($vars->query_vars['category_name'])){
			wp_redirect (get_category_link (get_category_by_path ($vars->query_vars['category_name'])));
			$didRedirect = true;
		}
 
		if($didRedirect)
			die();
	}
 
	// Workaround for WP 2.3
	global $wp_db_version;
	if ($wp_db_version > 6000 && isset ($vars->query_vars['category_name']))
	{
		$vars->query_vars['category_name'] = str_replace ('.html', '', $vars->query_vars['category_name']);
		$vars->matched_query               = str_replace ('.html', '', $vars->matched_query);
	}
 
	return $vars;
}

4 Comments

Thinkpad R500 Ubuntu Fan Control

Ubuntu has a rather nasty bug when it comes to temperature control on the Thinkpad line of laptops. The fans run at a lower RPM than necessary, which results in overheating and random shutdowns. The overheating has also caused perminant damage to some of the cells in my battery, significantly decreasing battery life.

Thinkfan is a utility that manually adjusts the speed of the fan based off of the system temperature, rather than leaving it up to acpi.

Setup steps:

  1. Install thinkfan:
    apt-get install thinkfan
  2. Set thinkpad_acpi to allow manual fan control:
    echo "options thinkpad_acpi fan_control=1" >> /etc/modprobe.d/thinkfan.conf
  3. Set thinkfan to start automatically by setting
    START=yes

    in /etc/default/thinkfan

  4. Either reboot or reload the thinkpad_acpi module, and start thinkfan
    rmmod thinkpad_acpi && modprobe thinkpad_acpi fan_control=1 && /etc/init.d/thinkfan start

You can watch the fan information by issuing:

watch -n 0.5 'cat /proc/acpi/ibm/thermal ; cat /proc/acpi/ibm/fan | egrep "(speed|level):" ; cat /proc/cpuinfo | grep MHz'

If “level” has a value between 0 and 7, and changes by times, your thinkfan daemon is working.

Thanks to Jamie Strandboge and mejo

No Comments