7

I am writing my own administration and, off course I am using Smarty. Now, what I would like to do is to add a access check function much similar to the {if} tag.

What I would like to write is:

{userAccess module='MyModule' action='WriteMessage'}
Yeey.. I can write something. My name is {$myName}.
{/userAccess}

but I can't figure out how to. Can someone please point me into the right direction? Also, if possible adding and {else} to it. So the code would be:

{userAccess module='MyModule' action='WriteMessage'}
Yeey.. I can write something. My name is {$myName}.
{else}
Nooo.. :( I don't have access.
{/userAccess}
hakre
  • 193,403
  • 52
  • 435
  • 836
Paul Peelen
  • 10,073
  • 15
  • 85
  • 168

2 Answers2

2

I solved it creating my own "internal" function for smarty. This might not be the way Smarty intended it to be used, but it sure works for me... which is the most important thing for me.

This is my end result:

<?php
/**
 * Smarty Internal Plugin Compile UserAccess
 * 
 * Compiles the {useraccess} {useraccesselse} {/useraccess} tags
 * 
 * @package Smarty
 * @subpackage Compiler
 * @author Paul Peelen
 */

/**
 * Smarty Internal Plugin Compile useraccess Class
 */
class Smarty_Internal_Compile_useraccess extends Smarty_Internal_CompileBase {
    // attribute definitions
    public $required_attributes = array('module', 'action');
    public $optional_attributes = array('userid');                  // Not yet implemented
    public $shorttag_order = array('module','action','userid');

    /**
     * Compiles code for the {useraccess} tag
     * 
     * @param array $args array with attributes module parser
     * @param object $compiler compiler object
     * @param array $parameter array with compilation parameter
     * @return string compiled code
     */
    public function compile($args, $compiler, $parameter)
    {
        $this->compiler = $compiler;
        $tpl = $compiler->template; 
        // check and get attributes
        $_attr = $this->_get_attributes($args);

        $module = $_attr['module'];
        $action = $_attr['action'];

        if (!is_string($module) || !is_string($action))
        {
            exit ("ERROR");
        }

        $this->_open_tag('useraccess', array('useraccess', $this->compiler->nocache, $module, $action));
        $this->compiler->nocache = $this->compiler->nocache | $this->compiler->tag_nocache;

        $output = "<?php ";
        $output .= "\$oAuth = \$GLOBALS['oAuth'];\n";
        $output .= " \$_smarty_tpl->tpl_vars[$module] = new Smarty_Variable;\n";
        $compiler->local_var[$module] = true;

        $output .= " \$_smarty_tpl->tpl_vars[$action] = new Smarty_Variable;\n";
        $compiler->local_var[$action] = true;

        $output .= "if (\$oAuth->getUserSubRights($action,$module)) {";
        $output .= "?>";

        return $output;
    } 
} 

/**
 * Smarty Internal Plugin Compile UserAccessElse Class
 */
class Smarty_Internal_Compile_UserAccessElse extends Smarty_Internal_CompileBase {
    /**
     * Compiles code for the {useraccesselse} tag
     * 
     * @param array $args array with attributes module parser
     * @param object $compiler compiler object
     * @param array $parameter array with compilation parameter
     * @return string compiled code
     */
    public function compile($args, $compiler, $parameter)
    {
        $this->compiler = $compiler; 
        // check and get attributes
        $_attr = $this->_get_attributes($args);

        list($_open_tag, $nocache, $item, $key) = $this->_close_tag(array('useraccess'));
        $this->_open_tag('useraccesselse', array('useraccesselse', $nocache, $item, $key));

        return "<?php } else { ?>";
    } 
} 

/**
 * Smarty Internal Plugin Compile UserAccessclose Class
 */
class Smarty_Internal_Compile_UserAccessclose extends Smarty_Internal_CompileBase {
    /**
     * Compiles code for the {/useraccess} tag
     * 
     * @param array $args array with attributes module parser
     * @param object $compiler compiler object
     * @param array $parameter array with compilation parameter
     * @return string compiled code
     */
    public function compile($args, $compiler, $parameter)
    {
        $this->compiler = $compiler; 
        // check and get attributes
        $_attr = $this->_get_attributes($args); 
        // must endblock be nocache?
        if ($this->compiler->nocache) {
            $this->compiler->tag_nocache = true;
        } 

        list($_open_tag, $this->compiler->nocache, $item, $key) = $this->_close_tag(array('useraccess', 'useraccesselse'));
        unset($compiler->local_var[$item]);
        if ($key != null) {
            unset($compiler->local_var[$key]);
        } 

        return "<?php } ?>";
    } 
} 

I hope this helps anybody who has this problem in the future.

Paul Peelen
  • 10,073
  • 15
  • 85
  • 168
  • Great solution, I stumbled upon this the other day and also leveraged creating new compile level blocks for an issue I had. – Scuzzy Aug 02 '22 at 05:08
0

You could try registerPlugin.

$smarty->registerPlugin("block","userAccess", array('YourClass', 'your_function'));

and your class:

class YourClass {
    static function your_function($params, $content, $smarty, &$repeat, $template) {
        $module = $params['module'];
        $action = $params['action'];

        if ($action == 'WriteMessage' && $user_may_write_message) {
            return $content;
        else
            return '';
    }
}

The problem here is that you are not so easiliy able to use variables inside this block. Maybe you can send the inner content to smarty again, but since it only allows template files in the function fetch() I'm not quite sure if this works.

What could help though is the smarty function eval, but I have not worked with it yet.

Sascha Galley
  • 15,711
  • 5
  • 37
  • 51
  • Thanks! I looked at that and tried it, but just as you explained, the inner content is not renered by smarty. Which is a requirement. – Paul Peelen Aug 10 '11 at 14:59
  • I found another function called [eval](http://www.smarty.net/docs/en/language.function.eval.tpl)...maybe this can help you – Sascha Galley Aug 10 '11 at 15:27
  • You'll want to use register_block. I'm not sure how best to handle the else condition within it, but it will at least evaluate the contents as Smarty code for you. http://www.smarty.net/docsv2/en/api.register.block.tpl – craigmc Aug 10 '11 at 15:32
  • I'll have anohter look. So far I tried copying the foreach function and adapting it to my requirements. Maybe that works. – Paul Peelen Aug 10 '11 at 15:38