Magento 1.9 – Fatal Error: Call to a Member Function on Boolean

blocksmagento-1.9module

I've created a custom module for SSO with Discourse.

Exact error:

Fatal error: Call to a member function setSecret() on boolean in /home/website/public_html/app/design/frontend/theme/path/template/custompages/sso.phtml on line 9

I'm using the following template sso.phtml:

<?php

$sso = Mage::app()->getLayout()->createBlock('namespace/ssohelper');




$secret = "secret_phrase";
$sso->setSecret($secret);

// load payload
$payload = $_GET['sso'];
$signature = $_GET['sig'];

// validate payload
if(!($sso->validatePayload($payload,$signature))) {
  // invalid, Deny
  header("HTTPS/1.1 403 Forbidden");
  echo("Bad SSO request");
  die();
}

$nonce = $sso->getNonce($payload);

$loggedIn = Mage::getSingleton('customer/session')->isLoggedIn();
 if($loggedIn) {
  $sess = Mage::getSingleton('customer/session');
  $username = $sess->getCustomer()->getUsername();
  $email = $sess->getCustomer()->getEmail();
  $external_id = $sess->getCustomer()->getId();

  $extraParameters = array(
     'username' => $username,
     'name' => $username,
    'avatar_url' => $avatar
   );
}


// build query string and redirect back to forum
$query = $sso->getSignInString($nonce, $external_id, $email, $extraParameters);
header('Location: https://forum.website.come/session/sso_login?' . $query);
exit(0);

My config.xml:

<?xml version="1.0"?>

<config>
    <modules>
        <Namespace_SsoHelper>
            <version>0.1.1</version>
        </Namespace_SsoHelper>
    </modules>    
    <global>
      <blocks>
        <ssohelper>
            <class>Namespace_SsoHelper_Block</class>
        </ssohelper>
      </blocks>
    </global>

  </config>

My SsoHelper.php with Block:

<?php

use Namespace\SsoHelper\Exception\PayloadException;


class Namespace_SsoHelper_Block_SsoHelper extends Mage_Core_Block_Template
{
  public function __construct(){
    parent::__construct();
    # getting default settings
  }

private $secret;


public function setSecret($secret)
{
    $this->secret = $secret;

    return $this;
}

/**
 * @param $payload
 * @param $signature
 * @return mixed
 */
public function validatePayload($payload, $signature)
{
    $payload = urldecode($payload);

    return $this->signPayload($payload) === $signature;
}

/**
 * @param $payload
 * @return mixed
 * @throws PayloadException
 */
public function getNonce($payload)
{
    $payload = urldecode($payload);
    $query = array();
    parse_str(base64_decode($payload), $query);
    if (!array_key_exists('nonce', $query)) {
        throw new PayloadException('Nonce not found in payload');
    }

    return $query['nonce'];
}

/**
 * @param $payload
 * @return mixed
 * @throws PayloadException
 */
public function getReturnSSOURL($payload)
{
    $payload = urldecode($payload);
    $query = array();
    parse_str(base64_decode($payload), $query);
    if (!array_key_exists('return_sso_url', $query)) {
        throw new PayloadException('Return SSO URL not found in payload');
    }

    return $query['return_sso_url'];
}

/**
 * @param $nonce
 * @param $external_id
 * @param $email
 * @param array $extraParameters
 * @return string
 */
public function getSignInString($nonce, $external_id, $email, $extraParameters = [])
{

    $parameters = array(
            'nonce'       => $nonce,
            'external_id' => $external_id,
            'email'       => $email,
        ) + $extraParameters;

    $payload = base64_encode(http_build_query($parameters));

    $data = array(
        'sso' => $payload,
        'sig' => $this->signPayload($payload),
    );

    return http_build_query($data);
}

/**
 * @param $payload
 * @return string
 */
    protected function signPayload($payload)
    {
        return hash_hmac('sha256', $payload, $this->secret);
    }
}

This is my first time creating a custom module using a Block class.

Best Answer

Very similar to Viveks answer but try replacing

$sso = Mage::app()->getLayout()->createBlock('namespace/ssohelper');

with

$sso = Mage::app()->getLayout()->createBlock('ssohelper/ssoHelper'); 

I believe the namespace and block name casing are incorrect. Ultimately the createBlock call isn't returning anything so what your passing it is not being mapped to the block you created.