array(),
'relate_to_many' => array(),
);
foreach ($GLOBALS['_PX_models'] as $model => $relations) {
foreach ($relations as $type => $related) {
foreach ($related as $related_model) {
if (!isset($_r[$type][$related_model])) {
$_r[$type][$related_model] = array();
}
$_r[$type][$related_model][] = $model;
}
}
}
$_r['foreignkey'] = $_r['relate_to'];
$_r['manytomany'] = $_r['relate_to_many'];
$GLOBALS['_PX_models_related'] = $_r;
// $GLOBALS['_PX_signal'] is automatically set by the require
// statement and possibly in the configuration file.
if ($usecache) {
$s = var_export(array($GLOBALS['_PX_models'],
$GLOBALS['_PX_models_related'],
$GLOBALS['_PX_signal']), true);
if (@file_put_contents($cache, '$val) {
if (0 === strpos($key, $pfx)) {
if (!$strip) {
$ret[$key] = $val;
} else {
$ret[substr($key, $pfx_len)] = $val;
}
}
}
return $ret;
}
/**
* Returns a given object.
*
* Loads automatically the corresponding class file if needed.
* If impossible to get the class $model, exception is thrown.
*
* @param string Model to load.
* @param mixed Extra parameters for the constructor of the model.
*/
public static function factory($model, $params=null)
{
if ($params !== null) {
return new $model($params);
}
return new $model();
}
/**
* Load a class depending on its name.
*
* Throw an exception if not possible to load the class.
*
* @param string Class to load.
*/
public static function loadClass($class)
{
if (class_exists($class, false)) {
return;
}
$file = str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php';
include $file;
if (!class_exists($class, false)) {
$error = 'Impossible to load the class: '.$class."\n".
'Tried to include: '.$file."\n".
'Include path: '.get_include_path();
throw new Exception($error);
}
}
/**
* Load a function depending on its name.
*
* The implementation file of the function
* MyApp_Youpla_Boum_Stuff() is MyApp/Youpla/Boum.php That way it
* is possible to group all the related function in one file.
*
* Throw an exception if not possible to load the function.
*
* @param string Function to load.
*/
public static function loadFunction($function)
{
if (function_exists($function)) {
return;
}
$elts = explode('_', $function);
array_pop($elts);
$file = implode(DIRECTORY_SEPARATOR, $elts) . '.php';
if (false !== ($file=Pluf::fileExists($file))) {
include $file;
}
if (!function_exists($function)) {
throw new Exception('Impossible to load the function: '.$function);
}
}
/**
* Hack for [[php file_exists()]] that checks the include_path.
*
* Use this to see if a file exists anywhere in the include_path.
*
*
* $file = 'path/to/file.php';
* if (Pluf::fileExists('path/to/file.php')) {
* include $file;
* }
*
*
* @credits Paul M. Jones
*
* @param string $file Check for this file in the include_path.
* @return mixed Full path to the file if the file exists and
* is readable in the include_path, false if not.
*/
public static function fileExists($file)
{
$file = trim($file);
if (!$file) {
return false;
}
// using an absolute path for the file?
// dual check for Unix '/' and Windows '\',
// or Windows drive letter and a ':'.
$abs = ($file[0] == '/' || $file[0] == '\\' || $file[1] == ':');
if ($abs && file_exists($file)) {
return $file;
}
// using a relative path on the file
$path = explode(PATH_SEPARATOR, ini_get('include_path'));
foreach ($path as $dir) {
// strip Unix '/' and Windows '\'
$target = rtrim($dir, '\\/').DIRECTORY_SEPARATOR.$file;
if (file_exists($target)) {
return $target;
}
}
// never found it
return false;
}
/**
* Helper to load the default database connection.
*
* This method is just dispatching to the function define in the
* configuration by the 'db_get_connection' key or use the default
* 'Pluf_DB_getConnection'. If you want to use your own function,
* take a look at the Pluf_DB_getConnection function to use the
* same approach for your method.
*
* The extra parameters can be used to selectively connect to a
* given database. When the ORM is getting a connection, it is
* passing the current model as parameter. That way you could get
* different databases for different models.
*
* @param mixed Extra parameters.
* @return resource DB connection.
*/
public static function &db($extra=null)
{
$func = Pluf::f('db_get_connection', 'Pluf_DB_getConnection');
Pluf::loadFunction($func);
$a = $func($extra);
return $a;
}
}
/**
* Translate a string.
*
* @param string String to be translated.
* @return string Translated string.
*/
function __($str)
{
$locale = (isset($GLOBALS['_PX_current_locale'])) ? $GLOBALS['_PX_current_locale'] : 'en';
if (!empty($GLOBALS['_PX_locale'][$locale][$str][0])) {
return $GLOBALS['_PX_locale'][$locale][$str][0];
}
return $str;
}
/**
* Translate the plural form of a string.
*
* @param string Singular form of the string.
* @param string Plural form of the string.
* @param int Number of elements.
* @return string Translated string.
*/
function _n($sing, $plur, $n)
{
$locale = (isset($GLOBALS['_PX_current_locale'])) ? $GLOBALS['_PX_current_locale'] : 'en';
if (isset($GLOBALS['_PX_current_locale_plural_form'])) {
$pform = $GLOBALS['_PX_current_locale_plural_form'];
} else {
$pform = Pluf_Translation::getPluralForm($locale);
}
$index = Pluf_Translation::$pform($n);
if (!empty($GLOBALS['_PX_locale'][$locale][$sing.'#'.$plur][$index])) {
return $GLOBALS['_PX_locale'][$locale][$sing.'#'.$plur][$index];
}
// We have no translations or default English
if ($n == 1) {
return $sing;
}
return $plur;
}
/**
* Autoload function.
*
* @param string Class name.
*/
function __autoload($class_name)
{
try {
Pluf::loadClass($class_name);
} catch (Exception $e) {
if (Pluf::f('debug')) {
print $e->getMessage();
die();
}
eval("class $class_name {
function __construct() {
throw new Exception('Class $class_name not found');
}
static function __callstatic(\$m, \$args) {
throw new Exception('Class $class_name not found');
}
}");
}
}
/**
* Exception to catch the PHP errors.
*
* @credits errd
* @see http://www.php.net/manual/en/function.set-error-handler.php
*/
class PlufErrorHandlerException extends Exception
{
public function setLine($line)
{
$this->line = $line;
}
public function setFile($file)
{
$this->file = $file;
}
}
/**
* The function that is the real error handler.
*/
function PlufErrorHandler($code, $string, $file, $line)
{
if (0 == error_reporting()) return false;
if (E_STRICT == $code
&&
(
0 === strpos($file, Pluf::f('pear_path','/usr/share/php/'))
or
false !== strripos($file, 'pear') // if pear in the path, ignore
)
) {
return;
}
$exception = new PlufErrorHandlerException($string, $code);
$exception->setLine($line);
$exception->setFile($file);
throw $exception;
}
// Set the error handler only if not performing the unittests.
if (!defined('IN_UNIT_TESTS')) {
set_error_handler('PlufErrorHandler', error_reporting());
}
/**
* Shortcut needed all over the place.
*
* Note that in some cases, we need to escape strings not in UTF-8, so
* this is not possible to safely use a call to htmlspecialchars. This
* is why str_replace is used.
*
* @param string Raw string
* @return string HTML escaped string
*/
function Pluf_esc($string)
{
return str_replace(array('&', '"', '<', '>'),
array('&', '"', '<', '>'),
(string) $string);
}