XML views in CakePHP 2.x

In a CakePHP project, I needed to extract an XML string from the database and display it as an XML page. The docs suggested this would be easy with the XmlView, but I struggled to get it to work. However,  after a fair amount of fiddling around, I found an easy way to display an XML view.

Here’s what I had to do:

  • Enable parsing of .xml extensions in routes.php:
    Router::parseExtensions('xml');
  • Set the viewClass to Xml in the controller:
    $this->viewClass = 'Xml';
  • Create a simple xml view in Views/YourController/xml/xml.ctp, and echo $xml in this view:
    <?php echo $xml; ?>
  • Back in the controller, set the XML string to the view:
    $this->set('xml', $xmlString);
  • Finally, render using the xml view you have just created (this must be after the ‘set’ line above):
    $this->render('xml');

Unfortunately, this does not take advantage of the _serialize key, which would mean you don’t need to create a view file at all, but I just couldn’t get this to work with an XML string, despite trying various combinations of CakePHP’s Xml Class functions.

Authenticate (SSO) Vanilla users with a CakePHP 2 application using Vanilla’s jsConnect Plugin

Using your existing CakePHP website to authenticate users into a Vanilla forum (so they don’t have to setup another account) is fairly simple…once you know how:

In your Cake site:

  1. Download the PHP jsConnect client library as described here
  2. Create a ‘vanilla’ directory in app/Vendor and copy into it functions.jsconnect.php from the download in 1.
  3. In UsersController.php add:
    App::import(
     'Vendor',
     'FunctionsJsconnect',
     array('file' => 'vanilla' . DS . 'functions.jsconnect.php')
    );
  4. Paste index.php from the download in 1 into View/Users and rename it as vanilla_authenticate.ctp. Edit so that it contains only:
    // 1. Get your client ID and secret here. These must match those in your jsConnect settings.
    $clientID = "your_client_id_from_js_connect_plugin_settings_page";
    $secret = "your_secret_from_js_connect_plugin_settings_page";
    // 3. Fill in the user information in a way that Vanilla can understand.
    // CHANGE THESE FOUR LINES.
    $user['uniqueid'] = $user_data['your_cake_id_field'];
    $user['name'] = $user_data['your_cake_username_field'];
    $user['email'] = $user_data['your_cake_email_field'];
    $user['photourl'] = $user_data['your_cake_avatar_field'];
    // 4. Generate the jsConnect string.
    // This should be true unless you are testing. 
    // You can also use a hash name like md5, sha1 etc which must be the name as the connection settings in Vanilla.
    $secure = true; 
    WriteJsConnect($user, $_GET, $clientID, $secret, $secure);
  5. In UsersController.php, add a vanilla_authenticate action:
    public function vanilla_authenticate(){
        if ($this->Auth->loggedIn()){
             //user is logged in so pass necessary data through to view
             $this->layout = 'ajax';
             $user_data = $this->Auth->user();
             $this->set('user_data', $user_data);
             }
         }
  6. Again in UsersController.php, modify your login action:
    public function login() {
        if ($this->request->is('post')) {
            ...
            //Do your normal login business which includes the line
            $this->redirect($this->Auth->redirectUrl()); //after successful login
            ...
            }
        //add following to handle get request from jsConnect
        else{
            if(isset($this->request->query['source'])&&$this->request->query['source']=="vanilla"){
    	    //we need to redirect to vanilla after login so change redirectURL
    	    $this->Auth->redirectUrl('http://www.yourvanillasite.com/index.php?p=/entry/jsconnect&client_id=your_client_id_from_js_connect_plugin_settings_page&Target=http://www.yourvanillasite.com'); //big thanks to @hgtonight for this snippet
    	    }
    	}
        }

In your Vanilla forum:

  1. Download and enable the jsConnect plugin (at the moment, the advice is to use 1.03 as 1.4.1 is still buggy, reporting a ‘regex’ error);
  2. In the jsConnect plugin settings:
    • autogenerate (using the button at the bottom) a ClientID and Secret;
    • the Site Name: Your Cake Site – this will appear as ‘Sign in with {site name}’ when users go to the Vanilla forum
    • Authenticate URL:  http://www.yourcakesite.com/users/vanilla_authenticate
    • Sign In URL: http://www.yourcakesite.com/users/login?source=vanilla
    • Register URL: http://www.yourcakesite.com/users/register

Well, that’s what worked for me anyway….

Vanilla Community’s x00 tells me that you can avoid the complicated redirect in Cake Step 6 above (and replace with:

$this->Auth->redirectUrl('www.yourvanillasite.com');

if you use the jsConnect AutoSignIn Plugin…but I haven’t tried this yet.

Good luck.

Complete Idiots Guide to using Composer with CakePHP

I recently wanted to use Miles Johnson’s Forum Plugin for CakePHP in a project, and when I came to install it, saw that he recommends (insists on, in fact) using Composer to do this, to take care of ensuring all the dependencies are installed. Never having used Composer before, I took a look at his post on using Composer with CakePHP, which probably counts as an idiots guide for most people, but still wasn’t basic enough for me. Therefore, I thought I would write a complete idiots guide!

The steps I had to go through to get it working were as follows:

  • Install Composer – I am on Windows, so just downloaded and ran the Windows installer, which seemed to work fine
  • Ensure that the openssl extension is enabled in php.ini, i.e. uncomment this line: extension=php_openssl.dll
  • Create a composer.json file in your app directory and add the dependencies, e.g. for the Forum plugin:
    {
       "config": {
          "vendor-dir": "Vendor"
       },
       "require": {
          "mjohnson/forum": "5.*"
       }
    }
  • Run composer install in the app directory. This should install all of the dependencies (in the Vendor or Plugin directories of your app, as appropriate) and create an autoload.php file in the Vendor directory
  • Add the following at the start of your Config/core.php file to make use of Composer’s autoloading capabilities:
    require_once dirname(__DIR__) . '/Vendor/autoload.php';

That should deal with all of the dependencies, in this case for the Forum Plugin. It is still necessary to load the Plugins in the Config/bootstrap.php file. For the Forum Plugin, this is does as follows:

CakePlugin::load('Utility', array('bootstrap' => true, 'routes' => true));
CakePlugin::load('Admin', array('bootstrap' => true, 'routes' => true));
CakePlugin::load('Forum', array('bootstrap' => true, 'routes' => true));