Smarty Forum Index Smarty
The discussions here are for Smarty, a template engine for the PHP programming language.
Plug-in directories are not scanned in correct order

 
Post new topic   Reply to topic    Smarty Forum Index -> Plugins
View previous topic :: View next topic  
Author Message
cbj4074
Smarty Regular


Joined: 10 Nov 2011
Posts: 49

PostPosted: Thu Jun 28, 2012 8:04 pm    Post subject: Plug-in directories are not scanned in correct order Reply with quote

According to the relevant documentation ( http://www.smarty.net/docs/en/variable.plugins.dir.tpl ):

Quote:

... Smarty will search for your plugin in each plugin directory in the order they are given."


This statement is ambiguous in that it does not make clear whether Smarty will use the first match or the last.

What happens when plugins with the same name exist in multiple plugin directories?

In my particular case, the behavior is not consistent. Smarty seems to load the plugin that it finds first in some cases, and the plugin that it finds last in others.

Some may be wondering, "Why would one ever want to have two plugins with the same name in different directories?" The short answer is, "For the same reason that PHP implements method overriding in extender classes."

I have several plugins that I consider to be "universal"; that is, they are useful for nearly any project. I store these plugins in a shared code repository (in Smarty's default plugin directory).

On the other hand, I have plugins that I consider to be specific to a particular project; these plugins often extend the functionality of their universal counterparts. I store these plugins in a project-specific repository.

As such, I have done the following:

Code:

$smarty = new Smarty();

//Project-specific plugins exist here.
$smarty->addPluginsDir(DOMAIN_ROOT . 'libraries-internal/smarty-plugins/');

//Universal plugins exist here.
$smarty->addPluginsDir(PREBUILT_CLASS_PATH . 'Smarty-3.0.8/' . 'libs/plugins/');


As the above snippet demonstrates, I am defining the project-specific directory first, so that Smarty will use the project-specific plugin over its more generic counterpart (if a project-specific version exists; otherwise, Smarty will find and use the universal version).

However, the above snippet performs unpredictably, even though I always call the plugin by the same name:

Code:

{com_domain_print_critical_error message=$criticalError}


Is anybody able to clarify the behavior I am observing? Is this operator error? Inadequate documentation? A use-case that was not considered?

I'm using Smarty 3.0.8.

Thanks for any help!
Back to top
View user's profile Send private message
U.Tews
Administrator


Joined: 22 Nov 2006
Posts: 4625
Location: Hamburg / Germany

PostPosted: Thu Jun 28, 2012 8:21 pm    Post subject: Reply with quote

Note that the libs/plugins folder of the distribution is setup by default and will be the first folder searched.

If you need project specific folders first you must use something like

Code:
//Project-specific plugins exist here.
$smarty->setPluginsDir(DOMAIN_ROOT . 'libraries-internal/smarty-plugins/');

//Universal plugins exist here.
$smarty->addPluginsDir(PREBUILT_CLASS_PATH . 'Smarty-3.0.8/' . 'libs/plugins/');
Back to top
View user's profile Send private message
rodneyrehm
Administrator


Joined: 30 Mar 2007
Posts: 698
Location: Germany, border to Switzerland

PostPosted: Thu Jun 28, 2012 8:25 pm    Post subject: Reply with quote

Code:
$smarty = new Smarty();
executes
Code:
$smarty->setPluginsDir(SMARTY_PLUGINS_DIR);
try
Code:
$smarty->setPluginsDir(array(
  DOMAIN_ROOT . 'libraries-internal/smarty-plugins/',
  PREBUILT_CLASS_PATH . 'Smarty-3.0.8/' . 'libs/plugins/'
));


Also, a plugin is only loaded if it isn't yet known to the execution runtime. Including a plugin-file manually makes that plugin known to the runtime. The function exists and is - obviously - not loaded again.
_________________
Twitter
Back to top
View user's profile Send private message Visit poster's website
cbj4074
Smarty Regular


Joined: 10 Nov 2011
Posts: 49

PostPosted: Mon Jul 02, 2012 2:58 pm    Post subject: Reply with quote

Thank you both for the reply.

The line

Code:

$smarty = new Smarty();


was there simply to demonstrate how I was instantiating Smarty. I'm not calling that line every time I want to change the plugin directories.

Both of your suggestions seem to work, which raises a final question:

Are these two blocks the same, functionally?

Code:

$smarty->setPluginsDir(array(
  DOMAIN_ROOT . 'libraries-internal/smarty-plugins/',
  PREBUILT_CLASS_PATH . 'Smarty-3.0.8/' . 'libs/plugins/'
));


Code:

//Project-specific plugins exist here.
$smarty->setPluginsDir(DOMAIN_ROOT . 'libraries-internal/smarty-plugins/');

//Universal plugins exist here.
$smarty->addPluginsDir(PREBUILT_CLASS_PATH . 'Smarty-3.0.8/' . 'libs/plugins/');


In other words, does calling setPluginsDir() with several paths within an array have the same effect as calling setPluginsDir() with the first path to be searched, and then calling addPluginsDir() for each additional path to be searched?
Back to top
View user's profile Send private message
rodneyrehm
Administrator


Joined: 30 Mar 2007
Posts: 698
Location: Germany, border to Switzerland

PostPosted: Mon Jul 02, 2012 3:00 pm    Post subject: Reply with quote

cbj4074 wrote:
In other words, does calling setPluginsDir() with several paths within an array have the same effect as calling setPluginsDir() with the first path to be searched, and then calling addPluginsDir() for each additional path to be searched?


yep!
_________________
Twitter
Back to top
View user's profile Send private message Visit poster's website
cbj4074
Smarty Regular


Joined: 10 Nov 2011
Posts: 49

PostPosted: Tue Jul 03, 2012 4:05 pm    Post subject: Reply with quote

Hmm, I thought the issue was resolved, but I'm seeing the issue again: Smarty is using the plugin from the second directory.

Here's the code (exactly as U.Tews suggested previously):

Code:

//Project-specific plugins exist here.
$smarty->setPluginsDir(DOMAIN_ROOT . 'libraries-internal/smarty-plugins/');

//Universal plugins exist here.
$smarty->addPluginsDir(array(
      PREBUILT_CLASS_PATH . 'Smarty-3.0.8/' . 'libs/plugins/',
));


I have two PHP pages that use the exact same application class constructor in which Smarty is initialized (see code snippet above).

If I var_dump() the Smarty object on each page, here's what I see for the "plugins_dir" property (it's the same for both pages):

Code:

public 'plugins_dir' =>
    array (size=2)
      0 => string 'C:/Users/User/Documents/Apache/protected/libraries-internal/smarty-plugins/' (length=83)
      1 => string 'C:/Users/User/Documents/Apache/protected/libraries-external/Smarty-3.0.8/libs/plugins/' (length=94)


Clearly, the project-specific plugin directory is registered first.

So, why is Smarty using the plugin from the second directory in one instance and not the other?

To be clear, Smarty (correctly) uses the plugin from the first directory on one page, but (incorrectly) uses the plugin from the second directory on another page.

Also, if I rename the plugin in the second directory temporarily, Smarty throws a fatal "Call to undefined function". So, not only does Smarty look in the wrong directory first, but it doesn't check the other directory when the plugin doesn't exist in the first directory that is examined.

Any ideas? Thanks again.
Back to top
View user's profile Send private message
rodneyrehm
Administrator


Joined: 30 Mar 2007
Posts: 698
Location: Germany, border to Switzerland

PostPosted: Tue Jul 03, 2012 4:08 pm    Post subject: Reply with quote

a) what's the plugins name?
b) are you doing anything with the plugin besides calling it from inside a template?
c) are both applications sharing the same compiled-cache or is each instance compiling their own templates?
d) are both instances running the same smarty version?
e) do you mind upgrading to Smarty 3.1.11?
_________________
Twitter
Back to top
View user's profile Send private message Visit poster's website
U.Tews
Administrator


