Smarty template engine: Unable to load template 'file:header.tpl' - php

I developed a CodeIgniter application using Smarty template engine and Codeigniter 3.0.0, everything works well . But after upgrading Codeigniter (from 3.0.0 to 3.1.5) there is a Smarty error:
Unable to load template 'file:header.tpl'
Header.tpl is behind application/views/smarty_templates
I have a codeigniter library that recall Smarty Libraries:
<?php
require_once(APPPATH . 'third_party/smarty/libs/Smarty.class.php');
class CI_Smarty extends Smarty
{
function __construct()
{
parent::__construct();
$CI->load->config('smarty');
$this->ci = & get_instance();
log_message('debug',$this->setTemplateDir);
$this->compile_dir = "/tmp/.smarty_templates_c";
$this->template_dir = APPPATH . "views/smarty_templates";
$this->assign('APPPATH', APPPATH);
$this->assign('BASEPATH', BASEPATH);
$this->assign('SITEURL', site_url());
$this->assign('BASEURL', base_url());
// Assign CodeIgniter object by reference to CI
if (method_exists($this, 'assignByRef')) {
$ci =& get_instance();
$this->assignByRef("ci", $ci);
}
log_message('debug', "Smarty Class Initialized");
}
/**
* Parse a template using the Smarty engine
*
* This is a convenience method that combines assign() and
* display() into one step.
*
* Values to assign are passed in an associative array of
* name => value pairs.
*
* If the output is to be returned as a string to the caller
* instead of being output, pass true as the third parameter.
*
* #access public
* #param string
* #param array
* #param bool
* #return string
*/
function view($template, $data = array(), $return = FALSE)
{
foreach ($data as $key => $val) {
$this->assign($key, $val);
}
if ($return == FALSE) {
$CI =& get_instance();
if (method_exists($CI->output, 'set_output')) {
$CI->output->set_output($this->fetch($template));
} else {
$CI->output->final_output = $this->fetch($template);
}
return;
} else {
return $this->fetch($template);
}
}
}

Related

Cannot declare class ABC, because the name is already in use

Here am getting an error like Fatal error: Cannot declare class ABC, because the name is already in use in while listing all controller names and functions in project.In order to get i got an library from surroundings and placed it.library looks like this
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
/***
* File: (Codeigniterapp)/libraries/Controllerlist.php
*
* A simple library to list al your controllers with their methods.
* This library will return an array with controllers and methods
*
* The library will scan the "controller" directory and (in case of) one (1) subdirectory level deep
* for controllers
*
* Usage in one of your controllers:
*
* $this->load->library('controllerlist');
* print_r($this->controllerlist->getControllers());
*
* #author Peter Prins
*/
class ControllerList {
/**
* Codeigniter reference
*/
private $CI;
/**
* Array that will hold the controller names and methods
*/
private $aControllers;
// Construct
function __construct() {
// Get Codeigniter instance
$this->CI = get_instance();
// Get all controllers
$this->setControllers();
}
/**
* Return all controllers and their methods
* #return array
*/
public function getControllers() {
return $this->aControllers;
}
/**
* Set the array holding the controller name and methods
*/
public function setControllerMethods($p_sControllerName, $p_aControllerMethods) {
$this->aControllers[$p_sControllerName] = $p_aControllerMethods;
}
/**
* Search and set controller and methods.
*/
private function setControllers() {
// Loop through the controller directory
foreach(glob(APPPATH . 'controllers/*') as $controller) {
// if the value in the loop is a directory loop through that directory
if(is_dir($controller)) {
// Get name of directory
$dirname = basename($controller, 'EXT');
// Loop through the subdirectory
foreach(glob(APPPATH . 'controllers/'.$dirname.'/*') as $subdircontroller) {
// Get the name of the subdir
$subdircontrollername = basename($subdircontroller, EXT);
// Load the controller file in memory if it's not load already
if(!class_exists($subdircontrollername)) {
$this->CI->load->file($subdircontroller);
}
// Add the controllername to the array with its methods
$aMethods = get_class_methods($subdircontrollername);
$aUserMethods = array();
foreach($aMethods as $method) {
if($method != '__construct' && $method != 'get_instance' && $method != $subdircontrollername) {
$aUserMethods[] = $method;
}
}
$this->setControllerMethods($subdircontrollername, $aUserMethods);
}
}
else if(pathinfo($controller, PATHINFO_EXTENSION) == "php"){
// value is no directory get controller name
$controllername = basename($controller, 'EXT');
// Load the class in memory (if it's not loaded already)
if(!class_exists($controllername)) {
var_dump($controller);
$this->CI->load->file($controller);
}
// Add controller and methods to the array
$aMethods = get_class_methods($controllername);
//var_dump($aMethods);
$aUserMethods = array();
if(is_array($aMethods)){
foreach($aMethods as $method) {
if($method != '__construct' && $method != 'get_instance' && $method != $controllername) {
$aUserMethods[] = $method;
}
}
}
$this->setControllerMethods($controllername, $aUserMethods);
}
}
}
}
// EOF
Here am getting error in the line $this->CI->load->file($controller);.when i call this library in my controller am getting error what i mentioned in title.Is it a problem of php version,Here it is telling that controller class name is already called so it cannot be call again.

