Initial import

This commit is contained in:
Juan Ferrer Toribio 2015-01-23 13:38:29 +01:00
commit 1fca98aea3
13 changed files with 632 additions and 0 deletions

9
configure.php Normal file
View File

@ -0,0 +1,9 @@
<?php
set_include_path
(
get_include_path ()
.PATH_SEPARATOR.__DIR__.'/package/usr/share/php'
);
?>

9
package/DEBIAN/control Normal file
View File

@ -0,0 +1,9 @@
Package: php-vn-lib
Version: 1.0-5
Architecture: all
Maintainer: Juan Ferrer Toribio <juan@verdnatura.es>
Depends: php5-mysql
Section: misc
Priority: optional
Description: PHP libraries
PHP libraries.

View File

@ -0,0 +1,222 @@
<?php
namespace Vn\Db;
require_once ('vn/sql/sql.php');
require_once ('vn/db/exception.php');
use Vn\Sql\Render;
class Conn
{
private $conn = NULL;
private $isOpen = FALSE;
/**
* Opens a new connection to the database.
*
* @param string $host The host name
* @param string $user The user name to authenticate
* @param string $pass The user password
* @param string $name The default schema name
*
* @return boolean %TRUE on success, %FALSE otherwise
**/
function open ($host, $user, $pass, $name)
{
$conn = $this->conn = mysqli_init ();
$conn->options (MYSQLI_READ_DEFAULT_FILE, __DIR__.'/my.cnf');
@$conn->real_connect ($host, $user, $pass, $name);
if (mysqli_connect_errno ())
{
sleep (1);
throw new Exception (mysqli_connect_errno (), mysqli_connect_error ());
return FALSE;
}
$this->isOpen = TRUE;
$this->query ('SET CHARACTER SET utf8');
return TRUE;
}
/**
* Closes the current connection, if it's closed does nothing.
**/
function close ()
{
if ($this->isOpen)
$this->conn->close ();
$this->isOpen = FALSE;
}
/**
* Checks whether the connection is open.
*
* @return boolean %TRUE if connection is open, %FALSE otherwise
**/
function isOpen ()
{
return $this->isOpen;
}
/**
* Executes the query and gets it's first row.
*
* @param string $query The SQL query
* @param mixed[] $params The query parameters
*
* @return mixed[] An associative array with the first row, %NULL if error
**/
function getRow ($query, $params = NULL)
{
$result = $this->query ($query, $params);
if ($result && ($row = $result->fetch_assoc ()))
return $row;
return NULL;
}
/**
* Executes the query and gets the first value of the first row.
*
* @param string $query The SQL query
* @param mixed[] $params The query parameters
*
* @return mixed The value or %NULL if error
**/
function getValue ($query, $params = NULL)
{
$result = $this->query ($query, $params);
if ($result && ($row = $result->fetch_row ()))
return $row[0];
return NULL;
}
/**
* Executes the query stored in the specified file and gets the result.
*
* @param string $query The SQL query
* @param mixed[] $params The query parameters
*
* @return mixed The value or %NULL if error
**/
function queryFromFile ($file, $params = NULL)
{
$query = file_get_contents ($file);
if ($query)
return $this->query ($query, $params);
return NULL;
}
/**
* Executes the query and gets the result.
*
* @param string $query The SQL query
* @param mixed[] $params The query parameters
*
* @return mixed The value or %NULL if error
**/
function query ($query, $params = NULL)
{
$result = $this->conn->query (Render::toString ($query, $params));
if (!$result)
$this->checkError ();
else
while ($this->moreResults ())
$this->nextResult ();
return $result;
}
/**
* Execute multiple queries separated by semicolons.
*
* @param string $query The SQL query
* @param mixed[] $params The query parameters
*
* @return mixed The value or %NULL if error
**/
function multiQuery ($query, $params = NULL)
{
$success = $this->conn->multi_query (Render::toString ($query, $params));
if (!$success)
$this->checkError ();
return $success;
}
function storeResult ()
{
$result = $this->conn->store_result ();
if (!$result)
$this->checkError ();
return $result;
}
function moreResults ()
{
return $this->conn->more_results ();
}
function nextResult ()
{
return $this->conn->next_result ();
}
private function checkError ()
{
if ($this->conn->errno)
{
$code = $this->conn->errno;
$message = $this->conn->error;
$sql = 'SELECT es_es message, 2000 + id AS id '.
'FROM sql_error WHERE code = @err';
if ($code == 1305 && ($row = $this->getRow ($sql)))
throw new Exception ($row['id'], $row['message']);
else
throw new Exception ($code, $message);
}
}
function checkWarnings ()
{
if ($this->conn->warning_count > 0)
if ($result = $this->conn->query ('SHOW WARNINGS'))
{
$warnings = [];
$sql = 'SELECT es_es message, 3000 + id AS id '.
'FROM sql_warning WHERE code = @warn';
while ($row = $result->fetch_assoc ())
{
if ($row['Code'] == 1265
&& ($warning = $this->getRow ($sql)))
{
$row['Code'] = $warning['id'];
$row['Message'] = $warning['message'];
}
$warnings[] = $row;
}
return $warnings;
}
return NULL;
}
}
?>

View File

@ -0,0 +1,6 @@
<?php
require_once ('vn/sql/sql.php');
require_once ('vn/db/conn.php');
?>

View File

@ -0,0 +1,20 @@
<?php
namespace Vn\Db;
/**
* Class used to store information about database errors.
**/
class Exception extends \Exception
{
/**
* @param string $code The code of message
* @param string $message The message string
**/
function __construct ($code, $message)
{
parent::__construct ($message, $code);
}
}
?>

View File

@ -0,0 +1,2 @@
[client]
enable-cleartext-plugin = 1

View File

@ -0,0 +1,7 @@
<?php
require_once ('vn/lib/type.php');
require_once ('vn/lib/locale.php');
require_once ('vn/lib/log.php');
?>

View File

@ -0,0 +1,112 @@
<?php
namespace
{
use Vn\Lib\Locale;
function i($stringId)
{
echo Locale::getString ($stringId);
}
function s($stringId)
{
return Locale::getString ($stringId);
}
}
namespace Vn\Lib
{
class Locale
{
static $localeSet = FALSE;
static $locale = 'en';
static $strings = [];
static $paths = [];
/**
* Sets the locale.
*
* @param string $locale The locale with 2 digits format, or %NULL to
* set the default
**/
static function set ($locale = NULL)
{
if (!isset ($locale))
$locale = self::$locale;
self::$locale = $locale;
setlocale (LC_ALL, $locale);
self::$localeSet = TRUE;
foreach (self::$paths as $path)
self::loadFile ($path);
}
/**
* Gets the locale.
*
* @return string The locale with 2 digits format
**/
static function get ()
{
return self::$locale;
}
/**
* Gets the translation of a string, if no translation is found the same
* string is returned.
*
* @param string $stringId The string to translate
* @return string The translated string
**/
static function getString ($stringId)
{
if (isset (self::$strings[$stringId]))
return self::$strings[$stringId];
else
return $stringId;
}
/**
* Adds a path where a JSON file with translations is located.
*
* @param string $path The JSON file path
**/
static function addPath ($path)
{
self::$paths[$path] = TRUE;
if (self::$localeSet)
self::loadFile ($path);
}
/**
* Loads translations from a JSON file.
*
* @param string $path The JSON file path
**/
static function loadFile ($path)
{
$file = stream_resolve_include_path ('locale/'. self::$locale .'/'. $path .'.json');
if (file_exists ($file)
&& ($jsonString = file_get_contents ($file)))
self::addTranslations (json_decode ($jsonString, TRUE));
}
/**
* Adds a set of translations to the database.
*
* @param array $strings Associative array of every string and its
* translation
**/
static function addTranslations ($strings)
{
foreach ($strings as $string => &$translation)
self::$strings[$string] = &$translation;
}
}
}
?>

View File

@ -0,0 +1,75 @@
<?php
namespace Vn\Lib;
class Log
{
private static $fd = NULL;
private static $count;
private static $file;
static function init ($file)
{
self::close ();
self::$file = $file;
self::$fd = fopen ($file, 'a');
self::rename ();
set_error_handler ('Vn\Lib\Log::phpHandler', E_ALL);
}
static function phpHandler ($no, $str, $file, $line, $context)
{
self::write ('PHP: %s:%d: %s', $file, $line, $str);
switch ($no)
{
case E_ERROR:
case E_PARSE:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
self::write ('PHP: Could not continue, exiting.');
self::close ();
exit (1);
}
return TRUE;
}
static function close ()
{
if (self::$fd != NULL)
{
fclose (self::$fd);
self::$fd = NULL;
}
}
static function write ()
{
if (self::$fd == NULL)
return;
if (self::$count > 5000)
self::rename ();
self::$count += fprintf (self::$fd, "%s: %s\n"
,strftime ('%Y-%m-%d %T')
,call_user_func_array ('sprintf', func_get_args ())
);
}
static private function rename ()
{
if (filesize (self::$file) > 1000000)
{
self::close ();
$rename = self::$file.'.1';
if (file_exists ($rename))
unlink ($rename);
rename (self::$file, $rename);
self::$fd = fopen ($file, 'a');
}
self::$count = 0;
}
}
?>