Joined: 22 Nov 2006
Posts: 4625
Location: Hamburg / Germany

PostPosted: Tue Jul 03, 2012 4:21 pm    Post subject: Reply with quote

Note that Smarty saves the location of the plugins at compile time in the compiled template files. If you have changed the configuration of the plugin directories you must clear the cache and compiled template folders to make sure that the templates get recompiled with the correct setting.
Back to top
View user's profile Send private message
cbj4074
Smarty Regular


Joined: 10 Nov 2011
Posts: 49

PostPosted: Tue Jul 03, 2012 4:37 pm    Post subject: Reply with quote

Thanks for the exceptional support and speedy replies, guys.

U.Tews, deleting all compiled templates seems to have fixed the problem. Upon subsequent page refreshes, the correct plugin is used. Thank you for the clarification there. Operator error -- my bad!

Rodney, for academic purposes, I'm happy to answer your questions:

a) smarty_function_com_domain_print_critical_error

b) No.

c) The pages share the same $smarty->compile_dir. (And template caching is disabled altogether, for what that's worth.)

d) Yes.

e) Not at all, but given that U.Tews suggestion did the trick, it may not be necessary.

Thanks again, both of you. I'll post back if anything changes.
Back to top
View user's profile Send private message
rodneyrehm
Administrator


Joined: 30 Mar 2007
Posts: 698
Location: Germany, border to Switzerland

PostPosted: Tue Jul 03, 2012 4:41 pm    Post subject: Reply with quote

cbj4074 wrote:
e) Not at all, but given that U.Tews suggestion did the trick, it may not be necessary.


There have been quite some bugs fixed and performance enhancements pushed since 3.1.8 was released in February… While you don't *need* to update, you *want* to nonetheless Smile
_________________
Twitter
Back to top
View user's profile Send private message Visit poster's website
cbj4074
Smarty Regular


Joined: 10 Nov 2011
Posts: 49

PostPosted: Wed Jul 11, 2012 7:47 pm    Post subject: Reply with quote

Thanks, I did go ahead and upgrade to 3.1.11. No issues.

This seems like a silly question, but how do I mark the thread "SOLVED"?
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Smarty Forum Index -> Plugins All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP