Location: PHPKode > scripts > Internationalization and Localization > internationalization-and-localization/FileDataSource.class.php
<?php

/**
 * Project:     CWF: Cricava Web Framework
 * File:        FileDataSource.class.php
 *
 * @link http://www.cricava.com/
 * @copyright 2005-2009 Cricava Technologies, Inc.
 * @author Mariano Iglesias <hide@address.com>
 * @package com.cricava.cwf
 * @version 1.0
 */

/**#@+
 * Includes
 */
require_once(dirname(__FILE__) . '/DataSource.class.php');
require_once(dirname(__FILE__) . '/Dommer.class.php');
/**#@-*/

/**
 * This class implements a file based data source.
 *
 * @author  Mariano Iglesias
 * @package com.cricava.cwf
 * @subpackage i18n
 * @since   1.0
 */

class FileDataSource extends DataSource
{
	/**
	 * The settings, along with languages & locales
	 *
	 * @access private
	 * @since 1.0
	 * @var array
	 */
	var $settings;

	/**
	 * Creates a new instance of FileDataSource.
	 *
	 * @param string	Path to the XML configuration file
	 *
	 * @access public
	 * @since 1.0
	 */
	function & FileDataSource($configurationFile)
	{
		$this->databaseConnection =& $databaseConnection;

		$this->settings =& $this->parseSettings($configurationFile);
	}

	/**
	 * Function that handles the fetching of elements.
	 * <ul>
	 * <li>If no element specified, it will load all elements for a section.</li>
	 * <li>If no section specified, it will load all sections for the current container.</li>
	 * </ul>
	 *
	 * @param string	The language to use
	 * @param string	The locale to use (can be null)
	 * @param string	The container to use
	 * @param string	The section from where to get elements
	 * @param string	The element to obtain
	 *
	 * @return array	An indexed array by container, section, and elements
	 *
	 * @access public
	 * @since 1.0
	 */
	function & fetch($language, $locale, $container, $section = null, $element = null)
	{
		if (!isset($this->settings) || !isset($this->settings['path']) || !isset($this->settings['extension']))
		{
			return $elements;
		}

		$fileNames = array();

		if ($dirHandle = opendir($this->settings['path']))
		{
			// Get all file paths that are language files, and leave only those for current container

			while (($currentFileName = readdir($dirHandle)) !== false)
			{
				$currentFile = $this->settings['path'] . '/' . $currentFileName;
				
				if (strlen($currentFileName) > strlen($this->settings['extension']))
				{
					$currentExtension = substr($currentFile, strlen($currentFile) - strlen($this->settings['extension']));
					
					if (strcasecmp($currentExtension, $this->settings['extension']) == 0)
					{
						$currentFileName = basename($currentFile, '.' . $this->settings['extension']);
						$currentFileName = substr($currentFileName, 0, strrpos($currentFileName, '.'));
						
						if (strcasecmp($currentFileName, $container) == 0)
						{
							$fileNames[] = $currentFile;
						}
					}
				}
			}

			closedir($dirHandle);
		}

		if (count($fileNames) > 0)
		{
			$currentLanguageFile = $this->settings['path'] . '/' . $container;
			$currentLanguageFile .= '.' . $language;

			if (isset($locale))
			{
				$currentLanguageFile .= '_' . $locale;
			}

			$currentLanguageFile .= '.' . $this->settings['extension'];

			// Look if there's a language file that matches localization

			if (!in_array($currentLanguageFile, $fileNames))
			{
				// There's not, a language file just for current language

				$currentLanguageFile = $this->settings['path'] . '/' . $container . '.' . $language . '.' . $this->settings['extension'];

				if (!in_array($currentLanguageFile, $fileNames))
				{
					// There's not, look for first language file that matches current language

					$found = false;

					for ($i=0; $found == false && $i < count($fileNames); $i++)
					{
						$currentFileName = $fileNames[$i];

						$currentLanguageFile = baseName($currentFileName, '.' . $this->settings['extension']);

						if (strpos($currentLanguageFile, $language) !== false && strpos($currentLanguageFile, $language) == 0)
						{
							$found = true;

							$currentLanguageFile = $currentFileName;
						}
					}

					if ($found == false)
					{
						$currentLanguageFile = null;
					}
				}

			}
		}

		if (isset($currentLanguageFile))
		{
			$result =& parse_ini_file($currentLanguageFile, true);

			// Convert to single quotes to double quotes

			foreach ($result as $languageSection=>$languageElements)
			{
				foreach ($languageElements as $key=>$value)
				{
					$elements[$container][$languageSection][$key] = str_replace("''", "\"", $value);
				}
			}
		}

		return $elements;
	}