View File

@ -0,0 +1,65 @@
<?php
$n = -1;
define ('TYPE_NULL' , ++$n);
define ('TYPE_INTEGER' , ++$n);
define ('TYPE_TIME' , ++$n);
define ('TYPE_DATE' , ++$n);
define ('TYPE_DATE_TIME', ++$n);
define ('TYPE_STRING' , ++$n);
define ('TYPE_DOUBLE' , ++$n);
define ('TYPE_BOOLEAN' , ++$n);
define ('TYPE_OBJECT' , ++$n);
class Time extends DateTime {}
class Date extends DateTime {}
function get_type ($value)
{
if (is_int ($value))
return TYPE_INTEGER;
elseif (is_float ($value))
return TYPE_DOUBLE;
elseif (is_string ($value))
return TYPE_STRING;
elseif (is_bool ($value))
return TYPE_BOOLEAN;
elseif (is_object ($value))
{
if ($value instanceof Time)
return TYPE_TIME;
elseif ($value instanceof Date)
return TYPE_DATE;
elseif ($value instanceof DateTime)
return TYPE_DATE_TIME;
else
return TYPE_OBJECT;
}
return TYPE_NULL;
}
function set_type (& $value, $type)
{
switch ($type)
{
case TYPE_INTEGER:
settype ($value, 'integer');
break;
case TYPE_DOUBLE:
settype ($value, 'float');
break;
case TYPE_STRING:
settype ($value, 'string');
break;
case TYPE_BOOLEAN:
settype ($value, 'boolean');
break;
case TYPE_NULL:
$value = NULL;
break;
}
}
?>

View File

@ -0,0 +1,57 @@
<?php
namespace Vn\Sql;
require_once ('vn/lib/lib.php');
require_once ('vn/sql/value.php');
class Render
{
static function toString (&$query, &$paramsMap = NULL)
{
if (isset ($paramsMap) && is_array ($paramsMap) && count ($paramsMap) > 0)
{
$i = 0;
$params = [];
foreach ($paramsMap as $key => $value)
$params[$key] = (new Value ($value))->render ();
$replaceFunc = function ($matches) use (&$params, &$i)
{
$key = substr ($matches[0], 1);
if (strlen ($key) == 0)
$key = $i++;
if (isset ($params[$key]))
return $params[$key];
return '#'. $key;
};
return preg_replace_callback ('/#\w*/', $replaceFunc, $query);
}
else
return $query;
}
static function printf ($arg)
{
$count = count ($arg);
if ($count > 1)
{
for ($n = 1; $n < $count; $n++)
{
$obj = new Value ($arg[$n]);
$arg[$n] = $obj->render ();
}
return call_user_func_array ('sprintf', $arg);
}
else
return $arg[0];
}
}
?>

View File

@ -0,0 +1,7 @@
<?php
require_once ('vn/lib/lib.php');
require_once ('vn/sql/render.php');
require_once ('vn/sql/value.php');
?>

View File

@ -0,0 +1,41 @@
<?php
namespace Vn\Sql;
require_once ('vn/lib/lib.php');
class Value
{
var $value;
function __construct ($value)
{
$this->value = $value;
}
function render ()
{
$value = $this->value;
if ($value === NULL)
return 'NULL';
switch (get_type ($value))
{
case TYPE_STRING:
return '\'' . addslashes ($value) . '\'';
case TYPE_DATE:
return strftime ('\'%Y-%m-%d\'', $value->getTimestamp ());
case TYPE_TIME:
return strftime ('\'%T\'', $value->getTimestamp ());
case TYPE_DATE_TIME:
return strftime ('\'%Y-%m-%d %T\'', $value->getTimestamp ());
case TYPE_BOOLEAN:
return ($value) ? 'TRUE' : 'FALSE';
default:
return $value;
}
}
}
?>