Message: Array to string conversion only in PHP7 Codeigniter

I have added PHP7 to my local server and I got this error:
Message: Array to string conversion Filename:
libraries/Data_views_array.php Line Number: 59
data = $this->CI->$this_data[0]->$method($pass_var);
I found this post: PHP Notice: Array to string conversion only on PHP 7 and I changed my code to:
data = $this->CI->$this_data[0]->{$method($pass_var)};
but I got a different error:
Message: Call to undefined function get_page_id()
Everything works in PHP 5.6 and I don't know how to make it work in PHP 7.
Please help.
class Data_views_array {
var $CI;
public function __construct() {
$this->CI =& get_instance();
}
public function action_per_module($array_modules) {
$array_to_display = array();
$array_view_data = array();
if (!$array_modules) {
return false;
}
else {
while (list($key, $this_data) = each($array_modules)) {
/*
* $this_data[0] - is the controller name
* loading this model
*/
$this->CI->load->library($this_data[0]);
if ($this_data[2] == 'NULL') {
/*
* if there are no arguments (method and passing variable)
* the model is called
*/
$data = $this->CI->$this_data[0];
}
else {
/*
* getting method and passing variable from arguments
*/
//echo $this_data[2]. " - json<br>";
$obj = json_decode($this_data[2]);
$method = key(get_object_vars($obj));
//echo $method. " - method<br>";
$pass_var = $obj->$method;
/*
* getting data for view
*/
$data = $this->CI->$this_data[0]->$method($pass_var);
}
/*
* name of the View
*/
$view = $this_data[1];
/*
* adding the pair of View to the $array_view_data
*/
array_push($array_view_data, $view);
array_push($array_view_data, $data);
/*
* passing View Array to Display array
*/
array_push($array_to_display, $array_view_data);
/*
* clear the array of the pair of View and passing variable
*/
unset($array_view_data);
$array_view_data = array();
}
}
return $array_to_display;
}
}
The first Class that is called - $this_data[0]== page_title_display from library has method: get_page_id($page_id). This class gets the Title of the page.
Why the same script works in PHP 5.6 and it does not work in PHP 7?
Why the get_page_id function is found in PHP 5.6 but not in PHP 7?
class Page_title_display {
var $CI;
public function __construct(){
$this->CI =& get_instance();
}
public function get_page_id($page_id) {
$this->CI->load->model('pageTitle_model');
$title = $this->CI->pageTitle_model->getPagetitle($page_id);
return $title;
}
}
I solved this issue. For some reason PHP 7 does not like when $this_data[0] is used as a part of array.:
data = $this->CI->$this_data[0]->$method($pass_var);
First solution: I assigned this value to a variable:
$libControl = $this_data[0];
data = $this->CI->$libControl->$method($pass_var);
Second solution: only $this_data[0] in brackets:
data = $this->CI->{$this_data[0]}->$method($pass_var);

PHP strict standards error text added to results on the page