	/**
	 * Obtain the list of languages and their locales.
	 *
	 * @param string	The language to use when obtaining language & locale names
	 * @param boolean	true if you want to obtain only active languages & locales, false otherwise
	 *
	 * @return array	The list of languages
	 *
	 * @access public
	 * @since 1.0
	 */
	function & fetchLanguages($language, $onlyActive = true)
	{
		if (!isset($this->settings) || !isset($this->settings['languages']) || count($this->settings['languages']) == 0)
		{
			return $languages;
		}

		$languages = $this->settings['languages'];

		if (isset($languages) && is_array($languages))
		{
			foreach ($languages as $code=>$currentLanguage)
			{
				$languages[$code]['name'] = isset($currentLanguage['name'][$language]) ? $currentLanguage['name'][$language] : '';

				if ($onlyActive == true)
				{
					unset($languages[$code]['active']);
				}

				if (isset($currentLanguage['locales']) && is_array($currentLanguage['locales']))
				{
					foreach ($currentLanguage['locales'] as $localeCode=>$currentLocale)
					{
						$languages[$code]['locales'][$localeCode]['name'] = isset($currentLocale['name'][$language]) ? $currentLocale['name'][$language] : '';

						if ($onlyActive == true)
						{
							unset($languages[$code]['locales'][$localeCode]['active']);
						}
					}

					$languages[$code]['locales'] = $this->sabsi($languages[$code]['locales'], 'name');
				}
			}

			$languages = $this->sabsi($languages, 'name');
		}

		return $languages;
	}

	/**
	 * Returns the path to language files.
	 *
	 * @return string	Path to language files.
	 *
	 * @access public
	 * @since 1.0
	 */
	function getPath()
	{
		return $this->settings['path'];
	}

	/**
	 * Sets the path to language files.
	 *
	 * @param string	Path to language files.
	 *
	 * @access public
	 * @since 1.0
	 */
	function setPath($path)
	{
		$this->settings['path'] = $path;
	}

