Projekt

Obecné

Profil

« Předchozí | Další » 

Revize 2339

Přidáno uživatelem Ondřej Fibich před asi 10 roky(ů)

Nova branch pro reseni #921

Zobrazit rozdíly:

freenetis/branches/modularity/application/libraries/Filter_form.php
<?php defined('SYSPATH') or die('No direct script access.');
/*
* This file is part of open source system FreenetIS
* and it is released under GPLv3 licence.
*
* More info about licence can be found:
* http://www.gnu.org/licenses/gpl-3.0.html
*
* More info about project can be found:
* http://www.freenetis.org/
*
*/
/**
* This is library for filter form
*
* @author Michal Kliment
* @version 1.0
*/
class Filter_form
{
/**
* Template to show filter form
* @var string
*/
protected $template = 'filter_form_template';
/**
* Array of all filters
* @var array
*/
protected $filters = array();
/**
* Array of all filter's values
* @var array
*/
protected $values = array();
/**
* Array of all filter's types
* @var array
*/
protected $types = array();
/**
* Array of all filter's operations
* @var array
*/
protected $operations = array();
/**
* Array of all filter's tables
* @var array
*/
protected $tables = array();
/**
* Array of boolean values whether filter is default
* @var array
*/
protected $default = array();
/**
* Count of default filters
* @var integer
*/
protected $default_count = 0;
/**
*Array with states (on/off) of filters
* @var array
*/
protected $states = array();
/**
* Default query for filter form
* @var integer
*/
protected $default_query_id = NULL;
/**
* Base URL of filter form
*
* @var string
*/
protected $base_url = NULL;
/**
* State of possibility of add new query
*
* @var boolean
*/
protected $can_add = FALSE;
/**
* Indicates whether the filter form configuration was loaded from database.
*
* @var boolean
*/
protected $loaded_from_saved_query = FALSE;
/**
* Indicates whether the filter form configuration that was loaded from
* database is default.
*
* @var boolean
*/
protected $loaded_from_default_saved_query = FALSE;
/**
* Definition of constants
*/
const OPER_CONTAINS = 1;
const OPER_CONTAINS_NOT = 2;
const OPER_IS = 3;
const OPER_IS_NOT = 4;
const OPER_EQUAL = 5;
const OPER_EQUAL_NOT = 6;
const OPER_SMALLER = 7;
const OPER_SMALLER_OR_EQUAL = 8;
const OPER_GREATER = 9;
const OPER_GREATER_OR_EQUAL = 10;
const OPER_BIT_IS = 11;
const OPER_BIT_IS_NOT = 12;
const OPER_NETWORK_IS_IN = 13;
const OPER_NETWORK_IS_NOT_IN = 14;
const OPER_IS_EMPTY = 15;
const OPER_IS_NOT_EMPTY = 16;
/**
* Array with definition of all operations
* @var array
*/
protected $opers = array
(
self::OPER_CONTAINS => array
(
'name' => 'contains',
'sql' => "LIKE '%{VALUE}%' COLLATE utf8_general_ci",
),
self::OPER_CONTAINS_NOT => array
(
'name' => 'contains not',
'sql' => "NOT LIKE '%{VALUE}%' COLLATE utf8_general_ci",
),
self::OPER_IS => array
(
'name' => 'is',
'sql' => "LIKE '{VALUE}' COLLATE utf8_general_ci"
),
self::OPER_IS_NOT => array
(
'name' => 'is not',
'sql' => "NOT LIKE '{VALUE}' COLLATE utf8_general_ci" ,
),
self::OPER_EQUAL => array
(
'name' => '=',
'sql' => "= '{VALUE}'",
),
self::OPER_EQUAL_NOT => array
(
'name' => '!=',
'sql' => "<> '{VALUE}'",
),
self::OPER_SMALLER => array
(
'name' => '<',
'sql' => "< '{VALUE}'",
),
self::OPER_SMALLER_OR_EQUAL => array
(
'name' => '<=',
'sql' => "<= '{VALUE}'",
),
self::OPER_GREATER => array
(
'name' => '>',
'sql' => "> '{VALUE}'",
),
self::OPER_GREATER_OR_EQUAL => array
(
'name' => '>=',
'sql' => ">= '{VALUE}'",
),
self::OPER_BIT_IS => array
(
'name' => 'is',
'sql' => "& {VALUE} > 0",
),
self::OPER_BIT_IS_NOT => array
(
'name' => 'is not',
'sql' => "& {VALUE} = 0",
),
self::OPER_NETWORK_IS_IN => array
(
'name' => 'is in',
'pattern' => '/^(?P<VALUE1>((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9][0-9])|[0-9])\.((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9][0-9])|[0-9])\.((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9][0-9])|[0-9])\.((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9][0-9])|[0-9]))\/(?P<VALUE2>(3[0-2])|(2[0-9])|(1[0-9])|([0-9]))$/',
'sql' => "& (0xffffffff<<(32-{VALUE2}) & 0xffffffff) = inet_aton('{VALUE1}')",
'function' => 'inet_aton'
),
self::OPER_NETWORK_IS_NOT_IN => array
(
'name' => 'is not in',
'pattern' => '/^(?P<VALUE1>((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9][0-9])|[0-9])\.((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9][0-9])|[0-9])\.((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9][0-9])|[0-9])\.((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9][0-9])|[0-9]))\/(?P<VALUE2>(3[0-2])|(2[0-9])|(1[0-9])|([0-9]))$/',
'sql' => "& (0xffffffff<<(32-{VALUE2}) & 0xffffffff) <> inet_aton('{VALUE1}')",
'function' => 'inet_aton'
),
self::OPER_IS_EMPTY => array
(
'name' => 'is empty',
'sql' => 'LIKE ""',
'null' => TRUE
),
self::OPER_IS_NOT_EMPTY => array
(
'name' => 'is not empty',
'sql' => 'NOT LIKE ""',
'null' => TRUE
)
);
/**
* Array with definition of types and its operations
* @var array
*/
protected $operation_types = array
(
'combo' => array
(
self::OPER_IS,
self::OPER_IS_NOT,
self::OPER_CONTAINS,
self::OPER_CONTAINS_NOT
),
'select' => array
(
self::OPER_IS,
self::OPER_IS_NOT
),
'text' => array
(
self::OPER_CONTAINS,
self::OPER_CONTAINS_NOT,
self::OPER_IS,
self::OPER_IS_NOT,
self::OPER_IS_EMPTY,
self::OPER_IS_NOT_EMPTY
),
'number' => array
(
self::OPER_EQUAL,
self::OPER_EQUAL_NOT,
self::OPER_SMALLER,
self::OPER_SMALLER_OR_EQUAL,
self::OPER_GREATER,
self::OPER_GREATER_OR_EQUAL
),
'bit' => array
(
self::OPER_BIT_IS,
self::OPER_BIT_IS_NOT
),
'date' => array
(
self::OPER_EQUAL,
self::OPER_EQUAL_NOT,
self::OPER_SMALLER,
self::OPER_SMALLER_OR_EQUAL,
self::OPER_GREATER,
self::OPER_GREATER_OR_EQUAL
),
'select_number' => array
(
self::OPER_IS,
self::OPER_IS_NOT,
self::OPER_EQUAL,
self::OPER_EQUAL_NOT,
self::OPER_SMALLER,
self::OPER_SMALLER_OR_EQUAL,
self::OPER_GREATER,
self::OPER_GREATER_OR_EQUAL
),
'network_address' => array
(
self::OPER_IS,
self::OPER_IS_NOT,
self::OPER_CONTAINS,
self::OPER_CONTAINS_NOT,
self::OPER_NETWORK_IS_IN,
self::OPER_NETWORK_IS_NOT_IN
)
);
/**
* Array with definition of minlengths of types
* @var array
*/
protected $minlengths = array
(
'combo' => 0,
'select' => 0,
'text' => 1,
'bit' => 0,
'date' => 1,
'select_number' => 0,
'network_address' => 1
);
/**
* Array with definition of return type of type (key or value)
* @var array
*/
protected $returns = array
(
'combo' => 'value',
'select' => 'key',
'text' => 'value',
'bit' => 'key',
'number' => 'value',
'date' => 'value',
'select_number' => 'key',
'network_address' => 'value'
);
/**
* Boolean value whether it is first load of filters (#442)
* @var boolean
*/
protected $first_load = FALSE;
/**
* Constructor, sets table name and compiles values from $_GET
*
* @author Michal Kliment
* @param string $table
*/
public function __construct($table = '', $base_url = '')
{
$this->table = $table;
$this->base_url = ($base_url != '') ? $base_url : url_lang::current(2);
$this->template = new View ($this->template);
$this->types = array();
$this->operations = array();
$this->values = array();
// create query model
$this->query_model = new Filter_query_Model();
// loads all queries belongs to current url
$this->queries = $this->query_model->get_all_queries_by_url($this->base_url);
foreach ($this->queries as $query)
{
// find default query
if ($query->default)
$this->default_query_id = $query->id;
}
$query = Input::instance()->get('query');
// load query from database (because of #895 can be from different URL)
if ($query && is_numeric($query))
{
$loaded_query = new Filter_query_Model($query);
if ($loaded_query && $loaded_query->id) {
$data = json_decode($loaded_query->values, TRUE);
$on = @$data["on"];
$types = @$data["types"];
$operations = @$data["opers"];
$values = @$data["values"];
$tables = @$data["tables"];
$this->loaded_from_saved_query = TRUE;
}
else
{
$on = $types = $operations = $values = $tables = NULL;
status::warning('Invalid saved query');
}
$this->first_load = FALSE;
}
// load query from URL
else
{
$on = Input::instance()->get('on');
$types = Input::instance()->get('types');
$operations = Input::instance()->get('opers');
$values = Input::instance()->get('values');
$tables = Input::instance()->get('tables');
$this->can_add = TRUE;
$this->loaded_from_saved_query = FALSE;
$this->first_load = FALSE;
}
$this->keys = Input::instance()->get('keys');
$this->vals = Input::instance()->get('vals');
// query is empty, use default from database
if (!$on && !$types && !$operations && !$values && !$tables && $this->default_query_id)
{
$data = json_decode($this->queries[$this->default_query_id]->values, TRUE);
$on = @$data["on"];
$types = @$data["types"];
$operations = @$data["opers"];
$values = @$data["values"];
$tables = @$data["tables"];
$this->can_add = FALSE;
$this->loaded_from_saved_query = TRUE;
$this->loaded_from_default_saved_query = TRUE;
$this->first_load = TRUE;
}
// load data
if (count($values))
{
$this->tables = $tables;
$offset = 0;
for ($i=0;$i<=max(array_keys($values));$i++)
{
if (isset($on[$i]) && is_array($values[$i]))
{
$this->states[$i-$offset] = $on[$i];
$this->values[$i-$offset] = array_map("trim", $values[$i]);
$this->types[$i-$offset] = $types[$i];
$this->operations[$i-$offset] = $operations[$i];
}
else
$offset++;
}
}
else
{
$this->can_add = FALSE;
$this->first_load = TRUE;
}
}
/**
* Automatic loads filters from $_GET
*
* @author Michal Kliment
* @return int
*/
public function autoload()
{
$loaded = 0;
foreach ($this->types as $i => $type)
{
$loaded++;
$filter = new Filter($type, isset($this->tables[$type]) ? $this->tables[$type] : '');
if (isset($this->keys[$filter->name]))
{
$this->values[$i] = $this->keys[$filter->name][array_search($this->values[$i], $this->vals[$filter->name])];
}
$this->filters[$type] = $filter;
}
return $loaded;
}
/**
* Adds new filter to filter form
*
* @author Michal Kliment
* @param string $name
* @return Filter object
*/
public function add($name, $table = NULL)
{
if (!$table)
{
$table = $this->table;
}
else
{
$name .= '/'.$table;
}
$filter = new Filter($name, $table);
$this->filters[$name] = $filter;
return $filter;
}
/**
* Loads default filter's values
*
* @author Michal Kliment
* @return int
*/
private function load_default()
{
if (!count ($this->values))
{
foreach ($this->filters as $filter)
{
foreach ($filter->default as $default)
{
$this->states[] = TRUE;
$this->values[] = (is_array($default['value'])) ? $default['value'] : array($default['value']);
$this->types[] = $filter->name;
$this->operations[] = $default['oper'];
$this->default[] = 1;
$this->default_count++;
}
}
}
return $this->default_count;
}
/**
* Renders filter form as HTML
*
* @author Michal Kliment
* @return string
*/
public function html()
{
// load default filter's values
$this->load_default();
$types = $this->types;
$type_options = array();
$states = $this->states;
$operations = $this->operations;
$operation_options = array();
$values = $this->values;
$tables = $this->tables;
$default = $this->default;
$keys = array();
$js_data = array();
// iterate all filters
foreach ($this->filters as $filter)
{
$type_options[$filter->name] = $filter->label;
$tables[$filter->name] = $filter->table;
// save data for javascript
$js_data[$filter->name]["returns"] = $this->returns[$filter->type];
if ($filter->values)
{
foreach ($filter->values as $key => $value)
$js_data[$filter->name]["values"][$key] = $value;
}
else
$js_data[$filter->name]["values"] = '';
foreach ($this->operation_types[$filter->type] as $operation_type)
$js_data[$filter->name]["operations"][$operation_type] = __($this->opers[$operation_type]['name']);
$js_data[$filter->name]["callback"] = $filter->callback;
$js_data[$filter->name]["classes"] = (is_array($filter->class)) ? $filter->class : array('all' => $filter->class);
$js_data[$filter->name]["css_classes"] = $filter->css_class;
}
foreach ($this->opers as $i => $operation)
$operation_options[$i] = __($operation['name']);
// add one extra empty filter
$types[] = NULL;
$states[] = 0;
$operations[] = NULL;
$values[] = NULL;
$default[] = NULL;
$this->template->base_url = $this->base_url;
$this->template->types = $types;
$this->template->type_options = $type_options;
$this->template->states = $states;
$this->template->operations = $operations;
$this->template->operation_options = $operation_options;
$this->template->values = $values;
$this->template->tables = $tables;
$this->template->default = $default;
$this->template->keys = $keys;
$this->template->classes = $filter->css_class;
$this->template->js_data = $js_data;
$this->template->queries = $this->queries;
$this->template->can_add = $this->can_add;
return $this->template->render();
}
/**
* Returns SQL query (only part after WHERE) to use in model methods
*
* @param mixed $approved_keys Array which defined columns which should be used in query.
* @author Michal Kliment
* @return string
*/
public function as_sql ($approved_keys = FALSE)
{
// loads default filter's values
$this->load_default();
$offset = 0;
$queries = array();
foreach ($this->types as $i => $type)
{
if (is_array($approved_keys) && !in_array($type, $approved_keys))
{ // not allowed => continue
continue;
}
if (!array_key_exists($type, $this->filters))
{
throw new InvalidArgumentException('Invalid option: ' . $type);
}
$filter = $this->filters[$type];
$sub_queries = array();
$values = array();
if ($this->returns[$filter->type] == 'key')
{
foreach ($this->values[$i] as $value)
{
$values[] = $value;
if (isset($filter->values[$value]))
$values[] = $filter->values[$value];
}
}
else
$values = $this->values[$i];
$notquery = false;
foreach ($values as $value)
{
if (!isset($this->opers[$this->operations[$i]]))
continue;
$sql = $this->opers[$this->operations[$i]]['sql'];
if (strpos($this->opers[$this->operations[$i]]['name'], 'not'))
$notquery = true;
if (isset($this->opers[$this->operations[$i]]['pattern']))
{
if (!preg_match(
$this->opers[$this->operations[$i]]['pattern'],
Database::instance()->escape_str($value), $matches
))
{
continue;
}
foreach ($matches as $key => $value)
$sql = str_replace('{'.$key.'}', Database::instance()->escape_str($value), $sql);
}
$table_pom = mb_strlen($filter->table) ? $filter->table . '.' : '';
$name_pom = (strpos($filter->name, '/') == FALSE ? $filter->name : substr($filter->name, 0, strpos($filter->name, '/')));
$column = Database::instance()->escape_column(Database::instance()->escape_str($table_pom . $name_pom));
if (isset($this->opers[$this->operations[$i]]['function']))
$query = $this->opers[$this->operations[$i]]['function']. "($column)";
else
$query = $column;
$query .= " ". str_replace("{VALUE}", Database::instance()->escape_str($value), $sql);
$sub_queries[] = $query;
}
if ($notquery)
$operator = 'AND';
else
$operator = 'OR';
$queries[] = "(".implode(" $operator ", $sub_queries).")";
}
return implode(" AND ", $queries);
}
/**
*
* @return array
*/
public function as_array()
{
// loads default filter's values
$this->load_default();
$data = array();
foreach ($this->types as $i => $type)
{
$filter = $this->filters[$type];
$value = array_map('trim', $this->values[$i]);
if ($this->returns[$filter->type] == 'key' &&
arr::search($value, $filter->values) !== FALSE)
{
$value = arr::search($value, $filter->values);
}
$data[] = array
(
'key' => $filter->name,
'value' => $value,
'op' => $this->operations[$i]
);
}
return $data;
}
/**
* Indicates whether the filter form configuration was loaded from database.
*
* @return boolean
*/
public function is_loaded_from_saved_query()
{
return $this->loaded_from_saved_query;
}
/**
* Indicates whether the filter form configuration that was loaded from
* database is default.
*
* @return boolean
*/
public function is_loaded_from_default_saved_query()
{
return $this->loaded_from_default_saved_query;
}
/**
* Indicates whether it is first load
*
* @return boolean
*/
public function is_first_load()
{
return $this->first_load;
}
/**
* Returns base URL of the filter form.
*
* @return string URL
*/
public function get_base_url()
{
return $this->base_url;
}
/**
* Prints filter form as HTML
*
* @author Michal Kliment
* @return string
*/
public function __toString()
{
return $this->html();
}
}
freenetis/branches/modularity/application/libraries/MY_Controller.php
<?php defined('SYSPATH') or die('No direct script access.');
/*
* This file is part of open source system FreenetIS
* and it is released under GPLv3 licence.
*
* More info about licence can be found:
* http://www.gnu.org/licenses/gpl-3.0.html
*
* More info about project can be found:
* http://www.freenetis.org/
*
*/
// numbers of errors
define('ACCESS', 1);
define('EMAIL', 2);
define('DATABASE', 3);
define('DATABASE_DOWNGRATE', 9);
define('DATABASE_OLD_MECHANISM', 10);
define('DATABASE_UPGRADE_NOT_ENABLED', 11);
define('RECORD', 4);
define('PAGE', 5);
define('WRITABLE', 7);
define('READONLY', 8);
// numbers of warnings, their identifier numbers have to differ from error messages
// for example when programmer misleads error and warning
define('PARAMETER', 1001);
/**
* Main controller creates menu, handles changes in svn repository (database upgrade), ...
*
* BE CAREFUL HERE, CATCH EVERY EXCEPTION, OTHERWISE FREENETIS
* WITH JUST SMALL ERROR BECOMES COMPLETELY UNUSABLE
*/
class Controller extends Controller_Core
{
/** @var integer */
const ICON_ERROR = 1;
/** @var integer */
const ICON_GOOD = 2;
/** @var integer */
const ICON_HELP = 3;
/** @var integer */
const ICON_INFO = 4;
/** @var integer */
const ICON_WARNING = 5;
/**
* Controller singleton
*
* @var Controller
*/
private static $instance;
/**
* Paths for which login is not required
*
* @var array
*/
private static $login_not_required = array
(
/* login, scheduler, instalation */
'login',
'forgotten_password',
'scheduler/run',
'installation',
'setup_config',
'setup_config/htaccess',
'setup_config/setup',
'redirect/logo',
/* registration */
'registration',
'registration/complete',
'js/registration',
'json/get_streets_by_town',
'json/get_address',
'address_points/get_gps_by_address',
'address_points/get_gps_by_address_string',
);
/** @var unknown_type */
public $arr;
/** @var Setting_Model Settings */
public $settings = NULL;
/** @var integer */
public $popup = 0;
/** @var integer */
public $dialog = 0;
/** @var boolean */
public $noredirect = FALSE;
/** @var boolean */
public $user_has_voip = 0;
/** @var string */
public $ip_address_span = '';
/** @var integer */
public $unread_user_mails = 0;
/** @var integer */
public $count_of_unclosed_logged_errors = 0;
/** @var integer */
public $devices_down_count = 0;
/** @var Database_Result */
public $user_favourites_pages = NULL;
/** @var boolean $axo_doc_access Enable access to AXO doc */
public $axo_doc_access = FALSE;
/** @var integer $member_id ID of logged member */
protected $member_id;
/** @var integer $user_id ID of logged user */
protected $user_id;
/** @var integer $account_id ID of logged member account */
protected $member_account_id = 1;
/** @var Session */
protected $session;
/** @var $groups_aro_map Groups_aro_map_Model */
private $groups_aro_map;
/**
* Contruct of controller, creates singleton or return it
*/
public function __construct()
{
parent::__construct();
// This part only needs to be run once
if (self::$instance === NULL)
{
// init sessions
$this->session = Session::instance();
// store user ID from session
$this->user_id = $this->session->get('user_id', 0);
// store member ID from session
$this->member_id = $this->session->get('member_id', 0);
// test if visitor is logged in, or he accesses public
// controllers like registration, redirect, installation, etc.
if (!in_array(url_lang::current(), self::$login_not_required) &&
url_lang::current(1) != 'web_interface' &&
url_lang::current(2) != 'devices/export' &&
!$this->user_id)
{
// Not logged in - redirect to login page
$this->session->set_flash('err_message', __('Must be logged in'));
// Do not logout after login
if (url_lang::current(1) != 'login' &&
url_lang::current(1) != 'js')
{
$this->session->set('referer', url_lang::current());
}
else
{
$this->session->set('referer', '');
}
// Redirect to login
url::redirect('login');
// Die
die();
}
// init settings
$this->settings = new Settings();
// if true, freenetis will run in popup mode (without header and menu)
$this->popup = (isset($_GET['popup']) && $_GET['popup']) ? 1 : 0;
// if true, freenetis will run in text mod for dialog
$this->dialog = (isset($_GET['dialog']) && $_GET['dialog']) ? 1 : 0;
// if true, method redirect will not redirect
$this->noredirect = ($this->input->get('noredirect') || $this->input->post('noredirect'));
// config file doesn't exist, we must create it
if (!file_exists('config.php') || !file_exists('.htaccess'))
{
// protection before loop
if (url_lang::current(1) == 'setup_config')
return;
if (!file_exists('.htaccess'))
{
Settings::set('index_page', 1);
}
url::redirect('setup_config');
}
// protection before loop
if (url_lang::current(1) == 'installation')
{
return;
}
// test database connection
if (!db::test())
{
Controller::error(DATABASE);
}
// db schema version is null => we must run install
if (!Version::get_db_version())
{
url::redirect('installation');
}
// db schema is not up to date => we must run upgrade
else if (!Version::is_db_up_to_date())
{
// change database encoding if incorect
try
{
$db = Database::instance();
/**
* @todo in the future the collate should be used according
* to language system settings
*/
if ($db->get_variable_value('character_set_database') != 'utf8' ||
$db->get_variable_value('collation_database') != 'utf8_czech_ci')
{
$db->alter_db_character_set(
Config::get('db_name'), 'utf8', 'utf8_czech_ci'
);
}
}
catch (Exception $e)
{
Log::add_exception($e);
$m = __('Cannot set database character set to UTF8');
self::showbox($m, self::ICON_ERROR);
}
// try to open mutex file
if (($f = @fopen(server::base_dir().'/upload/mutex', 'w')) === FALSE)
{
// directory is not writeable
self::error(WRITABLE, server::base_dir().'/upload/');
}
// acquire an exclusive access to file
// wait while database is being updated
if (flock($f, LOCK_EX))
{
// first access - update db
// other access - skip
if (!Version::is_db_up_to_date())
{
try
{
Version::make_db_up_to_date();
}
catch (Not_Enabled_Upgrade_Exception $neu)
{
self::error(DATABASE_UPGRADE_NOT_ENABLED, $neu->getMessage());
}
catch (Old_Mechanism_Exception $ome)
{
self::error(DATABASE_OLD_MECHANISM);
}
catch (Database_Downgrate_Exception $dde)
{
self::error(DATABASE_DOWNGRATE);
}
catch (Exception $e)
{
throw new Exception(
__('Database upgrade failed') . ': ' .
$e->getMessage(), 0, $e
);
}
}
// unlock mutex file
flock($f, LOCK_UN);
}
// close mutex file
fclose($f);
}
// load these variables only if preprocessor is enabled and user is logged
if ($this->is_preprocesor_enabled() && $this->user_id)
{
// for preprocessing some variable
try
{
$this->preprocessor();
}
catch(Exception $e)
{
Log::add_exception($e);
}
}
// Singleton instance
self::$instance = $this;
}
}
/**
* Singleton instance of Controller.
*
* @author Michal Kliment
* @return Controller object
*/
public static function & instance()
{
// Create the instance if it does not exist
empty(self::$instance) and new Controller;
return self::$instance;
}
/**
* Function shows error of given message number.
*
* @param integer $message_type
* @param string $content
*/
public static function error($message_type, $content = NULL)
{
$response_code = NULL;
$fatal = FALSE;
switch ($message_type)
{
case ACCESS:
$message = url_lang::lang('states.Access denied');
$response_code = 403; // Forbidden
break;
case EMAIL:
$message = url_lang::lang('states.Failed to send e-mail') .
'<br />' . url_lang::lang('states.Please check settings.');
$response_code = 500; // Internal server error
break;
case DATABASE:
$message = url_lang::lang('states.Failed to connect to database') .
'<br />' . url_lang::lang('states.Please check settings.');
$response_code = 500; // Internal server error
$fatal = TRUE;
break;
case DATABASE_DOWNGRATE:
$message = url_lang::lang('states.Failed to update database') .
'<br />' . url_lang::lang('states.Downgrade not allowed.');
$response_code = 500; // Internal server error
$fatal = TRUE;
break;
case DATABASE_OLD_MECHANISM:
$message = url_lang::lang('states.Failed to update database') .
'<br /><br /><span style="font-size:12px">' .
url_lang::lang('help.old_upgrade_system') . '</span>';
$response_code = 500; // Internal server error
$fatal = TRUE;
break;
case DATABASE_UPGRADE_NOT_ENABLED:
$message = url_lang::lang('states.Failed to update database');
$response_code = 500; // Internal server error
$fatal = TRUE;
break;
case RECORD:
$message = url_lang::lang('states.This record does not exist');
$response_code = 404; // Not found
break;
case PAGE:
$message = url_lang::lang('states.Page not found');
$response_code = 404; // Not found
break;
case WRITABLE:
$message = url_lang::lang('states.Directory or file is not writable.');
$response_code = 500; // Internal server error
break;
case READONLY:
$message = url_lang::lang('states.Item is read only.');
$response_code = 403; // Internal server error
break;
default:
$message = url_lang::lang('states.Unknown error message');
$response_code = 500; // Internal server error
break;
}
self::showbox($message, self::ICON_ERROR, $content, $response_code, $fatal);
}
/**
* Function shows warning of given message number.
*
* @param integer $message_type
* @param string $content
*/
public static function warning($message_type, $content = NULL)
{
$response_code = NULL;
switch ($message_type)
{
case PARAMETER:
$message = url_lang::lang('states.Parameter required');
$response_code = 404; // Internal server error
break;
default:
$message = url_lang::lang('states.Unknown warning message');
$response_code = 500; // Internal server error
break;
}
self::showbox($message, self::ICON_WARNING, $content, $response_code);
}
/**
* Function renders error and warning messages.
*
* @param string $message Message to display
* @param integer $type Type of message (error, info, warning, etc.)
* @param string $content Some message that describe message in more detail way
* @param string $http_response_code Send some response code (xxx)
* @param boolean $fatal_error Is this error a fatal error?
*/
private static function showbox($message, $type, $content = NULL,
$http_response_code = NULL, $fatal_error = FALSE)
{
if ($fatal_error)
{
$view = new View('main_statesbox');
}
else
{
$view = new View('main');
}
$view->content = new View('statesbox');
$src = NULL;
switch ($type)
{
case self::ICON_ERROR:
$view->title = __('Error');
$src = 'media/images/states/error.png';
break;
case self::ICON_GOOD:
$view->title = __('Good');
$src = 'media/images/states/good.png';
break;
case self::ICON_HELP:
$view->title = __('Help');
$src = 'media/images/states/help.png';
break;
case self::ICON_INFO:
$view->title = __('Info');
$src = 'media/images/states/info.png';
break;
case self::ICON_WARNING:
$view->title = __('Warning');
$src = 'media/images/states/warning.png';
break;
}
if ($http_response_code)
{
header("HTTP/1.1 $http_response_code");
}
$view->content->icon = html::image(array
(
'src' => $src,
'width' => '100',
'height' => '100',
'alt' => 'Image',
'class' => 'noborder'
));
$view->content->message = $message;
if (isset($content))
{
$view->content->content = $content;
}
$view->loading_hide = TRUE;
$view->render(TRUE);
// must be die() - else it will be render twice !
die();
}
/**
* Checks user's access to system
*
* @author Ondřej Fibich
*
* @param type $axo_section_value AXO section value - Controller name
* @param type $axo_value AXO value - part of Controller
* @param type $aco_type ACO type of action (view, new, edit, delete, confirm)
* @param integer $member_id Member to check access
* @param boolean $force_own Force to use own rules for not logged user
* Used at: Phone_invoices_Controller#user_field()
* @return bool
*/
private function acl_check(
$axo_section, $axo_value, $aco_type, $member_id = NULL,
$force_own = FALSE)
{
// groups aro map loaded?
if (empty($this->groups_aro_map))
{
$this->groups_aro_map = new Groups_aro_map_Model();
}
// check own?
if (($member_id == $_SESSION['member_id']) || $force_own)
{
// check own access
if ($this->groups_aro_map->has_access(
$_SESSION['user_id'], $aco_type . '_own',
$axo_section, $axo_value
))
{
// access valid
return true;
}
}
// check all
return $this->groups_aro_map->has_access(
$_SESSION['user_id'], $aco_type . '_all',
$axo_section, $axo_value
);
}
/**
* Checks if user is in ARO group
*
* @author Ondřej Fibich
* @param integer $group_id ARO group ID
* @param integer $aro_id User ID
* @return boolean true if exists false otherwise
*/
public function is_user_in_group($aro_group_id, $aro_id)
{
return $this->groups_aro_map->groups_aro_map_exists($aro_group_id, $aro_id);
}
/**
* Fuction checks access rights
* Return true if currently logged user (stored in $_SESSION['user_id'])
* may view own $axo_value object in $axo_section
* (and in variable $member_id is his own id of member) or if currently logged user
* may view all $axo_value object in $axo_section else return false
*
* @param $axo_section Group of objects to view
* @param $axo_value Object to view
* @param $member_id Optional variable, id of other member
* who is being showed by logged member
* @param boolean $force_own Force to use own rules for not logged user
* Used at: Phone_invoices_Controller#user_field()
* @return boolean returns true if member has enough access rights
*/
public function acl_check_view(
$axo_section, $axo_value, $member_id = NULL, $force_own = FALSE)
{
return $this->acl_check(
$axo_section, $axo_value, 'view', $member_id, $force_own
);
}
/**
* Fuction checks access rights
* Return true if currently logged user (stored in $_SESSION['user_id'])
* may view own $axo_value object in $axo_section
* (and in variable $member_id is his own id of member) or if currently logged user
* may edit all $axo_value object in $axo_section else return false
*
* @param $axo_section Group of objects to edit
* @param $axo_value Object to edit
* @param $member_id Optional variable, id of other member
* who is being showed by logged member
* @param boolean $force_own Force to use own rules for not logged user
* Used at: Phone_invoices_Controller#user_field()
* @return boolean Returns true if member has enough access rights
*/
public function acl_check_edit(
$axo_section, $axo_value, $member_id = NULL, $force_own = FALSE)
{
return $this->acl_check(
$axo_section, $axo_value, 'edit', $member_id, $force_own
);
}
/**
* Fuction checks access rights
* Return true if currently logged user (stored in $_SESSION['user_id'])
* may view own $axo_value object in $axo_section
* (and in variable $member_id is his own id of member) or if currently logged user
* may add all $axo_value object in $axo_section else return false
*
* @param $axo_section Group of objects to edit
* @param $axo_value Object to add
* @param $member_id Optional variable, id of other member
* who is being showed by logged member
* @param boolean $force_own Force to use own rules for not logged user
* Used at: Phone_invoices_Controller#user_field()
* @return boolean Returns true if member has enough access rights
*/
public function acl_check_new(
$axo_section, $axo_value, $member_id = NULL, $force_own = FALSE)
{
return $this->acl_check(
$axo_section, $axo_value, 'new', $member_id, $force_own
);
}
/**
* Fuction checks access rights
* Return true if currently logged user (stored in $_SESSION['user_id'])
* may view own $axo_value object in $axo_section
* (and in variable $member_id is his own id of member) or if currently logged user
* may delete all $axo_value object in $axo_section else return false
*
* @param $axo_section Group of objects to edit
* @param $axo_value Object to delete
* @param $member_id Optional variable, id of other member
* who is being showed by logged member
* @param boolean $force_own Force to use own rules for not logged user
* Used at: Phone_invoices_Controller#user_field()
* @return boolean Returns true if member has enough access rights
*/
public function acl_check_delete(
$axo_section, $axo_value, $member_id = NULL, $force_own = FALSE)
{
return $this->acl_check(
$axo_section, $axo_value, 'delete', $member_id, $force_own
);
}
/**
* This methods defines whether the preprocessor of MY_Controller is loaded
* or not. By default preprocessor is loaded, for changing of this state
* this method should be overriden in child class. (#328)
*
* @author Ondřej Fibich
* @return boolean Is preprocessor loaded?
*/
protected function is_preprocesor_enabled()
{
return TRUE;
}
/**
* Function to preprocessing of some useful variables
*
* @author Michal Kliment
*/
private function preprocessor()
{
// helper class
$pm = new Preprocessor_Model();
$ra_ip = server::remote_addr();
// boolean variable if user has active voip number (for menu rendering)
$this->user_has_voip = (bool) $pm->has_voip_sips($this->user_id);
// count of unread mail messages of user
$this->unread_user_mails = $pm->count_all_unread_inbox_messages_by_user_id($this->user_id);
// is this page favourite
$this->is_favourite = $pm->is_users_favourite($this->user_id, url_lang::current());
// gets account id of memeber (do not use Member_Model::ASSOCIATION here!)
if ($this->acl_check_view('Accounts_Controller', 'transfers', $this->member_id) &&
$this->member_id != 1)
{
$this->member_account_id = $pm->get_first_member_account_id($this->member_id);
}
// ip address span
$this->ip_address_span = $ra_ip;
// DZOLO (2011-09-05)
// This function is wery slow, when internet connection is off.
/*if (($ptr_record = dns::get_ptr_record($this->ip_address_span)) != '')
{
$this->ip_address_span .= ' <i>(' . $ptr_record . ')</i>';
}*/
// allowed subnets are enabled
if (Settings::get('allowed_subnets_enabled') && $this->member_id &&
$this->acl_check_edit(
'Allowed_subnets_Controller', 'allowed_subnet', $this->member_id
))
{
// toggle button between allowed subnets
$as = $pm->get_allowed_subnet_by_member_and_ip_address(
... Rozdílový soubor je zkrácen, protože jeho délka přesahuje max. limit.

Také k dispozici: Unified diff