This is the error message generated:
Strict Standards: call_user_func_array() expects parameter 1 to be a
valid callback, non-static method
ModCareercoachoccupationsHelper::getRelated() should not be called
statically in
/customers/f/0/0/studiomitchell.agency/httpd.www/libraries/joomla/cache/controller/callback.php
on line 152
<?php
/**
* #package Joomla.Platform
* #subpackage Cache
*
* #copyright Copyright (C) 2005 - 2016 Open Source Matters, Inc. All rights reserved.
* #license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Joomla! Cache callback type object
*
* #since 11.1
*/
class JCacheControllerCallback extends JCacheController
{
/**
* Executes a cacheable callback if not found in cache else returns cached output and result
*
* Since arguments to this function are read with func_get_args you can pass any number of arguments to this method
* as long as the first argument passed is the callback definition.
*
* The callback definition can be in several forms:
* - Standard PHP Callback array see <https://secure.php.net/callback> [recommended]
* - Function name as a string eg. 'foo' for function foo()
* - Static method name as a string eg. 'MyClass::myMethod' for method myMethod() of class MyClass
*
* #return mixed Result of the callback
*
* #since 11.1
*/
public function call()
{
// Get callback and arguments
$args = func_get_args();
$callback = array_shift($args);
return $this->get($callback, $args);
}
/**
* Executes a cacheable callback if not found in cache else returns cached output and result
*
* #param mixed $callback Callback or string shorthand for a callback
* #param array $args Callback arguments
* #param mixed $id Cache ID
* #param boolean $wrkarounds True to use wrkarounds
* #param array $woptions Workaround options
*
* #return mixed Result of the callback
*
* #since 11.1
*/
public function get($callback, $args = array(), $id = false, $wrkarounds = false, $woptions = array())
{
// Normalize callback
if (is_array($callback))
{
// We have a standard php callback array -- do nothing
}
elseif (strstr($callback, '::'))
{
// This is shorthand for a static method callback classname::methodname
list ($class, $method) = explode('::', $callback);
$callback = array(trim($class), trim($method));
}
elseif (strstr($callback, '->'))
{
/*
* This is a really not so smart way of doing this... we provide this for backward compatability but this
* WILL! disappear in a future version. If you are using this syntax change your code to use the standard
* PHP callback array syntax: <https://secure.php.net/callback>
*
* We have to use some silly global notation to pull it off and this is very unreliable
*/
list ($object_123456789, $method) = explode('->', $callback);
global $$object_123456789;
$callback = array($$object_123456789, $method);
}
if (!$id)
{
// Generate an ID
$id = $this->_makeId($callback, $args);
}
$data = $this->cache->get($id);
$locktest = new stdClass;
$locktest->locked = null;
$locktest->locklooped = null;
if ($data === false)
{
$locktest = $this->cache->lock($id);
if ($locktest->locked == true && $locktest->locklooped == true)
{
$data = $this->cache->get($id);
}
}
$coptions = array();
if ($data !== false)
{
$cached = unserialize(trim($data));
$coptions['mergehead'] = isset($woptions['mergehead']) ? $woptions['mergehead'] : 0;
$output = ($wrkarounds == false) ? $cached['output'] : JCache::getWorkarounds($cached['output'], $coptions);
$result = $cached['result'];
if ($locktest->locked == true)
{
$this->cache->unlock($id);
}
}
else
{
if (!is_array($args))
{
$referenceArgs = !empty($args) ? array(&$args) : array();
}
else
{
$referenceArgs = &$args;
}
if ($locktest->locked == false)
{
$locktest = $this->cache->lock($id);
}
if (isset($woptions['modulemode']) && $woptions['modulemode'] == 1)
{
$document = JFactory::getDocument();
$coptions['modulemode'] = 1;
if (method_exists($document, 'getHeadData'))
{
$coptions['headerbefore'] = $document->getHeadData();
}
}
else
{
$coptions['modulemode'] = 0;
}
ob_start();
ob_implicit_flush(false);
$result = call_user_func_array($callback, $referenceArgs);
$output = ob_get_clean();
$coptions['nopathway'] = isset($woptions['nopathway']) ? $woptions['nopathway'] : 1;
$coptions['nohead'] = isset($woptions['nohead']) ? $woptions['nohead'] : 1;
$coptions['nomodules'] = isset($woptions['nomodules']) ? $woptions['nomodules'] : 1;
$cached = array(
'output' => ($wrkarounds == false) ? $output : JCache::setWorkarounds($output, $coptions),
'result' => $result,
);
// Store the cache data
$this->cache->store(serialize($cached), $id);
if ($locktest->locked == true)
{
$this->cache->unlock($id);
}
}
echo $output;
return $result;
}
/**
* Generate a callback cache ID
*
* #param callback $callback Callback to cache
* #param array $args Arguments to the callback method to cache
*
* #return string MD5 Hash
*
* #since 11.1
*/
protected function _makeId($callback, $args)
{
if (is_array($callback) && is_object($callback[0]))
{
$vars = get_object_vars($callback[0]);
$vars[] = strtolower(get_class($callback[0]));
$callback[0] = $vars;
}
return md5(serialize(array($callback, $args)));
}
}
The site retrieves the data but with this text error also above
the listing.
The callback.php line 152 is as follows:
$result = call_user_func_array($callback, $referenceArgs);
Any help would be great. Thanks
You'll get this error if you define the method non-statically:
class Foo {
public function bar() {
}
}
And then define $callback as either a string:
$callback = 'Foo::bar';
Or an array of strings:
$callback = ['Foo', 'bar'];
And then use it as an argument to call_user_func_array():
call_user_func_array($callback, []);
To avoid this, you can either define the method statically:
public static function bar() { ... }
Or use an instantiated object in your callback:
$callback = [new Foo(), 'bar'];