	/**
	 * Parses the XML configuration file for the file data source.
	 *
	 * @param string	Path to the XML configuration file
	 *
	 * @return array	The parsed configuration file
	 *
	 * @access private
	 * @since 1.0
	 */
	function & parseSettings($configurationFile)
	{
		$settings = null;

		if (is_file($configurationFile) && is_readable($configurationFile))
		{
			$settings = array();

			$dommer =& new Dommer($configurationFile);

			$rootElement =& $dommer->dominate();
			$rootElementName = $dommer->getNodeName($rootElement);

			if (strcasecmp($rootElementName, 'i18n') == 0)
			{
				$rootElementChildren =& $dommer->getChildren($rootElement);

				foreach ($rootElementChildren as $mainElement)
				{
					$mainElementName = $dommer->getNodeName($mainElement);
					$mainElementChildren =& $dommer->getChildren($mainElement);

					if (strcasecmp($mainElementName, 'settings') == 0)
					{
						foreach ($mainElementChildren as $settingsElement)
						{
							$settingsElementName = $dommer->getNodeName($settingsElement);
							$content = null;

							if (strcasecmp($settingsElementName, 'path') == 0)
							{
								$children =& $dommer->getChildren($settingsElement);

								if (isset($children) && count($children) > 0)
								{
									$content = $dommer->getNodeValue($children[0]);
								}
							}
							else if (strcasecmp($settingsElementName, 'extension') == 0)
							{
								$children =& $dommer->getChildren($settingsElement);

								if (isset($children) && count($children) > 0)
								{
									$content = $dommer->getNodeValue($children[0]);
								}
							}

							if (isset($content))
							{
								$settings[$settingsElementName] = $content;
							}
						}
					}
					else if (strcasecmp($mainElementName, 'languages') == 0)
					{
						foreach ($mainElementChildren as $languagesElement)
						{
							$languagesElementName = $dommer->getNodeName($languagesElement);

							if (strcasecmp($languagesElementName, 'language') == 0)
							{
								$language = array();

								$languagesChildren =& $dommer->getChildren($languagesElement);

								foreach ($languagesChildren as $languageElement)
								{
									$languageElementName = $dommer->getNodeName($languageElement);
									$content = null;

									if (strcasecmp($languageElementName, 'code') == 0)
									{
										$children =& $dommer->getChildren($languageElement);

										if (isset($children) && count($children) > 0)
										{
											$content = $dommer->getNodeValue($children[0]);

											$language[$languageElementName] = $content;
										}
									}
									else if (strcasecmp($languageElementName, 'active') == 0)
									{
										$children =& $dommer->getChildren($languageElement);

										if (isset($children) && count($children) > 0)
										{
											$content = $dommer->getNodeValue($children[0]);

											if (strcasecmp($content, 'true') == 0)
											{
												$content = true;
											}
											else
											{
												$content = false;
											}

											$language[$languageElementName] = $content;
										}
									}
									else if (strcasecmp($languageElementName, 'name') == 0)
									{
										$nameChildren =& $dommer->getChildren($languageElement);

										foreach($nameChildren as $element)
										{
											$content = null;

											$elementName = $dommer->getNodeName($element);
											$children =& $dommer->getChildren($element);

											if (isset($children) && count($children) > 0)
											{
												$content = $dommer->getNodeValue($children[0]);
											}

											if (isset($content))
											{
												if (!isset($language['name']))
												{
													$language['name'] = array();
												}

												$language['name'][$elementName] = $content;
											}
										}
									}
									else if (strcasecmp($languageElementName, 'locales') == 0)
									{
										$localesElementChildren =& $dommer->getChildren($languageElement);

										foreach ($localesElementChildren as $localesElement)
										{
											$localesElementName = $dommer->getNodeName($localesElement);

											if (strcasecmp($localesElementName, 'locale') == 0)
											{
												$locale = array();

												$localesChildren =& $dommer->getChildren($localesElement);

												foreach ($localesChildren as $localeElement)
												{
													$localeElementName = $dommer->getNodeName($localeElement);
													$content = null;

													if (strcasecmp($localeElementName, 'code') == 0)
													{
														$children =& $dommer->getChildren($localeElement);

														if (isset($children) && count($children) > 0)
														{
															$content = $dommer->getNodeValue($children[0]);

															$locale[$localeElementName] = $content;
														}
													}
													else if (strcasecmp($localeElementName, 'active') == 0)
													{
														$children =& $dommer->getChildren($localeElement);

														if (isset($children) && count($children) > 0)
														{
															$content = $dommer->getNodeValue($children[0]);

															if (strcasecmp($content, 'true') == 0)
															{
																$content = true;
															}
															else
															{
																$content = false;
															}

															$locale[$localeElementName] = $content;
														}
													}
													else if (strcasecmp($localeElementName, 'name') == 0)
													{
														$nameChildren =& $dommer->getChildren($localeElement);

														foreach($nameChildren as $element)
														{
															$content = null;

															$elementName = $dommer->getNodeName($element);
															$children =& $dommer->getChildren($element);

															if (isset($children) && count($children) > 0)
															{
																$content = $dommer->getNodeValue($children[0]);
															}

															if (isset($content))
															{
																if (!isset($locale['name']))
																{
																	$locale['name'] = array();
																}

																$locale['name'][$elementName] = $content;
															}
														}
													}
												}

												if (count($locale) > 0 && isset($locale['code']))
												{
													if (!isset($language['locales']))
													{
														$language['locales'] = array();
													}

													$language['locales'][$locale['code']] = $locale;
												}
											}
										}
									}
								}

								if (count($language) > 0 && isset($language['code']))
								{
									if (!isset($settings['languages']))
									{
										$settings['languages'] = array();
									}

									$settings['languages'][$language['code']] = $language;
								}
							}
						}
					}
				}
			}
		}

		return $settings;
	}

	/**
	 * Orders an indexed array on a specific key
	 *
	 * @param array	The array to order
	 * @param string	The index on which to sort
	 * @param string	The order ('asc' or 'desc')
	 * @param boolean	Wether to use natsort, or not
	 * @param boolean	If case should be distinguished when sorting
	 *
	 * @return array	The sorted array
	 *
	 * @access private
	 * @since 1.0
	 */
	function & sabsi (&$array, $index, $order='asc', $natsort=false, $case_sensitive=false)
	{
		if(is_array($array) && count($array)>0)
		{
			foreach(array_keys($array) as $key)
			{
				$temp[$key]=$array[$key][$index];
			}

			if(!$natsort)
			{
				($order=='asc')? asort($temp) : arsort($temp);
			}
			else
			{
				($case_sensitive)? natsort($temp) : natcasesort($temp);

				if($order!='asc')
				{
					$temp=array_reverse($temp,TRUE);
				}
			}

			foreach(array_keys($temp) as $key)
			{
				(is_numeric($key))? $sorted[]=$array[$key] : $sorted[$key]=$array[$key];
			}

			return $sorted;
		}

		return $array;
	}
}

?>
Return current item: Internationalization and Localization