2

I am using the Smarty Template engine (http://smarty.net) on a website but I have additional, custom Functions to handle template compiling tasks.

In order to be able to update the Smarty framework files (e.g. /smarty/Smarty.class.php) and not having to copy-paste my custom function into the Class inside Smarty.class.php, I thought "hey, let's just make my own Class and extend the Smarty Class!". However, I can't get this to work and would appreciate any enlightening advice :)

This is what I got at the moment:

  • Web-Root/
    • includes/
      • Smarty.inc.php
    • smartylib/
      • Smarty.class.php
      • Smarty_Compiler.class.php

Smarty.class.php

The third party vendor file and class that I don't wanna touch:

class Smarty {
    // various vars declarations
    public function __construct() {
        // ...
    }

    function _compile_source($resource_name, &$source_content, &$compiled_content, $cache_include_path=null) {
        // magic...
        $smarty_compiler = new $this->compiler_class;
        // more magic...
    }

    // more class methods declarations
}

Smarty_Compiler.class.php

Another third party vendor file and class that I don't wanna touch:

class Smarty_Compiler extends Smarty {
    // various vars and methods declarations...

    function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null) {
        $this->_trigger_fatal_error("syntax error: $error_msg", $this->_current_file, $this->_current_line_no, $file, $line, $error_type);
    }

    // more various methods declarations...
}

Smarty.inc.php

My custom Smarty include file with new Subclasses and instantiating the $smarty object:

/**
 * My extensions for the Smarty Class
 */
Class MySmarty extends Smarty {
    // different custom vars declarations

    /**
     * My ADDITIONAL custom Template Compile function
     */
    public function compile ($template, &$errors) {
        // custom code
    }
}

/**
 * My extensions for the Smarty_Compiler Class
 */
Class MySmarty_Compiler extends Smarty {
    // different custom vars declarations
    var $_manual_compiler_errors = array();

    /**
     * My REPLACEMENT _syntax_error function
     */
    public function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null) {
        global $_manual_compiler_errors;

        if ($_manual_compiler_errors) {
            array_push($_manual_compiler_errors, "smarty syntax error on line ".$this->_current_line_no.": $error_msg");
        }else{
            $this->_trigger_fatal_error("smarty syntax error: $error_msg", $this->_current_file, $this->_current_line_no, $file, $line, $error_type);
        }
    }
}

// Instantiate Smarty
include_once($_SERVER['DOCUMENT_ROOT'].'/smartylib/Smarty.class.php');
$smarty = new Smarty;
$smarty->debugging = true;
$smarty->force_compile = false;

Result and problem

Okay I hope my intentions are clear from above code snippets: I want the object $smarty to contain also

  1. my additional, new custom template function,
  2. and my replacement function

And because I use "extends" for my 2 classes declaration, I thought this should simply work by using:

$smarty->compile(...);
$smarty->_syntax_error(...);

But unfortunately it doesn't :( I COULD add my custom functions directly into the Smarty Class inside Smarty.class.php - but this will, obviously, make the file non-updateable.

What am I missing by using my 2 Subclasses extending the Smarty Class and while talking to the methods declared in them? Or how would you approach extending a third-party Class with custom/rewritten functions without touching the original code?

Thank you for any advice!

Oliver
  • 416
  • 5
  • 14
  • 1
    You are still instantiating the base Smarty class `$smarty = new Smarty;` instead of instantiating your extending class `$smarty = new MySmarty;` But that only takes care of part of it. From the abbreviated code, it is not clear how the `MySmarty_Compiler` class is to be used. That would need to be similarly instantiated by name. If you can provide more details on how that is used, someone can provide a more complete answer. – Michael Berkowski Jan 06 '16 at 02:23
  • Thank you @MichaelBerkowski! I didn't realise that I need to instantiate NOT the original "Smarty" class but my NEW Subclass to it - and that works so far yay. However, now I'm stumbling how to instantiate the second Subclass, "MySmarty_Compiler". Can I probably add something like `$smarty_compiler = new MySmarty_Compiler;` inside "MySmarty" Class __construct? Seems like I also need to reinstantiate this `$smarty_compiler` Object which originally is created within "Smarty" Class in Smarty.class.php. Btw. I added the code for MySmarty_Compiler Class... not sure if this helps though. – Oliver Jan 06 '16 at 09:03
  • `Class MySmarty_Compiler extends Smarty` ... this should be `Class MySmarty_Compiler extends Smarty_Compiler` right ? – Byscripts Jan 06 '16 at 09:16
  • @ByScripts well I'm not sure - it would actually be more logical I guess, yes. How do you properly extend a main class (Smarty) with instantiating multiple different subclasses (like MySmarty and MySmarty_Compiler)? :) – Oliver Jan 06 '16 at 09:24

1 Answers1

0

✅ Based on this stackoverflow-Question/Answers I was able to overcome my problem and getting the Code run with my custom Classes and Methods.

Solution (summarized)

Class MySmarty extends Smarty {
    ...
}

Class MySmarty_Compiler extends Smarty {
    function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null) {
        ...
    }
}

// Instantiate Smarty the new way
include_once($_SERVER['DOCUMENT_ROOT'].'/smartylib/Smarty.class.php');
$smarty = new MySmarty; // Instantiate my Subclass, it loads the Main Class too
$smarty_compiler = new MySmarty_Compiler; // Overwrite the $smarty_compiler Object with my second patched Subclass, which loads the Smarty_Compile Class too

If I still missed something or any recommendations, I'd be happy to hear about it :)

Community
  • 1
  • 1
Oliver
  • 416
  • 5
  • 14
  • Contrary to @ByScripts suggestion, it won't work when the 2nd subclass, MySmarty_Compiler, extends `Smarty_Compiler` - it only works when it extends the `Smarty` Class too, like the 1st custom Class. – Oliver Jan 06 '16 at 19:04