Dependency Injection Container PHP

I've recently learned about the advantages of using Dependency Injection (DI) in my PHP application.
However, I'm still unsure how to create my container for the dependencies. Before, I use a container from a framework and I want to understand how is he doing things in back and reproduce it.
For example:
The container from Zend 2. I understand that the container make class dynamic, he does not have to know about them from the beginning, he checks if he already has that class in his registry and if he has not he check if that class exist and what parameters has inside constructor and put it in his own registry so next time could take it from there, practical is doing everything dynamic and it is completing his own registry, so we do not have to take care of nothing once we implement the container as he can give as any class we want even if we just make that class.
Also if I want to getInstance for A which needs B and B needs C I understand that he doing this recursive and he goes and instantiate C then B and finally A.
So I understand the big picture and what is he suppose to do but I am not so sure about how to implement it.
You may be better off using one of the existing Dependency Containers out there, such as PHP-DI or Pimple. However, if you are looking for a simpler solution, then I've implemented a Dependency Container as part of an article that I wrote here: http://software-architecture-php.blogspot.com/
Here is the code for the container
class Container implements \DecoupledApp\Interfaces\Container\ContainerInterface
{
/**
* This function resolves the constructor arguments and creates an object
* #param string $dataType
* #return mixed An object
*/
private function createObject($dataType)
{
if(!class_exists($dataType)) {
throw new \Exception("$dataType class does not exist");
}
$reflectionClass = new \ReflectionClass($dataType);
$constructor = $reflectionClass->getConstructor();
$args = null;
$obj = null;
if($constructor !== null)
{
$block = new \phpDocumentor\Reflection\DocBlock($constructor);
$tags = $block->getTagsByName("param");
if(count($tags) > 0)
{
$args = array();
}
foreach($tags as $tag)
{
//resolve constructor parameters
$args[] = $this->resolve($tag->getType());
}
}
if($args !== null)
{
$obj = $reflectionClass->newInstanceArgs($args);
}
else
{
$obj = $reflectionClass->newInstanceArgs();
}
return $obj;
}
/**
* Resolves the properities that have a type that is registered with the Container.
* #param mixed $obj
*/
private function resolveProperties(&$obj)
{
$reflectionClass = new \ReflectionClass(get_class($obj));
$props = $reflectionClass->getProperties();
foreach($props as $prop)
{
$block = new \phpDocumentor\Reflection\DocBlock($prop);
//This assumes that there is only one "var" tag.
//If there are more than one, then only the first one will be considered.
$tags = $block->getTagsByName("var");
if(isset($tags[0]))
{
$value = $this->resolve($tags[0]->getType());
if($value !== null)
{
if($prop->isPublic()) {
$prop->setValue($obj, $value);
} else {
$setter = "set".ucfirst($prop->name);
if($reflectionClass->hasMethod($setter)) {
$rmeth = $reflectionClass->getMethod($setter);
if($rmeth->isPublic()){
$rmeth->invoke($obj, $value);
}
}
}
}
}
}
}
/**
*
* #param string $dataType
* #return object|NULL If the $dataType is registered, the this function creates the corresponding object and returns it;
* otherwise, this function returns null
*/
public function resolve($dataType)
{
$dataType = trim($dataType, "\\");
$obj = null;
if(isset($this->singletonRegistry[$dataType]))
{
//TODO: check if the class exists
$className = $this->singletonRegistry[$dataType];
$obj = $className::getInstance();
}
else if(isset($this->closureRegistry[$dataType]))
{
$obj = $this->closureRegistry[$dataType]();
}
else if(isset($this->typeRegistry[$dataType]))
{
$obj = $this->createObject($this->typeRegistry[$dataType]);
}
if($obj !== null)
{
//Now we need to resolve the object properties
$this->resolveProperties($obj);
}
return $obj;
}
/**
* #see \DecoupledApp\Interfaces\Container\ContainerInterface::make()
*/
public function make($dataType)
{
$obj = $this->createObject($dataType);
$this->resolveProperties($obj);
return $obj;
}
/**
*
* #param Array $singletonRegistry
* #param Array $typeRegistry
* #param Array $closureRegistry
*/
public function __construct($singletonRegistry, $typeRegistry, $closureRegistry)
{
$this->singletonRegistry = $singletonRegistry;
$this->typeRegistry = $typeRegistry;
$this->closureRegistry = $closureRegistry;
}
/**
* An array that stores the mappings of an interface to a concrete singleton class.
* The key/value pair corresond to the interface name/class name pair.
* The interface and class names are all fully qualified (i.e., include the namespaces).
* #var Array
*/
private $singletonRegistry;
/**
* An array that stores the mappings of an interface to a concrete class.
* The key/value pair corresond to the interface name/class name pair.
* The interface and class names are all fully qualified (i.e., include the namespaces).
* #var Array
*/
private $typeRegistry;
/**
* An array that stores the mappings of an interface to a closure that is used to create and return the concrete object.
* The key/value pair corresond to the interface name/class name pair.
* The interface and class names are all fully qualified (i.e., include the namespaces).
* #var Array
*/
private $closureRegistry;
}
The above code can be found here: https://github.com/abdulla16/decoupled-app (under the /Container folder)
You can register your dependencies as a singleton, as a type (every time a new object will be instantiated), or as a closure (the container will call the function that you register and that function is expected to return the instance).
For example,
$singletonRegistry = array();
$singletonRegistry["DecoupledApp\\Interfaces\\UnitOfWork\\UnitOfWorkInterface"] =
"\\DecoupledApp\\UnitOfWork\\UnitOfWork";
$typeRegistry = array();
$typeRegistry["DecoupledApp\\Interfaces\\DataModel\\Entities\\UserInterface"] =
"\\DecoupledApp\\DataModel\\Entities\\User";
$closureRegistry = array();
$closureRegistry["DecoupledApp\\Interfaces\\DataModel\\Repositories\\UserRepositoryInterface"] =
function() {
global $entityManager;
return $entityManager->getRepository("\\DecoupledApp\\DataModel\\Entities\\User");
};
$container = new \DecoupledApp\Container\Container($singletonRegistry, $typeRegistry, $closureRegistry);
This Container resolves properties of a class as well as the constructor parameters.
I have done a very simple IoC class which works as intended. I've investigated the IoC and DI pattern and especially after reading this answer. Let me know if something is not right or you have any questions .
<?php
class Dependency {
protected $object = null;
protected $blueprint = null;
/**
* #param $instance callable The callable passed to the IoC object.
*/
public function __construct($instance) {
if (!is_object($instance)) {
throw new InvalidArgumentException("Received argument should be object.");
}
$this->blueprint = $instance;
}
/**
* (Magic function)
*
* This function serves as man-in-the-middle for method calls,
* the if statement there serves for lazy loading the objects
* (They get created whenever you call the first method and
* all later calls use the same instance).
*
* This could allow laziest possible object definitions, like
* adding annotation parsing functionality which can extract everything during
* the call to the method. once the object is created it can get the annotations
* for the method, automatically resolve its dependencies and satisfy them,
* if possible or throw an error.
*
* all arguments passed to the method get passed to the method
* of the actual code dependency.
*
* #param $name string The method name to invoke
* #param $args array The array of arguments which will be passed
* to the call of the method
*
* #return mixed the result of the called method.
*/
public function __call($name, $args = array())
{
if (is_null($this->object)) {
$this->object = call_user_func($this->blueprint);
}
return call_user_func_array(array($this->object, $name), $args);
}
}
/*
* If the object implements \ArrayAccess you could
* have easier access to the dependencies.
*
*/
class IoC {
protected $immutable = array(); // Holds aliases for write-protected definitions
protected $container = array(); // Holds all the definitions
/**
* #param $alias string Alias to access the definition
* #param $callback callable The calback which constructs the dependency
* #param $immutable boolean Can the definition be overriden?
*/
public function register ($alias, $callback, $immutable = false) {
if (in_array($alias, $this->immutable)) {
return false;
}
if ($immutable) {
$this->immutable[] = $alias;
}
$this->container[$alias] = new Dependency($callback);
return $this;
}
public function get ($alias) {
if (!array_key_exists($alias, $this->container)) {
return null;
}
return $this->container[$alias];
}
}
class FooBar {
public function say()
{
return 'I say: ';
}
public function hello()
{
return 'Hello';
}
public function world()
{
return ', World!';
}
}
class Baz {
protected $argument;
public function __construct($argument)
{
$this->argument = $argument;
}
public function working()
{
return $this->argument->say() . 'Yep!';
}
}
/**
* Define dependencies
*/
$dic = new IoC;
$dic->register('greeter', function () {
return new FooBar();
});
$dic->register('status', function () use ($dic) {
return new Baz($dic->get('greeter'));
});
/**
* Real Usage
*/
$greeter = $dic->get('greeter');
print $greeter->say() . ' ' . $greeter->hello() . ' ' . $greeter->world() . PHP_EOL . '<br />';
$status = $dic->get('status');
print $status->working();
?>
I think the code is pretty self-explanatory, but let me know if something is not clear
Because I haven't find anything near what I wanted,I tried to implement on my own a container and I want to hear some opinion about how is looking,because I've start to learn php and oop a month ago a feedback is very important for me because I know I have many things to learn,so please feel free to bully my code :))
<!DOCTYPE html>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<?php
class ioc
{
private $defs;
static $instance;
private $reflection;
private function __construct()
{
$defs = array();
$reflection = array();
}
private function __clone()
{
;
}
public static function getInstance()
{
if (!self::$instance) {
self::$instance = new ioc();
}
return self::$instance;
}
public function getInstanceOf($class)
{
if (is_array($this->defs) && key_exists($class, $this->defs)) {
if (is_object($this->defs[$class])) {
return $this->defs[$class];
}
} else {
if (class_exists($class)) {
if (is_array($this->reflection) && key_exists($class, $this->reflection)) {
$reflection = $this->reflection[$class];
} else {
$reflection = new ReflectionClass($class);
$this->reflection[$class] = $reflection;
}
$constructor = $reflection->getConstructor();
if ($constructor) {
$params = $constructor->getParameters();
if ($params) {
foreach ($params as $param) {
$obj[] = $this->getInstanceOf($param->getName());
}
$class_instance = $reflection->newInstanceArgs($obj);
$this->register($class, $class_instance);
return $class_instance;
}
}
if (!$constructor || !$params) {
$class_instance = new $class;
$this->register($class, $class_instance);
return $class_instance;
}
}
}
}
public function register($key, $class)
{
$this->defs[$key] = $class;
}
}
?>

How to write my very own Smarty If-case

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}
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.
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.

Categories