Smarty is not expiring or overwriting its compiled and cached templates - php

I am using Smarty (latest version v4.3.0) for my PHP project. is not expiring or overwriting its compiled and cached templates. I have explicitly defined a NO-CACHE behaviour. The code for that is:
// Smarty & configuration
$this->smarty = new Smarty();
$this->smarty->caching = Smarty::CACHING_OFF;
$this->smarty->template_dir = $this->_base_path . /app/templates/';
$this->smarty->compile_dir = $this->_base_path . '/app/templates/templates_c';
$this->smarty->config_dir = $this->_base_path .
'/app/templates/config/';
$this->smarty->cache_dir = $this->_base_path . '/app/templates/cache/';
I've since removed it, but it had no affect. All my changes are being ignored. The first file that is created in my directory is the one that is not being overridden.
The directory permissions for the templates directory are: drwxrwxr-x www-data:root however the files being created in the directory are being created as follows:
-rw-r--r-- 1 www-data www-data 8585 Feb 6 21:29 8a59a03a5a13eaf28343fe9c9a076b3324d6ce8c_0.file.modal_calendar_event.tpl.php
How come my files cannot be overwritten? I am not seeing updated code as I push it.
I tried to add the following line (just to try and see if anything would update)
$this->smarty->clearAllCache();
But it doesn't even allow the compiled templates to be overridden.

Try setting $this->smarty->force_compile = true (docs)
Also make sure the template files are really getting updated/pulled after your push and the output is not cached by any other system that would cause this behavior.

Related

Having issues with getting root path directory from different folders

I am trying to connect a certain header file for different files in different folders. The problem is when having the same file included in for example /backend it will be easily called directly (as the index is also in /backend) but when calling it from backend/pages it doesnt recall the link structure anymore resulting in a deadlink.
I have tried every possible thing with ../ and different header files but that is a no go. Trying to find a solution such as the url below comes really close but yet I cannot seem to figure it.
Root path variable in a PHP project
What would be the best way to include the root automatically in an include or require for example.
If you're using a front controller (like an index.php file) that is starting and executing your entire application you can just set a constant there like define('APP_ROOT', __DIR__); and that'll set the root to be your front controller.
You can access your header file from anywhere then by doing APP_ROOT . "/includes/header.php"
If you are not using a front controller, then you can set this in each file. So for backend/pages it'd be something like ./../includes/header.php. or better still, use $_SERVER['DOCUMENT_ROOT'] to get the root of your application as provided by your web server vhosts config. (Apache of NGINX most likely)
$_SERVER['DOCUMENT_ROOT'] . "/app/backend/includes/header.php" for example.
What would be the best way to include the root automatically in an include or require for example.
I'm not aware of any method to do that without modifying PHP itself and re-compiling from source, but I could be wrong. Your root path will always be stored in $_SERVER['DOCUMENT_ROOT'].
I think what you might want to look into is autoloading and more specifically PSR-4 and composer.

Where is default cache directory for FilesystemAdapter in Symfony 3?

I'm on Windows and looking for the location of the cache generated by FileSystemAdapter. I thought it would be in var/cache of the application directory but it doesn't look like as when I clear it, it's still using the cache.
Any idea where it could be?
Filesystem Cache Adapter
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
$cache = new FilesystemAdapter(
// the subdirectory of the main cache directory where cache items are stored
$namespace = '',
// in seconds; applied to cache items that don't define their own lifetime
// 0 means to store the cache items indefinitely (i.e. until the files are deleted)
$defaultLifetime = 0,
// the main cache directory (the application needs read-write permissions on it)
// if none is specified, a directory is created inside the system temporary directory
$directory = null
);
note: if none is specified, a directory is created inside the system
temporary directory.
Also see: Removing Cache Items
Checking in the source code of the class, the class use this trait and if you don't specify a directory, it will use the function sys_get_temp_dir that return directory path used for temporary files.
For a Windows-based system could be:
C:\Windows\Temp
Hope this help

PHP `require_once` includes wrong file

