[smf2b3p] The filecache and laguages in a subdir

Started by feline, March 31, 2008, 06:54:10 AM

Previous topic - Next topic

feline

As a modwriter, I prefer to store templates and languages for mods in separate directorys.
Templates in /Themes/default/MyTeplates
Languages in /Themes/default/language/MyLanguages

That works NOT with the SMF filecache.
But .. it's a simple way to add this.

Step1.. Load.php
Replace the function loadLanguage with this

// Load a language file.  Tries the current and default themes as well as the user and global languages.
function loadLanguage($template_name, $lang = '', $fatal = true, $force_reload = false)
{
global $user_info, $language, $settings, $context;
global $cachedir, $db_show_debug, $sourcedir;
static $already_loaded = array();

// remove pathes inside (add by Feline)
$cache_template_name = str_replace(array('/', '\''), '_', $template_name);

// Default to the user's language.
if ($lang == '')
$lang = isset($user_info['language']) ? $user_info['language'] : $language;

if (!$force_reload && isset($already_loaded[$template_name]) && $already_loaded[$template_name] == $lang)
return $lang;

// What theme are we in?
$theme_name = basename($settings['theme_url']);
if (empty($theme_name))
$theme_name = 'unknown';

// Keep track of what we're up to soldier.
if ($db_show_debug === true)
$context['debug']['language_files'][] = $template_name . '.' . $lang . ' (' . $theme_name . ')';

// Is this cached? If not recache!
if (!file_exists($cachedir . '/lang_' . $cache_template_name . '_' . $lang . '_' . $theme_name . '.php'))
{
require_once($sourcedir . '/ManageMaintenance.php');
$do_include = cacheLanguage($template_name, $lang, $fatal, $theme_name);
}
// Otherwise just get it, get it, get it.
else
template_include($cachedir . '/lang_' . $cache_template_name . '_' . $lang . '_' . $theme_name . '.php');

// Remember what we have loaded, and in which language.
$already_loaded[$template_name] = $lang;

// Return the language actually loaded.
return $lang;
}


Step 2.. ManageMaintenance.php
Replace the function cacheLanguage with this

// This function caches the relevant language files, and if the cache doesn't work includes them with eval.
function cacheLanguage($template_name, $lang, $fatal, $theme_name)
{
global $language, $settings, $txt, $modSettings;
global $sourcedir, $cachedir, $smcFunc;

// remove pathes inside (add by Feline)
$cache_template_name = str_replace(array('/', '\''), '_', $template_name);

// Is the file writable?
$can_write = !empty($modSettings['cache_enable']) && is_writable($cachedir) ? 1 : 0;

// Assume it's not invalid!
$invalid_file_found = false;

// Lets assume we can cache the file and include it.
$do_include = true;

// Make sure we have $settings - if not we're in trouble and need to find it!
if (empty($settings['default_theme_dir']))
{
require_once($sourcedir . '/ScheduledTasks.php');
loadEssentialThemeData();
}

// Open the file to write to.
if ($can_write)
{
$fh = fopen($cachedir . '/lang_' . $cache_template_name . '_' . $lang . '_' . $theme_name . '.php', 'w');
@flock($fp, LOCK_EX);
fwrite($fh, '<?php' . "\n"); } // For each file open it up and write it out! foreach (explode('+', $template_name) as $template) { // Obviously, the current theme is most important to check. $attempts = array( array($settings['theme_dir'], $template, $lang, $settings['theme_url']), array($settings['theme_dir'], $template, $language, $settings['theme_url']), ); // Do we have a base theme to worry about? if (isset($settings['base_theme_dir'])) { $attempts[] = array($settings['base_theme_dir'], $template, $lang, $settings['base_theme_url']); $attempts[] = array($settings['base_theme_dir'], $template, $language, $settings['base_theme_url']); } // Fallback on the default theme if necessary. $attempts[] = array($settings['default_theme_dir'], $template, $lang, $settings['default_theme_url']); $attempts[] = array($settings['default_theme_dir'], $template, $language, $settings['default_theme_url']); // Try to find the language file. foreach ($attempts as $k => $file) if (file_exists($file[0] . '/languages/' . $file[1] . '.' . $file[2] . '.php')) { // Are we caching? if ($can_write) { foreach (file($file[0] . '/languages/' . $file[1] . '.' . $file[2] . '.php') as $line) { if (substr($line, 0, 2) != '?>' && substr($line, 0, 2) != '<?')
{
// Some common variables get parsed in...
$line = preg_replace('~\{NL\}~', '\\\\n', $line);
fwrite($fh, $line);
}
}
}
// If the cache directory is not writable we're having a bad day.
else
$do_include = false;

// Include it for fun.
require($file[0] . '/languages/' . $file[1] . '.' . $file[2] . '.php');

// Hmmm... do we really still need this?
$language_url = $file[3];
$lang = $file[2];

break;
}

// That couldn't be found!  Log the error, but *try* to continue normally.
if (!isset($language_url))
{
$invalid_file_found = true;

if ($fatal)
log_error(sprintf($txt['theme_language_error'], $template_name . '.' . $lang, 'template'));
break;
}
else
unset($language_url);
}

if ($can_write)
{
fwrite($fh, '?>');
@flock($fp, LOCK_UN);
fclose($fh);

// If we couldn't find the file don't cache it!
if ($invalid_file_found)
@unlink($cachedir . '/lang_' . $cache_template_name . '_' . $lang . '_' . $theme_name . '.php');
}

return $do_include;
}


I hope, that will by implemented in next release ...

Fel

SleePy

feline,

I realized I missed this topic because you changed the icon on me :P

Even if you are storing it in a custom location, you should be using unique file names.
The problem with storing the actual file path is you then add more to the file name. Which is limited on some systems. Even with a hashing method it still would be longer and compressing the name would add in load which would really defeat the purpose of using a cache if it takes longer to get the file than it did to make the query.
Jeremy D ~ Site Team / SMF Developer ~ GitHub Profile ~ Join us on IRC @ Libera.chat/#smf ~ Support the SMF Support team!

karlbenson

Hmm.

Probably from a end-users perspective, its probably better having single directory for sources/templates/languages.
Unless your adding something like 20+ files in it.

Maybe thats me. I find nothing worse than having to traverse directories only to find it contain a couple of files.

For installing mods aswell. Knowing sources go in folder x, templates in y, and languages in z, is alot easier than subfolder of x ... etc.

feline

Quote from: SleePy on May 06, 2008, 11:32:05 PM
Even if you are storing it in a custom location, you should be using unique file names.
The problem with storing the actual file path is you then add more to the file name. Which is limited on some systems. Even with a hashing method it still would be longer and compressing the name would add in load which would really defeat the purpose of using a cache if it takes longer to get the file than it did to make the query.

I dont understand that, what you say.

What I mean is a simple change of a existing function, so i can store languagefiles in ANY directory.

It's a abstruse thing, to fillin the SMF language directory with many other languagefiles.

Fel

SleePy

if you want to store the whole file path in there so it knows where the custom location is, then that extends the length of the directory. The only way to correctly load that language cache would be to hash that path and use it in the file name.
Most Systems have a file name limit (I believe windows is 254). So you can't go over that with a file name. If the path to the files is already lets say 150 characters to get to the file. Then you might just run into a limit because of a supper long name.
Jeremy D ~ Site Team / SMF Developer ~ GitHub Profile ~ Join us on IRC @ Libera.chat/#smf ~ Support the SMF Support team!

Advertisement: