Merge branch 'devel' of dev.sourcefabric.org:airtime into devel

This commit is contained in:
Naomi Aro 2012-05-07 14:29:02 +02:00
commit 41e7150462
23 changed files with 461 additions and 185 deletions

View file

@ -12,21 +12,26 @@ require_once "DateHelper.php";
require_once "OsPath.php";
require_once __DIR__.'/controllers/plugins/RabbitMqPlugin.php';
//DateTime in PHP 5.3.0+ need a default timezone set. Set to UTC initially
//in case Application_Model_Preference::GetTimezone fails and creates needs to create
//a log entry. This log entry requires a call to date(), which then complains that
//timezone isn't set. Setting a default timezone allows us to create a a graceful log
//that getting the real timezone failed, without PHP complaining that it cannot log because
//there is no timezone :|.
date_default_timezone_set('UTC');
date_default_timezone_set(Application_Model_Preference::GetTimezone());
global $CC_CONFIG;
$CC_CONFIG['airtime_version'] = Application_Model_Preference::GetAirtimeVersion();
require_once __DIR__."/configs/navigation.php";
//DateTime in PHP 5.3.0+ need a default timezone set.
date_default_timezone_set(Application_Model_Preference::GetTimezone());
Zend_Validate::setDefaultNamespaces("Zend");
$front = Zend_Controller_Front::getInstance();
$front->registerPlugin(new RabbitMqPlugin());
//Logging::debug($_SERVER['REQUEST_URI']);
/* The bootstrap class should only be used to initialize actions that return a view.
Actions that return JSON will not use the bootstrap class! */
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap

View file

@ -45,7 +45,7 @@ class Application_Common_OsPath{
/* Similar to the os.path.join python method
* http://stackoverflow.com/a/1782990/276949 */
function join() {
public static function join() {
$args = func_get_args();
$paths = array();

View file

@ -0,0 +1,109 @@
<?php
class Airtime_Zend_Log extends Zend_Log
{
/**
*
* @var boolean
*/
protected $_registeredErrorHandler = false;
/**
*
* @var array|boolean
*/
protected $_errorHandlerMap = false;
/**
*
* @var callback
*/
protected $_origErrorHandler = null;
public function __construct(Zend_Log_Writer_Abstract $writer = null)
{
parent::__construct($writer);
}
/**
* Error Handler will convert error into log message, and then call the original error handler
*
* @link http://www.php.net/manual/en/function.set-error-handler.php Custom error handler
* @param int $errno
* @param string $errstr
* @param string $errfile
* @param int $errline
* @param array $errcontext
* @return boolean
*/
public function errorHandler($errno, $errstr, $errfile, $errline, $errcontext)
{
$errorLevel = error_reporting();
if ($errorLevel && $errno) {
if (isset($this->_errorHandlerMap[$errno])) {
$priority = $this->_errorHandlerMap[$errno];
} else {
$priority = Zend_Log::INFO;
}
$this->log($errstr, $priority, array('errno'=>$errno, 'file'=>$errfile, 'line'=>$errline, 'context'=>$errcontext));
}
if ($this->_origErrorHandler !== null) {
return call_user_func($this->_origErrorHandler, $errno, $errstr, $errfile, $errline, $errcontext);
}
return false;
}
/**
* Register Logging system as an error handler to log php errors
* Note: it still calls the original error handler if set_error_handler is able to return it.
*
* Errors will be mapped as:
* E_NOTICE, E_USER_NOTICE => NOTICE
* E_WARNING, E_CORE_WARNING, E_USER_WARNING => WARN
* E_ERROR, E_USER_ERROR, E_CORE_ERROR, E_RECOVERABLE_ERROR => ERR
* E_DEPRECATED, E_STRICT, E_USER_DEPRECATED => DEBUG
* (unknown/other) => INFO
*
* @link http://www.php.net/manual/en/function.set-error-handler.php Custom error handler
*
* @return Zend_Log
*/
public function registerErrorHandler()
{
// Only register once. Avoids loop issues if it gets registered twice.
if ($this->_registeredErrorHandler) {
return $this;
}
$this->_origErrorHandler = set_error_handler(array($this, 'errorHandler'));
// Contruct a default map of phpErrors to Zend_Log priorities.
// Some of the errors are uncatchable, but are included for completeness
$this->_errorHandlerMap = array(
E_NOTICE => Zend_Log::NOTICE,
E_USER_NOTICE => Zend_Log::NOTICE,
E_WARNING => Zend_Log::WARN,
E_CORE_WARNING => Zend_Log::WARN,
E_USER_WARNING => Zend_Log::WARN,
E_ERROR => Zend_Log::ERR,
E_USER_ERROR => Zend_Log::ERR,
E_CORE_ERROR => Zend_Log::ERR,
E_RECOVERABLE_ERROR => Zend_Log::ERR,
E_STRICT => Zend_Log::DEBUG,
);
// PHP 5.3.0+
if (defined('E_DEPRECATED')) {
$this->_errorHandlerMap['E_DEPRECATED'] = Zend_Log::DEBUG;
}
if (defined('E_USER_DEPRECATED')) {
$this->_errorHandlerMap['E_USER_DEPRECATED'] = Zend_Log::DEBUG;
}
$this->_registeredErrorHandler = true;
return $this;
}
}

View file

@ -6,9 +6,18 @@ class Logging {
private static $_path;
public static function getLogger(){
if (!isset(self::$logger)) {
if (!isset(self::$_logger)) {
$writer = new Zend_Log_Writer_Stream(self::$_path);
self::$_logger = new Zend_Log($writer);
if (Zend_Version::compareVersion("1.11") > 0){
//Running Zend version 1.10 or lower. Need to instantiate our
//own Zend Log class with backported code from 1.11.
require_once __DIR__."/AirtimeLog.php";
self::$_logger = new Airtime_Zend_Log($writer);
} else {
self::$_logger = new Zend_Log($writer);
}
self::$_logger->registerErrorHandler();
}
return self::$_logger;
}

View file

@ -3,96 +3,109 @@
class Application_Model_Preference
{
public static function SetValue($key, $value, $isUserValue = false){
global $CC_CONFIG;
$con = Propel::getConnection();
public static function SetValue($key, $value, $isUserValue = false){
try {
$con = Propel::getConnection();
//called from a daemon process
if(!class_exists("Zend_Auth", false) || !Zend_Auth::getInstance()->hasIdentity()) {
$id = NULL;
}
else {
$auth = Zend_Auth::getInstance();
$id = $auth->getIdentity()->id;
}
//called from a daemon process
if(!class_exists("Zend_Auth", false) || !Zend_Auth::getInstance()->hasIdentity()) {
$id = NULL;
}
else {
$auth = Zend_Auth::getInstance();
$id = $auth->getIdentity()->id;
}
$key = pg_escape_string($key);
$value = pg_escape_string($value);
$key = pg_escape_string($key);
$value = pg_escape_string($value);
//Check if key already exists
$sql = "SELECT COUNT(*) FROM cc_pref"
." WHERE keystr = '$key'";
//For user specific preference, check if id matches as well
if($isUserValue) {
$sql .= " AND subjid = '$id'";
}
$result = $con->query($sql)->fetchColumn(0);
if($value == "") {
$value = "NULL";
}else {
$value = "'$value'";
}
if($result == 1) {
// result found
if(is_null($id) || !$isUserValue) {
// system pref
$sql = "UPDATE cc_pref"
." SET subjid = NULL, valstr = $value"
." WHERE keystr = '$key'";
} else {
// user pref
$sql = "UPDATE cc_pref"
. " SET valstr = $value"
. " WHERE keystr = '$key' AND subjid = $id";
}
} else {
// result not found
if(is_null($id) || !$isUserValue) {
// system pref
$sql = "INSERT INTO cc_pref (keystr, valstr)"
." VALUES ('$key', $value)";
} else {
// user pref
$sql = "INSERT INTO cc_pref (subjid, keystr, valstr)"
." VALUES ($id, '$key', $value)";
}
}
return $con->exec($sql);
}
public static function GetValue($key, $isUserValue = false){
global $CC_CONFIG;
$con = Propel::getConnection();
//Check if key already exists
$sql = "SELECT COUNT(*) FROM cc_pref"
." WHERE keystr = '$key'";
//For user specific preference, check if id matches as well
if ($isUserValue) {
$auth = Zend_Auth::getInstance();
if($auth->hasIdentity()) {
$id = $auth->getIdentity()->id;
$sql .= " AND subjid = '$id'";
}
}
$result = $con->query($sql)->fetchColumn(0);
if ($result == 0)
return "";
else {
$sql = "SELECT valstr FROM cc_pref"
//Check if key already exists
$sql = "SELECT COUNT(*) FROM cc_pref"
." WHERE keystr = '$key'";
//For user specific preference, check if id matches as well
if($isUserValue && $auth->hasIdentity()) {
$sql .= " AND subjid = '$id'";
}
//For user specific preference, check if id matches as well
if($isUserValue) {
$sql .= " AND subjid = '$id'";
}
$result = $con->query($sql)->fetchColumn(0);
return ($result !== false) ? $result : "";
if($value == "") {
$value = "NULL";
}else {
$value = "'$value'";
}
if($result == 1) {
// result found
if(is_null($id) || !$isUserValue) {
// system pref
$sql = "UPDATE cc_pref"
." SET subjid = NULL, valstr = $value"
." WHERE keystr = '$key'";
} else {
// user pref
$sql = "UPDATE cc_pref"
. " SET valstr = $value"
. " WHERE keystr = '$key' AND subjid = $id";
}
} else {
// result not found
if(is_null($id) || !$isUserValue) {
// system pref
$sql = "INSERT INTO cc_pref (keystr, valstr)"
." VALUES ('$key', $value)";
} else {
// user pref
$sql = "INSERT INTO cc_pref (subjid, keystr, valstr)"
." VALUES ($id, '$key', $value)";
}
}
$con->exec($sql);
} catch (Exception $e){
header('HTTP/1.0 503 Service Unavailable');
Logging::log("Could not connect to database.");
exit;
}
}
public static function GetValue($key, $isUserValue = false){
try {
$con = Propel::getConnection();
//Check if key already exists
$sql = "SELECT COUNT(*) FROM cc_pref"
." WHERE keystr = '$key'";
//For user specific preference, check if id matches as well
if ($isUserValue) {
$auth = Zend_Auth::getInstance();
if($auth->hasIdentity()) {
$id = $auth->getIdentity()->id;
$sql .= " AND subjid = '$id'";
}
}
$result = $con->query($sql)->fetchColumn(0);
if ($result == 0)
return "";
else {
$sql = "SELECT valstr FROM cc_pref"
." WHERE keystr = '$key'";
//For user specific preference, check if id matches as well
if($isUserValue && $auth->hasIdentity()) {
$sql .= " AND subjid = '$id'";
}
$result = $con->query($sql)->fetchColumn(0);
return ($result !== false) ? $result : "";
}
} catch (Exception $e) {
header('HTTP/1.0 503 Service Unavailable');
Logging::log("Could not connect to database.");
exit;
}
}
@ -561,10 +574,12 @@ class Application_Model_Preference
public static function GetAirtimeVersion(){
if (defined('APPLICATION_ENV') && APPLICATION_ENV == "development" && function_exists('exec')){
return self::GetValue("system_version")."+".exec("git rev-parse --short HEAD");
} else {
return self::GetValue("system_version");
$version = exec("git rev-parse --short HEAD 2>/dev/null", $out, $return_code);
if ($return_code == 0){
return self::GetValue("system_version")."+".$version;
}
}
return self::GetValue("system_version");
}
public static function GetLatestVersion(){

View file

@ -25,6 +25,12 @@ class Application_Model_Scheduler {
$this->epochNow = microtime(true);
$this->nowDT = DateTime::createFromFormat("U.u", $this->epochNow, new DateTimeZone("UTC"));
if ($this->nowDT === false){
// DateTime::createFromFormat does not support millisecond string formatting in PHP 5.3.2 (Ubuntu 10.04).
// In PHP 5.3.3 (Ubuntu 10.10), this has been fixed.
$this->nowDT = DateTime::createFromFormat("U", time(), new DateTimeZone("UTC"));
}
$this->user = Application_Model_User::GetCurrentUser();
}
@ -190,6 +196,12 @@ class Application_Model_Scheduler {
$endEpoch = bcadd($startEpoch , (string) $durationSeconds, 6);
$dt = DateTime::createFromFormat("U.u", $endEpoch, new DateTimeZone("UTC"));
if ($dt === false) {
//PHP 5.3.2 problem
$dt = DateTime::createFromFormat("U", intval($endEpoch), new DateTimeZone("UTC"));
}
return $dt;
}

View file

@ -91,6 +91,27 @@ class Application_Model_StoredFile {
}
else {
$dbMd = array();
if (isset($p_md["MDATA_KEY_YEAR"])){
// We need to make sure to clean this value before inserting into database.
// If value is outside of range [-2^31, 2^31-1] then postgresl will throw error
// when trying to retrieve this value. We could make sure number is within these bounds,
// but simplest is to do substring to 4 digits (both values are garbage, but at least our
// new garbage value won't cause errors). If the value is 2012-01-01, then substring to
// 4 digits is an OK result.
// CC-3771
$year = $p_md["MDATA_KEY_YEAR"];
if (strlen($year) > 4){
$year = substr($year, 0, 4);
}
if (!is_numeric($year)){
$year = 0;
}
$p_md["MDATA_KEY_YEAR"] = $year;
}
foreach ($p_md as $mdConst => $mdValue) {
$dbMd[constant($mdConst)] = $mdValue;
}
@ -235,7 +256,9 @@ class Application_Model_StoredFile {
foreach ($c['user'] as $constant => $value) {
if (preg_match('/^MDATA_KEY/', $constant)) {
if (isset($dbmd_copy[$value])) {
$md[$constant] = $this->getDbColMetadataValue($value);
$propelColumn = $dbmd_copy[$value];
$method = "get$propelColumn";
$md[$constant] = $this->_file->$method();
}
}
}