I have a development tree on a Linux Ubuntu 14.04-LTS machine like this, with three identical branches:
main -+-- leonardo --- project --- htdocs -+- panel --- index.php
| |
| +- config.php
|
+-- federico --- project --- htdocs -+- panel --- index.php
| |
| +- config.php
|
+-- carlo ------ project --- htdocs -+- panel --- index.php
| |
| +- config.php
..... (you get my drift).
There are neither soft links nor hard links. The config.php file is in svn-ignore and is different between all branches
There is an Apache server and there is a virtualHost for each developer, so I can see my development version at http://leonardo.project.local or Federico's at http://federico.project.local .
While investigating the current weirdness, the two files are these:
<?php // this is panel/index.php
echo "I am " . __FILE__ . "\n";
echo "I will include " . realpath('../config.php') . "\n";
require_once '../config.php';
<?php // this is config.php
echo "I am " . __FILE__ . "\n";
exit();
The expected output of course would be:
I am leonardo/project/htdocs/panel/index.php
I will include /var/www/main/leonardo/project/htdocs/config.php
I am leonardo/project/htdocs/config.php
But the actual output is:
I am leonardo/project/htdocs/panel/index.php
I will include /var/www/main/leonardo/project/htdocs/config.php
I am federico/project/htdocs/config.php
The additional weirdness is that
echo "I will include " . realpath('../config.php') . "\n";
require_once realpath('../config.php');
works.
TL;DR require_once and realpath disagree about where '../config.php' actually is.
The really strange thing is that I do not see how a script running in leonardo/project/htdocs/panel/ could know about federico/project/htdocs/config.php; it ought to go four directories up, then explore very many subdirectories.
I'm almost beginning to suspect that this could be something filesystem- or even kernel- related.
The filesystem is ext4, the kernel is 3.13.0-55-generic #92-Ubuntu SMP Sun Jun 14 18:32:20 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux. The machine is a virtual x64 on the latest VMware Workstation.
Checks
PHP's include_path only includes . and /usr/local/php5/pear.
as stated earlier, no files in the branch are symlinks, and the inode counts for all involved files indicate there are no cross links. The files are indeed different.
all files are really there, it's not a "last ditch include".
from command line, in leonardo...panel, I run "cat ../config.php" and I get my config.php, as expected. It is only from PHP that the wrong file gets included.
restarting Apache (just in case) availed nothing. I'll next try and reboot the whole VM, but to do that I need to freeze several services and it will take me a while.
everything was hunky dory up to yesterday (I wasn't here then). There were no system updates, no reboots, and not even remote logins in the last three days. Uptime is now eight days.
I'm an idiot: I can too know to the minute when this started happening by checking the integration test logs. Have asked for them, expecting them after lunch.
It's worth checking what your include_path is set to (this can be done using get_include_path).
require and include will behave differently given an absolute and relative path. When you use
require_once realpath('../config.php');
This is doing:
require_once '/var/www/main/leonardo/project/htdocs/config.php';
Which works as you'd expect.
The weirdness in the following:
require_once '../config.php';
occurs because PHP will check each entry in the include path for a matching file and return the first matching entry. Hence it's likely that the path to the federico config is being checked first.
Have you checked any potential opcode caches and their settings?
In the past I have had some issues there, eg not detecting changed files.
Specifically, this situation can and will happen if opcache.use_cwd setting is set to zero.
opcache.use_cwd boolean
If enabled, OPcache appends the current working directory to the script key, thereby eliminating possible collisions between files with
the same base name. Disabling this directive improves performance,
but may break existing applications.
If this happens, then the first user or phpunit script accessing a file of a given name in a different directory (e.g. leonardo/config.php vs federico/config.php) will "prime" the cache with that file. The file system functions such as realpath will not be affected and will continue working. References using absolute paths will continue working. References with relative paths will be broken in a quite insidious way.
For until you have only one person working, that person has the cache primed for his needs and will notice nothing. Then you come back to work, and you start loading his files.
On a side note, the setting might cause unintentional information disclosure, because the setting is system wide. So you know that your ISP has a broken use_cwd, you know that another site includes '../inc/credit_cards.php', you prepare the same path in your site and include a file with the same name. get_defined_vars() might have you pwn the other site's login or database system. (Haven't checked, but given what happened, don't see why not).
UPDATE
I checked with the above configuration on PHP5.6 and an old backed up VM (we have time-machine snapshots of the last five years :-) ). I was indeed able to read all defined global variables in a different virtual host to which I had no access, overriding authentication.
This problem was discovered in 2016 but the tests they thought of did not extend to tricking opcache into including some one else's file by creating a file with the same name.
I have also re-run the same test on our current dev VM, and the problem appears to have gone away, even if the configuration has changed so much that I'm not sure they're comparable anymore.
I am considering renaming shared-host config.inc.php files to something like config.a72b1qTy.inc.php.

