Can't add new Smarty plugins - php

Directory structure:
smarty
------plugins
------myplugins
---------------function.myfnc.php
in file function.myfnc.php:
function smarty_function_myfnc($params, &$smarty) {
///code here
}
add plugin:
$smary->addPluginsDir(/path/to/myplugins);
but, when i call in file display.tpl:
{myfnc p="value"}
this is error:
Call to undefined function smarty_function_myfnc()
somebody can help me?

Probably problem is your path to your plugins dir. You should add before your myplugins the same path as you use for requiring Smarty.class.php.
For example I have code:
<?php
require 'smarty/Smarty.class.php';
$smarty = new Smarty;
$smarty->setTemplateDir('templates');
$smarty->addPluginsDir('smarty/myplugins');
var_dump($smarty->getPluginsDir());
echo $smarty->fetch('temp.tpl');
At the beginning I have require 'smarty/Smarty.class.php'; - my path to Smarty.class.php is smarty so when I have folder myplugins which is inside smarty folder as in your case I need to use smarty/myplugins and not only myplugins.
And then I have templates/temp.tpl file with content:
{myfnc p="value"}
and file smarty/myplugins/function.myfnc.php with content:
<?php
function smarty_function_myfnc($params, Smarty_Internal_Template $template)
{
return strtoupper($params['p']);
}
?>
And output for template is VALUE with capital letters as defined in my function.
So as you see it works without a problem.

Related

Require classes not working on PHP View Page

I don't know why my classes failed to load because of my folder structure it works in some places but not in some other places.
below is my folder
classes/
Rating.php
class Rating
{
public __construct($conn){
$this->conn = $conn
}
}
autolader/
class_Autoloader.php
spl_autoload_register(function($class_name){
include '../classes/'. $class_name'. '.php';
});
product.php
require 'autoloader/class_autoloader.php';
I now needed to add the spl_autoloader function to the product page before it worked. Also after uploading my code to Heroku my product page is not working. i will be glad if anyone can help.
Try specifying the path like this;
<?php
$path = $_SERVER['DOCUMENT_ROOT']."/thefolderyourscriptisin/";
require_once ($path."myscript.php");
?>

Include statement not working in PHP/Yii2

I have two files, the first one being in the main directory, console_output.php:
<?php
class console_output
{
function write_to_logfile($text) {
file_put_contents("log.txt", $text);
}
}
?>
and the second one in a subdirectory, xController.php
<?php
...import stuff...
include ("../console_output.php");
class xController extends Controller{
...do_stuff..
function doMoreStuff(){
...
$console_output = new console_output();
$console_output->write_to_logfile("did Stuff");
}
}
?>
This is all in Yii2 framework, in case that matters. I have tried with apps/console_output.php and ../console_output.php, but it fails either way.
When I use apps/console_output.php, the error is
include(app/console_output.php) [https://secure.php.net/manual/en/function.include.php'>function.include.php]: failed to open stream: No such file or directory
The error is shown right at the include statement.
Using ../console_output.php in the include statement gives me an error at
$console_output->write_to_logfile("did Stuff");
with the message
Class 'app\controllers\console_output' not found
I have no idea what I'm doing wrong here. Can you help me out please?
Yii(2) offers multiple shortcuts to various paths. The most commonly used one is
Yii::$app->urlManager->baseUrl
So You can include your php file like:
$url = Yii::$app->urlManager->baseUrl.'/../console_output.php';
include $url;
You relative path Def nation is wrong. You are using .. that mean you moving a director up from current script. You need to use "subdirectory/script.php"

How do you add a lib namespace to Wordpress roots sage?

Following the documentation written here, I added a file to lib directory containing:
<?php
namespace Theme\URIs;
/**
* Returns theme images directory uri
*/
function get_images_directory_uri() {
return get_template_directory_uri() . '/assets/images';
}
Which I then tried calling from a template file with:
<?php print Theme\URIs\get_images_directory_uri(); ?>
Calling this however, returned a Fatal error: Call to undefined function Theme\URIs\get_images_directory_uri().
The solution is to add the file to the $sage_includes array in functions.php, so it looks like this:
$sage_includes = [
'lib/assets.php', // Scripts and stylesheets
'lib/extras.php', // Custom functions
'lib/setup.php', // Theme setup
'lib/titles.php', // Page titles
'lib/wrapper.php', // Theme wrapper class
'lib/uris.php' // Project URIs
];
This imports the file to be used in the theme.
The present documentation does not explain this. (I assumed it simply imported all files in the libs directory...)
Not the question (I can't comment yet) but unless you've changed the directory structure your function should probably return:
get_template_directory_uri() . '/dist/images';
As the images in /assets/images get optimised and then copied to /dist/images.

Import an HTML file from inside a Twig template

I want to import an HTML file from inside a Twig template. The HTML file is located at /var/files/5 (with no extension). And I render the template like this:
$path = $_SERVER['DOCUMENT_ROOT'] . '/../var/files/5';
$content = $this->get('templating')->render('ProConvocationBundle:Default:definitive-view.html.twig', array('path' => $path));
Inside the Twig template I import the HTML file like this:
{% include path %}
but it is not finding the path: Unable to find template "/myDocumentRoot/../app/var/files/5"
I've also tried several relative paths without success. Any idea of how to achieve it?
What causes this exception?
After digging in the Twig code a little, the following seems to cause this exception:
Twig tries to load the file from a known path/namespace, being bundle names (like /var/www/myApplication/src/AcmeBundle/Resources/views) and the app path being myApplication/app/Resources/views). Anyway it doesn't accept absolute paths, since it always tries to add a known path to the beginning of the given file.
<?php
// Twig/Loader/Filesystem.php
class Twig_Loader_Filesystem {
// ...
protected function findTemplate()
{
// ...
foreach ($this->paths[$namespace] as $path) {
if (is_file($path.'/'.$shortname)) {
return $this->cache[$name] = $path.'/'.$shortname;
}
}
throw new Twig_Error_Loader(sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace])));
}
So it basically isn't possible to include a file by an absolue path, like in your example.
How to solve this?
You've got a bunch of possibilities to achieve this behaviour:
Add the path to the template loader
See post by #Adam Elsodaney
Move the file
You could simply move your file from app/var/files to app/Resources/views/var/files and use the path var/files/5 to include the file. This is probably not a suitable solution, since you want to keep those files in place.
Write a Twig Extension
You could write your own extension that provides a function named something like include_absolute() that simply returns file_get_contents($yourPath).
More on Twig extensions: http://symfony.com/doc/current/cookbook/templating/twig_extension.html
Be aware that you would might need to add the |raw filter to the output of the Twig function since a lot of stuff gets escaped everywhere.
In Symfony, you should make everything relative to the Kernel root directory which is the app directory.
$uploadedTemplatesDir = $this->get('kernel')->getRootDir() . '/../var/files';
Then add this to your templating loader
$this->get('twig.loader')->addPath($uploadedTemplatesDir);

