Файл: base-sys/base/bol/language_service.php
Строк: 860
<?php
class BOL_LanguageService
{
private static $currentLanguage = null;
private $languageCacheDir; // = PEEP_DIR_ROOT.'peep_plugin_files'.DS;
private $language = array();
private $languageDao;
private $prefixDao;
private $keyDao;
private $valueDao;
private $exceptionPrefixes = array( "mobile", "nav", "peep_custom" ); // section which importing without checking plugin key
private function __construct( $includeCache = true )
{
$this->languageDao = BOL_LanguageDao::getInstance();
$this->prefixDao = BOL_LanguagePrefixDao::getInstance();
$this->keyDao = BOL_LanguageKeyDao::getInstance();
$this->valueDao = BOL_LanguageValueDao::getInstance();
$this->languageCacheDir = PEEP::getPluginManager()->getPlugin('base')->getPluginFilesDir();
if ( $includeCache )
{
$this->loadFromCahce();
}
}
private function loadFromCahce()
{
$allLanguages = $this->getLanguages();
// exit if no active laguages
if ( empty($allLanguages) ) {
return;
}
$filename = $this->languageCacheDir . $this->getCacheFilename($this->getCurrent()->getId());
$language = array();
// include cache file
include $filename;
$this->language = $language;
}
private function getCacheFilename( $languageId )
{
return "lang_{$languageId}.php";
}
public function generateCache( $languageId )
{
$event = new BASE_CLASS_EventCollector('base.add_global_lang_keys');
PEEP::getEventManager()->trigger($event);
$globalVars = call_user_func_array('array_merge', $event->getData());
$values = $this->keyDao->findAllWithValues($languageId);
$result = array();
foreach ( $values as $v )
{
$key = $v['prefix'] . '+' . $v['key'];
$v['value'] = UTIL_String::replaceVars($v['value'], $globalVars);
$result[$key] = $v['value'];
}
$cacheContent = "<?phpn$language[{$languageId}] = " . var_export($result, true) . ";n?>";
$filename = $this->languageCacheDir . 'lang_' . $languageId . '.php';
file_put_contents($filename, $cacheContent);
@chmod($filename, 0666);
$this->loadFromCahce();
}
public function generateCacheForAllActiveLanguages()
{
$langs = $this->findActiveList();
foreach ( $langs as $lang )
{
/* @var $lang BOL_Language */
$this->generateCache($lang->id);
}
}
/**
* Class instance
*
* @var BOL_LanguageService
*/
private static $classInstance;
/**
* Returns class instance
*
* @return BOL_LanguageService
*/
public static function getInstance( $includeCache = true )
{
if ( !isset(self::$classInstance) )
{
self::$classInstance = new self($includeCache);
}
return self::$classInstance;
}
/**
* Adds new key and value
*
* @param int $languageId
* @param string $prefix
* @param string $key
* @param string $value
*
* @return BOL_LanguageValue
*
* @throws 'Such prefix doesn't exist..' Exception
*/
public function addValue( $languageId, $prefix, $key, $value, $generateCache = true )
{
$list = array();
$prefixDto = $this->prefixDao->findByPrefix($prefix);
$prefixId = $prefixDto->id;
$keyDao = $this->keyDao;
if ( null === ( $keyDto = $this->findKey($prefix, $key) ) )
{
$keyDto = new BOL_LanguageKey();
$keyDto->setPrefixId($prefixId)
->setKey($key);
$keyDao->save($keyDto);
}
$valueDto = new BOL_LanguageValue();
$valueDto->setLanguageId($languageId)
->setKeyId($keyDto->getId())
->setValue($value);
$valueDao = $this->valueDao;
$valueDao->save($valueDto);
if ( $generateCache === true )
{
$this->generateCache($valueDto->languageId);
}
return $valueDto;
}
/**
* Adds or updates new key and value
*
* @param int $languageId
* @param string $prefix
* @param string $key
* @param string $value
*
* @return BOL_LanguageValue
*
* @throws 'Such prefix doesn't exist..' Exception
*/
public function addOrUpdateValue( $languageId, $prefix, $key, $value, $generateCache = true )
{
$prefixDto = $this->prefixDao->findByPrefix($prefix);
if ( null === ( $keyDto = $this->findKey($prefix, $key) ) )
{
$keyDto = new BOL_LanguageKey();
$keyDto->setPrefixId($prefixDto->id)
->setKey($key);
$this->keyDao->save($keyDto);
}
$valueDto = $this->findValue($languageId, $keyDto->id);
if ( $valueDto === null )
{
$valueDto = new BOL_LanguageValue();
}
$valueDto->setLanguageId($languageId)
->setKeyId($keyDto->getId())
->setValue($value);
$this->valueDao->save($valueDto);
if ( $generateCache === true )
{
$this->generateCache($valueDto->languageId);
}
return $valueDto;
}
/**
* Adds new Prefix
*
* @throws 'Duplicated prefix..' exception
*/
public function addPrefix( $prefix, $label )
{
if ( self::isPrefixExist($prefix) )
{
throw new Exception('Duplicated prefix..');
}
$prefixDto = new BOL_LanguagePrefix();
$prefixDto->setPrefix($prefix)
->setLabel($label);
$this->prefixDao->save($prefixDto);
return $prefixDto;
}
private function isPrefixExist( $prefix )
{
$prefixDto = $this->prefixDao->findPrefixId($prefix);
return ( $prefixDto !== null);
}
public function findLastKeyList( $first, $count, $prefix = null )
{
return $this->valueDao->findLastKeyList($first, $count, $prefix);
}
public function countKeyByPrefix( $prefix )
{
$keyDao = BOL_LanguageKeyDao::getInstance();
$prefixId = $this->findPrefixId($prefix);
return $keyDao->countKeyByPrefix($prefixId);
}
public function getText( $languageId, $prefix, $key )
{
PEEP::getEventManager()->trigger( new PEEP_Event('servicelangtools.lang_used_log', array( 'prefix' => $prefix, 'key' => $key)) );
return ( isset($this->language[$languageId][$prefix . '+' . $key]) ) ? $this->language[$languageId][$prefix . '+' . $key] : null;
}
public function getValue( $languageId, $prefix, $key )
{
$prefixDto = $this->findPrefix($prefix);
if ( empty($prefixDto) )
{
return null;
}
$keyId = $this->keyDao->findKeyId($prefixDto->getId(), $key);
if ( empty($keyId) )
{
return null;
}
return $this->valueDao->findValue($languageId, $keyId);
}
public function getPrefixList()
{
return $this->prefixDao->findAll();
}
public function getLanguages()
{
return $this->languageDao->findAll();
}
public function findSearchResultKeyList( $languageId, $first, $count, $search )
{
return $this->valueDao->findSearchResultKeyList($languageId, $first, $count, $search);
}
public function countSearchResultKeys( $languageId, $search )
{
return $this->valueDao->countSearchResultKeys($languageId, $search);
}
public function findKeySearchResultKeyList( $languageId, $first, $count, $search )
{
return $this->valueDao->findKeySearchResultKeyList($languageId, $first, $count, $search);
}
public function countKeySearchResultKeys( $languageId, $search )
{
return $this->valueDao->countKeySearchResultKeys($languageId, $search);
}
/**
* Add new lang key
*
* @param int $prefixId
* @param string $key
* @return BOL_LanguageKey
*/
public function addKey( $prefixId, $key )
{
$dto = new BOL_LanguageKey();
$dto->setKey($key);
$dto->setPrefixId($prefixId);
BOL_LanguageKeyDao::getInstance()->save($dto);
return $dto;
}
public function findPrefixId( $prefix )
{
return $this->prefixDao->findPrefixId($prefix);
}
public function deleteKey( $keyId, $refreshCache = false )
{
if ( empty($keyId) )
{
throw new InvalidArgumentException("Empty key id passed");
}
$this->valueDao->deleteByKeyId($keyId);
$this->keyDao->deleteById($keyId);
if ( $refreshCache )
{
$this->generateCacheForAllActiveLanguages();
}
}
public function exportLanguage( $languageId )
{
$xml = new DOMDocument('1.0', 'utf-8');
$rootElement = $xml->createElement("language");
$prefixes = $this->getPrefixList();
/* @var $prefix BOL_LanguagePrefix */
foreach ( $prefixes as $prefix )
{
/* @var $prefixElement DOMElement */
$prefixElement = $xml->createElement('prefix');
$prefixElement->setAttribute('name', $prefix->getPrefix());
$rootElement->appendChild($prefixElement);
}
$xml->appendChild($rootElement);
}
public function getLanguageXML( $id )
{
$dto = $this->findById($id);
$xml = new DOMDocument('1.0', 'utf-8');
/* @var $rootElement DomElement */
$rootElement = $xml->createElement('language');
$rootElement->setAttribute('tag', $dto->getTag());
$rootElement->setAttribute('label', $dto->getLabel());
$rootElement->setAttribute('rtl', $dto->getRtl());
$xml->appendChild($rootElement);
return $xml->saveXML();
}
public function getPrefixXML( $id, $languageId )
{
/* @var $prefix BOL_LanguagePrefix */
if ( ($prefix = BOL_LanguagePrefixDao::getInstance()->findById($id)) == null )
throw new Exception("Prefix with id: {$id}, doesn't exist");
$xml = new DOMDocument('1.0', 'utf-8');
$language = $this->findById($languageId);
/* @var $rootElement DomElement */
$rootElement = $xml->createElement('prefix');
$rootElement->setAttribute('name', $prefix->getPrefix());
$rootElement->setAttribute('label', $prefix->getLabel());
$rootElement->setAttribute('language_tag', $language->getTag());
$rootElement->setAttribute('language_label', $language->getLabel());
$keyDao = $this->keyDao;
$keys = $keyDao->findAllPrefixKeys($id);
foreach ( $keys as $key ) /* @var $key BOL_LanguageKey */
{
$keyElement = $xml->createElement('key'); /* @var $keyElement DomElement */
$keyElement->setAttribute('name', $key->getKey());
$valDao = $this->valueDao;
$value = $valDao->findValue($languageId, $key->getId());
if ( $value != null )
{
$valueNode = $xml->createElement('value');
$valueNode->appendChild($xml->createTextNode($value->getValue()));
$keyElement->appendChild($valueNode);
}
$rootElement->appendChild($keyElement);
}
$xml->appendChild($rootElement);
$XML = $xml->saveXML();
return $XML;
}
public function importPrefix( $xml, $refreshCache=false, $importOnlyActivePluginPrefix = false )
{
if ( false === ( $prefixesXml = $xml->xpath("/prefix") ) )
{
return false;
}
$service = $this;
$languageTag = (string) $prefixesXml[0]->attributes()->language_tag;
$prefixName = strval($prefixesXml[0]->attributes()->name);
if ( $importOnlyActivePluginPrefix && !in_array($prefixName, $this->getExceptionPrefixes()) )
{
$plugin = BOL_PluginService::getInstance()->findPluginByKey($prefixName);
if ( empty($plugin) )
{
return false;
}
}
if ( null === ( $language = $service->findByTag($languageTag) ) )
{
$language = new BOL_Language();
$language->
setTag($languageTag)->setLabel((string) $prefixesXml[0]->attributes()->language_label)
->setOrder($service->findMaxOrder() + 1)
->setStatus('inactive');
$language->setRtl((string) $prefixesXml[0]->attributes()->language_rtl);
$service->save($language);
}
if ( null === ( $prefix = $service->findPrefix($prefixName) ))
{
$prefix = new BOL_LanguagePrefix();
$prefix->setPrefix($prefixName)
->setLabel(strval($prefixesXml[0]->attributes()->label));
$service->savePrefix($prefix);
}
$keysXml = $prefixesXml[0]->xpath('child::key');
foreach ( $keysXml as $keyXml )
{
if ( null === ($key = $service->findKey((string) $prefixesXml[0]->attributes()->name, (string) $keyXml->attributes()->name)) )
{
$key = new BOL_LanguageKey();
$key->setKey((string) $keyXml->attributes()->name)->
setPrefixId($prefix->getId());
$service->saveKey($key);
}
if ( null === ( $value = $service->findValue($language->getId(), $key->getId()) ) )
{
$value = new BOL_LanguageValue();
$value->setLanguageId($language->getId())->
setKeyId($key->getId())->
setValue((string) $keyXml->value);
$service->saveValue($value, false);
}
if ( $refreshCache )
{
$this->generateCache($language->getId());
}
}
}
/**
* @param integer $id
* @return BOL_Language
*/
public function findById( $id )
{
return $this->languageDao->findById($id);
}
public function save( $dto )
{
return $this->languageDao->save($dto);
}
public function findMaxOrder()
{
return $this->languageDao->findMaxOrder();
}
/**
*
* @return BOL_Language
*/
public function getCurrent()
{
//printVar(self::$currentLanguage);
if ( self::$currentLanguage === null )
{
if ( !empty($_GET['language_id']) )
{
PEEP::getSession()->set('base.language_id', $_GET['language_id']);
}
else if ( !empty($_COOKIE['base_language_id']) )
{
PEEP::getSession()->set('base.language_id', $_COOKIE['base_language_id']);
}
$session_language_id = PEEP::getSession()->get('base.language_id');
//printVar($session_language_id);
if ( !empty($session_language_id) )
{
/* @var $languageDto BOL_Language */
$languageDto = $this->findById($session_language_id);
if ( $languageDto === null || $languageDto->getStatus() !== 'active' )
{
$languageDto = $this->languageDao->getCurrent();
}
}
else
{
$languageDto = $this->languageDao->getCurrent();
}
setcookie('base_language_id', (string) $languageDto->getId(), time() + 60 * 60 * 24 * 30, "/");
$this->setCurrentLanguage($languageDto, false);
}
//printVar(self::$currentLanguage);
return self::$currentLanguage;
}
public function setCurrentLanguage( BOL_Language $language, $loadFromCache = true )
{
self::$currentLanguage = $language;
if ( $loadFromCache )
{
$this->loadFromCahce();
}
}
public function resetCurrentLanguage()
{
unset($_COOKIE['base_language_id']);
PEEP::getSession()->delete('base.language_id');
self::$currentLanguage = null;
$this->getCurrent();
}
public function findAll()
{
return $this->languageDao->findAll();
}
public function findMissingKeys( $languageId, $first, $count )
{
return $this->keyDao->findMissingKeys($languageId, $first, $count);
}
public function findMissingKeyCount( $languageId )
{
return $this->keyDao->findMissingKeyCount($languageId);
}
public function isKeyUnique( $prefix, $key )
{
$prefixId = $this->findPrefixId($prefix);
return $this->keyDao->findKeyId($prefixId, $key) === null;
}
/**
*
* @param string $tag
* @return BOL_Language
*/
public function findByTag( $tag )
{
return $this->languageDao->findByTag($tag);
}
public function delete( BOL_Language $language )
{
$this->valueDao->deleteValues($language->getId());
$this->languageDao->delete($language);
$this->generateCache($language->getId());
}
public function deleteValue( BOL_LanguageValue $value, $generateCache = true )
{
$this->valueDao->delete($value);
if ( $generateCache === true )
{
$this->generateCache($value->languageId);
}
}
/**
*
* @param string $prefix
* @param string $key
* @return BOL_LanguageKey
*/
public function findKey( $prefix, $key )
{
$prefixId = $this->prefixDao->findPrefixId($prefix);
$id = $this->keyDao->findKeyId($prefixId, $key);
if ( $id === null )
{
return null;
}
return $this->keyDao->findById($id);
}
public function cloneLanguage( $id, $label, $tag )
{
$languageClone = new BOL_Language();
$languageClone->setLabel($label)
->setTag($tag)
->setStatus('inactive')
->setOrder($this->findMaxOrder() + 1);
$this->save($languageClone);
$prefixes = ( null == ($prefixes = $this->getPrefixList()) ) ? array() : $prefixes;
foreach ( $prefixes as $prefix ) /* @var $prefix BOL_LanguagePrefix */
{
$keys = (null === $keys = $this->findAllPrefixKeys($prefix->getId())) ? array() : $keys;
foreach ( $keys as $key )/* @var $key BOL_LanguageKey */
{
$value = $this->findValue($id, $key->getId()); /* @var $value BOL_LanguageValue */
if ( $value === null )
continue;
$valueClone = new BOL_LanguageValue();
$valueClone->setKeyId($value->getKeyId())->setLanguageId($languageClone->getId())->setValue($value->getValue());
$this->saveValue($valueClone, false);
}
}
$this->generateCache($languageClone->getId());
}
public function findAllPrefixKeys( $prefixId )
{
return $this->keyDao->findAllPrefixKeys($prefixId);
}
public function coundAllPrefixKeys( $prefixId )
{
return $this->keyDao->countAllPrefixKeys($prefixId);
}
/**
*
* @param int $languageId
* @param int $keyId
* @return BOL_LanguageValue
*/
public function findValue( $languageId, $keyId )
{
return $this->valueDao->findValue($languageId, $keyId);
}
public function saveValue( BOL_LanguageValue $dto, $generateCache = true )
{
$this->valueDao->save($dto);
if ( $generateCache === true )
{
$this->generateCache($dto->languageId);
}
}
public function countActiveLanguages()
{
return $this->languageDao->countActiveLanguages();
}
public function savePrefix( $dto )
{
$this->prefixDao->save($dto);
}
/**
* @param string $prefix
* @return BOL_LanguagePrefix
*/
public function findPrefix( $prefix )
{
return $this->prefixDao->findByPrefix($prefix);
}
public function saveKey( $dto )
{
$this->keyDao->save($dto);
}
public static function getImportDirPath()
{
return PEEP::getPluginManager()->getPlugin('admin')->getPluginFilesDir() . 'languages' . DS . 'import' . DS;
}
public static function getExportDirPath()
{
return PEEP::getPluginManager()->getPlugin('admin')->getPluginFilesDir() . 'languages' . DS . 'export' . DS;
}
public static function getTmpDirPath()
{
return PEEP::getPluginManager()->getPlugin('admin')->getPluginFilesDir() . 'languages' . DS . 'tmp' . DS;
}
public function findActiveList()
{
return $this->languageDao->findActiveList();
}
public function generateCustomKey( $value )
{
$value = trim($value);
$len = 300;
$key = preg_replace("/[^A-z ^0-9 ]/u", '_', ( mb_strlen($value) > $len ? mb_substr($value, 0, $len) : $value));
$key = preg_replace("/[^w]/u", '_', $key);
$key = str_replace(' ', '_', $key);
$key = preg_replace("/(_)+/u", '_', $key);
return mb_strtolower($key);
}
public function countAllKeys()
{
return $this->keyDao->countAll();
}
public function findPrefixById( $id )
{
return $this->prefixDao->findById($id);
}
public function findAllPrefixes()
{
return $this->prefixDao->findAll();
}
public function deletePrefix( $id, $refreshCache = false )
{
$keys = $this->keyDao->findAllPrefixKeys($id);
foreach ( $keys as $key )
{
$this->deleteKey($key->getId());
}
$this->prefixDao->deleteById($id);
if ( $refreshCache )
{
$this->generateCacheForAllActiveLanguages();
}
}
public function importPrefixFromZip( $path, $key, $refreshCache=true, $addLanuage=false )
{
$importDir = $this->getImportDirPath() . $key . DS;
mkdir($importDir);
chmod($importDir, 0777);
$this->cleanImportDir($importDir);
$zip = new ZipArchive();
$zip->open($path);
$zip->extractTo($importDir);
$zip->close();
$arr = glob("{$importDir}language_*");
$langsToImport = array();
$prefixesToImport = array();
foreach ( $arr as $index => $dir )
{
$dh = opendir($dir);
$langXmlE = simplexml_load_file($dir . DS . 'language.xml'); /* @var $xmlElement SimpleXMLElement */
$l = array('label' => strval($langXmlE->attributes()->label), 'tag' => strval($langXmlE->attributes()->tag));
if ( !in_array($l, $langsToImport) )
{
$langsToImport[] = $l;
}
while ( false !== ( $file = readdir($dh) ) )
{
if ( $file == '.' || $file == '..' )
continue;
if ( is_dir("{$dir}/{$file}") )
{
//printVar("$file/");
}
else
{
if ( $file == 'language.xml' )
{
continue;
}
$xmlElement = simplexml_load_file("{$dir}/{$file}"); /* @var $xmlElement SimpleXMLElement */
$arr = $xmlElement->xpath('/prefix/key');
$tmp = $xmlElement->xpath('/prefix');
$prefixElement = $tmp[0];
$p = array('label' => strval($prefixElement->attributes()->label), 'prefix' => strval($prefixElement->attributes()->name));
if ( !in_array($p, $prefixesToImport) )
$prefixesToImport[] = $p;
}
}
}
$languages = $this->getLanguages();
$activateFirstLang = empty($languages);
foreach ( $langsToImport as $langToImport )
{
if ( !$this->findByTag($langToImport['tag']) )
{
if ( $addLanuage )
{
$dto = new BOL_Language();
$dto->setLabel($langToImport['label'])
->setTag($langToImport['tag'])
->setStatus( ($activateFirstLang ? 'active' : 'inactive') )
->setOrder($this->findMaxOrder() + 1);
$this->save($dto);
$activateFirstLang = false;
}
else
{
continue;
}
}
foreach ( $prefixesToImport as $prefixToImport )
{
$xml = simplexml_load_file($importDir . "language_{$langToImport['tag']}" . DS . "{$prefixToImport['prefix']}.xml");
$this->importPrefix($xml, false);
}
if ( $refreshCache )
{
$this->generateCacheForAllActiveLanguages();
}
}
UTIL_File::removeDir($importDir);
}
private function cleanImportDir( $dir )
{
$dh = opendir($dir);
while ( ( $node = readdir($dh) ) )
{
if ( $node == '.' || $node == '..' )
continue;
if ( is_dir($dir . $node) )
{
UTIL_File::removeDir($dir . $node);
continue;
}
unlink($dir . $node);
}
}
public function getExceptionPrefixes()
{
return $this->exceptionPrefixes;
}
}