openshift php file not found ( same syntax in localhost )

The openshift I'm using is a DIY catridge with nginx + php 5.5.8 + phalcon 1.2.4
I have a directory structure as below
website
public
index.php
app
config
config.php
loader.php
routes.php
services.php
the problem is in my public/index.php i do
try {
/**
* Read the configuration
*/
if (file_exists(__DIR__ . "/../app/config/config.php"))
{
$config = include __DIR__ . "/../app/config/config.php";
}else{
throw new Exception("Failed to include 'config.php'");
}
and it failed
Failed to include 'config.php'
#0 {main}
Is this something to do with openshift? cause I'm doing it correct in my localhost(although it is in apache for localhost) The script should load the config.php
(changed from is_file to file_exist as it make more sense)
openshift does not deny the usage of the config.php file name, make sure you have added it into your git repository and that it is not ignored by any .gitignore files.
Are you sure the file exists? Also, check out if the parent directory has "+x". Quoted from PHP manual (http://php.net/is_file):
Note that is_file() returns false if the parent directory doesn't have
+x set for you; this make sense, but other functions such as readdir() don't seem to have this limitation. The end result is that you can
loop through a directory's files but is_file() will always fail.
Just found the problem that althought my local repo has above file but not config.php .
Probability 1: Probably because openshift deny the usage of config.php file name
Probability 2: Something bug happened when doing git push
Now dueling with another bug however this bug has been settled

Smarty PHP Template Engine - file permission errors and missing templates

I am having a lot of headaches with the Smarty PHP Template Engine - Version 2.6.0 (smarty.net)
An error I keep getting in my error_log is
PHP Fatal error: Smarty error: unable to write to $compile_dir
'/var/www/vhosts/domain/library/templates/compiled'. Be sure
$compile_dir is writable by the web server user. in
/var/www/vhosts/domain/library/Smarty-2.6.0/libs/Smarty.class.php on
line 1088
I have made the folder and files writable with permissions set to 777 but still this error keeps happening.
It is making updating the template files a nightmare as currently I am updating the code in two places -> the templates folder and the compiled folder. It's like no compilation is happening so editing the already compiled file is the only way I can make a change to the site.
However, I had a template file that was being included in another template file and this was not in the compiled directory. After making a simple text change in this file has now completely removed that section of the site and the page just breaks that section is supposed to appear.
I am completely stumped with this and am hoping some of you with Smarty experience will be able to help me out.
Thank you in advance.
make sure you assign the compile dir in the smarty configuration file
here is sample of the config i use and it's working fine with me
/////Smarty including
require_once('libs/Smarty.class.php');
$smarty = new Smarty();
$smarty->template_dir = 'template'; // template folder
$smarty->compile_dir = 'cache'; // Create a Folder Cache with 777 Permission
This Settings works fine with latest smarty edition Smarty 3.x.
You need to edit the file httpd.conf
vim +231 /etc/httpd/conf/httpd.conf
See what User and and Group are specified there,
if for example you see this:
User asterisk
Group asterisk
Then you need to give permission to that user/group on the directory /var/www/
chown -R asterisk:asterisk /var/www/

Categories