File paths that works with all directories

In PHP when we include or require some file using some initializers like the following. How can we overcome filepath issues which occurs if you include the same initializer in a sub-directory or different location.
<?php
// settings
$settings = array('config');
foreach ($settings as $setting) {
require_once "../system/settings/{$setting}.php";
}
// neutrals
$neutrals = array('functions');
foreach ($neutrals as $neutral) {
require_once "../system/neutrals/{$neutral}.php";
}
// helpers
$helpers = array('database', 'file', 'logger', 'user', 'session', 'database');
foreach ($helpers as $helper) {
require_once "../system/helpers/{$helper}.php";
}
// models
$models = array('test');
foreach ($models as $model) {
require_once "../system/models/{$model}.php";
}
?>
Above script is in a file all_initializer.php. The hurdle here is that i cant use the same initializer in a public sub-directory or other location as it will occur fatal errors (if its a required file) of file not found.
EDIT
For e.g. I am using this initialzer in a public folder in a index.php file then there's a sub-directory in the public folder public/sub. How can I use the same initializer in public/sub/index.php as I used in public/index.php ?
You could use the file_exists to avoid fatal errors
// neutrals
$neutrals = array('functions');
foreach ($neutrals as $neutral) {
if (file_exists("../system/neutrals/{$neutral}.php")
{
require_once "../system/neutrals/{$neutral}.php";
}
else
{
// Do some logging here so as to know that something went wrong
}
}
As for the path issues you are referring to, you can include this file from anywhere so long as you supply the proper base path for your operations. Defining a ROOT_PATH in your index.php file would help you detect where your script is and what it needs to load.
So for instance if you have this structure:
/system
/system/neutrals
/system/models
/public
/public/index.php
in your index.php you can define a ROOT_PATH constant that will be used throughout the application and serve as a point of reference.
// this points to the folder that has /public and /system
define('ROOT_PATH', dirname(dirname(__FILE__))));
You can also have a constant just for your system folder
define('SYSTEM_PATH', ROOT_PATH . '/system');
and then all your require_once declarations become:
require_once SYSTEM_PATH ."/neutrals/{$neutral}.php";
EDIT: Based on additional information in the question
Structure:
/all_includes.php
/system
/system/neutrals
/system/models
/public
/public/index.php
/public/sub/index_sub.php
In index.php you define
// this points to the folder that has /public and /system
define('ROOT_PATH', dirname(dirname(__FILE__))));
and then:
require_once ROOT_PATH . '/all_includes.php';
to do your initialization. The same thing happens in the public/sub/index_sub.php.
Your all_includes.php becomes:
// neutrals
$neutrals = array('functions');
foreach ($neutrals as $neutral) {
if (file_exists(ROOT_PATH . "/system/neutrals/{$neutral}.php")
{
require_once ROOT_PATH . "/system/neutrals/{$neutral}.php";
}
else
{
// Do some logging here so as to know that something went wrong
}
}
The way most of the php frameworks work is similar to the following, zend framework works like this:
Declare a constant APPLICATION_PATH and then make all the paths relative to this one.
define("APPLICATION_PATH", "/var/www/mysite");
And then all your requires will be relative to your APPLICATION_PATH.
require_once APPLICATION_PATH ."/system/helpers/{$helper}.php";
* With this approach you can include files from whatever script without issues. Because all the paths are going to be relative to your APPLICATION_PATH.
Simple.. don't use relative paths... in your foreach loops, you could do:
require($_SERVER['DOCUMENT_ROOT'].'/system/thing.php');
the pathing problem can be solved in this way, you have one file that is always in the same place. for example you have (this is you public html)
.
..
folder/subfolder/filetoinclude.php
folder2/includein.php
thefilefolder/thefile.php
ok now in the file php you have a variable
$path=dirname(__FILE__);
this will always give you the absolute path to that file, then you ca use this $path variable and build your include paths around it.
in this example you have to include $path.'../folder/subfolder/filetoinclude.php';
The pint is to alway use the same point of origin, and not use relative paths.
and then you can make a custom include function in thefile.php, and then the things get really easy.

Categories