Skip to content

Instantly share code, notes, and snippets.

@catch56
Created June 11, 2012 07:02
Show Gist options
  • Save catch56/2908806 to your computer and use it in GitHub Desktop.
Save catch56/2908806 to your computer and use it in GitHub Desktop.
locale
<?php
function locale($string = NULL, $context = NULL, $langcode = NULL) {
global $language_interface, $user;
// Use the advanced drupal_static() pattern, since this is called very often.
static $drupal_static_fast;
if (!isset($drupal_static_fast)) {
$drupal_static_fast['locale'] = &drupal_static(__FUNCTION__);
}
$locale_cache = &$drupal_static_fast['locale'];
if (empty($local_cache)) {
$locale_cache = new LocaleCache(array_keys($user->roles));
}
if (!isset($string)) {
// Return all cached strings if no string was specified
return $locale_cache->getAll();
}
$langcode = isset($langcode) ? $langcode : $language_interface->langcode;
return $locale_cache->get($string, $context, $langcode);
}
<?php
/**
* @file
* Definition of LocaleCache
*/
namespace Drupal\locale;
/**
* Dynamic building of the locale cache.
*/
class LocaleCache {
protected $rids = array();
protected $front_load_cids = array();
protected $data = array();
protected $keysToPersist = array();
public function __construct(array $roles) {
$this->rids = array_keys($roles);
$this->frontLoadCache();
}
public function __destruct() {
if (!empty($this-keysToPersist())) {
$data = array_keys($this->data) + $this->keysToPersist();
cache()->set("locale:frontload:" . implode(':', $this->rids), array_keys($this->data));
}
}
protected function frontLoadCache() {
// Get the list of cids to front load for this set of rids.
if ($cache = cache()->get("locale:frontload:" . implode(':', $this->rids))) {
// Frontloadem.
foreach (cache()->getMultiple($this->front_load_cids) as $cid => $cache) {
$this->data[$cid] = $cache->data;
}
}
}
function persist($cid) {
$this->keysToPersist[] = $cid;
}
/**
* Overrides DrupalCacheArray::resolveCacheMiss().
*/
public function get($string, $context, $langcode) {
$cid = "$langcode:$context:$string";
if (isset($this->data[$cid])) {
return $this->data[$cid];
}
$this->persist($cid);
// Even if we didn't frontload this string from cache, it still may be
// cached, so check before hitting the database.
if ($cache = cache()->get($cid)) {
$this->data[$cid] = $cache->data;
return $this->data[$cid];
}
// Cache miss, so fetch from the database.
$translation = db_query("SELECT s.lid, t.translation, s.version FROM {locales_source} s LEFT JOIN {locales_target} t ON s.lid = t.lid AND t.language = :language WHERE s.source = :source AND s.context = :context", array(
':language' => $langcode,
':source' => $string,
':context' => $context,
))->fetchObject();
if ($translation) {
if ($translation->version != VERSION) {
// This is the first use of this string under current Drupal version.
// Update the {locales_source} table to indicate the string is current.
db_update('locales_source')
->fields(array('version' => VERSION))
->condition('lid', $translation->lid)
->execute();
}
$value = !empty($translation->translation) ? $translation->translation : TRUE;
}
else {
// We don't have the source string, update the {locales_source} table to
// indicate the string is not translated.
db_merge('locales_source')
->insertFields(array(
'location' => request_uri(),
'version' => VERSION,
))
->key(array(
'source' => $offset,
'context' => $this->context,
))
->execute();
$value = TRUE;
}
cache()->set($cid, $value);
$this->data[$cid] = $value;
return $value;
}
/**
* Don't use this unless you know what you're doing.
*/
public function getAll() {
// Load all the things and return them.
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment